You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2010/08/11 14:50:11 UTC
svn commit: r984395 - in /jackrabbit/trunk:
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core...
Author: angela
Date: Wed Aug 11 12:50:11 2010
New Revision: 984395
URL: http://svn.apache.org/viewvc?rev=984395&view=rev
Log:
JCR-2635 : Disable Users
Modified:
jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/User.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/SimpleCredentialsAuthenticationTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java
Modified: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/User.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/User.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/User.java (original)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/User.java Wed Aug 11 12:50:11 2010
@@ -57,4 +57,36 @@ public interface User extends Authorizab
* @throws RepositoryException If an error occurs.
*/
void changePassword(String password) throws RepositoryException;
+
+ /**
+ * Disable this user thus preventing future login if the <code>reason</code>
+ * is a non-null String.<br>
+ * Note however, that this user will still be accessible by
+ * {@link UserManager#getAuthorizable}.
+ *
+ * @param reason String describing the reason for disable this user or
+ * <code>null</code> if the user account should be enabled again.
+ * @throws RepositoryException
+ */
+ void disable(String reason) throws RepositoryException;
+
+ /**
+ * Returns <code>true</code> if this user is disabled, <code>false</code>
+ * otherwise.
+ *
+ * @return <code>true</code> if this user is disabled, <code>false</code>
+ * otherwise.
+ * @throws RepositoryException
+ */
+ boolean isDisabled() throws RepositoryException;
+
+ /**
+ * Returns the String specified upon disabling this user or <code>null</code>
+ * if {@link #isDisabled()} returns <code>false</code>.
+ *
+ * @return The reason specified upon disabling this user or <code>null</code>
+ * if this user is not disabled.
+ * @throws RepositoryException
+ */
+ String getDisabledReason() throws RepositoryException;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java Wed Aug 11 12:50:11 2010
@@ -312,8 +312,8 @@ public abstract class AbstractLoginModul
try {
Principal userPrincipal = getPrincipal(creds);
if (userPrincipal == null) {
- // unknown principal or a Group-principal
- log.debug("Unknown User -> ignore.");
+ // unknown or disabled user or a group
+ log.debug("No valid user -> ignore.");
return false;
}
boolean authenticated;
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java Wed Aug 11 12:50:11 2010
@@ -76,7 +76,7 @@ public class DefaultLoginModule extends
* If the the userID cannot be resolved to a User or if obtaining the
* principal fail, <code>null</code> is returned.
*
- * @param credentials Credentions to retrieve the principal for.
+ * @param credentials Credentials to retrieve the principal for.
* @return a user principal or <code>null</code>.
* @see AbstractLoginModule#getPrincipal(Credentials)
*/
@@ -88,7 +88,12 @@ public class DefaultLoginModule extends
Authorizable authrz = userManager.getAuthorizable(userId);
if (authrz != null && !authrz.isGroup()) {
user = (User) authrz;
- principal = user.getPrincipal();
+ if (user.isDisabled()) {
+ // log message and return null -> login module returns false.
+ log.debug("User " + userId + " has been disabled.");
+ } else {
+ principal = user.getPrincipal();
+ }
}
} catch (RepositoryException e) {
// should not get here
@@ -130,17 +135,16 @@ public class DefaultLoginModule extends
@Override
protected boolean impersonate(Principal principal, Credentials credentials)
throws RepositoryException, FailedLoginException {
-
- Authorizable authrz = userManager.getAuthorizable(principal);
- if (authrz == null || authrz.isGroup()) {
- return false;
- }
- Subject impersSubject = getImpersonatorSubject(credentials);
- User user = (User) authrz;
- if (user.getImpersonation().allows(impersSubject)) {
- return true;
+ if (user != null) {
+ Subject impersSubject = getImpersonatorSubject(credentials);
+ if (user.getImpersonation().allows(impersSubject)) {
+ return true;
+ } else {
+ throw new FailedLoginException("attempt to impersonate denied for " + principal.getName());
+ }
} else {
- throw new FailedLoginException("attempt to impersonate denied for " + principal.getName());
+ log.debug("Failed to retrieve user to impersonate for principal name " + principal.getName());
+ return false;
}
}
-}
+}
\ No newline at end of file
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java Wed Aug 11 12:50:11 2010
@@ -54,6 +54,7 @@ interface UserConstants {
*/
Name P_USERID = NF.create(Name.NS_REP_URI, "userId");
Name P_PASSWORD = NF.create(Name.NS_REP_URI, "password");
+ Name P_DISABLED = NF.create(Name.NS_REP_URI, "disabled");
/**
* @deprecated As of 2.0 group membership is stored with the group node.
@@ -74,4 +75,4 @@ interface UserConstants {
Name NT_REP_GROUP = NF.create(Name.NS_REP_URI, "Group");
Name MIX_REP_IMPERSONATABLE = NF.create(Name.NS_REP_URI, "Impersonatable");
-}
\ No newline at end of file
+}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java Wed Aug 11 12:50:11 2010
@@ -20,6 +20,7 @@ import org.apache.jackrabbit.api.securit
import org.apache.jackrabbit.api.security.user.Impersonation;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.PropertyImpl;
import org.apache.jackrabbit.core.security.authentication.CryptedSimpleCredentials;
import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
@@ -126,6 +127,43 @@ public class UserImpl extends Authorizab
userManager.setProtectedProperty(getNode(), P_PASSWORD, v);
}
+ /**
+ * @see User#disable(String)
+ */
+ public void disable(String reason) throws RepositoryException {
+ if (isAdmin()) {
+ throw new RepositoryException("The administrator user cannot be disabled.");
+ }
+ if (reason == null) {
+ if (isDisabled()) {
+ // enable the user again.
+ PropertyImpl disableProp = getNode().getProperty(P_DISABLED);
+ userManager.removeProtectedItem(disableProp, getNode());
+ } // else: nothing to do.
+ } else {
+ Value v = getSession().getValueFactory().createValue(reason);
+ userManager.setProtectedProperty(getNode(), P_DISABLED, v);
+ }
+ }
+
+ /**
+ * @see User#isDisabled()
+ */
+ public boolean isDisabled() throws RepositoryException {
+ return getNode().hasProperty(P_DISABLED);
+ }
+
+ /**
+ * @see User#getDisabledReason()
+ */
+ public String getDisabledReason() throws RepositoryException {
+ if (isDisabled()) {
+ return getNode().getProperty(P_DISABLED).getString();
+ } else {
+ return null;
+ }
+ }
+
//--------------------------------------------------------------------------
/**
*
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java Wed Aug 11 12:50:11 2010
@@ -246,6 +246,23 @@ public class UserImporter extends Defaul
referenceTracker.processedReference(new Impersonators(a.getID(), vs));
return true;
+ } else if (UserConstants.P_DISABLED.equals(propName)) {
+ if (a.isGroup()) {
+ log.warn("Expected parent node of type rep:User.");
+ return false;
+ }
+ // minimal validation of the passed definition
+ if (def.isMultiple() || !UserConstants.NT_REP_USER.equals(def.getDeclaringNodeType())) {
+ // some other unexpected property definition -> cannot handle
+ log.warn("Unexpected definition for property rep:disabled");
+ return false;
+ }
+
+ Value v = protectedPropInfo.getValues(PropertyType.STRING, resolver)[0];
+ ((User) a).disable(v.getString());
+
+ return true;
+
} else if (UserConstants.P_MEMBERS.equals(propName)) {
if (!a.isGroup()) {
// unexpected parent type -> cannot handle
Modified: jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd Wed Aug 11 12:50:11 2010
@@ -600,6 +600,7 @@
[rep:User] > rep:Authorizable, rep:Impersonatable
- rep:password (STRING) protected mandatory
+ - rep:disabled (STRING) protected
[rep:Group] > rep:Authorizable
- rep:members (WEAKREFERENCE) protected multiple < 'rep:Authorizable'
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserTest.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserTest.java Wed Aug 11 12:50:11 2010
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.api.security.user;
+import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.test.NotExecutableException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -102,4 +103,84 @@ public class UserTest extends AbstractUs
save(superuser);
}
}
+
+ public void testDisable() throws Exception {
+ boolean remove = false;
+ Session s = getHelper().getReadOnlySession();
+
+ User user = null;
+ String userID = null;
+ String pw = "";
+
+ try {
+ User readonlyUser = getTestUser(s);
+ if (readonlyUser.isAdmin()) {
+ // configured readonly user is admin
+ // -> need to create another test user
+ pw = "test";
+ userID = getUserManager(superuser).createUser(getTestPrincipal().getName(), pw).getID();
+ remove = true;
+ } else {
+ userID = readonlyUser.getID();
+ }
+
+ user = (User) getUserManager(superuser).getAuthorizable(userID);
+
+ // by default a user isn't disabled
+ assertFalse(user.isDisabled());
+ assertNull(user.getDisabledReason());
+
+ // disable user
+ String reason = "readonly user is disabled!";
+ user.disable(reason);
+ save(superuser);
+ assertTrue(user.isDisabled());
+ assertEquals(reason, user.getDisabledReason());
+
+ // user must still be retrievable from user manager
+ assertNotNull(getUserManager(superuser).getAuthorizable(userID));
+ // ... and from principal manager as well
+ assertTrue(((JackrabbitSession) superuser).getPrincipalManager().hasPrincipal(user.getPrincipal().getName()));
+
+ // -> login must fail
+ try {
+ Session ss = getHelper().getRepository().login(new SimpleCredentials(userID, pw.toCharArray()));
+ ss.logout();
+ fail("A disabled user must not be allowed to login any more");
+ } catch (LoginException e) {
+ // success
+ }
+
+ // -> impersonating this user must fail
+ try {
+ Session ss = superuser.impersonate(new SimpleCredentials(userID, new char[0]));
+ ss.logout();
+ fail("A disabled user cannot be impersonated any more.");
+ } catch (LoginException e) {
+ // success
+ }
+
+ // enable user again
+ user.disable(null);
+ save(superuser);
+ assertFalse(user.isDisabled());
+
+ // -> login must succeed again
+ getHelper().getRepository().login(new SimpleCredentials(userID, pw.toCharArray())).logout();
+
+ } finally {
+ s.logout();
+
+ if (user != null) {
+ if (user.isDisabled()) {
+ user.disable(null);
+ }
+
+ if (remove) {
+ user.remove();
+ save(superuser);
+ }
+ }
+ }
+ }
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/SimpleCredentialsAuthenticationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/SimpleCredentialsAuthenticationTest.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/SimpleCredentialsAuthenticationTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authentication/SimpleCredentialsAuthenticationTest.java Wed Aug 11 12:50:11 2010
@@ -134,6 +134,17 @@ public class SimpleCredentialsAuthentica
public void changePassword(String password) throws RepositoryException {
}
+ public void disable(String reason) throws RepositoryException {
+ }
+
+ public boolean isDisabled() throws RepositoryException {
+ return false;
+ }
+
+ public String getDisabledReason() throws RepositoryException {
+ return null;
+ }
+
public String getID() throws RepositoryException {
return null;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java?rev=984395&r1=984394&r2=984395&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java Wed Aug 11 12:50:11 2010
@@ -194,6 +194,7 @@ public class UserImporterTest extends Ab
" <sv:property sv:name=\"jcr:uuid\" sv:type=\"String\"><sv:value>e358efa4-89f5-3062-b10d-d7316b65649e</sv:value></sv:property>" +
" <sv:property sv:name=\"rep:password\" sv:type=\"String\"><sv:value>{sha1}8efd86fb78a56a5145ed7739dcb00c78581c5375</sv:value></sv:property>" +
" <sv:property sv:name=\"rep:principalName\" sv:type=\"String\"><sv:value>t</sv:value></sv:property>" +
+ " <sv:property sv:name=\"rep:disabled\" sv:type=\"String\"><sv:value>disabledUser</sv:value></sv:property>" +
"</sv:node>";
NodeImpl target = (NodeImpl) sImpl.getNode(umgr.getUsersPath());
@@ -208,6 +209,8 @@ public class UserImporterTest extends Ab
assertFalse(newUser.isGroup());
assertEquals("t", newUser.getPrincipal().getName());
assertEquals("t", newUser.getID());
+ assertTrue(((User) newUser).isDisabled());
+ assertEquals("disabledUser", ((User) newUser).getDisabledReason());
NodeImpl n = ((UserImpl) newUser).getNode();
assertTrue(n.isNew());
@@ -216,6 +219,7 @@ public class UserImporterTest extends Ab
assertEquals("t", n.getName());
assertEquals("t", n.getProperty(UserConstants.P_PRINCIPAL_NAME).getString());
assertEquals("{sha1}8efd86fb78a56a5145ed7739dcb00c78581c5375", n.getProperty(UserConstants.P_PASSWORD).getString());
+ assertEquals("disabledUser", n.getProperty(UserConstants.P_DISABLED).getString());
// saving changes of the import -> must succeed. add mandatory
// props should have been created.