Return-Path: X-Original-To: apmail-jackrabbit-commits-archive@www.apache.org Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BA1959AC4 for ; Wed, 25 Jan 2012 13:42:57 +0000 (UTC) Received: (qmail 47197 invoked by uid 500); 25 Jan 2012 13:42:57 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 47170 invoked by uid 500); 25 Jan 2012 13:42:57 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 47163 invoked by uid 99); 25 Jan 2012 13:42:57 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 25 Jan 2012 13:42:57 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 25 Jan 2012 13:42:50 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id E5CA923889B8; Wed, 25 Jan 2012 13:42:28 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1235741 - in /jackrabbit/branches/2.4: ./ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/ jackrabbit-core/src/main/java/org/apache/ja... Date: Wed, 25 Jan 2012 13:42:28 -0000 To: commits@jackrabbit.apache.org From: jukka@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120125134228.E5CA923889B8@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jukka Date: Wed Jan 25 13:42:27 2012 New Revision: 1235741 URL: http://svn.apache.org/viewvc?rev=1235741&view=rev Log: 2.4: Merged revision 1235192 (JCR-3218) Modified: jackrabbit/branches/2.4/ (props changed) jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/action/PasswordValidationAction.java jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableActionTest.java jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java Propchange: jackrabbit/branches/2.4/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Wed Jan 25 13:42:27 2012 @@ -1,3 +1,3 @@ /jackrabbit/branches/JCR-2272:1173165-1176545 /jackrabbit/sandbox/JCR-2415-lucene-3.0:1060860-1064038 -/jackrabbit/trunk:1221447,1221579,1221593,1221789,1221818,1225179,1225191,1225196,1225207,1225525,1225528,1226452,1226472,1226515,1226750,1226863,1227171,1227240,1227590,1227593,1227615,1228058,1228149,1228155,1228160,1230507,1230681,1230688,1231204,1232035,1232100,1232404,1232831,1232920,1232922,1233069,1233344,1233446,1233468,1233471,1234807 +/jackrabbit/trunk:1221447,1221579,1221593,1221789,1221818,1225179,1225191,1225196,1225207,1225525,1225528,1226452,1226472,1226515,1226750,1226863,1227171,1227240,1227590,1227593,1227615,1228058,1228149,1228155,1228160,1230507,1230681,1230688,1231204,1232035,1232100,1232404,1232831,1232920,1232922,1233069,1233344,1233446,1233468,1233471,1234807,1235192 Modified: jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java?rev=1235741&r1=1235740&r2=1235741&view=diff ============================================================================== --- jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java (original) +++ jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java Wed Jan 25 13:42:27 2012 @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.Credentials; +import javax.jcr.RepositoryException; import javax.jcr.SimpleCredentials; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; @@ -168,6 +169,23 @@ public class CryptedSimpleCredentials im } /** + * Creates a hash of the specified password if it is found to be plain text. + * + * @param password + * @return + * @throws javax.jcr.RepositoryException + */ + public static String buildPasswordHash(String password) throws RepositoryException { + try { + return new CryptedSimpleCredentials("_", password).getPassword(); + } catch (NoSuchAlgorithmException e) { + throw new RepositoryException(e); + } catch (UnsupportedEncodingException e) { + throw new RepositoryException(e); + } + } + + /** * @param pwd Plain text password * @param algorithm The algorithm to be used for the digest. * @param salt The salt to be used for the digest. Modified: jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java?rev=1235741&r1=1235740&r2=1235741&view=diff ============================================================================== --- jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java (original) +++ jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java Wed Jan 25 13:42:27 2012 @@ -48,18 +48,13 @@ public class UserImpl extends Authorizab /** * Creates a hash of the specified password if it is found to be plain text. * - * @param password - * @return - * @throws RepositoryException + * @param password The password string. + * @return Hash for the given password string. + * @throws RepositoryException If an error occurs. + * @see CryptedSimpleCredentials#buildPasswordHash(String) */ static String buildPasswordValue(String password) throws RepositoryException { - try { - return new CryptedSimpleCredentials("_", password).getPassword(); - } catch (NoSuchAlgorithmException e) { - throw new RepositoryException(e); - } catch (UnsupportedEncodingException e) { - throw new RepositoryException(e); - } + return CryptedSimpleCredentials.buildPasswordHash(password); } //-------------------------------------------------------< Authorizable >--- Modified: jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java?rev=1235741&r1=1235740&r2=1235741&view=diff ============================================================================== --- jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java (original) +++ jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java Wed Jan 25 13:42:27 2012 @@ -140,6 +140,17 @@ public class UserImporter implements Pro private int importBehavior = ImportBehavior.IGNORE; + /** + * Container used to collect group members stored in protected nodes. + */ + private Membership currentMembership; + + /** + * Temporary store for the pw an imported new user to be able to call + * the creation actions irrespective of the order of protected properties + */ + private Map currentPw = new HashMap(1); + public boolean init(JackrabbitSession session, NamePathResolver resolver, boolean isWorkspaceImport, int uuidBehavior, ReferenceChangeTracker referenceTracker) { @@ -182,8 +193,10 @@ public class UserImporter implements Pro return initialized; } - // -----------------------------------------------------< ProtectedPropertyImporter >--- - + // -----------------------------------------< ProtectedPropertyImporter >--- + /** + * @see ProtectedPropertyImporter#handlePropInfo(org.apache.jackrabbit.core.NodeImpl, org.apache.jackrabbit.core.xml.PropInfo, org.apache.jackrabbit.spi.QPropertyDefinition) + */ public boolean handlePropInfo(NodeImpl parent, PropInfo protectedPropInfo, QPropertyDefinition def) throws RepositoryException { if (!initialized) { throw new IllegalStateException("Not initialized"); @@ -222,6 +235,22 @@ public class UserImporter implements Pro Value v = protectedPropInfo.getValues(PropertyType.STRING, resolver)[0]; String princName = v.getString(); userManager.setPrincipal(parent, new PrincipalImpl(princName)); + + /* + Execute authorizable actions for a NEW group as this is the + same place in the userManager#createGroup that the actions + are called. + In case of a NEW user the actions are executed if the password + has been imported before. + */ + if (parent.isNew()) { + if (a.isGroup()) { + userManager.onCreate((Group) a); + } else if (currentPw.containsKey(a.getID())) { + userManager.onCreate((User) a, currentPw.remove(a.getID())); + } + } + return true; } else if (UserConstants.P_PASSWORD.equals(propName)) { if (a.isGroup()) { @@ -236,8 +265,23 @@ public class UserImporter implements Pro } Value v = protectedPropInfo.getValues(PropertyType.STRING, resolver)[0]; - ((User) a).changePassword(v.getString()); + String pw = v.getString(); + ((User) a).changePassword(pw); + /* + Execute authorizable actions for a NEW user at this point after + having set the password if the principal name has already been + processed, otherwise postpone it. + */ + if (parent.isNew()) { + if (parent.hasProperty(UserConstants.P_PRINCIPAL_NAME)) { + userManager.onCreate((User) a, pw); + } else { + // principal name not yet available -> remember the pw + currentPw.clear(); + currentPw.put(a.getID(), pw); + } + } return true; } else if (UserConstants.P_IMPERSONATORS.equals(propName)) { @@ -314,10 +358,16 @@ public class UserImporter implements Pro } } + /** + * @see ProtectedPropertyImporter#handlePropInfo(org.apache.jackrabbit.core.NodeImpl, org.apache.jackrabbit.core.xml.PropInfo, org.apache.jackrabbit.spi.QPropertyDefinition) + */ public boolean handlePropInfo(NodeState parent, PropInfo protectedPropInfo, QPropertyDefinition def) throws RepositoryException { return false; } + /** + * @see org.apache.jackrabbit.core.xml.ProtectedPropertyImporter#processReferences() + */ public void processReferences() throws RepositoryException { if (!initialized) { throw new IllegalStateException("Not initialized"); @@ -494,25 +544,10 @@ public class UserImporter implements Pro } } - //------------------------------------------------------------< private >--- - private void handleFailure(String msg) throws RepositoryException { - switch (importBehavior) { - case ImportBehavior.IGNORE: - case ImportBehavior.BESTEFFORT: - log.warn(msg); - break; - case ImportBehavior.ABORT: - throw new ConstraintViolationException(msg); - default: - // no other behavior. nothing to do. - - } - } - - // -----------------------------------------------------< ProtectedNodeImporter >--- - - private Membership currentMembership; - + // ---------------------------------------------< ProtectedNodeImporter >--- + /** + * @see ProtectedNodeImporter#start(org.apache.jackrabbit.core.NodeImpl) + */ public boolean start(NodeImpl protectedParent) throws RepositoryException { String repMembers = resolver.getJCRName(UserConstants.NT_REP_MEMBERS); if (repMembers.equals(protectedParent.getPrimaryNodeType().getName())) { @@ -537,10 +572,16 @@ public class UserImporter implements Pro } } + /** + * @see ProtectedNodeImporter#start(org.apache.jackrabbit.core.state.NodeState) + */ public boolean start(NodeState protectedParent) { return false; } + /** + * @see ProtectedNodeImporter#start(org.apache.jackrabbit.core.NodeImpl) + */ public void startChildInfo(NodeInfo childInfo, List propInfos) throws RepositoryException { assert (currentMembership != null); @@ -558,14 +599,23 @@ public class UserImporter implements Pro } } + /** + * @see org.apache.jackrabbit.core.xml.ProtectedNodeImporter#endChildInfo() + */ public void endChildInfo() throws RepositoryException { } + /** + * @see ProtectedNodeImporter#end(org.apache.jackrabbit.core.NodeImpl) + */ public void end(NodeImpl protectedParent) throws RepositoryException { referenceTracker.processedReference(currentMembership); currentMembership = null; } + /** + * @see ProtectedNodeImporter#end(org.apache.jackrabbit.core.state.NodeState) + */ public void end(NodeState protectedParent) { } @@ -585,7 +635,28 @@ public class UserImporter implements Pro this.importBehavior = ImportBehavior.valueFromName(importBehaviorStr); } - //-------------------------------------------------------------------------- + //------------------------------------------------------------< private >--- + /** + * Handling the import behavior + * + * @param msg + * @throws RepositoryException + */ + private void handleFailure(String msg) throws RepositoryException { + switch (importBehavior) { + case ImportBehavior.IGNORE: + case ImportBehavior.BESTEFFORT: + log.warn(msg); + break; + case ImportBehavior.ABORT: + throw new ConstraintViolationException(msg); + default: + // no other behavior. nothing to do. + + } + } + + //------------------------------------------------------< inner classes >--- /** * Inner class used to postpone import of group membership to the very end * of the import. This allows to import membership of user/groups that Modified: jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java?rev=1235741&r1=1235740&r2=1235741&view=diff ============================================================================== --- jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java (original) +++ jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java Wed Jan 25 13:42:27 2012 @@ -1049,7 +1049,7 @@ public class UserManagerImpl extends Pro * @param pw The password. * @throws RepositoryException If an exception occurs. */ - private void onCreate(User user, String pw) throws RepositoryException { + void onCreate(User user, String pw) throws RepositoryException { for (AuthorizableAction action : authorizableActions) { action.onCreate(user, pw, session); } @@ -1063,7 +1063,7 @@ public class UserManagerImpl extends Pro * @param group The new group. * @throws RepositoryException If an exception occurs. */ - private void onCreate(Group group) throws RepositoryException { + void onCreate(Group group) throws RepositoryException { for (AuthorizableAction action : authorizableActions) { action.onCreate(group, session); } Modified: jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/action/PasswordValidationAction.java URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/action/PasswordValidationAction.java?rev=1235741&r1=1235740&r2=1235741&view=diff ============================================================================== --- jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/action/PasswordValidationAction.java (original) +++ jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/action/PasswordValidationAction.java Wed Jan 25 13:42:27 2012 @@ -17,6 +17,7 @@ package org.apache.jackrabbit.core.security.user.action; import org.apache.jackrabbit.api.security.user.User; +import org.apache.jackrabbit.core.security.authentication.CryptedSimpleCredentials; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,11 +101,19 @@ public class PasswordValidationAction ex * doesn't match the specified password pattern. */ private void validatePassword(String password) throws RepositoryException { - if (password != null) { + if (password != null && isPlainText(password)) { if (pattern != null && !pattern.matcher(password).matches()) { throw new ConstraintViolationException("Password violates password constraint (" + pattern.pattern() + ")."); } } } + private static boolean isPlainText(String password) { + try { + return !CryptedSimpleCredentials.buildPasswordHash(password).equals(password); + } catch (RepositoryException e) { + // failed to build hash from pw -> proceed with the validation. + return true; + } + } } \ No newline at end of file Modified: jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableActionTest.java URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableActionTest.java?rev=1235741&r1=1235740&r2=1235741&view=diff ============================================================================== --- jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableActionTest.java (original) +++ jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableActionTest.java Wed Jan 25 13:42:27 2012 @@ -230,7 +230,27 @@ public class AuthorizableActionTest exte } } + public void testPasswordValidationActionIgnoresHashedPwString() throws Exception { + User u = null; + try { + String uid = getTestPrincipal().getName(); + u = impl.createUser(uid, buildPassword(uid)); + + PasswordValidationAction pwAction = new PasswordValidationAction(); + pwAction.setConstraint("^.*(?=.{8,})(?=.*[a-z])(?=.*[A-Z]).*"); + setActions(pwAction); + + String hashed = ((UserImpl) u).buildPasswordValue("DWkej32H"); + u.changePassword(hashed); + + } finally { + if (u != null) { + u.remove(); + } + save(superuser); + } + } //-------------------------------------------------------------------------- private class TestAction extends AbstractAuthorizableAction { Modified: jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java?rev=1235741&r1=1235740&r2=1235741&view=diff ============================================================================== --- jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java (original) +++ jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java Wed Jan 25 13:42:27 2012 @@ -33,6 +33,8 @@ import org.apache.jackrabbit.core.config import org.apache.jackrabbit.core.security.SecurityConstants; import org.apache.jackrabbit.core.security.principal.PrincipalImpl; import org.apache.jackrabbit.core.security.user.UserImporter.ImportBehavior; +import org.apache.jackrabbit.core.security.user.action.AccessControlAction; +import org.apache.jackrabbit.core.security.user.action.AuthorizableAction; import org.apache.jackrabbit.core.util.ReferenceChangeTracker; import org.apache.jackrabbit.core.xml.ImportHandler; import org.apache.jackrabbit.core.xml.ProtectedNodeImporter; @@ -69,7 +71,11 @@ import javax.jcr.lock.LockException; import javax.jcr.nodetype.ConstraintViolationException; import javax.jcr.nodetype.NoSuchNodeTypeException; import javax.jcr.retention.RetentionManager; +import javax.jcr.security.AccessControlEntry; +import javax.jcr.security.AccessControlList; import javax.jcr.security.AccessControlManager; +import javax.jcr.security.AccessControlPolicy; +import javax.jcr.security.Privilege; import javax.jcr.version.VersionException; import javax.security.auth.Subject; import java.io.ByteArrayInputStream; @@ -128,6 +134,7 @@ public class UserImporterTest extends Ab } sImpl.save(); + // make sure the target node for group-import exists Authorizable administrators = umgr.getAuthorizable(SecurityConstants.ADMINISTRATORS_NAME); if (administrators == null) { groupIdToRemove = umgr.createGroup(new PrincipalImpl(SecurityConstants.ADMINISTRATORS_NAME)).getID(); @@ -655,8 +662,23 @@ public class UserImporterTest extends Ab } public void testImportNewMembers() throws IOException, RepositoryException, SAXException, NotExecutableException { - String xml = "" + - "rep:AuthorizableFolderrep:Groupb2f5ff47-4366-31b6-a533-d8dc3614845dgrep:Group0120a4f9-196a-3f9e-b9f5-23f31f914da7g1b2f5ff47-4366-31b6-a533-d8dc3614845d"; + String xml = "" + + "" + + "" + + " rep:AuthorizableFolder" + + "" + + "" + + " rep:Group" + + " b2f5ff47-4366-31b6-a533-d8dc3614845d" + + " g" + + "" + + "" + + " rep:Group" + + " 0120a4f9-196a-3f9e-b9f5-23f31f914da7" + + " g1" + + " b2f5ff47-4366-31b6-a533-d8dc3614845d" + + "" + + ""; NodeImpl target = (NodeImpl) sImpl.getNode(umgr.getGroupsPath()); try { @@ -1326,6 +1348,165 @@ public class UserImporterTest extends Ab } } + public void testActionExecutionForUser() throws Exception { + TestAction testAction = new TestAction(); + + umgr.setAuthorizableActions(new AuthorizableAction[] {testAction}); + + // import user + String xml = "\n" + + "" + + " rep:User" + + " e358efa4-89f5-3062-b10d-d7316b65649e" + + " pw" + + " tPrincipal" + + ""; + + NodeImpl target = (NodeImpl) sImpl.getNode(umgr.getUsersPath()); + try { + doImport(target, xml); + assertEquals(testAction.id, "t"); + assertEquals(testAction.pw, "pw"); + } finally { + sImpl.refresh(false); + } + } + + public void testActionExecutionForGroup() throws Exception { + TestAction testAction = new TestAction(); + + umgr.setAuthorizableActions(new AuthorizableAction[] {testAction}); + + // import group + String xml = "\n" + + "" + + " rep:Group" + + " b2f5ff47-4366-31b6-a533-d8dc3614845d" + + " gPrincipal" + + ""; + + NodeImpl target = (NodeImpl) sImpl.getNode(umgr.getGroupsPath()); + try { + doImport(target, xml); + assertEquals(testAction.id, "g"); + assertNull(testAction.pw); + } finally { + sImpl.refresh(false); + } + } + + public void testAccessControlActionExecutionForUser() throws Exception { + AccessControlAction a1 = new AccessControlAction(); + a1.setUserPrivilegeNames(Privilege.JCR_ALL); + + umgr.setAuthorizableActions(new AuthorizableAction[] {a1}); + + String xml = "\n" + + "" + + " rep:User" + + " e358efa4-89f5-3062-b10d-d7316b65649e" + + " {sha1}8efd86fb78a56a5145ed7739dcb00c78581c5375" + + " tPrincipal" + + ""; + + NodeImpl target = (NodeImpl) sImpl.getNode(umgr.getUsersPath()); + try { + doImport(target, xml); + + Authorizable a = umgr.getAuthorizable("t"); + assertNotNull(a); + assertFalse(a.isGroup()); + + AccessControlManager acMgr = sImpl.getAccessControlManager(); + AccessControlPolicy[] policies = acMgr.getPolicies(a.getPath()); + assertNotNull(policies); + assertEquals(1, policies.length); + assertTrue(policies[0] instanceof AccessControlList); + + AccessControlEntry[] aces = ((AccessControlList) policies[0]).getAccessControlEntries(); + assertEquals(1, aces.length); + assertEquals("tPrincipal", aces[0].getPrincipal().getName()); + + } finally { + sImpl.refresh(false); + } + } + + public void testAccessControlActionExecutionForUser2() throws Exception { + AccessControlAction a1 = new AccessControlAction(); + a1.setUserPrivilegeNames(Privilege.JCR_ALL); + + umgr.setAuthorizableActions(new AuthorizableAction[] {a1}); + + String xml = "\n" + + "" + + " rep:User" + + " e358efa4-89f5-3062-b10d-d7316b65649e" + + " tPrincipal" + + " {sha1}8efd86fb78a56a5145ed7739dcb00c78581c5375" + + ""; + + NodeImpl target = (NodeImpl) sImpl.getNode(umgr.getUsersPath()); + try { + doImport(target, xml); + + Authorizable a = umgr.getAuthorizable("t"); + assertNotNull(a); + assertFalse(a.isGroup()); + + AccessControlManager acMgr = sImpl.getAccessControlManager(); + AccessControlPolicy[] policies = acMgr.getPolicies(a.getPath()); + assertNotNull(policies); + assertEquals(1, policies.length); + assertTrue(policies[0] instanceof AccessControlList); + + AccessControlEntry[] aces = ((AccessControlList) policies[0]).getAccessControlEntries(); + assertEquals(1, aces.length); + assertEquals("tPrincipal", aces[0].getPrincipal().getName()); + + } finally { + sImpl.refresh(false); + } + } + + public void testAccessControlActionExecutionForGroup() throws Exception { + AccessControlAction a1 = new AccessControlAction(); + a1.setGroupPrivilegeNames(Privilege.JCR_READ); + + umgr.setAuthorizableActions(new AuthorizableAction[] {a1}); + + String xml = "\n" + + "" + + " rep:Group" + + " b2f5ff47-4366-31b6-a533-d8dc3614845d" + + " gPrincipal" + + ""; + + NodeImpl target = (NodeImpl) sImpl.getNode(umgr.getGroupsPath()); + try { + doImport(target, xml); + + Authorizable a = umgr.getAuthorizable("g"); + assertNotNull(a); + assertTrue(a.isGroup()); + + AccessControlManager acMgr = sImpl.getAccessControlManager(); + AccessControlPolicy[] policies = acMgr.getPolicies(a.getPath()); + assertNotNull(policies); + assertEquals(1, policies.length); + assertTrue(policies[0] instanceof AccessControlList); + + AccessControlEntry[] aces = ((AccessControlList) policies[0]).getAccessControlEntries(); + assertEquals(1, aces.length); + assertEquals("gPrincipal", aces[0].getPrincipal().getName()); + + } finally { + sImpl.refresh(false); + } + } + + //-------------------------------------------------------------------------- + private void doImport(NodeImpl target, String xml) throws IOException, SAXException, RepositoryException { InputStream in = new ByteArrayInputStream(xml.getBytes("UTF-8")); SessionImporter importer = new SessionImporter(target, sImpl, @@ -1377,6 +1558,25 @@ public class UserImporterTest extends Ab } + private final class TestAction implements AuthorizableAction { + private String id; + private String pw; + + public void onCreate(Group group, Session session) throws RepositoryException { + id = group.getID(); + } + public void onCreate(User user, String password, Session session) throws RepositoryException { + id = user.getID(); + pw = password; + } + public void onRemove(Authorizable authorizable, Session session) throws RepositoryException { + // ignore + } + public void onPasswordChange(User user, String newPassword, Session session) throws RepositoryException { + pw = newPassword; + } + } + private final class DummySession implements JackrabbitSession { private DummySession() {