Author: angela
Date: Tue May 28 13:33:16 2019
New Revision: 1860270

URL: http://svn.apache.org/viewvc?rev=1860270&view=rev
Log:
OAK-8360 : UserAuthentication.authenticate: improve readability

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserAuthentication.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserAuthenticationTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserAuthentication.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserAuthentication.java?rev=1860270&r1=1860269&r2=1860270&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserAuthentication.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserAuthentication.java
 Tue May 28 13:33:16 2019
@@ -103,28 +103,10 @@ class UserAuthentication implements Auth
 
         boolean success = false;
         try {
-            UserManager userManager = config.getUserManager(root, 
NamePathMapper.DEFAULT);
-            Authorizable authorizable = userManager.getAuthorizable(loginId);
-            if (authorizable == null) {
-                // best effort prevent user enumeration timing attacks
-                try {
-                    String hash = PasswordUtil.buildPasswordHash("oak");
-                    PasswordUtil.isSame(hash, "oak");
-                } catch (NoSuchAlgorithmException | 
UnsupportedEncodingException e) {
-                    // ignore
-                }
+            User user = getValidUser(config.getUserManager(root, 
NamePathMapper.DEFAULT), loginId);
+            if (user == null) {
                 return false;
             }
-
-            if (authorizable.isGroup()) {
-                throw new AccountNotFoundException("Not a user " + loginId);
-            }
-
-            User user = (User) authorizable;
-            if (user.isDisabled()) {
-                throw new AccountLockedException("User with ID " + loginId + " 
has been disabled: "+ user.getDisabledReason());
-            }
-
             if (credentials instanceof SimpleCredentials) {
                 SimpleCredentials creds = (SimpleCredentials) credentials;
                 Credentials userCreds = user.getCredentials();
@@ -133,12 +115,9 @@ class UserAuthentication implements Auth
                 }
                 checkSuccess(success, "UserId/Password mismatch.");
 
-                if (isPasswordExpired(user)) {
-                    // change the password if the credentials object has the
-                    // UserConstants.CREDENTIALS_ATTRIBUTE_NEWPASSWORD 
attribute set
-                    if (!changePassword(user, creds)) {
-                        throw new CredentialExpiredException("User password 
has expired");
-                    }
+                // change the password if the credentials object has the 
UserConstants.CREDENTIALS_ATTRIBUTE_NEWPASSWORD attribute set
+                if (isPasswordExpired(user) && !changePassword(user, creds)) {
+                    throw new CredentialExpiredException("User password has 
expired");
                 }
             } else if (credentials instanceof ImpersonationCredentials) {
                 ImpersonationCredentials ipCreds = (ImpersonationCredentials) 
credentials;
@@ -177,6 +156,29 @@ class UserAuthentication implements Auth
 
 
     
//--------------------------------------------------------------------------
+    @Nullable
+    private static User getValidUser(@NotNull UserManager userManager, 
@NotNull String loginId) throws RepositoryException, AccountNotFoundException, 
AccountLockedException {
+        Authorizable authorizable = userManager.getAuthorizable(loginId);
+        if (authorizable == null) {
+            // best effort prevent user enumeration timing attacks
+            try {
+                PasswordUtil.isSame(PasswordUtil.buildPasswordHash("oak"), 
"oak");
+            } catch (NoSuchAlgorithmException | UnsupportedEncodingException 
e) {
+                // ignore
+            }
+            return null;
+        }
+
+        if (authorizable.isGroup()) {
+            throw new AccountNotFoundException("Not a user " + loginId);
+        }
+        User user = (User) authorizable;
+        if (user.isDisabled()) {
+            throw new AccountLockedException("User with ID " + loginId + " has 
been disabled: "+ user.getDisabledReason());
+        }
+        return user;
+    }
+
     private static void checkSuccess(boolean success, String msg) throws 
LoginException {
         if (!success) {
             throw new FailedLoginException(msg);

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserAuthenticationTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserAuthenticationTest.java?rev=1860270&r1=1860269&r2=1860270&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserAuthenticationTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserAuthenticationTest.java
 Tue May 28 13:33:16 2019
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.Set;
 import javax.jcr.Credentials;
 import javax.jcr.GuestCredentials;
+import javax.jcr.RepositoryException;
 import javax.jcr.SimpleCredentials;
 import javax.security.auth.login.AccountLockedException;
 import javax.security.auth.login.AccountNotFoundException;
@@ -31,19 +32,30 @@ import javax.security.auth.login.LoginEx
 import 
org.apache.jackrabbit.api.security.authentication.token.TokenCredentials;
 import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.oak.AbstractSecurityTest;
 import org.apache.jackrabbit.oak.api.AuthInfo;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.spi.security.authentication.Authentication;
 import 
org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
+import 
org.apache.jackrabbit.oak.spi.security.authentication.PreAuthenticatedLogin;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.jetbrains.annotations.NotNull;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.internal.stubbing.answers.ThrowsException;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
 
 /**
  * UserAuthenticationTest...
@@ -85,25 +97,22 @@ public class UserAuthenticationTest exte
         assertFalse(a.authenticate(sc));
     }
 
-    @Test
+    @Test(expected = AccountNotFoundException.class)
     public void testAuthenticateResolvesToGroup() throws Exception {
         Group g = getUserManager(root).createGroup("g1");
         SimpleCredentials sc = new SimpleCredentials(g.getID(), 
"pw".toCharArray());
         Authentication a = new UserAuthentication(getUserConfiguration(), 
root, sc.getUserID());
 
         try {
+            // authenticating group should fail
             a.authenticate(sc);
-            fail("Authenticating Group should fail");
-        } catch (LoginException e) {
-            // success
-            assertTrue(e instanceof AccountNotFoundException);
         } finally {
             g.remove();
             root.commit();
         }
     }
 
-    @Test
+    @Test(expected = AccountLockedException.class)
     public void testAuthenticateResolvesToDisabledUser() throws Exception {
         User testUser = getTestUser();
         SimpleCredentials sc = new SimpleCredentials(testUser.getID(), 
testUser.getID().toCharArray());
@@ -113,11 +122,8 @@ public class UserAuthenticationTest exte
             getTestUser().disable("disabled");
             root.commit();
 
+            // authenticating disabled user should fail
             a.authenticate(sc);
-            fail("Authenticating disabled user should fail");
-        } catch (LoginException e) {
-            // success
-            assertTrue(e instanceof AccountLockedException);
         } finally {
             getTestUser().disable(null);
             root.commit();
@@ -125,7 +131,7 @@ public class UserAuthenticationTest exte
     }
 
     @Test
-    public void testAuthenticateInvalidSimpleCredentials() throws Exception {
+    public void testAuthenticateInvalidSimpleCredentials() {
         List<Credentials> invalid = new ArrayList<Credentials>();
         invalid.add(new SimpleCredentials(userId, "wrongPw".toCharArray()));
         invalid.add(new SimpleCredentials(userId, "".toCharArray()));
@@ -142,15 +148,9 @@ public class UserAuthenticationTest exte
         }
     }
 
-    @Test
+    @Test(expected = FailedLoginException.class)
     public void testAuthenticateIdMismatch() throws Exception {
-        try {
-            authentication.authenticate(new SimpleCredentials("unknownUser", 
"pw".toCharArray()));
-            fail("LoginException expected");
-        } catch (LoginException e) {
-            // success
-            assertTrue(e instanceof FailedLoginException);
-        }
+        authentication.authenticate(new SimpleCredentials("unknownUser", 
"pw".toCharArray()));
     }
 
     @Test
@@ -159,7 +159,7 @@ public class UserAuthenticationTest exte
     }
 
     @Test
-    public void testAuthenticateInvalidImpersonationCredentials() throws 
Exception {
+    public void testAuthenticateInvalidImpersonationCredentials() {
        List<Credentials> invalid = new ArrayList<Credentials>();
         invalid.add(new ImpersonationCredentials(new GuestCredentials(), 
adminSession.getAuthInfo()));
         invalid.add(new ImpersonationCredentials(new 
SimpleCredentials(adminSession.getAuthInfo().getUserID(), new char[0]), new 
TestAuthInfo()));
@@ -189,6 +189,26 @@ public class UserAuthenticationTest exte
         assertTrue(authentication.authenticate(new 
ImpersonationCredentials(sc, new TestAuthInfo())));
     }
 
+    @Test
+    public void testAuthenticateGuestCredentials() throws Exception {
+        UserAuthentication ua = new UserAuthentication(getUserConfiguration(), 
root, 
getUserConfiguration().getParameters().getConfigValue(UserConstants.PARAM_ANONYMOUS_ID,
 UserConstants.DEFAULT_ANONYMOUS_ID));
+        assertTrue(ua.authenticate(new GuestCredentials()));
+    }
+
+    @Test
+    public void testAuthenticatePreAuthCredentials() throws Exception {
+        
assertTrue(authentication.authenticate(PreAuthenticatedLogin.PRE_AUTHENTICATED));
+    }
+
+    @Test(expected = LoginException.class)
+    public void testAuthenticateWithFailingUserLookup() throws Exception {
+        UserManager um = mock(UserManager.class, 
withSettings().defaultAnswer(new ThrowsException(new RepositoryException())));
+        UserConfiguration uc = 
when(mock(UserConfiguration.class).getUserManager(any(Root.class), 
any(NamePathMapper.class))).thenReturn(um).getMock();
+
+        UserAuthentication ua = new UserAuthentication(uc, root, userId);
+        ua.authenticate(new SimpleCredentials(userId, userId.toCharArray()));
+    }
+
     @Test(expected = IllegalStateException.class)
     public void testGetUserIdBeforeLogin() {
        authentication.getUserId();


Reply via email to