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/11 15:31:19 UTC
svn commit: r1397041 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/
oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/
oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/ oak-jcr...
Author: angela
Date: Thu Oct 11 13:31:19 2012
New Revision: 1397041
URL: http://svn.apache.org/viewvc?rev=1397041&view=rev
Log:
OAK-50 : Implement User Management (WIP)
Modified:
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/spi/security/user/PasswordUtility.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/AbstractUserTest.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserTest.java
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=1397041&r1=1397040&r2=1397041&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 Thu Oct 11 13:31:19 2012
@@ -23,7 +23,6 @@ import javax.jcr.UnsupportedRepositoryOp
import org.apache.jackrabbit.api.security.user.Impersonation;
import org.apache.jackrabbit.api.security.user.User;
-import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.spi.security.principal.TreeBasedPrincipal;
import org.apache.jackrabbit.oak.spi.security.user.PasswordUtility;
@@ -31,8 +30,6 @@ import org.apache.jackrabbit.oak.spi.sec
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static org.apache.jackrabbit.oak.api.Type.STRING;
-
/**
* UserImpl...
*/
@@ -104,6 +101,9 @@ class UserImpl extends AuthorizableImpl
*/
@Override
public void changePassword(String password) throws RepositoryException {
+ if (password == null) {
+ throw new RepositoryException("Attempt to set 'null' password for user " + getID());
+ }
UserManagerImpl userManager = getUserManager();
userManager.onPasswordChange(this, password);
getUserProvider().setPassword(getTree(), password, true);
@@ -115,11 +115,7 @@ class UserImpl extends AuthorizableImpl
@Override
public void changePassword(String password, String oldPassword) throws RepositoryException {
// make sure the old password matches.
- String pwHash = null;
- PropertyState pwProp = getTree().getProperty(REP_PASSWORD);
- if (pwProp != null) {
- pwHash = pwProp.getValue(STRING);
- }
+ String pwHash = getUserProvider().getPasswordHash(getTree());
if (!PasswordUtility.isSame(pwHash, oldPassword)) {
throw new RepositoryException("Failed to change password: Old password does not match.");
}
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=1397041&r1=1397040&r2=1397041&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 Thu Oct 11 13:31:19 2012
@@ -269,10 +269,6 @@ class UserProviderImpl extends Authoriza
@Override
public void setPassword(Tree userTree, String password, boolean forceHash) throws RepositoryException {
- if (password == null) {
- log.debug("Password is null.");
- return;
- }
String pwHash;
if (forceHash || PasswordUtility.isPlainTextPassword(password)) {
try {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/PasswordUtility.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/PasswordUtility.java?rev=1397041&r1=1397040&r2=1397041&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/PasswordUtility.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/PasswordUtility.java Thu Oct 11 13:31:19 2012
@@ -108,7 +108,7 @@ public class PasswordUtility {
int iterations = config.getConfigValue(UserConfig.PARAM_PASSWORD_HASH_ITERATIONS, DEFAULT_ITERATIONS);
int saltSize = config.getConfigValue(UserConfig.PARAM_PASSWORD_SALT_SIZE, DEFAULT_SALT_SIZE);
- return buildPasswordHash(password, algorithm, iterations, saltSize);
+ return buildPasswordHash(password, algorithm, saltSize, iterations);
}
/**
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java?rev=1397041&r1=1397040&r2=1397041&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java Thu Oct 11 13:31:19 2012
@@ -33,6 +33,7 @@ import org.apache.jackrabbit.oak.api.Tre
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexHook;
import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
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.UserConfig;
import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
@@ -373,4 +374,62 @@ public class UserProviderImplTest extend
u2.remove();
}
}
+
+ @Test
+ public void testGetPasswordHash() throws Exception {
+ UserProvider up = createUserProvider();
+ Tree user = up.createUser("a", null);
+
+ assertNull(up.getPasswordHash(user));
+ }
+
+ @Test
+ public void testSetPassword() throws Exception {
+ UserProvider up = createUserProvider();
+ Tree user = up.createUser("a", null);
+
+ List<String> pwds = new ArrayList<String>();
+ pwds.add("pw");
+ pwds.add("");
+ pwds.add("{sha1}pw");
+
+ for (String pw : pwds) {
+ up.setPassword(user, pw, true);
+ String pwHash = up.getPasswordHash(user);
+ assertNotNull(pwHash);
+ assertTrue(PasswordUtility.isSame(pwHash, pw));
+ }
+
+ for (String pw : pwds) {
+ up.setPassword(user, pw, false);
+ String pwHash = up.getPasswordHash(user);
+ assertNotNull(pwHash);
+ if (!pw.startsWith("{")) {
+ assertTrue(PasswordUtility.isSame(pwHash, pw));
+ } else {
+ assertFalse(PasswordUtility.isSame(pwHash, pw));
+ assertEquals(pw, pwHash);
+ }
+ }
+ }
+
+ @Test
+ public void setPasswordNull() throws Exception {
+ UserProvider up = createUserProvider();
+ Tree user = up.createUser("a", null);
+
+ try {
+ up.setPassword(user, null, true);
+ fail("setting null password should fail");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ up.setPassword(user, null, false);
+ fail("setting null password should fail");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
}
Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/AbstractUserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/AbstractUserTest.java?rev=1397041&r1=1397040&r2=1397041&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/AbstractUserTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/AbstractUserTest.java Thu Oct 11 13:31:19 2012
@@ -40,6 +40,8 @@ import org.junit.Before;
*/
public abstract class AbstractUserTest extends AbstractJCRTest {
+ protected String testPw = "pw";
+
protected UserManager userMgr;
protected User user;
protected Group group;
@@ -51,7 +53,7 @@ public abstract class AbstractUserTest e
userMgr = getUserManager(superuser);
- user = userMgr.createUser(createUserId(), "pw");
+ user = userMgr.createUser(createUserId(), testPw);
group = userMgr.createGroup(createGroupId());
superuser.save();
}
Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserTest.java?rev=1397041&r1=1397040&r2=1397041&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserTest.java Thu Oct 11 13:31:19 2012
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.oak.jcr.security.user;
+import java.security.Principal;
+import javax.jcr.Credentials;
import javax.jcr.LoginException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -25,6 +27,7 @@ import javax.jcr.UnsupportedRepositoryOp
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.apache.jackrabbit.test.NotExecutableException;
import org.junit.Test;
@@ -73,122 +76,170 @@ public class UserTest extends AbstractUs
}
@Test
- public void testChangePassword() throws RepositoryException, NotExecutableException {
- String oldPw = getHelper().getProperty("javax.jcr.tck.superuser.pwd");
- if (oldPw == null) {
- // missing property
- throw new NotExecutableException();
+ public void testChangePasswordNull() throws RepositoryException, NotExecutableException {
+ // invalid 'null' pw string
+ try {
+ user.changePassword(null);
+ superuser.save();
+ fail("invalid pw null");
+ } catch (Exception e) {
+ // success
}
+ }
- User user = getTestUser(superuser);
+ @Test
+ public void testChangePassword() throws RepositoryException, NotExecutableException {
try {
- user.changePassword("pw");
- superuser.save();
+ String hash = getNode(user, superuser).getProperty(UserConstants.REP_PASSWORD).getString();
- // make sure the user can login with the new pw
- Session s = getHelper().getRepository().login(new SimpleCredentials(user.getID(), "pw".toCharArray()));
- s.logout();
- } finally {
- user.changePassword(oldPw);
+ user.changePassword("changed");
superuser.save();
+
+ assertFalse(hash.equals(getNode(user, superuser).getProperty(UserConstants.REP_PASSWORD).getString()));
+ } catch (Exception e) {
+ // success
}
}
@Test
- public void testChangePassword2() throws RepositoryException, NotExecutableException {
- String oldPw = getHelper().getProperty("javax.jcr.tck.superuser.pwd");
- if (oldPw == null) {
- // missing property
- throw new NotExecutableException();
+ public void testChangePasswordWithInvalidOldPassword() throws RepositoryException, NotExecutableException {
+ try {
+ user.changePassword("changed", "wrongOldPw");
+ superuser.save();
+ fail("old password didn't match -> changePassword(String,String) should fail.");
+ } catch (RepositoryException e) {
+ // success.
}
+ }
- User user = getTestUser(superuser);
+ @Test
+ public void testChangePasswordWithOldPassword() throws RepositoryException, NotExecutableException {
try {
- user.changePassword("pw");
+ String hash = getNode(user, superuser).getProperty(UserConstants.REP_PASSWORD).getString();
+
+ user.changePassword("changed", testPw);
superuser.save();
- Session s = getHelper().getRepository().login(new SimpleCredentials(user.getID(), oldPw.toCharArray()));
- s.logout();
- fail("superuser pw has changed. login must fail.");
- } catch (LoginException e) {
- // success
+ assertFalse(hash.equals(getNode(user, superuser).getProperty(UserConstants.REP_PASSWORD).getString()));
} finally {
- user.changePassword(oldPw);
+ user.changePassword(testPw);
superuser.save();
}
}
+ @Test
+ public void testLoginAfterChangePassword() throws RepositoryException {
+ user.changePassword("changed");
+ superuser.save();
+
+ // make sure the user can login with the new pw
+ Session s = getHelper().getRepository().login(new SimpleCredentials(user.getID(), "changed".toCharArray()));
+ s.logout();
+ }
+
@Test
- public void testChangePasswordWithOldPassword() throws RepositoryException, NotExecutableException {
- String oldPw = getHelper().getProperty("javax.jcr.tck.superuser.pwd");
- if (oldPw == null) {
- // missing property
- throw new NotExecutableException();
- }
-
- User user = getTestUser(superuser);
- try {
- try {
- user.changePassword("pw", "wrongOldPw");
- superuser.save();
- fail("old password didn't match -> changePassword(String,String) should fail.");
- } catch (RepositoryException e) {
- // success.
- }
+ public void testLoginAfterChangePassword2() throws RepositoryException, NotExecutableException {
+ try {
- user.changePassword("pw", oldPw);
+ user.changePassword("changed", testPw);
superuser.save();
// make sure the user can login with the new pw
- Session s = getHelper().getRepository().login(new SimpleCredentials(user.getID(), "pw".toCharArray()));
+ Session s = getHelper().getRepository().login(new SimpleCredentials(user.getID(), "changed".toCharArray()));
s.logout();
} finally {
- user.changePassword(oldPw);
+ user.changePassword(testPw);
superuser.save();
}
}
@Test
- public void testChangePasswordWithOldPassword2() throws RepositoryException, NotExecutableException {
- String oldPw = getHelper().getProperty("javax.jcr.tck.superuser.pwd");
- if (oldPw == null) {
- // missing property
- throw new NotExecutableException();
+ public void testLoginWithOldPassword() throws RepositoryException, NotExecutableException {
+ try {
+ user.changePassword("changed");
+ superuser.save();
+
+ Session s = getHelper().getRepository().login(new SimpleCredentials(user.getID(), testPw.toCharArray()));
+ s.logout();
+ fail("user pw has changed. login must fail.");
+ } catch (LoginException e) {
+ // success
}
+ }
- User user = getTestUser(superuser);
+ @Test
+ public void testLoginWithOldPassword2() throws RepositoryException, NotExecutableException {
try {
- user.changePassword("pw", oldPw);
+ user.changePassword("changed", testPw);
superuser.save();
- Session s = getHelper().getRepository().login(new SimpleCredentials(user.getID(), oldPw.toCharArray()));
+ Session s = getHelper().getRepository().login(new SimpleCredentials(user.getID(), testPw.toCharArray()));
s.logout();
fail("superuser pw has changed. login must fail.");
} catch (LoginException e) {
// success
} finally {
- user.changePassword(oldPw);
+ user.changePassword(testPw);
superuser.save();
}
}
@Test
- public void testDisable() throws Exception {
+ public void testEnabledByDefault() throws Exception {
// by default a user isn't disabled
assertFalse(user.isDisabled());
assertNull(user.getDisabledReason());
+ }
- // disable user
+ @Test
+ public void testDisable() throws Exception {
String reason = "readonly user is disabled!";
user.disable(reason);
superuser.save();
assertTrue(user.isDisabled());
assertEquals(reason, user.getDisabledReason());
+ }
+
+ @Test
+ public void testAccessDisabledUser() throws Exception {
+ user.disable("readonly user is disabled!");
+ superuser.save();
// user must still be retrievable from user manager
assertNotNull(getUserManager(superuser).getAuthorizable(user.getID()));
// ... and from principal manager as well
assertTrue(((JackrabbitSession) superuser).getPrincipalManager().hasPrincipal(user.getPrincipal().getName()));
+ }
+
+ @Test
+ public void testAccessPrincipalOfDisabledUser() throws Exception {
+ user.disable("readonly user is disabled!");
+ superuser.save();
+
+ Principal principal = user.getPrincipal();
+ assertTrue(((JackrabbitSession) superuser).getPrincipalManager().hasPrincipal(principal.getName()));
+ assertEquals(principal, ((JackrabbitSession) superuser).getPrincipalManager().getPrincipal(principal.getName()));
+ }
+
+ @Test
+ public void testEnableUser() throws Exception {
+ user.disable("readonly user is disabled!");
+ superuser.save();
+
+ // enable user again
+ user.disable(null);
+ superuser.save();
+ assertFalse(user.isDisabled());
+ assertNull(user.getDisabledReason());
+
+ // -> login must succeed again
+ getHelper().getRepository().login(new SimpleCredentials(user.getID(), "pw".toCharArray())).logout();
+ }
+
+ @Test
+ public void testLoginDisabledUser() throws Exception {
+ user.disable("readonly user is disabled!");
+ superuser.save();
// -> login must fail
try {
@@ -198,6 +249,12 @@ public class UserTest extends AbstractUs
} catch (LoginException e) {
// success
}
+ }
+
+ @Test
+ public void testImpersonateDisabledUser() throws Exception {
+ user.disable("readonly user is disabled!");
+ superuser.save();
// -> impersonating this user must fail
try {
@@ -207,13 +264,27 @@ public class UserTest extends AbstractUs
} catch (LoginException e) {
// success
}
+ }
- // enable user again
- user.disable(null);
- superuser.save();
- assertFalse(user.isDisabled());
+ public void testUserGetCredentials() throws RepositoryException, NotExecutableException {
+ try {
+ Credentials creds = user.getCredentials();
+ fail("getCredentials is not yet implemented");
+ } catch (UnsupportedRepositoryOperationException e) {
+ // expected
+ }
+ }
- // -> login must succeed again
- getHelper().getRepository().login(new SimpleCredentials(user.getID(), "pw".toCharArray())).logout();
+ public void testLoginWithGetCredentials() throws RepositoryException, NotExecutableException {
+ try {
+ Credentials creds = user.getCredentials();
+ Session s = getHelper().getRepository().login(creds);
+ s.logout();
+ fail("Login using credentials exposed on user must fail.");
+ } catch (UnsupportedRepositoryOperationException e) {
+ throw new NotExecutableException(e.getMessage());
+ } catch (LoginException e) {
+ // success
+ }
}
}
\ No newline at end of file