You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2012/10/09 11:30:22 UTC

svn commit: r1395932 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: security/authentication/ security/authentication/token/ security/user/ spi/security/user/

Author: angela
Date: Tue Oct  9 09:30:21 2012
New Revision: 1395932

URL: http://svn.apache.org/viewvc?rev=1395932&view=rev
Log:
 OAK-91 - Implement Authentication Support (WIP)
 OAK-50 - User Management (WIP)

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java?rev=1395932&r1=1395931&r2=1395932&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/AuthenticationImpl.java Tue Oct  9 09:30:21 2012
@@ -17,10 +17,16 @@
 package org.apache.jackrabbit.oak.security.authentication;
 
 import javax.jcr.Credentials;
+import javax.jcr.GuestCredentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.SimpleCredentials;
 import javax.security.auth.Subject;
 
+import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.spi.security.authentication.Authentication;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
+import org.apache.jackrabbit.oak.spi.security.user.AuthorizableType;
+import org.apache.jackrabbit.oak.spi.security.user.PasswordUtility;
 import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,12 +38,14 @@ public class AuthenticationImpl implemen
 
     private static final Logger log = LoggerFactory.getLogger(AuthenticationImpl.class);
 
-    private final String userID;
+    private final String userId;
     private final UserProvider userProvider;
     private final PrincipalProvider principalProvider;
 
-    public AuthenticationImpl(String userID, UserProvider userProvider, PrincipalProvider principalProvider) {
-        this.userID = userID;
+    private Tree userTree;
+
+    public AuthenticationImpl(String userId, UserProvider userProvider, PrincipalProvider principalProvider) {
+        this.userId = userId;
         this.userProvider = userProvider;
         this.principalProvider = principalProvider;
     }
@@ -47,19 +55,16 @@ public class AuthenticationImpl implemen
         // TODO
         return true;
 
-//        if (userProvider == null || userID == null) {
+//        Tree userTree = getUserTree();
+//        if (userTree == null || userProvider.isDisabled(userTree)) {
 //            return false;
 //        }
 //
 //        if (credentials instanceof SimpleCredentials) {
 //            SimpleCredentials creds = (SimpleCredentials) credentials;
-//            return userID.equals(creds.getUserID()) &&
-//                    PasswordUtility.isSame(userProvider.getPassword(userID), creds.getPassword());
-//        } else if (credentials instanceof GuestCredentials) {
-//            return userProvider.getAuthorizable(userID) != null;
+//            return PasswordUtility.isSame(userProvider.getPasswordHash(userTree), creds.getPassword());
 //        } else {
-//            // unsupported credentials object
-//            return false;
+//            return credentials instanceof GuestCredentials;
 //        }
     }
 
@@ -68,14 +73,27 @@ public class AuthenticationImpl implemen
         // TODO
         return true;
 
-//        if (userProvider == null || userID == null) {
+//        Tree userTree = getUserTree();
+//        if (userTree == null || userProvider.isDisabled(userTree)) {
+//            return false;
+//        } else {
 //            try {
-//                return userProvider.getImpersonation(userID, principalProvider).allows(subject);
+//                return userProvider.getImpersonation(userTree, principalProvider).allows(subject);
 //            } catch (RepositoryException e) {
 //                log.debug("Error while validating impersonation", e.getMessage());
 //                return false;
 //            }
 //        }
-//        return false;
+    }
+
+    //--------------------------------------------------------------------------
+    private Tree getUserTree() {
+        if (userProvider == null || userId == null) {
+            return null;
+        }
+        if (userTree == null) {
+            userTree = userProvider.getAuthorizable(userId, AuthorizableType.USER);
+        }
+        return userTree;
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java?rev=1395932&r1=1395931&r2=1395932&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/token/TokenProviderImpl.java Tue Oct  9 09:30:21 2012
@@ -270,10 +270,21 @@ public class TokenProviderImpl implement
     }
 
     @CheckForNull
