jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Julian Reschke (Commented) (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (JCR-3006) UserManager: concurrent user creation using same intermediate path fails
Date Wed, 28 Sep 2011 11:45:46 GMT

    [ https://issues.apache.org/jira/browse/JCR-3006?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13116354#comment-13116354
] 

Julian Reschke commented on JCR-3006:
-------------------------------------

For archival purposes, here's an attempt of doing 3) for createUser():

    /**
     * @see UserManager#createUser(String, String, java.security.Principal, String)
     */
    public User createUser(String userID, String password,
                           Principal principal, String intermediatePath)
            throws AuthorizableExistsException, RepositoryException {
        checkValidID(userID);
        if (password == null) {
            throw new IllegalArgumentException("Cannot create user: null password.");
        }
        // NOTE: principal validation during setPrincipal call.
        
        int tryCount = isAutoSave() ? 3 : 1;
        User user = null;
        NodeImpl userNode = null;
        
        while (tryCount > 0 && user == null) {
            tryCount -= 1;
            
            try {
                userNode = (NodeImpl) nodeCreator.createUserNode(userID, intermediatePath);
                setPrincipal(userNode, principal);
                setProperty(userNode, P_PASSWORD, getValue(UserImpl.buildPasswordValue(password)),
true);

                user = createUser(userNode);
                if (isAutoSave()) {
                    session.save();
                }
            } catch (RepositoryException e) {
                // something went wrong
                user = null;
                // revert changes
                session.refresh(false);

                if (e instanceof InvalidItemStateException && tryCount != 0) {
                    // try again
                    log.debug("Failed to create new User, retrying.");
                } else {
                    // re-throw
                    log.debug("Failed to create new User, reverting changes.");
                    throw e;
                }
            }
        }

        assert user != null;
        
        log.debug("User created: " + userID + "; " + userNode.getPath());
        return user;
    }

Note that this doesn't help for the non-autosave case (and would need to be extended to createGroup())
                
> UserManager: concurrent user creation using same intermediate path fails
> ------------------------------------------------------------------------
>
>                 Key: JCR-3006
>                 URL: https://issues.apache.org/jira/browse/JCR-3006
>             Project: Jackrabbit Content Repository
>          Issue Type: Bug
>          Components: security
>    Affects Versions: 2.2.7
>            Reporter: Stefan Guggisberg
>         Attachments: ConcurrentCreateUserTest.java, ConcurrentCreateUserTest.java, ConcurrentCreateUserTest.java,
JCR-3006.patch
>
>
> concurrently creating users using same intermediate path fails with "node ... has been
modified externally".
> the problem is the intermediate path. if it doesn't exist multiple threads try to create
it concurrently: 
> o.a.jackrabbit.core.security.user.UserManagerImpl, line 1310ff:
>             String[] segmts = defaultPath.split("/");
>             NodeImpl folder = (NodeImpl) session.getRootNode();
>             String authRoot = (isGroup) ? groupsPath : usersPath;
>             for (String segment : segmts) {
>                 if (segment.length() < 1) {
>                     continue;
>                 }
>                 if (folder.hasNode(segment)) {
>                     folder = (NodeImpl) folder.getNode(segment);
>                     if (Text.isDescendantOrEqual(authRoot, folder.getPath()) &&
>                             !folder.isNodeType(NT_REP_AUTHORIZABLE_FOLDER)) {
>                         throw new ConstraintViolationException("Invalid intermediate
path. Must be of type rep:AuthorizableFolder.");
>                     }
>                 } else {
>                     Node parent = folder;
>                     folder = addNode(folder, session.getQName(segment), NT_REP_AUTHORIZABLE_FOLDER);
>                 }
>             }
> the attached test case illustrates this issue/

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message