Author: angela
Date: Wed May 11 07:12:43 2016
New Revision: 1743322
URL: http://svn.apache.org/viewvc?rev=1743322&view=rev
Log:
OAK-4264 : Improve testing of SyncMBeanImpl (WIP)
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java?rev=1743322&r1=1743321&r2=1743322&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
(original)
+++
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
Wed May 11 07:12:43 2016
@@ -40,14 +40,14 @@ public class TestIdentityProvider implem
private final Map<String, ExternalUser> externalUsers = new HashMap<String,
ExternalUser>();
public TestIdentityProvider() {
- addGroup(new TestGroup("aa"));
- addGroup(new TestGroup("aaa"));
- addGroup(new TestGroup("a").withGroups("aa", "aaa"));
- addGroup(new TestGroup("b").withGroups("a"));
- addGroup(new TestGroup("c"));
- addGroup(new TestGroup("secondGroup"));
+ addGroup(new TestGroup("aa", getName()));
+ addGroup(new TestGroup("aaa", getName()));
+ addGroup(new TestGroup("a", getName()).withGroups("aa", "aaa"));
+ addGroup(new TestGroup("b", getName()).withGroups("a"));
+ addGroup(new TestGroup("c", getName()));
+ addGroup(new TestGroup("secondGroup", getName()));
- addUser(new TestUser(ID_TEST_USER)
+ addUser(new TestUser(ID_TEST_USER, getName())
.withProperty("name", "Test User")
.withProperty("profile/name", "Public Name")
.withProperty("profile/age", 72)
@@ -55,7 +55,7 @@ public class TestIdentityProvider implem
.withGroups("a", "b", "c")
);
- addUser(new TestUser(ID_SECOND_USER)
+ addUser(new TestUser(ID_SECOND_USER, getName())
.withProperty("profile/name", "Second User")
.withProperty("age", 24)
.withProperty("col", ImmutableList.of("v1", "v2", "v3"))
@@ -141,17 +141,17 @@ public class TestIdentityProvider implem
private final Map<String, Object> props = new HashMap<String,
Object>();
public TestIdentity() {
- this("externalId", "principalName");
+ this("externalId", "principalName", "test");
}
public TestIdentity(@Nonnull String userId) {
- this(userId, userId);
+ this(userId, userId, "test");
}
- public TestIdentity(@Nonnull String userId, @Nonnull String
principalName) {
+ public TestIdentity(@Nonnull String userId, @Nonnull String
principalName, @Nonnull String idpName) {
this.userId = userId;
this.principalName = principalName;
- id = new ExternalIdentityRef(userId, "test");
+ id = new ExternalIdentityRef(userId, idpName);
}
public TestIdentity(@Nonnull ExternalIdentity base) {
@@ -202,7 +202,7 @@ public class TestIdentityProvider implem
protected TestIdentity withGroups(String ... grps) {
for (String grp: grps) {
- groups.add(new ExternalIdentityRef(grp, "test"));
+ groups.add(new ExternalIdentityRef(grp, id.getProviderName()));
}
return this;
}
@@ -210,8 +210,8 @@ public class TestIdentityProvider implem
private static class TestUser extends TestIdentity implements ExternalUser
{
- private TestUser(String userId) {
- super(userId);
+ private TestUser(String userId, @Nonnull String idpName) {
+ super(userId, userId, idpName);
}
public String getPassword() {
@@ -222,8 +222,8 @@ public class TestIdentityProvider implem
private static class TestGroup extends TestIdentity implements
ExternalGroup {
- private TestGroup(String userId) {
- super(userId);
+ private TestGroup(@Nonnull String userId, @Nonnull String idpName) {
+ super(userId, userId, idpName);
}
@Nonnull
@@ -236,26 +236,14 @@ public class TestIdentityProvider implem
public static final class ForeignExternalUser extends
TestIdentityProvider.TestIdentity implements ExternalUser {
public ForeignExternalUser() {
- super();
- }
-
- @Nonnull
- @Override
- public ExternalIdentityRef getExternalId() {
- return new ExternalIdentityRef(getId(), "AnotherExternalIDP");
+ super("externalId", "principalName", "AnotherExternalIDP");
}
}
public static final class ForeignExternalGroup extends
TestIdentityProvider.TestIdentity implements ExternalGroup {
public ForeignExternalGroup() {
- super();
- }
-
- @Nonnull
- @Override
- public ExternalIdentityRef getExternalId() {
- return new ExternalIdentityRef(getId(), "AnotherExternalIDP");
+ super("externalId", "principalName", "AnotherExternalIDP");
}
@Nonnull
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java?rev=1743322&r1=1743321&r2=1743322&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java
(original)
+++
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java
Wed May 11 07:12:43 2016
@@ -16,23 +16,45 @@
*/
package
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.jmx;
+import java.util.Iterator;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import com.google.common.collect.Iterators;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+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.jcr.Jcr;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalGroup;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProvider;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProviderManager;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityRef;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalUser;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncContext;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncHandler;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncManager;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncResult;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.TestIdentityProvider;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncConfig;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncContext;
import
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class SyncMBeanImplTest {
@@ -42,10 +64,15 @@ public class SyncMBeanImplTest {
private static Repository REPOSITORY;
private ExternalIdentityProvider idp;
+ private ExternalIdentityProvider foreignIDP;
+ private DefaultSyncConfig syncConfig;
+ private SyncMBeanImpl syncMBean;
+
private SyncManager syncMgr;
- ExternalIdentityProviderManager idpMgr;
+ private ExternalIdentityProviderManager idpMgr;
- private SyncMBeanImpl syncMBean;
+ private Session session;
+ private UserManager userManager;
@BeforeClass
public static void beforeClass() {
@@ -53,15 +80,24 @@ public class SyncMBeanImplTest {
}
@Before
- public void before() {
- // TODO : proper setup
+ public void before() throws Exception {
idp = new TestIdentityProvider();
+ foreignIDP = new TestIdentityProvider() {
+ @Nonnull
+ public String getName() {
+ return "anotherIDP";
+ }
+
+ };
+ syncConfig = new DefaultSyncConfig();
+ syncConfig.user().setMembershipNestingDepth(1);
+
syncMgr = new SyncManager() {
@CheckForNull
@Override
public SyncHandler getSyncHandler(@Nonnull String name) {
if (SYNC_NAME.equals(name)) {
- return new DefaultSyncHandler(new DefaultSyncConfig());
+ return new DefaultSyncHandler(syncConfig);
} else {
return null;
}
@@ -79,8 +115,49 @@ public class SyncMBeanImplTest {
}
};
syncMBean = new SyncMBeanImpl(REPOSITORY, syncMgr, SYNC_NAME, idpMgr,
idp.getName());
+
+ session = REPOSITORY.login(new SimpleCredentials("admin",
"admin".toCharArray()));
+ if (!(session instanceof JackrabbitSession)) {
+ throw new IllegalStateException();
+ } else {
+ userManager = ((JackrabbitSession) session).getUserManager();
+ }
}
+ @After
+ public void after() throws Exception {
+ try {
+ session.refresh(false);
+ Iterator<ExternalIdentity> extIdentities =
Iterators.concat(idp.listGroups(), idp.listUsers());
+ while (extIdentities.hasNext()) {
+ Authorizable a =
userManager.getAuthorizable(extIdentities.next().getId());
+ if (a != null) {
+ a.remove();
+ }
+ }
+ session.save();
+ } finally {
+ session.logout();
+ }
+ }
+
+ private static void assertResultMessages(@Nonnull String[] resultMessages,
int expectedSize, @Nonnull String... expectedOperations) {
+ assertEquals(expectedSize, resultMessages.length);
+ for (int i = 0; i < resultMessages.length; i++) {
+ String rm = resultMessages[i];
+ String op = rm.substring(rm.indexOf(":") + 2, rm.indexOf("\","));
+ assertEquals(expectedOperations[i], op);
+ }
+ }
+
+ private SyncResult sync(@Nonnull ExternalIdentityProvider idp, @Nonnull
String id, boolean isGroup) throws Exception {
+ SyncContext ctx = new DefaultSyncContext(syncConfig, idp, userManager,
session.getValueFactory());
+ SyncResult res = ctx.sync((isGroup) ? idp.getGroup(id) :
idp.getUser(id));
+ session.save();
+ return res;
+ }
+
+
@Test
public void testGetSyncHandlerName() {
assertEquals(SYNC_NAME, syncMBean.getSyncHandlerName());
@@ -119,18 +196,245 @@ public class SyncMBeanImplTest {
}
}
+ /**
+ * test users have never been synced before => result must be NSA
+ */
@Test
- public void testSyncUsers() {
- // TODO
+ public void testSyncUsersBefore() {
+ String[] userIds = new String[] {TestIdentityProvider.ID_TEST_USER,
TestIdentityProvider.ID_SECOND_USER};
+
+ String[] result = syncMBean.syncUsers(userIds, false);
+ assertResultMessages(result, userIds.length, "nsa", "nsa");
+
+ result = syncMBean.syncUsers(userIds, true);
+ assertResultMessages(result, userIds.length, "nsa", "nsa");
}
@Test
- public void testSyncAllUsers() {
- // TODO
+ public void testSyncUsers() throws Exception {
+ sync(idp, TestIdentityProvider.ID_TEST_USER, false);
+
+ String[] userIds = new String[]{TestIdentityProvider.ID_TEST_USER,
TestIdentityProvider.ID_SECOND_USER};
+ String[] result = syncMBean.syncUsers(userIds, false);
+ assertResultMessages(result, userIds.length, "upd", "nsa");
+
+ result = syncMBean.syncUsers(userIds, true);
+ assertResultMessages(result, userIds.length, "upd", "nsa");
+ }
+
+ @Test
+ public void testSyncUsersAlwaysForcesSync() throws Exception {
+ sync(idp, TestIdentityProvider.ID_TEST_USER, false);
+
+ String[] userIds = new String[]{TestIdentityProvider.ID_TEST_USER,
TestIdentityProvider.ID_SECOND_USER};
+ syncConfig.user().setExpirationTime(Long.MAX_VALUE);
+
+ String[]result = syncMBean.syncUsers(userIds, false);
+ assertResultMessages(result, userIds.length, "upd", "nsa");
+ }
+
+ @Test
+ public void testSyncGroups() throws Exception {
+ sync(idp, "a", true);
+
+ String[] ids = new String[]{"a"};
+ syncConfig.group().setExpirationTime(Long.MAX_VALUE);
+
+ // force group sync is true by default => exp time is ignored
+ String[] result = syncMBean.syncUsers(ids, false);
+ assertResultMessages(result, ids.length, "upd");
+ }
+
+ @Test
+ public void testSyncUsersPurge() throws Exception {
+ User u = userManager.createUser("thirdUser", null);
+ u.setProperty(DefaultSyncContext.REP_EXTERNAL_ID,
session.getValueFactory().createValue(new ExternalIdentityRef(u.getID(),
idp.getName()).getString()));
+ session.save();
+
+ String[] ids = new String[]{u.getID()};
+ String[] result = syncMBean.syncUsers(ids, false);
+ assertResultMessages(result, ids.length, "mis");
+ assertNotNull(userManager.getAuthorizable(u.getID()));
+
+ result = syncMBean.syncUsers(ids, true);
+ assertResultMessages(result, ids.length, "del");
+ assertNull(userManager.getAuthorizable(u.getID()));
+ }
+
+ @Test
+ public void testSyncUsersNonExisting() {
+ String[] result = syncMBean.syncUsers(new String[] {"nonExisting"},
false);
+ assertResultMessages(result, 1, "nsa");
+ }
+
+ @Test
+ public void testSyncUsersLocal() {
+ String[] result = syncMBean.syncUsers(new String[]
{UserConstants.DEFAULT_ANONYMOUS_ID}, false);
+ assertResultMessages(result, 1, "for");
+ }
+
+ @Test
+ public void testSyncUsersLocalPurge() throws Exception {
+ String[] result = syncMBean.syncUsers(new String[]
{UserConstants.DEFAULT_ANONYMOUS_ID}, true);
+ assertResultMessages(result, 1, "for");
+
+
assertNotNull(userManager.getAuthorizable(UserConstants.DEFAULT_ANONYMOUS_ID));
}
@Test
- public void testSyncExternalUsers() {
+ public void testSyncUsersForeign() throws Exception {
+ // sync user from foreign IDP into the repository
+ SyncResult res = sync(foreignIDP, TestIdentityProvider.ID_TEST_USER,
false);
+
assertNotNull(userManager.getAuthorizable(TestIdentityProvider.ID_TEST_USER));
+
assertEquals(foreignIDP.getUser(TestIdentityProvider.ID_TEST_USER).getExternalId(),
res.getIdentity().getExternalIdRef());
+
+ // syncUsers with testIDP must detect the foreign status
+ String[] result = syncMBean.syncUsers(new
String[]{TestIdentityProvider.ID_TEST_USER}, false);
+ assertResultMessages(result, 1, "for");
+
assertNotNull(userManager.getAuthorizable(TestIdentityProvider.ID_TEST_USER));
+
+ // same expected with 'purge' set to true
+ result = syncMBean.syncUsers(new String[]
{TestIdentityProvider.ID_TEST_USER}, true);
+ assertResultMessages(result, 1, "for");
+
assertNotNull(userManager.getAuthorizable(TestIdentityProvider.ID_TEST_USER));
+ }
+
+ @Test
+ public void testSyncGroupsForeign() throws Exception {
+ // sync user from foreign IDP into the repository
+ SyncResult res = sync(foreignIDP, "a", true);
+ assertNotNull(userManager.getAuthorizable("a"));
+ assertEquals(foreignIDP.getGroup("a").getExternalId(),
res.getIdentity().getExternalIdRef());
+
+ // syncUsers with testIDP must detect the foreign status
+ String[] result = syncMBean.syncUsers(new String[]{"a"}, false);
+ assertResultMessages(result, 1, "for");
+ assertNotNull(userManager.getAuthorizable("a"));
+
+ // same expected with 'purge' set to true
+ result = syncMBean.syncUsers(new String[] {"a"}, true);
+ assertResultMessages(result, 1, "for");
+ assertNotNull(userManager.getAuthorizable("a"));
+ }
+
+ @Test
+ public void testInitialSyncExternalUsers() throws Exception {
+ ExternalUser externalUser =
idp.getUser(TestIdentityProvider.ID_TEST_USER);
+ String[] externalId = new String[]
{externalUser.getExternalId().getString()};
+
+ String[] result = syncMBean.syncExternalUsers(externalId);
+ assertResultMessages(result, 1, "add");
+
+ User testUser = userManager.getAuthorizable(externalUser.getId(),
User.class);
+ assertNotNull(testUser);
+
+ for (ExternalIdentityRef groupRef : externalUser.getDeclaredGroups()) {
+ assertNotNull(userManager.getAuthorizable(groupRef.getId()));
+ }
+ }
+
+ @Test
+ public void testInitialSyncExternalUsersNoNesting() throws Exception {
+ syncConfig.user().setMembershipNestingDepth(-1);
+
+ ExternalUser externalUser =
idp.getUser(TestIdentityProvider.ID_TEST_USER);
+ String[] externalId = new String[]
{externalUser.getExternalId().getString()};
+
+ String[] result = syncMBean.syncExternalUsers(externalId);
+ assertResultMessages(result, 1, "add");
+
+ User testUser = userManager.getAuthorizable(externalUser.getId(),
User.class);
+ assertNotNull(testUser);
+
+ for (ExternalIdentityRef groupRef : externalUser.getDeclaredGroups()) {
+ assertNull(userManager.getAuthorizable(groupRef.getId()));
+ }
+ }
+
+ @Test
+ public void testSyncExternalUsersLastSyncedProperty() throws Exception {
+ ExternalUser externalUser =
idp.getUser(TestIdentityProvider.ID_TEST_USER);
+ String[] externalId = new
String[]{externalUser.getExternalId().getString()};
+
+ syncMBean.syncExternalUsers(externalId);
+ User testUser = userManager.getAuthorizable(externalUser.getId(),
User.class);
+
+ long lastSynced =
testUser.getProperty(DefaultSyncContext.REP_LAST_SYNCED)[0].getLong();
+ for (ExternalIdentityRef groupRef : externalUser.getDeclaredGroups()) {
+ Group gr = userManager.getAuthorizable(groupRef.getId(),
Group.class);
+ long groupLastSynced =
gr.getProperty(DefaultSyncContext.REP_LAST_SYNCED)[0].getLong();
+
+ assertTrue(lastSynced == groupLastSynced);
+ }
+
+ // default value for forceGroup sync is defined to be 'true' => verify
result
+ syncMBean.syncExternalUsers(externalId);
+ testUser = userManager.getAuthorizable(externalUser.getId(),
User.class);
+ long lastSynced2 =
testUser.getProperty(DefaultSyncContext.REP_LAST_SYNCED)[0].getLong();
+
+ assertTrue(lastSynced < lastSynced2);
+ for (ExternalIdentityRef groupRef : externalUser.getDeclaredGroups()) {
+ Group gr = userManager.getAuthorizable(groupRef.getId(),
Group.class);
+ long groupLastSynced =
gr.getProperty(DefaultSyncContext.REP_LAST_SYNCED)[0].getLong();
+
+ assertTrue(lastSynced2 == groupLastSynced);
+ }
+ }
+
+ @Test
+ public void testInitialSyncExternalGroup() throws Exception {
+ ExternalGroup externalGroup = idp.getGroup("a");
+ String[] externalId = new String[]
{externalGroup.getExternalId().getString()};
+
+ String[] result = syncMBean.syncExternalUsers(externalId);
+ assertResultMessages(result, 1, "add");
+
+ Group aGroup = userManager.getAuthorizable(externalGroup.getId(),
Group.class);
+ assertNotNull(aGroup);
+
+ // membership of groups are not synced (unless imposed by user-sync
with membership depth)
+ for (ExternalIdentityRef groupRef : externalGroup.getDeclaredGroups())
{
+ assertNull(userManager.getAuthorizable(groupRef.getId()));
+ }
+ }
+
+ @Test
+ public void testSyncExternalNonExisting() throws Exception {
+ ExternalIdentityRef ref = new ExternalIdentityRef("nonExisting",
idp.getName());
+
+ String[] result = syncMBean.syncExternalUsers(new
String[]{ref.getString()});
+ assertResultMessages(result, 1, "nsi");
+ }
+
+ /**
+ * @see <a
href="https://issues.apache.org/jira/browse/OAK-4346">OAK-4346</a>
+ */
+ @Ignore("OAK-4346")
+ @Test
+ public void testSyncExternalLocal() throws Exception {
+ ExternalIdentityRef ref = new
ExternalIdentityRef(UserConstants.DEFAULT_ANONYMOUS_ID, null);
+
+ String[] result = syncMBean.syncExternalUsers(new
String[]{ref.getString()});
+ assertResultMessages(result, 1, "for");
+ }
+
+ /**
+ * @see <a
href="https://issues.apache.org/jira/browse/OAK-4346">OAK-4346</a>
+ */
+ @Ignore("OAK-4346")
+ @Test
+ public void testSyncExternalForeign() throws Exception {
+ ExternalIdentityRef ref = new
ExternalIdentityRef(TestIdentityProvider.ID_TEST_USER, "anotherIDP");
+
+ String[] result = syncMBean.syncExternalUsers(new
String[]{ref.getString()});
+ assertResultMessages(result, 1, "for");
+
+ result = syncMBean.syncExternalUsers(new String[] {ref.getString()});
+ assertResultMessages(result, 1, "for");
+ }
+
+ @Test
+ public void testSyncAllUsers() {
// TODO
}