+    private Tree getUserTree(Tree tokenTree) {
+        if (tokenTree != null) {
+            return tokenTree.getParent().getParent();
+        } else {
+            return null;
+        }
+    }
+
+    @CheckForNull
     private String getUserId(Tree tokenTree) {
         if (tokenTree != null) {
             Tree userTree = tokenTree.getParent().getParent();
-            return userProvider.getAuthorizableId(userTree);
+            if (userTree != null && !userProvider.isDisabled(userTree)) {
+                return userProvider.getAuthorizableId(userTree);
+            }
         }
 
         return null;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java?rev=1395932&r1=1395931&r2=1395932&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ImpersonationImpl.java Tue Oct  9 09:30:21 2012
@@ -93,7 +93,7 @@ class ImpersonationImpl implements Imper
      * @see org.apache.jackrabbit.api.security.user.Impersonation#grantImpersonation(Principal)
      */
     @Override
-    public synchronized boolean grantImpersonation(Principal principal) throws RepositoryException {
+    public boolean grantImpersonation(Principal principal) throws RepositoryException {
         String principalName = principal.getName();
         Principal p = principalProvider.getPrincipal(principalName);
         if (p == null) {
@@ -132,7 +132,7 @@ class ImpersonationImpl implements Imper
      * @see Impersonation#revokeImpersonation(java.security.Principal)
      */
     @Override
-    public synchronized boolean revokeImpersonation(Principal principal) throws RepositoryException {
+    public boolean revokeImpersonation(Principal principal) throws RepositoryException {
         String pName = principal.getName();
 
         Tree userTree = getUserTree();

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java?rev=1395932&r1=1395931&r2=1395932&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserImpl.java Tue Oct  9 09:30:21 2012
@@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.securi
 
 import java.security.Principal;
 import javax.jcr.Credentials;
-import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 
@@ -97,7 +96,7 @@ class UserImpl extends AuthorizableImpl 
      */
     @Override
     public Impersonation getImpersonation() throws RepositoryException {
-        return getUserProvider().getImpersonation(getID(), getUserManager().getPrincipalProvider());
+        return getUserProvider().getImpersonation(getTree(), getUserManager().getPrincipalProvider());
     }
 
     /**
@@ -132,18 +131,7 @@ class UserImpl extends AuthorizableImpl 
      */
     @Override
     public void disable(String reason) throws RepositoryException {
-        if (isAdmin()) {
-            throw new RepositoryException("The administrator user cannot be disabled.");
-        }
-        Tree userTree = getTree();
-        if (reason == null) {
-            if (isDisabled()) {
-                // enable the user again.
-                getUserProvider().setProtectedProperty(userTree, REP_DISABLED, (String) null, PropertyType.STRING);
-            } // else: not disabled -> nothing to
-        } else {
-            getUserProvider().setProtectedProperty(userTree, REP_DISABLED, reason, PropertyType.STRING);
-        }
+        getUserProvider().disable(getTree(), reason);
     }
 
     /**
@@ -151,7 +139,7 @@ class UserImpl extends AuthorizableImpl 
      */
     @Override
     public boolean isDisabled() throws RepositoryException {
-        return getTree().hasProperty(REP_DISABLED);
+        return getUserProvider().isDisabled(getTree());
     }
 
     /**
@@ -159,10 +147,6 @@ class UserImpl extends AuthorizableImpl 
      */
     @Override
     public String getDisabledReason() throws RepositoryException {
-        PropertyState disabled = getTree().getProperty(REP_DISABLED);
-        if (disabled != null) {
-            return disabled.getValue(STRING);
-        } else
-            return null;
+        return getUserProvider().getDisableReason(getTree());
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java?rev=1395932&r1=1395931&r2=1395932&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java Tue Oct  9 09:30:21 2012
@@ -260,14 +260,11 @@ class UserProviderImpl extends Authoriza
     }
 
     @Override
-    public String getPassword(String userID) {
-        Tree userTree = getAuthorizable(userID, AuthorizableType.USER);
-        if (userTree != null) {
-            NodeUtil n = new NodeUtil(userTree, valueFactory);
-            return n.getString(UserConstants.REP_PASSWORD, null);
-        } else {
-            return null;
-        }
+    public String getPasswordHash(Tree userTree) {
+        checkNotNull(userTree);
+
+        NodeUtil n = new NodeUtil(userTree, valueFactory);
+        return n.getString(UserConstants.REP_PASSWORD, null);
     }
 
     @Override
@@ -292,8 +289,45 @@ class UserProviderImpl extends Authoriza
     }
 
     @Override
-    public Impersonation getImpersonation(String userId, PrincipalProvider principalProvider) {
-        return new ImpersonationImpl(userId, this, principalProvider);
+    public Impersonation getImpersonation(Tree userTree, PrincipalProvider principalProvider) {
+        // FIXME: for login the impersonation could be based on the tree directly -> improve
+        return new ImpersonationImpl(getAuthorizableId(userTree), this, principalProvider);
+    }
+
+    @Override
+    public boolean isDisabled(Tree userTree) {
+        checkNotNull(userTree);
+
+        return userTree.hasProperty(REP_DISABLED);
+    }
+
+    @Override
+    public String getDisableReason(Tree userTree) {
+        checkNotNull(userTree);
+
+        PropertyState disabled = userTree.getProperty(REP_DISABLED);
+        if (disabled != null) {
+            return disabled.getValue(STRING);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void disable(Tree userTree, String reason) throws RepositoryException {
+        checkNotNull(userTree);
+
+        if (isAdminUser(userTree)) {
+            throw new RepositoryException("The administrator user cannot be disabled.");
+        }
+        if (reason == null) {
+            if (isDisabled(userTree)) {
+                // enable the user again.
+                setProtectedProperty(userTree, REP_DISABLED, (String) null, PropertyType.STRING);
+            } // else: not disabled -> nothing to
+        } else {
+            setProtectedProperty(userTree, REP_DISABLED, reason, PropertyType.STRING);
+        }
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java?rev=1395932&r1=1395931&r2=1395932&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java Tue Oct  9 09:30:21 2012
@@ -48,6 +48,14 @@ class UserValidator extends DefaultValid
     //----------------------------------------------------------< Validator >---
 
     @Override
+    public void propertyAdded(PropertyState after) throws CommitFailedException {
+        String name = after.getName();
+        if (REP_DISABLED.equals(name) && isAdminUser()) {
+            throw new CommitFailedException("Admin user cannot be disabled.");
+        }
+    }
+
+    @Override
     public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
         String name = before.getName();
         if (REP_PRINCIPAL_NAME.equals(name) || REP_AUTHORIZABLE_ID.equals(name)) {
@@ -86,7 +94,7 @@ class UserValidator extends DefaultValid
      * @param pathConstraint
      * @throws CommitFailedException
      */
-    void assertHierarchy(NodeUtil userNode, String pathConstraint) throws CommitFailedException {
+    private void assertHierarchy(NodeUtil userNode, String pathConstraint) throws CommitFailedException {
         if (!Text.isDescendant(pathConstraint, userNode.getTree().getPath())) {
             Exception e = new ConstraintViolationException("Attempt to create user/group outside of configured scope " + pathConstraint);
             throw new CommitFailedException(e);
@@ -102,4 +110,9 @@ class UserValidator extends DefaultValid
             parent = parent.getParent();
         }
     }
+
+    private boolean isAdminUser() {
+        // FIXME: add implementation
+        return false;
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java?rev=1395932&r1=1395931&r2=1395932&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java Tue Oct  9 09:30:21 2012
@@ -86,14 +86,16 @@ public interface UserProvider {
     boolean isAdminUser(Tree userTree);
 
     /**
-     * Returns the password hash for the user with the specified ID or {@code null}
-     * if the user does not exist or if the hash is not accessible for the editing
+     * Returns the password hash for the user with the specified user tree
+     * or {@code null} if the hash is not accessible for the editing
      * session.
      *
-     * @param userID The id of a user.
+     *
+     * @param userTree
      * @return the password hash or {@code null}.
      */
-    String getPassword(String userID);
+    @CheckForNull
+    String getPasswordHash(Tree userTree);
 
     /**
      * Set the password for the user identified by the specified {@code userTree}.
@@ -106,7 +108,15 @@ public interface UserProvider {
      */
     void setPassword(Tree userTree, String password, boolean forceHash) throws RepositoryException;
 
-    Impersonation getImpersonation(String userID, PrincipalProvider principalProvider);
+    @Nonnull
+    Impersonation getImpersonation(Tree userTree, PrincipalProvider principalProvider);
+
+    boolean isDisabled(Tree userTree);
+
+    @CheckForNull
+    String getDisableReason(Tree userTree);
+
+    void disable(Tree userTree, String reason) throws RepositoryException;
 
     void setProtectedProperty(Tree authorizableTree, String propertyName, String value, int propertyType);