Improve tokens management
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 10 Jan 2019 15:50:51 +0000 (16:50 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 10 Jan 2019 15:50:51 +0000 (16:50 +0100)
org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java
org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingAuthorization.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/AuthenticatingUser.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdapUserAdmin.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUserAdmin.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/TokenUtils.java [new file with mode: 0644]

index 53937c9d773e8fe78a82348fa0c7a5f79e4ed179..7d36a95076234a7b95c6fc18412aab340c355a73 100644 (file)
@@ -210,6 +210,10 @@ public class GroupsView implements ArgeoNames {
                                if (tmpBuilder.length() > 1) {
                                        builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
                                                        .append(LdapObjs.groupOfNames.name()).append(")");
+                                       // hide tokens
+                                       builder.append("(!(").append(LdapAttrs.DN).append("=*").append(NodeConstants.TOKENS_BASEDN)
+                                                       .append("))");
+
                                        if (!showSystemRoles)
                                                builder.append("(!(").append(LdapAttrs.DN).append("=*").append(NodeConstants.ROLES_BASEDN)
                                                                .append("))");
@@ -220,10 +224,12 @@ public class GroupsView implements ArgeoNames {
                                        if (!showSystemRoles)
                                                builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
                                                                .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*")
-                                                               .append(NodeConstants.ROLES_BASEDN).append(")))");
+                                                               .append(NodeConstants.ROLES_BASEDN).append("))(!(").append(LdapAttrs.DN).append("=*")
+                                                               .append(NodeConstants.TOKENS_BASEDN).append(")))");
                                        else
-                                               builder.append("(").append(LdapAttrs.objectClass.name()).append("=")
-                                                               .append(LdapObjs.groupOfNames.name()).append(")");
+                                               builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
+                                               .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*")
+                                               .append(NodeConstants.TOKENS_BASEDN).append(")))");
 
                                }
                                roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString());
index ad9eb24c52ac912c32f9568ca956f19869123405..7297513c2849afe1ab98a2af95ef83691a27df48 100644 (file)
@@ -1,11 +1,9 @@
 package org.argeo.cms.auth;
 
 import static org.argeo.naming.LdapAttrs.cn;
-import static org.argeo.naming.LdapAttrs.description;
 
 import java.io.IOException;
 import java.security.PrivilegedAction;
-import java.time.Instant;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -32,12 +30,12 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.internal.kernel.Activator;
 import org.argeo.naming.LdapAttrs;
-import org.argeo.naming.NamingUtils;
 import org.argeo.node.NodeConstants;
 import org.argeo.node.security.CryptoKeyring;
 import org.argeo.osgi.useradmin.AuthenticatingUser;
 import org.argeo.osgi.useradmin.IpaUtils;
 import org.argeo.osgi.useradmin.OsUserUtils;
+import org.argeo.osgi.useradmin.TokenUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceReference;
@@ -336,15 +334,17 @@ public class UserAdminLoginModule implements LoginModule {
        }
 
        protected Authorization getAuthorizationFromToken(UserAdmin userAdmin, Group tokenGroup) {
-               String expiryDateStr = (String) tokenGroup.getProperties().get(description.name());
-               if (expiryDateStr != null) {
-                       Instant expiryDate = NamingUtils.ldapDateToInstant(expiryDateStr);
-                       if (expiryDate.isBefore(Instant.now())) {
-                               if (log.isDebugEnabled())
-                                       log.debug("Token " + tokenGroup.getName() + " has expired.");
-                               return null;
-                       }
-               }
+               if (TokenUtils.isExpired(tokenGroup))
+                       return null;
+//             String expiryDateStr = (String) tokenGroup.getProperties().get(description.name());
+//             if (expiryDateStr != null) {
+//                     Instant expiryDate = NamingUtils.ldapDateToInstant(expiryDateStr);
+//                     if (expiryDate.isBefore(Instant.now())) {
+//                             if (log.isDebugEnabled())
+//                                     log.debug("Token " + tokenGroup.getName() + " has expired.");
+//                             return null;
+//                     }
+//             }
                Authorization auth = userAdmin.getAuthorization(tokenGroup);
                return auth;
        }
index 95b1f07adec9705e2802df0e2fea989ea9d2f003..385ea740e64f6df46227630e2cd053aed50b7302 100644 (file)
@@ -232,7 +232,6 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory
                return user;
        }
 
-       @SuppressWarnings("unchecked")
        @Override
        public Role[] getRoles(String filter) throws InvalidSyntaxException {
                UserDirectoryWorkingCopy wc = getWorkingCopy();
index b450b729e6129364e4bd8197253e8392e917455a..6729a2c2df1167fa873c18ebbc6e14cb356e59ae 100644 (file)
@@ -6,8 +6,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
-import javax.security.auth.x500.X500Principal;
-
 import org.osgi.service.useradmin.Authorization;
 
 class AggregatingAuthorization implements Authorization {
index cc1dadb9bc9e0be189673a578a060fafee37a5e1..b09c8df5eee20cb633d3fbe602352202a4ac7ecf 100644 (file)
@@ -13,7 +13,6 @@ import java.util.Set;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 
-import org.argeo.naming.LdapAttrs;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.useradmin.Authorization;
 import org.osgi.service.useradmin.Group;
@@ -89,7 +88,7 @@ public class AggregatingUserAdmin implements UserAdmin {
                String usernameToUse;
                String displayNameToUse;
                if (user instanceof Group) {
-                       String ownerDn = (String) user.getProperties().get(LdapAttrs.owner.name());
+                       String ownerDn = TokenUtils.userDn((Group) user);
                        if (ownerDn != null) {// tokens
                                UserAdmin ownerUserAdmin = findUserAdmin(ownerDn);
                                User ownerUser = (User) ownerUserAdmin.getRole(ownerDn);
index 6bf1441b504fa5c9671d84818beeb42379601783..939b03852247cfd0973900b9745c7f93bdc3aeb9 100644 (file)
@@ -48,13 +48,13 @@ public class AuthenticatingUser implements User {
                return User.USER;
        }
 
-       @SuppressWarnings("rawtypes")
+       @SuppressWarnings({ "rawtypes", "unchecked" })
        @Override
        public Dictionary getProperties() {
                throw new UnsupportedOperationException();
        }
 
-       @SuppressWarnings("rawtypes")
+       @SuppressWarnings({ "rawtypes", "unchecked" })
        @Override
        public Dictionary getCredentials() {
                return credentials;
index 6dbf6c2d7f79819a3fda2db25ce3654bac55e3b1..10a75feb02bd220b7ffdcb46092479ebe133b302 100644 (file)
@@ -78,7 +78,6 @@ public class LdapUserAdmin extends AbstractUserDirectory {
                }
        }
 
-       @SuppressWarnings("unchecked")
        @Override
        protected AbstractUserDirectory scope(User user) {
                Dictionary<String, Object> credentials = user.getCredentials();
index 8668152d6d7aac69a77c20d879cc92b75e10b539..e75c698221b9ee63b07e5f322d124f8bd4463a8a 100644 (file)
@@ -51,7 +51,6 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                super(uri, properties);
        }
 
-       @SuppressWarnings("unchecked")
        @Override
        protected AbstractUserDirectory scope(User user) {
                Dictionary<String, Object> credentials = user.getCredentials();
@@ -180,7 +179,6 @@ public class LdifUserAdmin extends AbstractUserDirectory {
                return users.containsKey(dn) || groups.containsKey(dn);
        }
 
-       @SuppressWarnings("unchecked")
        protected List<DirectoryUser> doGetRoles(Filter f) {
                ArrayList<DirectoryUser> res = new ArrayList<DirectoryUser>();
                if (f == null) {
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/TokenUtils.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/TokenUtils.java
new file mode 100644 (file)
index 0000000..83c1d76
--- /dev/null
@@ -0,0 +1,87 @@
+package org.argeo.osgi.useradmin;
+
+import static org.argeo.naming.LdapAttrs.description;
+import static org.argeo.naming.LdapAttrs.owner;
+
+import java.security.Principal;
+import java.time.Instant;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.security.auth.Subject;
+
+import org.argeo.naming.NamingUtils;
+import org.osgi.service.useradmin.Group;
+
+/**
+ * Canonically implements the Argeo token conventions.
+ */
+public class TokenUtils {
+       public static Set<String> tokensUsed(Subject subject, String tokensBaseDn) {
+               Set<String> res = new HashSet<>();
+               for (Principal principal : subject.getPrincipals()) {
+                       String name = principal.getName();
+                       if (name.endsWith(tokensBaseDn)) {
+                               try {
+                                       LdapName ldapName = new LdapName(name);
+                                       String token = ldapName.getRdn(ldapName.size()).getValue().toString();
+                                       res.add(token);
+                               } catch (InvalidNameException e) {
+                                       throw new UserDirectoryException("Invalid principal " + principal, e);
+                               }
+                       }
+               }
+               return res;
+       }
+
+       /** The user related to this token group */
+       public static String userDn(Group tokenGroup) {
+               return (String) tokenGroup.getProperties().get(owner.name());
+       }
+
+       public static boolean isExpired(Group tokenGroup) {
+               return isExpired(tokenGroup, Instant.now());
+
+       }
+
+       public static boolean isExpired(Group tokenGroup, Instant instant) {
+               String expiryDateStr = (String) tokenGroup.getProperties().get(description.name());
+               if (expiryDateStr != null) {
+                       Instant expiryDate = NamingUtils.ldapDateToInstant(expiryDateStr);
+                       if (expiryDate.isBefore(instant)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+//     private final String token;
+//
+//     public TokenUtils(String token) {
+//             this.token = token;
+//     }
+//
+//     public String getToken() {
+//             return token;
+//     }
+//
+//     @Override
+//     public int hashCode() {
+//             return token.hashCode();
+//     }
+//
+//     @Override
+//     public boolean equals(Object obj) {
+//             if ((obj instanceof TokenUtils) && ((TokenUtils) obj).token.equals(token))
+//                     return true;
+//             return false;
+//     }
+//
+//     @Override
+//     public String toString() {
+//             return "Token #" + hashCode();
+//     }
+
+}