OAK-12190 Add createUserWithAbsolutePath and createGroupWithAbsolutePath to UserManager API#2868
OAK-12190 Add createUserWithAbsolutePath and createGroupWithAbsolutePath to UserManager API#2868nscendoni wants to merge 12 commits into
Conversation
…olutePath Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
anchela
left a comment
There was a problem hiding this comment.
first bunch of comments..... will take another look later today
| default User createUserWithAbsolutePath(@NotNull String userID, @Nullable String password, | ||
| @NotNull Principal principal, @NotNull String absoluteOakPath) | ||
| throws AuthorizableExistsException, UnsupportedRepositoryOperationException, RepositoryException { | ||
| throw new UnsupportedRepositoryOperationException("createUserWithAbsolutePath is not supported by this implementation"); |
There was a problem hiding this comment.
ideally we would have a default implementation that avoids having to touch the old jackrabbit code.
| */ | ||
| @NotNull | ||
| default Group createGroupWithAbsolutePath(@NotNull String groupID, @NotNull Principal principal, | ||
| @NotNull String oakPath) |
There was a problem hiding this comment.
see above it should be 'absolutePath' and the description should make it clear that this is a JCR path not an oak path.
naming should be consistent with the user method.
| default Group createGroupWithAbsolutePath(@NotNull String groupID, @NotNull Principal principal, | ||
| @NotNull String oakPath) | ||
| throws AuthorizableExistsException, UnsupportedRepositoryOperationException, RepositoryException { | ||
| throw new UnsupportedRepositoryOperationException("createGroupWithAbsolutePath is not supported by this implementation"); |
There was a problem hiding this comment.
see above. ideally we have a default implementation
| @NotNull | ||
| @Override | ||
| public User createUserWithAbsolutePath(@NotNull final String userID, @Nullable final String password, | ||
| @NotNull final Principal principal, @NotNull final String absoluteOakPath) |
| @NotNull | ||
| @Override | ||
| public Group createGroupWithAbsolutePath(@NotNull final String groupID, @NotNull final Principal principal, | ||
| @NotNull final String oakPath) |
| Group createGroup(@NotNull String groupID, @NotNull Principal principal, @Nullable String intermediatePath) throws AuthorizableExistsException, RepositoryException; | ||
|
|
||
| /** | ||
| * Creates a new {@code Group} at the specified absolute Oak repository path. |
There was a problem hiding this comment.
the javadoc should describe what happens in the following cases:
- the path collides with an existing node
- the last segment (name) violates the contract of the configured authorizableNodeName
…ide default implementations, and convert to Oak path in UserManagerImpl
anchela
left a comment
There was a problem hiding this comment.
found new stuff.... UserProvider.createX would add an additional segment for the node name
also: do you want to offer this method also for service-users? they come with a separate create method.
| checkValidPrincipal(principal, false); | ||
|
|
||
| String oakPath = namePathMapper.getOakPath(absolutePath); | ||
| if (oakPath == null) { |
There was a problem hiding this comment.
i would move those duplicate lines from here and the group method into a private method getOakPath
| if (oakPath == null) { | ||
| throw new RepositoryException("Invalid path: " + absolutePath); | ||
| } | ||
| Tree userTree = userProvider.createUser(userID, oakPath); |
There was a problem hiding this comment.
the userProvider.createUser call will add an additional element for the user node.
this will not result in the absolute path being uses as it....
| throw new RepositoryException("Invalid path: " + absolutePath); | ||
| } | ||
| Tree userTree = userProvider.createUser(userID, oakPath); | ||
| setPrincipal(userTree, principal); |
There was a problem hiding this comment.
lines 267-276 will be duplicated from the regular create user call, no?
please refactor to avoid duplciation
| checkValidPrincipal(principal, true); | ||
|
|
||
| String oakPath = namePathMapper.getOakPath(absolutePath); | ||
| if (oakPath == null) { |
| if (oakPath == null) { | ||
| throw new RepositoryException("Invalid path: " + absolutePath); | ||
| } | ||
| Tree groupTree = userProvider.createGroup(groupID, oakPath); |
There was a problem hiding this comment.
same as above... this will not use the absolute path as it is but will add a node-name segment generated with the available authorizablenodename implentation.
…User/GroupWithAbsolutePath
…ser/buildGroup helpers; add unit tests
anchela
left a comment
There was a problem hiding this comment.
just minor nitpicking left. the rest all looks good now.
@nscendoni let me know what you think about my comments.
| tree = tree.getParent(); | ||
| } | ||
| if (!tree.exists()) { | ||
| throw new AccessDeniedException("Missing permission to create intermediate authorizable folders."); |
There was a problem hiding this comment.
the exception message may be a bit misleading. it's actually that read permission is lacking to read an existing parent path, no? ((note: i am seeing this now but i may be consistent with the existing code)). maybe still worth doing better here: "Unable to retrieve authorizable parent folder" (or something like that)
| * If a node already exists at the resolved location, the implementation may | ||
| * append a numeric suffix to the node name to avoid the collision. | ||
| * <p> | ||
| * If the last segment of the resolved node name violates the contract of the |
There was a problem hiding this comment.
the current implementation does not do that. so, i would recommend to state "an ConstraintViolationException may be thrown".
or if we want to keep that as a mandate then the impl should verify... but there is currently no API in AuthorizableNodeName to verify a given name... this would need to be added.
either way fine with me.
| default Group createGroupWithAbsolutePath(@NotNull String groupID, @NotNull Principal principal, | ||
| @NotNull String absolutePath) | ||
| throws AuthorizableExistsException, UnsupportedRepositoryOperationException, RepositoryException { | ||
| return createGroup(groupID, principal, absolutePath); |
There was a problem hiding this comment.
calling the method that takes an intermediate path will not yield the desired result, no? maybe throwing "unsupportedrepositoryoperationexception" would be more aligned with the api contract. wdyt?
| * the group node must be created. The path must start with {@code /} and must | ||
| * be within the configured group root. | ||
| * <p> | ||
| * If a node already exists at the resolved location, the implementation may |
There was a problem hiding this comment.
i am not 100% convinced about this option to add a suffix. this reads like a contradiction to the mandate that the resulting group node has indeed the specified path. wdyt?
| default User createUserWithAbsolutePath(@NotNull String userID, @Nullable String password, | ||
| @NotNull Principal principal, @NotNull String absolutePath) | ||
| throws AuthorizableExistsException, UnsupportedRepositoryOperationException, RepositoryException { | ||
| return createUser(userID, password, principal, absolutePath); |
There was a problem hiding this comment.
see comment with createGroupWithAbsolute path below. same here
Verify that absolute JCR paths supplied to the two new methods are properly converted from the session-local namespace mapping to the internal Oak path representation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Ai-Assisted-By: claude
anchela
left a comment
There was a problem hiding this comment.
@nscendoni the changes look good to me now. in addition i asked claude to create test cases for renamed namespaces -> additions to RemappingTest.java.
@Amoratinos do you want to take a look as well before we merge?
OAK-12190: Add remapping tests for createUser/GroupWithAbsolutePath
No description provided.