Author: angela
Date: Thu Dec 17 09:30:21 2015
New Revision: 1720499
URL: http://svn.apache.org/viewvc?rev=1720499&view=rev
Log:
OAK-3519 : Some improvement to SyncMBeanImpl
Added:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncRuntimeException.java
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/
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/pom.xml
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImpl.java
Modified: jackrabbit/oak/trunk/oak-auth-external/pom.xml
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/pom.xml?rev=1720499&r1=1720498&r2=1720499&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-auth-external/pom.xml Thu Dec 17 09:30:21 2015
@@ -154,6 +154,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-jcr</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
Added:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java?rev=1720499&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java
(added)
+++
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java
Thu Dec 17 09:30:21 2015
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.jmx;
+
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.security.auth.Subject;
+
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.commons.json.JsonUtil;
+import org.apache.jackrabbit.oak.spi.security.authentication.SystemSubject;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityException;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityProvider;
+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.SyncException;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncHandler;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncResult;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncedIdentity;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncResultImpl;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncedIdentity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class Delegatee {
+
+ private static final Logger log = LoggerFactory.getLogger(Delegatee.class);
+
+ private static final String ERROR_CREATE_DELEGATEE = "Unable to create
delegatee";
+ private static final String ERROR_SYNC_USER = "Error while syncing user
{}";
+
+ private final SyncHandler handler;
+ private final ExternalIdentityProvider idp;
+ private final UserManager userMgr;
+ private final Session systemSession;
+
+ private SyncContext context;
+
+ private Delegatee(@Nonnull SyncHandler handler, @Nonnull
ExternalIdentityProvider idp,
+ @Nonnull JackrabbitSession systemSession) throws
SyncException, RepositoryException {
+ this.handler = handler;
+ this.idp = idp;
+
+ this.systemSession = systemSession;
+ this.userMgr = systemSession.getUserManager();
+ this.context = handler.createContext(idp, userMgr,
systemSession.getValueFactory());
+
+ log.info("Created delegatee for SyncMBean with session: {} {}",
systemSession, systemSession.getUserID());
+ }
+
+ static Delegatee createInstance(final @Nonnull Repository repository,
@Nonnull SyncHandler handler, @Nonnull ExternalIdentityProvider idp) {
+ Session systemSession;
+ try {
+ systemSession = Subject.doAs(SystemSubject.INSTANCE, new
PrivilegedExceptionAction<Session>() {
+ @Override
+ public Session run() throws RepositoryException {
+ if (repository instanceof JackrabbitRepository) {
+ // this is to bypass GuestCredentials injection in the
"AbstractSlingRepository2"
+ return ((JackrabbitRepository) repository).login(null,
null, null);
+ } else {
+ return repository.login(null, null);
+ }
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw new SyncRuntimeException(ERROR_CREATE_DELEGATEE, e);
+ }
+
+ if (!(systemSession instanceof JackrabbitSession)) {
+ systemSession.logout();
+ throw new SyncRuntimeException("Unable to create SyncContext:
JackrabbitSession required.");
+ }
+ try {
+ return new Delegatee(handler, idp, (JackrabbitSession)
systemSession);
+ } catch (RepositoryException e) {
+ systemSession.logout();
+ throw new SyncRuntimeException(ERROR_CREATE_DELEGATEE, e);
+ } catch (SyncException e) {
+ systemSession.logout();
+ throw new SyncRuntimeException(ERROR_CREATE_DELEGATEE, e);
+ }
+ }
+
+ void close() {
+ if (context != null) {
+ context.close();
+ context = null;
+ }
+ if (systemSession.isLive()) {
+ systemSession.logout();
+ }
+ }
+
+ /**
+ * @see SynchronizationMBean#syncUsers(String[], boolean)
+ */
+ @Nonnull
+ String[] syncUsers(@Nonnull String[] userIds, boolean purge) {
+ context.setKeepMissing(!purge)
+ .setForceGroupSync(true)
+ .setForceUserSync(true);
+ List<String> list = new ArrayList<String>();
+ for (String userId: userIds) {
+ try {
+ append(list, syncUser(userId));
+ } catch (SyncException e) {
+ log.warn(ERROR_SYNC_USER, userId, e);
+ }
+ }
+ return list.toArray(new String[list.size()]);
+ }
+
+ /**
+ * @see SynchronizationMBean#syncAllUsers(boolean)
+ */
+ @Nonnull
+ String[] syncAllUsers(boolean purge) {
+ try {
+ List<String> list = new ArrayList<String>();
+ context.setKeepMissing(!purge)
+ .setForceGroupSync(true)
+ .setForceUserSync(true);
+ Iterator<SyncedIdentity> iter = handler.listIdentities(userMgr);
+ while (iter.hasNext()) {
+ SyncedIdentity id = iter.next();
+ if (isMyIDP(id)) {
+ try {
+ append(list, syncUser(id.getId()));
+ } catch (SyncException e) {
+ log.error(ERROR_SYNC_USER, id, e);
+ append(list, id, e);
+ }
+ }
+ }
+ return list.toArray(new String[list.size()]);
+ } catch (RepositoryException e) {
+ throw new IllegalStateException("Error retrieving users for
syncing", e);
+ }
+ }
+
+ /**
+ * @see SynchronizationMBean#syncExternalUsers(String[])
+ */
+ @Nonnull
+ String[] syncExternalUsers(@Nonnull String[] externalIds) {
+ List<String> list = new ArrayList<String>();
+ context.setForceGroupSync(true).setForceUserSync(true);
+ for (String externalId : externalIds) {
+ ExternalIdentityRef ref =
ExternalIdentityRef.fromString(externalId);
+ try {
+ ExternalIdentity id = idp.getIdentity(ref);
+ SyncResult r;
+ if (id != null) {
+ r = syncUser(id);
+ } else {
+ r = new DefaultSyncResultImpl(
+ new DefaultSyncedIdentity("", ref, false, -1),
+ SyncResult.Status.NO_SUCH_IDENTITY
+ );
+ }
+ append(list, r);
+ } catch (ExternalIdentityException e) {
+ log.warn("error while fetching the external identity {}",
externalId, e);
+ append(list, ref, e);
+ } catch (SyncException e) {
+ log.error(ERROR_SYNC_USER, ref, e);
+ append(list, ref, e);
+ }
+ }
+ return list.toArray(new String[list.size()]);
+ }
+
+ /**
+ * @see SynchronizationMBean#syncAllExternalUsers()
+ */
+ @Nonnull
+ String[] syncAllExternalUsers() {
+ List<String> list = new ArrayList<String>();
+ context.setForceGroupSync(true).setForceUserSync(true);
+ try {
+ Iterator<ExternalUser> iter = idp.listUsers();
+ while (iter.hasNext()) {
+ ExternalUser user = iter.next();
+ try {
+ SyncResult r = syncUser(user);
+ if (r.getIdentity() == null) {
+ r = new DefaultSyncResultImpl(
+ new DefaultSyncedIdentity(user.getId(),
user.getExternalId(), false, -1),
+ SyncResult.Status.NO_SUCH_IDENTITY
+ );
+ log.warn("sync failed. {}", r.getIdentity());
+ } else {
+ log.info("synced {}", r.getIdentity());
+ }
+ append(list, r);
+ } catch (SyncException e) {
+ log.error(ERROR_SYNC_USER, user, e);
+ append(list, user.getExternalId(), e);
+ }
+ }
+ return list.toArray(new String[list.size()]);
+ } catch (ExternalIdentityException e) {
+ throw new SyncRuntimeException("Unable to retrieve external
users", e);
+ }
+ }
+
+ /**
+ * @see SynchronizationMBean#listOrphanedUsers()
+ */
+ @Nonnull
+ String[] listOrphanedUsers() {
+ List<String> list = new ArrayList<String>();
+ try {
+ Iterator<SyncedIdentity> iter = handler.listIdentities(userMgr);
+ while (iter.hasNext()) {
+ SyncedIdentity id = iter.next();
+ if (isMyIDP(id)) {
+ try {
+ ExternalIdentityRef ref = id.getExternalIdRef();
+ ExternalIdentity extId = (ref == null) ? null :
idp.getIdentity(ref);
+ if (extId == null) {
+ list.add(id.getId());
+ }
+ } catch (ExternalIdentityException e) {
+ log.error("Error while fetching external identity {}",
id, e);
+ }
+ }
+ }
+ } catch (RepositoryException e) {
+ log.error("Error while listing orphaned users", e);
+ }
+ return list.toArray(new String[list.size()]);
+ }
+
+ /**
+ * @see SynchronizationMBean#purgeOrphanedUsers()
+ */
+ @Nonnull
+ String[] purgeOrphanedUsers() {
+ context.setKeepMissing(false);
+ List<String> list = new ArrayList<String>();
+ for (String userId : listOrphanedUsers()) {
+ try {
+ append(list, syncUser(userId));
+ } catch (SyncException e) {
+ log.warn(ERROR_SYNC_USER, userId, e);
+ }
+ }
+ return list.toArray(new String[list.size()]);
+ }
+
+ //------------------------------------------------------------< private
>---
+
+ private boolean isMyIDP(@Nonnull SyncedIdentity id) {
+ ExternalIdentityRef ref = id.getExternalIdRef();
+ String providerName = (ref == null) ? null : ref.getProviderName();
+ return providerName != null && (providerName.isEmpty() ||
providerName.equals(idp.getName()));
+ }
+
+
+ @Nonnull
+ private SyncResult syncUser(@Nonnull ExternalIdentity id) throws
SyncException {
+ try {
+ SyncResult r = context.sync(id);
+ systemSession.save();
+ return r;
+ } catch (RepositoryException e) {
+ throw new SyncException(e);
+ }
+ }
+
+ @Nonnull
+ private SyncResult syncUser(@Nonnull String userId) throws SyncException {
+ try {
+ SyncResult r = context.sync(userId);
+ systemSession.save();
+ return r;
+ } catch (RepositoryException e) {
+ throw new SyncException(e);
+ }
+ }
+
+ private static void append(@Nonnull List<String> list, @Nonnull SyncResult
r) {
+ SyncedIdentity syncedIdentity = r.getIdentity();
+ String uid = JsonUtil.getJsonString((syncedIdentity == null ? null :
syncedIdentity.getId()));
+ ExternalIdentityRef externalIdentityRef = (syncedIdentity == null) ?
null : syncedIdentity.getExternalIdRef();
+ String eid = (externalIdentityRef == null) ? "\"\"" :
JsonUtil.getJsonString(externalIdentityRef.getString());
+ String jsonStr = String.format("{op:\"%s\",uid:%s,eid:%s}",
getOperationFromStatus(r.getStatus()), uid, eid);
+ list.add(jsonStr);
+ }
+
+ private static void append(@Nonnull List<String> list, @Nonnull
ExternalIdentityRef idRef, @Nonnull Exception e) {
+ String eid = JsonUtil.getJsonString(idRef.getString());
+ String msg = JsonUtil.getJsonString(e.toString());
+ String jsonStr = String.format("{op:\"ERR\",uid:\"\",eid:%s,msg:%s}",
eid, msg);
+ list.add(jsonStr);
+ }
+
+ private static void append(@Nonnull List<String> list, @Nonnull
SyncedIdentity id, @Nonnull Exception e) {
+ String uid = JsonUtil.getJsonString(id.getId());
+ ExternalIdentityRef ref = id.getExternalIdRef();
+ String eid = (ref == null) ? "\"\"" :
JsonUtil.getJsonString(ref.getString());
+ String msg = JsonUtil.getJsonString(e.toString());
+ list.add(String.format("{op:\"ERR\",uid:%s,eid:%s,msg:%s}", uid, eid,
msg));
+ }
+
+ private static String getOperationFromStatus(SyncResult.Status syncStatus)
{
+ String op;
+ switch (syncStatus) {
+ case NOP:
+ op = "nop";
+ break;
+ case ADD:
+ op = "add";
+ break;
+ case UPDATE:
+ op = "upd";
+ break;
+ case DELETE:
+ op = "del";
+ break;
+ case NO_SUCH_AUTHORIZABLE:
+ op = "nsa";
+ break;
+ case NO_SUCH_IDENTITY:
+ op = "nsi";
+ break;
+ case MISSING:
+ op = "mis";
+ break;
+ case FOREIGN:
+ op = "for";
+ break;
+ default:
+ op = "";
+ }
+ return op;
+ }
+}
Modified:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImpl.java?rev=1720499&r1=1720498&r2=1720499&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImpl.java
Thu Dec 17 09:30:21 2015
@@ -16,42 +16,18 @@
*/
package
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.jmx;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
import javax.annotation.Nonnull;
import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-
-import org.apache.jackrabbit.api.JackrabbitRepository;
-import org.apache.jackrabbit.api.JackrabbitSession;
-import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.commons.json.JsonUtil;
-import org.apache.jackrabbit.oak.spi.security.authentication.SystemSubject;
-import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
-import
org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityException;
+
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.SyncException;
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.SyncedIdentity;
-import
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncResultImpl;
-import
org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncedIdentity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * {@code SyncMBeanImpl}...
+ * Implementation of the {@link SynchronizationMBean} interface.
*/
public class SyncMBeanImpl implements SynchronizationMBean {
@@ -88,288 +64,10 @@ public class SyncMBeanImpl implements Sy
log.error("No idp available for name", idpName);
throw new IllegalArgumentException("No idp manager available for
name " + idpName);
}
- try {
- return new Delegatee(handler, idp);
- } catch (SyncException e) {
- throw new IllegalArgumentException("Unable to create delegatee",
e);
- }
- }
-
- private final class Delegatee {
-
- private SyncHandler handler;
-
- private ExternalIdentityProvider idp;
-
- private SyncContext context;
-
- private UserManager userMgr;
-
- private Session systemSession;
-
- private Delegatee(@Nonnull SyncHandler handler, @Nonnull
ExternalIdentityProvider idp) throws SyncException {
- this.handler = handler;
- this.idp = idp;
- try {
- systemSession = Subject.doAs(SystemSubject.INSTANCE, new
PrivilegedExceptionAction<Session>() {
- @Override
- public Session run() throws RepositoryException {
- if (repository instanceof JackrabbitRepository) {
- // this is to bypass GuestCredentials injection in
the "AbstractSlingRepository2"
- return ((JackrabbitRepository)
repository).login(null, null, null);
- } else {
- return repository.login(null, null);
- }
- }
- });
- } catch (PrivilegedActionException e) {
- throw new SyncException(e);
- }
- try {
- context = handler.createContext(idp, userMgr =
((JackrabbitSession) systemSession).getUserManager(),
systemSession.getValueFactory());
- } catch (Exception e) {
- systemSession.logout();
- throw new SyncException(e);
- }
-
- log.info("Created delegatee for SyncMBean with session: {} {}",
systemSession, systemSession.getUserID());
- }
-
- private void close() {
- if (context != null) {
- context.close();
- context = null;
- }
- if (systemSession != null) {
- systemSession.logout();
- }
- }
-
- /**
- * @see SynchronizationMBean#syncUsers(String[], boolean)
- */
- @Nonnull
- public String[] syncUsers(@Nonnull String[] userIds, boolean purge) {
- context.setKeepMissing(!purge)
- .setForceGroupSync(true)
- .setForceUserSync(true);
- List<String> result = new ArrayList<String>();
- for (String userId: userIds) {
- try {
- SyncResult r = context.sync(userId);
- systemSession.save();
- result.add(getJSONString(r));
- } catch (Exception e) {
- log.warn("Error while syncing user {}", userId, e);
- }
- }
- return result.toArray(new String[result.size()]);
- }
-
- /**
- * @see SynchronizationMBean#syncAllUsers(boolean)
- */
- @Nonnull
- public String[] syncAllUsers(boolean purge) {
- try {
- List<String> list = new ArrayList<String>();
- context.setKeepMissing(!purge)
- .setForceGroupSync(true)
- .setForceUserSync(true);
- Iterator<SyncedIdentity> iter =
handler.listIdentities(userMgr);
- while (iter.hasNext()) {
- SyncedIdentity id = iter.next();
- if (isMyIDP(id)) {
- try {
- SyncResult r = context.sync(id.getId());
- systemSession.save();
- list.add(getJSONString(r));
- } catch (Exception e) {
- log.error("Error while syncing user {}", id, e);
- list.add(getJSONString(id, e));
- }
- }
- }
- return list.toArray(new String[list.size()]);
- } catch (RepositoryException e) {
- throw new IllegalStateException("Error retrieving users for
syncing", e);
- }
- }
-
- /**
- * @see SynchronizationMBean#syncExternalUsers(String[])
- */
- @Nonnull
- public String[] syncExternalUsers(@Nonnull String[] externalIds) {
- List<String> list = new ArrayList<String>();
- context.setForceGroupSync(true).setForceUserSync(true);
- for (String externalId: externalIds) {
- ExternalIdentityRef ref =
ExternalIdentityRef.fromString(externalId);
- try {
- ExternalIdentity id = idp.getIdentity(ref);
- if (id != null) {
- SyncResult r = context.sync(id);
- systemSession.save();
- list.add(getJSONString(r));
- } else {
- SyncResult r = new DefaultSyncResultImpl(
- new DefaultSyncedIdentity("", ref, false, -1),
- SyncResult.Status.NO_SUCH_IDENTITY
- );
- list.add(getJSONString(r));
- }
- } catch (ExternalIdentityException e) {
- log.warn("error while fetching the external identity {}",
externalId, e);
- list.add(getJSONString(ref, e));
- } catch (Exception e) {
- log.error("Error while syncing user {}", ref, e);
- list.add(getJSONString(ref, e));
- }
- }
- return list.toArray(new String[list.size()]);
- }
-
- /**
- * @see SynchronizationMBean#syncAllExternalUsers()
- */
- @Nonnull
- public String[] syncAllExternalUsers() {
- List<String> list = new ArrayList<String>();
- context.setForceGroupSync(true).setForceUserSync(true);
- try {
- Iterator<ExternalUser> iter = idp.listUsers();
- while (iter.hasNext()) {
- ExternalUser user = iter.next();
- try {
- SyncResult r = context.sync(user);
- systemSession.save();
- if (r.getIdentity() == null) {
- r = new DefaultSyncResultImpl(
- new DefaultSyncedIdentity(user.getId(),
user.getExternalId(), false, -1),
- SyncResult.Status.NO_SUCH_IDENTITY
- );
- log.warn("sync failed. {}", r.getIdentity());
- } else {
- log.info("synced {}", r.getIdentity());
- }
- list.add(getJSONString(r));
- } catch (Exception e) {
- log.error("Error while syncing user {}", user, e);
- list.add(getJSONString(user.getExternalId(), e));
- }
- }
- return list.toArray(new String[list.size()]);
- } catch (ExternalIdentityException e) {
- throw new IllegalArgumentException("Unable to retrieve
external users", e);
- }
- }
-
- /**
- * @see SynchronizationMBean#listOrphanedUsers()
- */
- @Nonnull
- public String[] listOrphanedUsers() {
- List<String> list = new ArrayList<String>();
- try {
- Iterator<SyncedIdentity> iter =
handler.listIdentities(userMgr);
- while (iter.hasNext()) {
- SyncedIdentity id = iter.next();
- if (isMyIDP(id)) {
- try {
- ExternalIdentityRef ref = id.getExternalIdRef();
- ExternalIdentity extId = ref == null ? null :
idp.getIdentity(ref);
- if (extId == null) {
- list.add(id.getId());
- }
- } catch (Exception e) {
- log.error("Error while fetching external identity
{}", id, e);
- }
- }
- }
- } catch (RepositoryException e) {
- log.error("Error while listing orphaned users", e);
- }
- return list.toArray(new String[list.size()]);
- }
-
- /**
- * @see SynchronizationMBean#purgeOrphanedUsers()
- */
- @Nonnull
- public String[] purgeOrphanedUsers() {
- context.setKeepMissing(false);
- List<String> result = new ArrayList<String>();
- for (String userId: listOrphanedUsers()) {
- try {
- SyncResult r = context.sync(userId);
- systemSession.save();
- result.add(getJSONString(r));
- } catch (Exception e) {
- log.warn("Error while syncing user {}", userId, e);
- }
- }
- return result.toArray(new String[result.size()]);
- }
-
- private boolean isMyIDP(@Nonnull SyncedIdentity id) {
- String providerName = id.getExternalIdRef() == null
- ? null
- : id.getExternalIdRef().getProviderName();
- return providerName != null && (providerName.isEmpty() ||
providerName.equals(idp.getName()));
- }
- }
-
- private static String getJSONString(@Nonnull SyncResult r) {
- String op;
- switch (r.getStatus()) {
- case NOP:
- op = "nop";
- break;
- case ADD:
- op = "add";
- break;
- case UPDATE:
- op = "upd";
- break;
- case DELETE:
- op = "del";
- break;
- case NO_SUCH_AUTHORIZABLE:
- op = "nsa";
- break;
- case NO_SUCH_IDENTITY:
- op = "nsi";
- break;
- case MISSING:
- op = "mis";
- break;
- case FOREIGN:
- op = "for";
- break;
- default:
- op = "";
- }
- SyncedIdentity syncedIdentity = r.getIdentity();
- String uid = JsonUtil.getJsonString((syncedIdentity == null ? null :
syncedIdentity.getId()));
- ExternalIdentityRef externalIdentityRef = (syncedIdentity == null) ?
null : syncedIdentity.getExternalIdRef();
- String eid = (externalIdentityRef == null) ? "\"\"" :
JsonUtil.getJsonString(externalIdentityRef.getString());
- return String.format("{op:\"%s\",uid:%s,eid:%s}", op, uid, eid);
- }
-
- private static String getJSONString(@Nonnull SyncedIdentity id, @Nonnull
Exception e) {
- String uid = JsonUtil.getJsonString(id.getId());
- String eid = (id.getExternalIdRef() == null) ? "\"\"" :
JsonUtil.getJsonString(id.getExternalIdRef().getString());
- String msg = JsonUtil.getJsonString(e.toString());
- return String.format("{op:\"ERR\",uid:%s,eid:%s,msg:%s}", uid, eid,
msg);
- }
-
- private static String getJSONString(ExternalIdentityRef ref, Exception e) {
- String eid = JsonUtil.getJsonString(ref.getString());
- String msg = JsonUtil.getJsonString(e.toString());
- return String.format("{op:\"ERR\",uid:\"\",eid:%s,msg:%s}", eid, msg);
+ return Delegatee.createInstance(repository, handler, idp);
}
-
//---------------------------------------------------------------------------------------<
SynchronizationMBean >---
+ //-----------------------------------------------< SynchronizationMBean
>---
@Nonnull
@Override
public String getSyncHandlerName() {
Added:
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncRuntimeException.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncRuntimeException.java?rev=1720499&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncRuntimeException.java
(added)
+++
jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncRuntimeException.java
Thu Dec 17 09:30:21 2015
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.jmx;
+
+import javax.annotation.Nonnull;
+
+public class SyncRuntimeException extends RuntimeException {
+
+ public SyncRuntimeException(@Nonnull String message) {
+ super(message);
+ }
+
+ public SyncRuntimeException(@Nonnull String message, @Nonnull Throwable
throwable) {
+ super(message, throwable);
+ }
+}
\ No newline at end of file
Added:
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=1720499&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java
(added)
+++
jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SyncMBeanImplTest.java
Thu Dec 17 09:30:21 2015
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.jmx;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.jcr.Repository;
+
+import org.apache.jackrabbit.oak.jcr.Jcr;
+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.SyncHandler;
+import
org.apache.jackrabbit.oak.spi.security.authentication.external.SyncManager;
+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.impl.DefaultSyncHandler;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class SyncMBeanImplTest {
+
+ private static final String SYNC_NAME = "testSyncName";
+
+ private static Repository REPOSITORY;
+
+ private ExternalIdentityProvider idp;
+ private SyncManager syncMgr;
+ ExternalIdentityProviderManager idpMgr;
+
+ private SyncMBeanImpl syncMBean;
+
+ @BeforeClass
+ public static void beforeClass() {
+ REPOSITORY = new Jcr().createRepository();
+ }
+
+ @Before
+ public void before() {
+ // TODO : proper setup
+ idp = new TestIdentityProvider();
+ syncMgr = new SyncManager() {
+ @CheckForNull
+ @Override
+ public SyncHandler getSyncHandler(@Nonnull String name) {
+ if (SYNC_NAME.equals(name)) {
+ return new DefaultSyncHandler(new DefaultSyncConfig());
+ } else {
+ return null;
+ }
+ }
+ };
+ idpMgr = new ExternalIdentityProviderManager() {
+ @CheckForNull
+ @Override
+ public ExternalIdentityProvider getProvider(@Nonnull String name) {
+ if (name.equals(idp.getName())) {
+ return idp;
+ } else {
+ return null;
+ }
+ }
+ };
+ syncMBean = new SyncMBeanImpl(REPOSITORY, syncMgr, SYNC_NAME, idpMgr,
idp.getName());
+ }
+
+ @Test
+ public void testGetSyncHandlerName() {
+ assertEquals(SYNC_NAME, syncMBean.getSyncHandlerName());
+ }
+
+ @Test
+ public void testInvalidSyncHandlerName() {
+ SyncMBeanImpl syncMBean = new SyncMBeanImpl(REPOSITORY, syncMgr,
"invalid", idpMgr, idp.getName());
+ assertEquals("invalid", syncMBean.getSyncHandlerName());
+
+ // calling any sync-operation must fail due to the invalid
configuration
+ try {
+ syncMBean.syncAllExternalUsers();
+ fail("syncAllExternalUsers with invalid SyncHandlerName must
fail");
+ } catch (IllegalArgumentException e) {
+ //success
+ }
+ }
+
+ @Test
+ public void testGetIDPName() {
+ assertEquals(idp.getName(), syncMBean.getIDPName());
+ }
+
+ @Test
+ public void testInvalidIDPName() {
+ SyncMBeanImpl syncMBean = new SyncMBeanImpl(REPOSITORY, syncMgr,
SYNC_NAME, idpMgr, "invalid");
+ assertEquals("invalid", syncMBean.getIDPName());
+
+ // calling any sync-operation must fail due to the invalid
configuration
+ try {
+ syncMBean.syncAllExternalUsers();
+ fail("syncAllExternalUsers with invalid IDP name must fail");
+ } catch (IllegalArgumentException e) {
+ //success
+ }
+ }
+
+ @Test
+ public void testSyncUsers() {
+ // TODO
+ }
+
+ @Test
+ public void testSyncAllUsers() {
+ // TODO
+ }
+
+ @Test
+ public void testSyncExternalUsers() {
+ // TODO
+ }
+
+ @Test
+ public void testSyncAllExternalUsers() {
+ // TODO
+ }
+
+ @Test
+ public void testListOrphanedUsers() {
+ // TODO
+ }
+
+ @Test
+ public void testPurgeOrphanedUsers() {
+ // TODO
+ }
+}
\ No newline at end of file