Continue framework clean up.
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 10 Aug 2016 17:41:06 +0000 (17:41 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 10 Aug 2016 17:41:06 +0000 (17:41 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@9082 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

27 files changed:
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeDeployConfig.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java
org.argeo.cms/src/org/argeo/cms/internal/transaction/SimpleTransaction.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/transaction/SimpleTransactionManager.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/transaction/UuidXid.java [deleted file]
org.argeo.security.core/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/LdifUserAdmin.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/UserAdminConf.java
org.argeo.security.core/src/org/argeo/osgi/useradmin/internal/UserDirectoryFactory.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/AbstractUserAdminWrapper.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminUtils.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminWrapper.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteGroups.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/DeleteUsers.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/commands/NewUser.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupsView.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserBatchUpdateWizard.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserEditor.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UserMainPage.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/UsersView.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/CommonNameLP.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/DomainNameLP.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/MailLP.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserAdminAbstractLP.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/providers/UserFilter.java

index 49f8c20a50be2580e8751683224a9fea25d367cb..cb22e2790c055f7e021cd9a3dbdfd419e5dd095e 100644 (file)
@@ -30,8 +30,8 @@ import org.osgi.framework.FrameworkUtil;
 
 /** Package utilities */
 class KernelUtils implements KernelConstants {
-       private final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
-       private final static String OSGI_CONFIGURATION_AREA = "osgi.configuration.area";
+       final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
+       final static String OSGI_CONFIGURATION_AREA = "osgi.configuration.area";
 
        static Dictionary<String, ?> asDictionary(Properties props) {
                Hashtable<String, Object> hashtable = new Hashtable<String, Object>();
@@ -73,19 +73,20 @@ class KernelUtils implements KernelConstants {
 
        static URI getOsgiInstanceUri(String relativePath) {
                String osgiInstanceBaseUri = getFrameworkProp(OSGI_INSTANCE_AREA);
-                       return safeUri(osgiInstanceBaseUri + (relativePath != null ? relativePath : ""));
+               return safeUri(osgiInstanceBaseUri + (relativePath != null ? relativePath : ""));
        }
 
-//     static String getOsgiInstancePath(String relativePath) {
-//             try {
-//                     if (relativePath == null)
-//                             return getOsgiInstanceDir().getCanonicalPath();
-//                     else
-//                             return new File(getOsgiInstanceDir(), relativePath).getCanonicalPath();
-//             } catch (IOException e) {
-//                     throw new CmsException("Cannot get instance path for " + relativePath, e);
-//             }
-//     }
+       // static String getOsgiInstancePath(String relativePath) {
+       // try {
+       // if (relativePath == null)
+       // return getOsgiInstanceDir().getCanonicalPath();
+       // else
+       // return new File(getOsgiInstanceDir(), relativePath).getCanonicalPath();
+       // } catch (IOException e) {
+       // throw new CmsException("Cannot get instance path for " + relativePath,
+       // e);
+       // }
+       // }
 
        static File getOsgiConfigurationFile(String relativePath) {
                try {
@@ -195,14 +196,14 @@ class KernelUtils implements KernelConstants {
        private static BundleContext getBundleContext() {
                return getBundleContext(KernelUtils.class);
        }
-       
-       private static URI safeUri(String uri){
-               if(uri==null)
+
+       private static URI safeUri(String uri) {
+               if (uri == null)
                        throw new CmsException("URI cannot be null");
                try {
                        return new URI(uri);
                } catch (URISyntaxException e) {
-                       throw new CmsException("Dadly formatted URI "+uri, e);
+                       throw new CmsException("Dadly formatted URI " + uri, e);
                }
        }
 
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeDeployConfig.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeDeployConfig.java
new file mode 100644 (file)
index 0000000..85906b0
--- /dev/null
@@ -0,0 +1,100 @@
+package org.argeo.cms.internal.kernel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.SortedMap;
+import java.util.function.Function;
+
+import javax.naming.InvalidNameException;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+import org.argeo.cms.CmsException;
+import org.argeo.node.NodeConstants;
+import org.argeo.node.RepoConf;
+import org.argeo.util.naming.AttributesDictionary;
+import org.argeo.util.naming.LdifParser;
+import org.argeo.util.naming.LdifWriter;
+
+class NodeDeployConfig {
+       private final String BASE = "ou=deploy,ou=node";
+       private final Path path;
+       private final Function<String, String> getter;
+
+       private final SortedMap<LdapName, Attributes> configurations;
+
+       public NodeDeployConfig(Function<String, String> getter) {
+               String osgiConfigurationArea = getter.apply(KernelUtils.OSGI_CONFIGURATION_AREA);
+               try {
+                       this.path = Paths.get(new URI(osgiConfigurationArea));
+               } catch (URISyntaxException e) {
+                       throw new IllegalArgumentException("Cannot parse " + getter.apply(KernelUtils.OSGI_CONFIGURATION_AREA), e);
+               }
+               this.getter = getter;
+
+               if (!Files.exists(path))
+                       try (Writer writer = Files.newBufferedWriter(path)) {
+                               Files.createFile(path);
+                               LdifWriter ldifWriter = new LdifWriter(writer);
+                       } catch (IOException e) {
+                               throw new CmsException("Cannot create " + path, e);
+                       }
+               
+               try (InputStream in = Files.newInputStream(path)) {
+                       configurations = new LdifParser().read(in);
+               } catch (IOException e) {
+                       throw new CmsException("Cannot read " + path, e);
+               }
+       }
+
+       public Dictionary<String, Object> getConfiguration(String servicePid) {
+               LdapName dn;
+               try {
+                       dn = new LdapName("ou=" + servicePid + "," + BASE);
+               } catch (InvalidNameException e) {
+                       throw new IllegalArgumentException("Cannot parse DN", e);
+               }
+               if (configurations.containsKey(dn))
+                       return new AttributesDictionary(configurations.get(dn));
+               else
+                       return null;
+       }
+       
+       static Dictionary<String, Object> getStatePropertiesFromEnvironment(Function<String, String> getter) {
+               Hashtable<String, Object> props = new Hashtable<>();
+               // i18n
+               copyFrameworkProp(getter, NodeConstants.I18N_DEFAULT_LOCALE, props);
+               copyFrameworkProp(getter, NodeConstants.I18N_LOCALES, props);
+               // user admin
+               copyFrameworkProp(getter, NodeConstants.ROLES_URI, props);
+               copyFrameworkProp(getter, NodeConstants.USERADMIN_URIS, props);
+               // data
+               for (RepoConf repoConf : RepoConf.values())
+                       copyFrameworkProp(getter, NodeConstants.NODE_REPO_PROP_PREFIX + repoConf.name(), props);
+               // TODO add other environment sources
+               return props;
+       }
+
+       static Dictionary<String, Object> getUserAdminPropertiesFromEnvironment(Function<String, String> getter) {
+               Hashtable<String, Object> props = new Hashtable<>();
+               copyFrameworkProp(getter, NodeConstants.ROLES_URI, props);
+               copyFrameworkProp(getter, NodeConstants.USERADMIN_URIS, props);
+               return props;
+       }
+
+       private static void copyFrameworkProp(Function<String, String> getter, String key,
+                       Dictionary<String, Object> props) {
+               String value = getter.apply(key);
+               if (value != null)
+                       props.put(key, value);
+       }
+
+}
index 8f1c36860e525e73b2d1c2a0c1d0a6dde20193e0..fd9ba31dfbe76ba6cd0e502fc42b042fadbfaa23 100644 (file)
@@ -365,7 +365,7 @@ class NodeUserAdmin implements UserAdmin, ManagedService, KernelConstants {
                }
 
                Dictionary<String, ?> nodeRolesProperties = UserAdminConf.uriAsProperties(nodeRolesUri);
-               if (!nodeRolesProperties.get(UserAdminConf.baseDn.property()).equals(baseNodeRoleDn)) {
+               if (!nodeRolesProperties.get(UserAdminConf.baseDn.name()).equals(baseNodeRoleDn)) {
                        throw new CmsException("Invalid base dn for node roles");
                        // TODO deal with "mounted" roles with a different baseDN
                }
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/transaction/SimpleTransaction.java b/org.argeo.cms/src/org/argeo/cms/internal/transaction/SimpleTransaction.java
deleted file mode 100644 (file)
index f3a27fe..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-package org.argeo.cms.internal.transaction;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-class SimpleTransaction implements Transaction, Status {
-       private final static Log log = LogFactory.getLog(SimpleTransaction.class);
-
-       private final Xid xid;
-       private int status = Status.STATUS_ACTIVE;
-       private final List<XAResource> xaResources = new ArrayList<XAResource>();
-
-       private final SimpleTransactionManager transactionManager;
-
-       public SimpleTransaction(SimpleTransactionManager transactionManager) {
-               this.xid = new UuidXid();
-               this.transactionManager = transactionManager;
-       }
-
-       @Override
-       public synchronized void commit() throws RollbackException,
-                       HeuristicMixedException, HeuristicRollbackException,
-                       SecurityException, IllegalStateException, SystemException {
-               status = STATUS_PREPARING;
-               for (XAResource xaRes : xaResources) {
-                       if (status == STATUS_MARKED_ROLLBACK)
-                               break;
-                       try {
-                               xaRes.prepare(xid);
-                       } catch (XAException e) {
-                               status = STATUS_MARKED_ROLLBACK;
-                               log.error("Cannot prepare " + xaRes + " for " + xid, e);
-                       }
-               }
-               if (status == STATUS_MARKED_ROLLBACK) {
-                       rollback();
-                       throw new RollbackException();
-               }
-               status = STATUS_PREPARED;
-
-               status = STATUS_COMMITTING;
-               for (XAResource xaRes : xaResources) {
-                       if (status == STATUS_MARKED_ROLLBACK)
-                               break;
-                       try {
-                               xaRes.commit(xid, false);
-                       } catch (XAException e) {
-                               status = STATUS_MARKED_ROLLBACK;
-                               log.error("Cannot prepare " + xaRes + " for " + xid, e);
-                       }
-               }
-               if (status == STATUS_MARKED_ROLLBACK) {
-                       rollback();
-                       throw new RollbackException();
-               }
-
-               // complete
-               status = STATUS_COMMITTED;
-               if (log.isDebugEnabled())
-                       log.debug("COMMITTED  " + xid);
-               clearResources(XAResource.TMSUCCESS);
-               transactionManager.unregister(xid);
-       }
-
-       @Override
-       public synchronized void rollback() throws IllegalStateException,
-                       SystemException {
-               status = STATUS_ROLLING_BACK;
-               for (XAResource xaRes : xaResources) {
-                       try {
-                               xaRes.rollback(xid);
-                       } catch (XAException e) {
-                               log.error("Cannot rollback " + xaRes + " for " + xid, e);
-                       }
-               }
-
-               // complete
-               status = STATUS_ROLLEDBACK;
-               if (log.isDebugEnabled())
-                       log.debug("ROLLEDBACK " + xid);
-               clearResources(XAResource.TMFAIL);
-               transactionManager.unregister(xid);
-       }
-
-       @Override
-       public synchronized boolean enlistResource(XAResource xaRes)
-                       throws RollbackException, IllegalStateException, SystemException {
-               if (xaResources.add(xaRes)) {
-                       try {
-                               xaRes.start(getXid(), XAResource.TMNOFLAGS);
-                               return true;
-                       } catch (XAException e) {
-                               log.error("Cannot enlist " + xaRes, e);
-                               return false;
-                       }
-               } else
-                       return false;
-       }
-
-       @Override
-       public synchronized boolean delistResource(XAResource xaRes, int flag)
-                       throws IllegalStateException, SystemException {
-               if (xaResources.remove(xaRes)) {
-                       try {
-                               xaRes.end(getXid(), flag);
-                       } catch (XAException e) {
-                               log.error("Cannot delist " + xaRes, e);
-                               return false;
-                       }
-                       return true;
-               } else
-                       return false;
-       }
-
-       protected void clearResources(int flag) {
-               for (XAResource xaRes : xaResources)
-                       try {
-                               xaRes.end(getXid(), flag);
-                       } catch (XAException e) {
-                               log.error("Cannot end " + xaRes, e);
-                       }
-               xaResources.clear();
-       }
-
-       @Override
-       public synchronized int getStatus() throws SystemException {
-               return status;
-       }
-
-       @Override
-       public void registerSynchronization(Synchronization sync)
-                       throws RollbackException, IllegalStateException, SystemException {
-               throw new UnsupportedOperationException();
-       }
-
-       @Override
-       public void setRollbackOnly() throws IllegalStateException, SystemException {
-               status = STATUS_MARKED_ROLLBACK;
-       }
-
-       @Override
-       public int hashCode() {
-               return xid.hashCode();
-       }
-
-       Xid getXid() {
-               return xid;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/transaction/SimpleTransactionManager.java b/org.argeo.cms/src/org/argeo/cms/internal/transaction/SimpleTransactionManager.java
deleted file mode 100644 (file)
index 30d9b72..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-package org.argeo.cms.internal.transaction;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
-import javax.transaction.UserTransaction;
-import javax.transaction.xa.Xid;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.CmsException;
-
-public class SimpleTransactionManager implements TransactionManager,
-               UserTransaction {
-       private final static Log log = LogFactory
-                       .getLog(SimpleTransactionManager.class);
-
-       private ThreadLocal<SimpleTransaction> current = new ThreadLocal<SimpleTransaction>();
-
-       private Map<Xid, SimpleTransaction> knownTransactions = Collections
-                       .synchronizedMap(new HashMap<Xid, SimpleTransaction>());
-       private SyncRegistry syncRegistry = new SyncRegistry();
-
-       @Override
-       public void begin() throws NotSupportedException, SystemException {
-               if (getCurrent() != null)
-                       throw new NotSupportedException(
-                                       "Nested transactions are not supported");
-               SimpleTransaction transaction = new SimpleTransaction(this);
-               knownTransactions.put(transaction.getXid(), transaction);
-               current.set(transaction);
-               if (log.isDebugEnabled())
-                       log.debug("STARTED    " + transaction.getXid());
-       }
-
-       @Override
-       public void commit() throws RollbackException, HeuristicMixedException,
-                       HeuristicRollbackException, SecurityException,
-                       IllegalStateException, SystemException {
-               if (getCurrent() == null)
-                       throw new IllegalStateException(
-                                       "No transaction registered with the current thread.");
-               getCurrent().commit();
-       }
-
-       @Override
-       public int getStatus() throws SystemException {
-               if (getCurrent() == null)
-                       return Status.STATUS_NO_TRANSACTION;
-               return getTransaction().getStatus();
-       }
-
-       @Override
-       public Transaction getTransaction() throws SystemException {
-               return getCurrent();
-       }
-
-       protected SimpleTransaction getCurrent() throws SystemException {
-               SimpleTransaction transaction = current.get();
-               if (transaction == null)
-                       return null;
-               int status = transaction.getStatus();
-               if (Status.STATUS_COMMITTED == status
-                               || Status.STATUS_ROLLEDBACK == status) {
-                       current.remove();
-                       return null;
-               }
-               return transaction;
-       }
-       
-       void unregister(Xid xid){
-               knownTransactions.remove(xid);
-       }
-
-       @Override
-       public void resume(Transaction tobj) throws InvalidTransactionException,
-                       IllegalStateException, SystemException {
-               if (getCurrent() != null)
-                       throw new IllegalStateException("Transaction " + current.get()
-                                       + " already registered");
-               current.set((SimpleTransaction) tobj);
-       }
-
-       @Override
-       public void rollback() throws IllegalStateException, SecurityException,
-                       SystemException {
-               if (getCurrent() == null)
-                       throw new IllegalStateException(
-                                       "No transaction registered with the current thread.");
-               getCurrent().rollback();
-       }
-
-       @Override
-       public void setRollbackOnly() throws IllegalStateException, SystemException {
-               if (getCurrent() == null)
-                       throw new IllegalStateException(
-                                       "No transaction registered with the current thread.");
-               getCurrent().setRollbackOnly();
-       }
-
-       @Override
-       public void setTransactionTimeout(int seconds) throws SystemException {
-               throw new UnsupportedOperationException();
-       }
-
-       @Override
-       public Transaction suspend() throws SystemException {
-               Transaction transaction = getCurrent();
-               current.remove();
-               return transaction;
-       }
-
-       public TransactionSynchronizationRegistry getTsr() {
-               return syncRegistry;
-       }
-
-       private class SyncRegistry implements TransactionSynchronizationRegistry {
-               @Override
-               public Object getTransactionKey() {
-                       try {
-                               SimpleTransaction transaction = getCurrent();
-                               if (transaction == null)
-                                       return null;
-                               return getCurrent().getXid();
-                       } catch (SystemException e) {
-                               throw new CmsException("Cannot get transaction key", e);
-                       }
-               }
-
-               @Override
-               public void putResource(Object key, Object value) {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public Object getResource(Object key) {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public void registerInterposedSynchronization(Synchronization sync) {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public int getTransactionStatus() {
-                       try {
-                               return getStatus();
-                       } catch (SystemException e) {
-                               throw new CmsException("Cannot get status", e);
-                       }
-               }
-
-               @Override
-               public boolean getRollbackOnly() {
-                       try {
-                               return getStatus() == Status.STATUS_MARKED_ROLLBACK;
-                       } catch (SystemException e) {
-                               throw new CmsException("Cannot get status", e);
-                       }
-               }
-
-               @Override
-               public void setRollbackOnly() {
-                       try {
-                               getCurrent().setRollbackOnly();
-                       } catch (Exception e) {
-                               throw new CmsException("Cannot set rollback only", e);
-                       }
-               }
-
-       }
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/transaction/UuidXid.java b/org.argeo.cms/src/org/argeo/cms/internal/transaction/UuidXid.java
deleted file mode 100644 (file)
index 18975ea..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.argeo.cms.internal.transaction;
-
-import java.io.Serializable;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.UUID;
-
-import javax.transaction.xa.Xid;
-
-/**
- * Implementation of {@link Xid} based on {@link UUID}, using max significant
- * bits as global transaction id, and least significant bits as branch
- * qualifier.
- */
-public class UuidXid implements Xid, Serializable {
-       private static final long serialVersionUID = -5380531989917886819L;
-       public final static int FORMAT = (int) serialVersionUID;
-
-       private final static int BYTES_PER_LONG = Long.SIZE / Byte.SIZE;
-
-       private final int format;
-       private final byte[] globalTransactionId;
-       private final byte[] branchQualifier;
-       private final String uuid;
-       private final int hashCode;
-
-       public UuidXid() {
-               this(UUID.randomUUID());
-       }
-
-       public UuidXid(UUID uuid) {
-               this.format = FORMAT;
-               this.globalTransactionId = uuidToBytes(uuid.getMostSignificantBits());
-               this.branchQualifier = uuidToBytes(uuid.getLeastSignificantBits());
-               this.uuid = uuid.toString();
-               this.hashCode = uuid.hashCode();
-       }
-
-       public UuidXid(Xid xid) {
-               this(xid.getFormatId(), xid.getGlobalTransactionId(), xid
-                               .getBranchQualifier());
-       }
-
-       private UuidXid(int format, byte[] globalTransactionId,
-                       byte[] branchQualifier) {
-               this.format = format;
-               this.globalTransactionId = globalTransactionId;
-               this.branchQualifier = branchQualifier;
-               this.uuid = bytesToUUID(globalTransactionId, branchQualifier)
-                               .toString();
-               this.hashCode = uuid.hashCode();
-       }
-
-       @Override
-       public int getFormatId() {
-               return format;
-       }
-
-       @Override
-       public byte[] getGlobalTransactionId() {
-               return Arrays.copyOf(globalTransactionId, globalTransactionId.length);
-       }
-
-       @Override
-       public byte[] getBranchQualifier() {
-               return Arrays.copyOf(branchQualifier, branchQualifier.length);
-       }
-
-       @Override
-       public int hashCode() {
-               return hashCode;
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (this == obj)
-                       return true;
-               if (obj instanceof UuidXid) {
-                       UuidXid that = (UuidXid) obj;
-                       return Arrays.equals(globalTransactionId, that.globalTransactionId)
-                                       && Arrays.equals(branchQualifier, that.branchQualifier);
-               }
-               if (obj instanceof Xid) {
-                       Xid that = (Xid) obj;
-                       return Arrays.equals(globalTransactionId,
-                                       that.getGlobalTransactionId())
-                                       && Arrays
-                                                       .equals(branchQualifier, that.getBranchQualifier());
-               }
-               return uuid.equals(obj.toString());
-       }
-
-       @Override
-       protected Object clone() throws CloneNotSupportedException {
-               return new UuidXid(format, globalTransactionId, branchQualifier);
-       }
-
-       @Override
-       public String toString() {
-               return uuid;
-       }
-
-       public UUID asUuid() {
-               return bytesToUUID(globalTransactionId, branchQualifier);
-       }
-
-       public static byte[] uuidToBytes(long bits) {
-               ByteBuffer buffer = ByteBuffer.allocate(BYTES_PER_LONG);
-               buffer.putLong(0, bits);
-               return buffer.array();
-       }
-
-       public static UUID bytesToUUID(byte[] most, byte[] least) {
-               if (most.length < BYTES_PER_LONG)
-                       most = Arrays.copyOf(most, BYTES_PER_LONG);
-               if (least.length < BYTES_PER_LONG)
-                       least = Arrays.copyOf(least, BYTES_PER_LONG);
-               ByteBuffer buffer = ByteBuffer.allocate(2 * BYTES_PER_LONG);
-               buffer.put(most, 0, BYTES_PER_LONG);
-               buffer.put(least, 0, BYTES_PER_LONG);
-               buffer.flip();
-               return new UUID(buffer.getLong(), buffer.getLong());
-       }
-
-       // public static void main(String[] args) {
-       // UUID uuid = UUID.randomUUID();
-       // System.out.println(uuid);
-       // uuid = bytesToUUID(uuidToBytes(uuid.getMostSignificantBits()),
-       // uuidToBytes(uuid.getLeastSignificantBits()));
-       // System.out.println(uuid);
-       // }
-}
index 768610b8e22ae68262e8f8ca9d54abd5851ba70f..121fb3500480b955447d47fa2be0053e971d66c5 100644 (file)
@@ -57,13 +57,8 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory {
        private List<String> credentialAttributeIds = Arrays.asList(new String[] { LdifName.userPassword.name() });
 
        private TransactionManager transactionManager;
-       // private TransactionSynchronizationRegistry transactionRegistry;
-       // private Xid editingTransactionXid = null;
        private WcXaResource xaResource = new WcXaResource(this);
 
-       // POSIX
-       private String homeDirectoryBase = "/home";
-
        AbstractUserDirectory(Dictionary<String, ?> props) {
                properties = new Hashtable<String, Object>();
                for (Enumeration<String> keys = props.keys(); keys.hasMoreElements();) {
@@ -85,7 +80,7 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory {
                String readOnlyStr = UserAdminConf.readOnly.getValue(properties);
                if (readOnlyStr == null) {
                        readOnly = readOnlyDefault(uri);
-                       properties.put(UserAdminConf.readOnly.property(), Boolean.toString(readOnly));
+                       properties.put(UserAdminConf.readOnly.name(), Boolean.toString(readOnly));
                } else
                        readOnly = new Boolean(readOnlyStr);
 
@@ -111,21 +106,13 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory {
        }
 
        boolean isEditing() {
-               // if (editingTransactionXid == null)
-               // return false;
-               // return workingCopy.get() != null;
                return xaResource.wc() != null;
        }
 
        protected UserDirectoryWorkingCopy getWorkingCopy() {
-               // UserDirectoryWorkingCopy wc = workingCopy.get();
                UserDirectoryWorkingCopy wc = xaResource.wc();
                if (wc == null)
                        return null;
-               // if (wc.getXid() == null) {
-               // workingCopy.set(null);
-               // return null;
-               // }
                return wc;
        }
 
@@ -139,24 +126,12 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory {
                if (transaction == null)
                        throw new UserDirectoryException("A transaction needs to be active in order to edit");
                if (xaResource.wc() == null) {
-                       // UserDirectoryWorkingCopy wc = new UserDirectoryWorkingCopy(this);
                        try {
                                transaction.enlistResource(xaResource);
-                               // editingTransactionXid = wc.getXid();
-                               // workingCopy.set(wc);
                        } catch (Exception e) {
                                throw new UserDirectoryException("Cannot enlist " + xaResource, e);
                        }
                } else {
-                       // UserDirectoryWorkingCopy wc = xaResource.wc();
-                       // if (wc == null)
-                       // throw new UserDirectoryException("Transaction "
-                       // + editingTransactionXid + " already editing");
-                       // else if
-                       // (!editingTransactionXid.equals(workingCopy.get().getXid()))
-                       // throw new UserDirectoryException("Working copy Xid "
-                       // + workingCopy.get().getXid() + " inconsistent with"
-                       // + editingTransactionXid);
                }
        }
 
@@ -336,62 +311,6 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory {
                return actuallyDeleted;
        }
 
-       // // POSIX
-       // /** Generate path for a new user home */
-       // protected String generateHomeDirectory(String username) {
-       // String base = homeDirectoryBase;
-       // int atIndex = username.indexOf('@');
-       // if (atIndex > 0) {
-       // String domain = username.substring(0, atIndex);
-       // String name = username.substring(atIndex + 1);
-       // return base + '/' + firstCharsToPath(domain, 2) + '/' + domain + '/' +
-       // firstCharsToPath(name, 2) + '/'
-       // + name;
-       // } else if (atIndex == 0 || atIndex == (username.length() - 1)) {
-       // throw new ArgeoException("Unsupported username " + username);
-       // } else {
-       // return base + '/' + firstCharsToPath(username, 2) + '/' + username;
-       // }
-       // }
-       //
-       // protected long max(String attr) {
-       // long max;
-       // try {
-       // List<DirectoryUser> users = doGetRoles(FrameworkUtil.createFilter("(" +
-       // attr + "=*)"));
-       // max = 1000;
-       // for (DirectoryUser user : users) {
-       // long uid =
-       // Long.parseLong(user.getAttributes().get(attr).get().toString());
-       // if (uid > max)
-       // max = uid;
-       // }
-       // } catch (Exception e) {
-       // throw new UserDirectoryException("Cannot get max of " + attr, e);
-       // }
-       // return max;
-       // }
-
-       // /**
-       // * Creates depth from a string (typically a username) by adding levels
-       // based
-       // * on its first characters: "aBcD",2 => a/aB
-       // */
-       // public static String firstCharsToPath(String str, Integer nbrOfChars) {
-       // if (str.length() < nbrOfChars)
-       // throw new ArgeoException("String " + str + " length must be greater or
-       // equal than " + nbrOfChars);
-       // StringBuffer path = new StringBuffer("");
-       // StringBuffer curr = new StringBuffer("");
-       // for (int i = 0; i < nbrOfChars; i++) {
-       // curr.append(str.charAt(i));
-       // path.append(curr);
-       // if (i < nbrOfChars - 1)
-       // path.append('/');
-       // }
-       // return path.toString();
-       // }
-
        // TRANSACTION
        protected void prepare(UserDirectoryWorkingCopy wc) {
 
@@ -405,10 +324,6 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory {
 
        }
 
-       // void clearEditingTransactionXid() {
-       // editingTransactionXid = null;
-       // }
-
        // UTILITIES
        protected LdapName toDn(String name) {
                try {
@@ -419,7 +334,6 @@ abstract class AbstractUserDirectory implements UserAdmin, UserDirectory {
        }
 
        // GETTERS
-
        String getMemberAttributeId() {
                return memberAttributeId;
        }
index fbedeb79c81422917fb035b261aaedd296510a99..366c32fa0da5edf1e41fae8518706ba0a5742f04 100644 (file)
@@ -51,8 +51,8 @@ public class LdifUserAdmin extends AbstractUserDirectory {
 
        private static Dictionary<String, Object> fromUri(String uri, String baseDn) {
                Hashtable<String, Object> res = new Hashtable<String, Object>();
-               res.put(UserAdminConf.uri.property(), uri);
-               res.put(UserAdminConf.baseDn.property(), baseDn);
+               res.put(UserAdminConf.uri.name(), uri);
+               res.put(UserAdminConf.baseDn.name(), baseDn);
                return res;
        }
 
index baf487bb033cda57419034d8ffac1d00e4525c4d..5a9cd8c410d68afb7b6ed3644140c043388a15a1 100644 (file)
@@ -37,7 +37,7 @@ public enum UserAdminConf {
        /** Read-only source */
        readOnly(null);
 
-       public final static String PREFIX = "argeo.useradmin";
+       public final static String FACTORY_PID = "org.argeo.osgi.useradmin.config";
 
        /** The default value. */
        private Object def;
@@ -50,13 +50,14 @@ public enum UserAdminConf {
                return def;
        }
 
-       /** For use as Java property. */
+       /**
+        * For use as Java property.
+        * 
+        * @deprecated use {@link #name()} instead
+        */
+       @Deprecated
        public String property() {
-               return getPrefix() + '.' + name();
-       }
-
-       public String getPrefix() {
-               return PREFIX;
+               return name();
        }
 
        public String getValue(Dictionary<String, ?> properties) {
@@ -68,14 +69,16 @@ public enum UserAdminConf {
 
        @SuppressWarnings("unchecked")
        public <T> T getRawValue(Dictionary<String, ?> properties) {
-               Object res = properties.get(property());
+               Object res = properties.get(name());
                if (res == null)
                        res = getDefault();
                return (T) res;
        }
 
+       /** @deprecated use {@link #valueOf(String)} instead */
+       @Deprecated
        public static UserAdminConf local(String property) {
-               return UserAdminConf.valueOf(property.substring(PREFIX.length() + 1));
+               return UserAdminConf.valueOf(property);
        }
 
        /** Hides host and credentials. */
@@ -83,27 +86,24 @@ public enum UserAdminConf {
                StringBuilder query = new StringBuilder();
 
                boolean first = true;
-               for (Enumeration<String> keys = properties.keys(); keys
-                               .hasMoreElements();) {
+               for (Enumeration<String> keys = properties.keys(); keys.hasMoreElements();) {
                        String key = keys.nextElement();
-                       if (key.startsWith(PREFIX) && !key.equals(baseDn.property())
-                                       && !key.equals(uri.property())) {
+                       if (!key.startsWith("java") && !key.equals(baseDn.name()) && !key.equals(uri.name())) {
                                if (first)
                                        first = false;
                                else
                                        query.append('&');
-                               query.append(local(key).name());
+                               query.append(valueOf(key).name());
                                query.append('=').append(properties.get(key).toString());
                        }
                }
 
-               String bDn = (String) properties.get(baseDn.property());
+               String bDn = (String) properties.get(baseDn.name());
                try {
-                       return new URI(null, null, bDn != null ? '/' + bDn : null,
-                                       query.length() != 0 ? query.toString() : null, null);
+                       return new URI(null, null, bDn != null ? '/' + bDn : null, query.length() != 0 ? query.toString() : null,
+                                       null);
                } catch (URISyntaxException e) {
-                       throw new UserDirectoryException(
-                                       "Cannot create URI from properties", e);
+                       throw new UserDirectoryException("Cannot create URI from properties", e);
                }
        }
 
@@ -113,8 +113,7 @@ public enum UserAdminConf {
                        URI u = new URI(uriStr);
                        String scheme = u.getScheme();
                        String path = u.getPath();
-                       String bDn = path.substring(path.lastIndexOf('/') + 1,
-                                       path.length());
+                       String bDn = path.substring(path.lastIndexOf('/') + 1, path.length());
                        if (bDn.endsWith(".ldif"))
                                bDn = bDn.substring(0, bDn.length() - ".ldif".length());
 
@@ -128,20 +127,18 @@ public enum UserAdminConf {
                                        credentials = userInfo.length > 1 ? userInfo[1] : null;
                                } else if (scheme.equals("file")) {
                                } else
-                                       throw new UserDirectoryException("Unsupported scheme "
-                                                       + scheme);
+                                       throw new UserDirectoryException("Unsupported scheme " + scheme);
                        Map<String, List<String>> query = splitQuery(u.getQuery());
                        for (String key : query.keySet()) {
                                UserAdminConf ldapProp = UserAdminConf.valueOf(key);
                                List<String> values = query.get(key);
                                if (values.size() == 1) {
-                                       res.put(ldapProp.property(), values.get(0));
+                                       res.put(ldapProp.name(), values.get(0));
                                } else {
-                                       throw new UserDirectoryException(
-                                                       "Only single values are supported");
+                                       throw new UserDirectoryException("Only single values are supported");
                                }
                        }
-                       res.put(baseDn.property(), bDn);
+                       res.put(baseDn.name(), bDn);
                        if (principal != null)
                                res.put(Context.SECURITY_PRINCIPAL, principal);
                        if (credentials != null)
@@ -149,48 +146,42 @@ public enum UserAdminConf {
                        if (scheme != null) {
                                URI bareUri = new URI(scheme, null, u.getHost(), u.getPort(),
                                                scheme.equals("file") ? u.getPath() : null, null, null);
-                               res.put(uri.property(), bareUri.toString());
+                               res.put(uri.name(), bareUri.toString());
                        }
                        return res;
                } catch (Exception e) {
-                       throw new UserDirectoryException("Cannot convert " + uri
-                                       + " to properties", e);
+                       throw new UserDirectoryException("Cannot convert " + uri + " to properties", e);
                }
        }
 
-       private static Map<String, List<String>> splitQuery(String query)
-                       throws UnsupportedEncodingException {
+       private static Map<String, List<String>> splitQuery(String query) throws UnsupportedEncodingException {
                final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
                if (query == null)
                        return query_pairs;
                final String[] pairs = query.split("&");
                for (String pair : pairs) {
                        final int idx = pair.indexOf("=");
-                       final String key = idx > 0 ? URLDecoder.decode(
-                                       pair.substring(0, idx), "UTF-8") : pair;
+                       final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
                        if (!query_pairs.containsKey(key)) {
                                query_pairs.put(key, new LinkedList<String>());
                        }
-                       final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder
-                                       .decode(pair.substring(idx + 1), "UTF-8") : null;
+                       final String value = idx > 0 && pair.length() > idx + 1
+                                       ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;
                        query_pairs.get(key).add(value);
                }
                return query_pairs;
        }
 
        public static void main(String[] args) {
-               Dictionary<String, ?> props = uriAsProperties("ldap://"
-                               + "uid=admin,ou=system:secret@localhost:10389"
-                               + "/dc=example,dc=com"
-                               + "?readOnly=false&userObjectClass=person");
+               Dictionary<String, ?> props = uriAsProperties("ldap://" + "uid=admin,ou=system:secret@localhost:10389"
+                               + "/dc=example,dc=com" + "?readOnly=false&userObjectClass=person");
                System.out.println(props);
                System.out.println(propertiesAsUri(props));
 
-               System.out
-                               .println(uriAsProperties("file://some/dir/dc=example,dc=com.ldif"));
+               System.out.println(uriAsProperties("file://some/dir/dc=example,dc=com.ldif"));
 
-               props = uriAsProperties("/dc=example,dc=com.ldif?readOnly=true"
-                               + "&userBase=ou=CoWorkers,ou=People&groupBase=ou=Roles");
+               props = uriAsProperties(
+                               "/dc=example,dc=com.ldif?readOnly=true" + "&userBase=ou=CoWorkers,ou=People&groupBase=ou=Roles");
                System.out.println(props);
                System.out.println(propertiesAsUri(props));
        }
diff --git a/org.argeo.security.core/src/org/argeo/osgi/useradmin/internal/UserDirectoryFactory.java b/org.argeo.security.core/src/org/argeo/osgi/useradmin/internal/UserDirectoryFactory.java
new file mode 100644 (file)
index 0000000..2182028
--- /dev/null
@@ -0,0 +1,45 @@
+package org.argeo.osgi.useradmin.internal;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.argeo.osgi.useradmin.LdapUserAdmin;
+import org.argeo.osgi.useradmin.LdifUserAdmin;
+import org.argeo.osgi.useradmin.UserAdminConf;
+import org.argeo.osgi.useradmin.UserDirectory;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+public class UserDirectoryFactory implements ManagedServiceFactory {
+       private final BundleContext bc = FrameworkUtil.getBundle(UserDirectoryFactory.class).getBundleContext();
+
+       private Map<String, UserDirectory> userDirectories = new HashMap<>();
+
+       @Override
+       public String getName() {
+               return "User Directories Factory";
+       }
+
+       @Override
+       public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
+               String uri = (String) properties.get(UserAdminConf.uri.name());
+               UserDirectory userDirectory = uri.startsWith("ldap:") ? new LdapUserAdmin(properties)
+                               : new LdifUserAdmin(properties);
+               Dictionary<String, Object> regProps = new Hashtable<>();
+               regProps.put(Constants.SERVICE_PID, pid);
+               regProps.put(UserAdminConf.uri.name(), uri);
+               bc.registerService(UserDirectory.class, userDirectory, regProps);
+               userDirectories.put(pid, userDirectory);
+       }
+
+       @Override
+       public void deleted(String pid) {
+               userDirectories.remove(pid);
+       }
+
+}
diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/AbstractUserAdminWrapper.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/AbstractUserAdminWrapper.java
new file mode 100644 (file)
index 0000000..e222656
--- /dev/null
@@ -0,0 +1,105 @@
+package org.argeo.security.ui.admin.internal;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.transaction.Status;
+import javax.transaction.UserTransaction;
+
+import org.argeo.ArgeoException;
+import org.argeo.cms.auth.AuthConstants;
+import org.argeo.osgi.useradmin.UserAdminConf;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.useradmin.UserAdmin;
+import org.osgi.service.useradmin.UserAdminEvent;
+import org.osgi.service.useradmin.UserAdminListener;
+
+/**
+ * Base useradmin wrapper. Implementing application might extends to add
+ * business specific behaviour
+ */
+public abstract class AbstractUserAdminWrapper {
+       // private Log log = LogFactory.getLog(UserAdminWrapper.class);
+
+       private UserAdmin userAdmin;
+       private ServiceReference<UserAdmin> userAdminServiceReference;
+       private UserTransaction userTransaction;
+
+       /* USER ADMIN LISTENER MANAGEMENT */
+       List<UserAdminListener> listeners = new ArrayList<UserAdminListener>();
+
+       // TODO implement safer mechanism
+       public void addListener(UserAdminListener userAdminListener) {
+               if (!listeners.contains(userAdminListener))
+                       listeners.add(userAdminListener);
+       }
+
+       /**
+        * Starts a transaction if none already exists and notify the userAdmin
+        * listeners.Must be called from the UI Thread.
+        */
+       public UserTransaction beginTransactionIfNeeded() {
+               try {
+                       if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) {
+                               userTransaction.begin();
+                       }
+                       return userTransaction;
+               } catch (Exception e) {
+                       throw new ArgeoException("Unable to begin transaction", e);
+               }
+       }
+
+       // Expose this?
+       public void removeListener(UserAdminListener userAdminListener) {
+               if (listeners.contains(userAdminListener))
+                       listeners.remove(userAdminListener);
+       }
+
+       public void notifyListeners(UserAdminEvent event) {
+               for (UserAdminListener listener : listeners)
+                       listener.roleChanged(event);
+       }
+
+       public Map<String, String> getKnownBaseDns(boolean onlyWritable) {
+               Map<String, String> dns = new HashMap<String, String>();
+               for (String uri : userAdminServiceReference.getPropertyKeys()) {
+                       if (!uri.startsWith("/"))
+                               continue;
+                       Dictionary<String, ?> props = UserAdminConf.uriAsProperties(uri);
+                       String readOnly = UserAdminConf.readOnly.getValue(props);
+                       String baseDn = UserAdminConf.baseDn.getValue(props);
+
+                       if (onlyWritable && "true".equals(readOnly))
+                               continue;
+                       if (baseDn.equalsIgnoreCase(AuthConstants.ROLES_BASEDN))
+                               continue;
+                       dns.put(baseDn, uri);
+               }
+               return dns;
+       }
+
+       public UserAdmin getUserAdmin() {
+               return userAdmin;
+       }
+
+       public UserTransaction getUserTransaction() {
+               return userTransaction;
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setUserAdmin(UserAdmin userAdmin) {
+               this.userAdmin = userAdmin;
+       }
+
+       public void setUserTransaction(UserTransaction userTransaction) {
+               this.userTransaction = userTransaction;
+       }
+
+       public void setUserAdminServiceReference(
+                       ServiceReference<UserAdmin> userAdminServiceReference) {
+               this.userAdminServiceReference = userAdminServiceReference;
+       }
+}
\ No newline at end of file
diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminUtils.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/UserAdminUtils.java
new file mode 100644 (file)
index 0000000..0fc4fc1
--- /dev/null
@@ -0,0 +1,242 @@
+package org.argeo.security.ui.admin.internal;
+
+import java.security.AccessController;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+
+import org.argeo.ArgeoException;
+import org.argeo.cms.CmsView;
+import org.argeo.cms.auth.AuthConstants;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.util.CmsUtils;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.osgi.useradmin.LdifName;
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+/** Centralise common patterns to manage roles with a user admin */
+public class UserAdminUtils {
+
+       /** Retrieves a {@link Role} given a LDAP name */
+       public final static Role getRole(UserAdmin userAdmin, LdapName dn) {
+               Role role = userAdmin.getRole(dn.toString());
+               return role;
+       }
+
+       /** Retrieves the unique local username given a {@link User}. */
+       public final static String getUsername(User user) {
+               String username = null;
+               if (user instanceof Group)
+                       username = getProperty(user, LdifName.cn.name());
+               else
+                       username = getProperty(user, LdifName.uid.name());
+               return username;
+       }
+
+       /**
+        * Easily retrieves one of the {@link Role}'s property or an empty String if
+        * the requested property is not defined
+        */
+       public final static String getProperty(Role role, String key) {
+               Object obj = role.getProperties().get(key);
+               if (obj != null)
+                       return (String) obj;
+               else
+                       return "";
+       }
+
+       // CENTRALIZE SOME METHODS UNTIL API IS STABLE
+       /** Simply checks if current user is registered */
+       public static boolean isRegistered() {
+               return !CurrentUser.isAnonymous();
+       }
+
+       /** Simply checks if current user as a home */
+       public static boolean hasHome() {
+               return isRegistered();
+       }
+
+       // SELF HELPERS
+       /** Simply retrieves the current logged-in user display name. */
+       public static User getCurrentUser(UserAdmin userAdmin) {
+               return (User) getRole(userAdmin, getCurrentUserLdapName());
+       }
+
+       /** Simply retrieves the current logged-in user display name. */
+       public static String getCurrentUserDisplayName(UserAdmin userAdmin) {
+               String username = getCurrentUsername();
+               return getUserDisplayName(userAdmin, username);
+       }
+
+       /** Simply retrieves the current logged-in user display name. */
+       public static String getCurrentUserMail(UserAdmin userAdmin) {
+               String username = getCurrentUsername();
+               return getUserMail(userAdmin, username);
+       }
+
+       /** Returns the local name of the current connected user */
+       public final static String getUsername(UserAdmin userAdmin) {
+               LdapName dn = getCurrentUserLdapName();
+               return getUsername((User) getRole(userAdmin, dn));
+       }
+
+       /** Returns true if the current user is in the specified role */
+       public static boolean isUserInRole(String role) {
+               Set<String> roles = CurrentUser.roles();
+               return roles.contains(role);
+       }
+
+       /** Simply checks if current user is the same as the passed one */
+       public static boolean isCurrentUser(User user) {
+               String userName = getProperty(user, LdifName.dn.name());
+               try {
+                       LdapName selfUserName = getCurrentUserLdapName();
+                       LdapName userLdapName = new LdapName(userName);
+                       if (userLdapName.equals(selfUserName))
+                               return true;
+                       else
+                               return false;
+               } catch (InvalidNameException e) {
+                       throw new ArgeoException("User " + user + " has an unvalid dn: "
+                                       + userName, e);
+               }
+       }
+
+       public final static LdapName getCurrentUserLdapName() {
+               String name = getCurrentUsername();
+               return getLdapName(name);
+       }
+
+       /** Simply retrieves username for current user, generally a LDAP dn */
+       public static String getCurrentUsername() {
+               Subject subject = currentSubject();
+               String name = subject.getPrincipals(X500Principal.class).iterator()
+                               .next().toString();
+               return name;
+       }
+
+       /**
+        * Fork of the {@link CurrentUser#currentSubject} method that is private.
+        * TODO Enhance and factorize
+        */
+       private static Subject currentSubject() {
+               CmsView cmsView = CmsUtils.getCmsView();
+               if (cmsView != null)
+                       return cmsView.getSubject();
+               Subject subject = Subject.getSubject(AccessController.getContext());
+               if (subject != null)
+                       return subject;
+               throw new RuntimeException("Cannot find related subject");
+       }
+
+       // HOME MANAGEMENT
+       /**
+        * Simply retrieves the *relative* path to the current user home node from
+        * the base home node
+        */
+       public static String getCurrentUserHomeRelPath() {
+               return getHomeRelPath(getCurrentUsername());
+       }
+
+       /**
+        * Simply retrieves the *relative* path to the home node of a user given its
+        * userName
+        */
+       public static String getHomeRelPath(String userName) {
+               String id = getUserUid(userName);
+               String currHomePath = JcrUtils.firstCharsToPath(id, 2) + "/" + id;
+               return currHomePath;
+       }
+
+       // HELPERS TO RETRIEVE REMARKABLE PROPERTIES
+       /** Simply retrieves the user uid from his dn with no useradmin */
+       public static String getUserUid(String dn) {
+               LdapName ldapName = getLdapName(dn);
+               Rdn last = ldapName.getRdn(ldapName.size() - 1);
+               if (last.getType().toLowerCase().equals(LdifName.uid.name())
+                               || last.getType().toLowerCase().equals(LdifName.cn.name()))
+                       return (String) last.getValue();
+               else
+                       throw new ArgeoException("Cannot retrieve user uid, "
+                                       + "non valid dn: " + dn);
+       }
+
+       /**
+        * Returns the local username if no user with this dn is found or if the
+        * found user has no defined display name
+        */
+       public static String getUserDisplayName(UserAdmin userAdmin, String dn) {
+               Role user = getRole(userAdmin, getLdapName(dn));
+               if (user == null)
+                       return getUserUid(dn);
+               String displayName = getProperty(user, LdifName.displayName.name());
+               if (EclipseUiUtils.isEmpty(displayName))
+                       displayName = getProperty(user, LdifName.cn.name());
+               if (EclipseUiUtils.isEmpty(displayName))
+                       return getUserUid(dn);
+               else
+                       return displayName;
+       }
+
+       /**
+        * Returns null if no user with this dn is found or if the found user has no
+        * defined mail
+        */
+       public static String getUserMail(UserAdmin userAdmin, String dn) {
+               Role user = getRole(userAdmin, getLdapName(dn));
+               if (user == null)
+                       return null;
+               else
+                       return getProperty(user, LdifName.mail.name());
+       }
+
+       // VARIOUS UI HELPERS
+       public final static String buildDefaultCn(String firstName, String lastName) {
+               return (firstName.trim() + " " + lastName.trim() + " ").trim();
+       }
+
+       /** Simply retrieves a display name of the relevant domain */
+       public final static String getDomainName(User user) {
+               String dn = user.getName();
+               if (dn.endsWith(AuthConstants.ROLES_BASEDN))
+                       return "System roles";
+               try {
+                       LdapName name = new LdapName(dn);
+                       List<Rdn> rdns = name.getRdns();
+                       String dname = null;
+                       int i = 0;
+                       loop: while (i < rdns.size()) {
+                               Rdn currrRdn = rdns.get(i);
+                               if (!LdifName.dc.name().equals(currrRdn.getType()))
+                                       break loop;
+                               else {
+                                       String currVal = (String) currrRdn.getValue();
+                                       dname = dname == null ? currVal : currVal + "." + dname;
+                               }
+                               i++;
+                       }
+                       return dname;
+               } catch (InvalidNameException e) {
+                       throw new ArgeoException("Unable to get domain name for " + dn, e);
+               }
+       }
+
+       // Local Helpers
+       /** Simply retrieves a LDAP name from a dn with no exception */
+       public static LdapName getLdapName(String dn) {
+               try {
+                       return new LdapName(dn);
+               } catch (InvalidNameException e) {
+                       throw new ArgeoException("Cannot parse LDAP name " + dn, e);
+               }
+       }
+}
\ No newline at end of file
index 43ce58da9fba74bb7f06c0ea9bb7a3b5f8acd551..ff4018a2c6dcaf9c16220a37f96a4d17d9c2d687 100644 (file)
@@ -12,7 +12,7 @@ import org.osgi.service.useradmin.UserAdminListener;
 
 /** Centralize interaction with the UserAdmin in this bundle */
 public class UserAdminWrapper extends
-               org.argeo.cms.util.useradmin.UserAdminWrapper {
+               org.argeo.security.ui.admin.internal.AbstractUserAdminWrapper {
        // private Log log = LogFactory.getLog(UserAdminWrapper.class);
 
        // Registered listeners
index 868aa0fc7f6a3239ad5591f1b2cb315d63f4b94b..d21cc48b153ff3b2fef922ae655ac8e1d353f850 100644 (file)
@@ -19,8 +19,8 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.argeo.security.ui.admin.internal.parts.UserEditorInput;
 import org.eclipse.core.commands.AbstractHandler;
index 87da43cdf14f7495c14ee3ba45837baf9cb014d3..3e2644f6fb06c7b088c00bae36cd6716a174b508 100644 (file)
@@ -19,8 +19,8 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.argeo.security.ui.admin.internal.parts.UserEditorInput;
 import org.eclipse.core.commands.AbstractHandler;
index e408b1bee1793163eca3aead29d2831c6e4d14b3..77230390bd2b81b99883962c59b6d276c4d871db 100644 (file)
@@ -24,13 +24,13 @@ import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 
 import org.argeo.ArgeoException;
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.osgi.useradmin.LdifName;
 import org.argeo.osgi.useradmin.UserAdminConf;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
index 4a441a1a2d4a3c19651d7dfef7ba4e28528150bb..9527479885ad27003ac024c75870c2051ca91412 100644 (file)
@@ -19,13 +19,13 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.osgi.useradmin.LdifName;
 import org.argeo.security.ui.admin.SecurityAdminImages;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.argeo.security.ui.admin.internal.parts.UserEditor.GroupChangeListener;
 import org.argeo.security.ui.admin.internal.parts.UserEditor.MainInfoListener;
index 6b193f4441551b2e195e2e28527081bbefa09069..620e1d37886eb1c661c8bfe17241f8ff031fa336 100644 (file)
@@ -22,7 +22,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
 import org.argeo.cms.auth.AuthConstants;
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
@@ -30,6 +29,7 @@ import org.argeo.jcr.ArgeoNames;
 import org.argeo.osgi.useradmin.LdifName;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
 import org.argeo.security.ui.admin.internal.UiUserAdminListener;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.argeo.security.ui.admin.internal.providers.CommonNameLP;
 import org.argeo.security.ui.admin.internal.providers.DomainNameLP;
index d2dbadd085db8338f8ca52e322e673808d986032..6f581853c3641084b6d1771dea3bbeb4004e8827 100644 (file)
@@ -12,13 +12,13 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
 import org.argeo.cms.auth.AuthConstants;
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.osgi.useradmin.LdifName;
 import org.argeo.security.ui.admin.internal.UiAdminUtils;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.argeo.security.ui.admin.internal.providers.CommonNameLP;
 import org.argeo.security.ui.admin.internal.providers.DomainNameLP;
index 715d343105f302c580b0d6e26f98176775aaf85a..796d2cdd45c6f77e10402a97a248e557e95eff9e 100644 (file)
@@ -19,10 +19,10 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.argeo.ArgeoException;
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.osgi.useradmin.LdifName;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
 import org.argeo.security.ui.admin.internal.UiUserAdminListener;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.swt.events.ModifyEvent;
index 833ae32a78513013b730c4b20ac070b63487a954..06b430f74920c848d647b460dcc76f67a35279f0 100644 (file)
@@ -21,13 +21,13 @@ import java.util.List;
 
 import org.argeo.ArgeoException;
 import org.argeo.cms.auth.AuthConstants;
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.osgi.useradmin.LdifName;
 import org.argeo.security.ui.admin.SecurityAdminImages;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.argeo.security.ui.admin.internal.parts.UserEditor.GroupChangeListener;
 import org.argeo.security.ui.admin.internal.parts.UserEditor.MainInfoListener;
index edafa28511d34c993a326b5ba84b7cec6a378780..5bb50a40f654d92b1484221b2963f8dcfb707ef3 100644 (file)
@@ -20,7 +20,6 @@ import java.util.List;
 
 import org.argeo.ArgeoException;
 import org.argeo.cms.auth.AuthConstants;
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.eclipse.ui.ColumnDefinition;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
@@ -28,6 +27,7 @@ import org.argeo.jcr.ArgeoNames;
 import org.argeo.osgi.useradmin.LdifName;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
 import org.argeo.security.ui.admin.internal.UiUserAdminListener;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
 import org.argeo.security.ui.admin.internal.providers.CommonNameLP;
 import org.argeo.security.ui.admin.internal.providers.DomainNameLP;
index d45c0b603d1e7d30fd47683caea323602e4e5acd..5b6fbdd3eaa5fc822942257e4c00c9cb30d37c21 100644 (file)
@@ -1,7 +1,7 @@
 package org.argeo.security.ui.admin.internal.providers;
 
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.osgi.useradmin.LdifName;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.osgi.service.useradmin.User;
 
 /** Simply declare a label provider that returns the common name of a user */
index 795fd0af3fe6b3cb728c4658fcd86156c34355d6..b1d84a155501fa58286a8b52d6a9f8003a0b20a8 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.security.ui.admin.internal.providers;
 
-import org.argeo.cms.util.useradmin.UserAdminUtils;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.osgi.service.useradmin.User;
 
 /** The human friendly domain name for the corresponding user. */
index 0a6dcb604f8dd264f2d879efdbffbb3fe48a9818..d24cab67a9730d5753764dbd0d661f0d8199442c 100644 (file)
@@ -1,7 +1,7 @@
 package org.argeo.security.ui.admin.internal.providers;
 
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.osgi.useradmin.LdifName;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.osgi.service.useradmin.User;
 
 /** Simply declare a label provider that returns the Primary Mail of a user */
index 39bac0a2af4a4ae114430747d1bcfa19659445c0..5ca476a7d493dbc1335a9dc81ad7395b40c9fb67 100644 (file)
@@ -4,7 +4,7 @@ import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 
 import org.argeo.ArgeoException;
-import org.argeo.cms.util.useradmin.UserAdminUtils;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.viewers.ColumnLabelProvider;
 import org.eclipse.swt.SWT;
index 5f753d1c369c21c0f8204da06cdbafa446ab0475..2a230dd6bff99cb8b722dc7eb0617d8a9c0294c5 100644 (file)
@@ -3,8 +3,8 @@ package org.argeo.security.ui.admin.internal.providers;
 import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty;
 
 import org.argeo.cms.auth.AuthConstants;
-import org.argeo.cms.util.useradmin.UserAdminUtils;
 import org.argeo.osgi.useradmin.LdifName;
+import org.argeo.security.ui.admin.internal.UserAdminUtils;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerFilter;
 import org.osgi.service.useradmin.User;