Introduce Tokens and Argeo Studio styling
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 26 Sep 2018 14:07:18 +0000 (16:07 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 26 Sep 2018 14:07:18 +0000 (16:07 +0200)
org.argeo.cms.ui.theme/rap/argeo-studio.css [new file with mode: 0644]
org.argeo.cms.ui/src/org/argeo/cms/script/cms.js
org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/ou=tokens,ou=node.ldif [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/naming/LdapAttrs.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java
org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifAuthorization.java

diff --git a/org.argeo.cms.ui.theme/rap/argeo-studio.css b/org.argeo.cms.ui.theme/rap/argeo-studio.css
new file mode 100644 (file)
index 0000000..2d75555
--- /dev/null
@@ -0,0 +1,21 @@
+Composite.qa {
+       background-color: gray;
+       color: white;
+}
+
+Button[PUSH].qa {
+       color: white;
+       background-color: gray;
+       padding: 0px;
+       spacing: 0px;
+       border: none;
+}
+
+Composite.support {
+       background-color: red;
+}
+
+Label.support {
+       background-color: red;
+       color: white;
+}
index 1aacd2c4a91deb564aa67d4813c98a6f7c080a10..2ffcf9e751b6a374bfaeae44b623d3a5fe50d4c0 100644 (file)
@@ -22,6 +22,13 @@ function loadNode(node) {
        return fromJson
 }
 
+function newArea(parent, style, layout) {
+       var control = new Composite(parent, SWT.NONE)
+       control.setLayout(layout)
+       CmsUtils.style(control, style)
+       return control
+}
+
 function newLabel(parent, style, text) {
        var control = new Label(parent, SWT.NONE)
        control.setText(text)
@@ -30,6 +37,14 @@ function newLabel(parent, style, text) {
        return control
 }
 
+function newButton(parent, style, text) {
+       var control = new Button(parent, SWT.FLAT)
+       control.setText(text)
+       CmsUtils.style(control, style)
+       CmsUtils.markup(control)
+       return control
+}
+
 function newFormLabel(parent, style, text) {
        return newLabel(parent, style, '<b>' + text + '</b>')
 }
index 4862c57ac03a0faf0ddc5cb0e4f14f2e298f2562..16cc7ac19548141679bc25d9c5c4c8673bc5475f 100644 (file)
@@ -1,8 +1,12 @@
 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.security.cert.X509Certificate;
+import java.time.Instant;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -29,6 +33,8 @@ 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;
@@ -37,6 +43,7 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
 
@@ -128,6 +135,21 @@ public class UserAdminLoginModule implements LoginModule {
                        sharedState.put(CmsAuthUtils.SHARED_STATE_PWD, password);
                }
                User user = searchForUser(userAdmin, username);
+
+               // Tokens
+               if (user == null) {
+                       String token = username;
+                       Group tokenGroup = searchForToken(userAdmin, token);
+                       if (tokenGroup != null) {
+                               Authorization tokenAuthorization = getAuthorizationFromToken(userAdmin, tokenGroup);
+                               if (tokenAuthorization != null) {
+                                       bindAuthorization = tokenAuthorization;
+                                       authenticatedUser = (User) userAdmin.getRole(bindAuthorization.getName());
+                                       return true;
+                               }
+                       }
+               }
+
                if (user == null)
                        return true;// expect Kerberos
 
@@ -299,4 +321,24 @@ public class UserAdminLoginModule implements LoginModule {
                }
 
        }
+
+       protected Group searchForToken(UserAdmin userAdmin, String token) {
+               String dn = cn + "=" + token + "," + NodeConstants.TOKENS_BASEDN;
+               Group tokenGroup = (Group) userAdmin.getRole(dn);
+               return tokenGroup;
+       }
+
+       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;
+                       }
+               }
+               Authorization auth = userAdmin.getAuthorization(tokenGroup);
+               return auth;
+       }
 }
index b42220a6c8701635d22012b532ed4a32e3ad1ce5..8ad51fc9f0b3dc4ef68169b81bd0a164b5fc51b0 100644 (file)
@@ -245,7 +245,8 @@ class DeployConfig implements ConfigurationListener {
                try (Writer writer = Files.newBufferedWriter(deployConfigPath)) {
                        new LdifWriter(writer).write(deployConfigs);
                } catch (IOException e) {
-                       throw new CmsException("Cannot save deploy configs", e);
+                       // throw new CmsException("Cannot save deploy configs", e);
+                       log.error("Cannot save deploy configs", e);
                }
        }
 
index 8a22b480f0106f22861f4bfe2a63695ef54054d0..1efedd7595f59280ed646758067d651bd4b1302d 100644 (file)
@@ -123,6 +123,23 @@ class InitUtils {
                }
                uris.add(nodeRolesUri);
 
+               // node tokens
+               String nodeTokensUri = getFrameworkProp(NodeConstants.TOKENS_URI);
+               String baseNodeTokensDn = NodeConstants.TOKENS_BASEDN;
+               if (nodeTokensUri == null) {
+                       nodeTokensUri = baseNodeTokensDn + ".ldif";
+                       File nodeRolesFile = new File(nodeBaseDir, nodeRolesUri);
+                       if (!nodeRolesFile.exists())
+                               try {
+                                       FileUtils.copyInputStreamToFile(InitUtils.class.getResourceAsStream(baseNodeTokensDn + ".ldif"),
+                                                       nodeRolesFile);
+                               } catch (IOException e) {
+                                       throw new CmsException("Cannot copy demo resource", e);
+                               }
+                       // nodeRolesUri = nodeRolesFile.toURI().toString();
+               }
+               uris.add(nodeTokensUri);
+
                // Business roles
                String userAdminUris = getFrameworkProp(NodeConstants.USERADMIN_URIS);
                if (userAdminUris == null) {
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/ou=tokens,ou=node.ldif b/org.argeo.cms/src/org/argeo/cms/internal/kernel/ou=tokens,ou=node.ldif
new file mode 100644 (file)
index 0000000..4ae9b88
--- /dev/null
@@ -0,0 +1,4 @@
+dn: ou=tokens,ou=node
+objectClass: organizationalUnit
+objectClass: top
+ou: tokens
index fe03e82f32daa0eaeff29a4e06b9825cb432b6a7..171b83a0f9e47026d38de41523a50e3e9967b352 100644 (file)
@@ -266,9 +266,9 @@ public enum LdapAttrs implements SpecifiedName {
        userPKCS12("2.16.840.1.113730.3.1.216", "RFC 2798"),
        /** */
        displayName("2.16.840.1.113730.3.1.241", "RFC 2798"),
-       
+
        // Sun memberOf
-       memberOf("1.2.840.113556.1.2.102","389 DS memberOf"),
+       memberOf("1.2.840.113556.1.2.102", "389 DS memberOf"),
 
        // KERBEROS (partial)
        krbPrincipalName("2.16.840.1.113719.1.301.6.8.1", "Novell Kerberos Schema Definitions"),
@@ -311,4 +311,10 @@ public enum LdapAttrs implements SpecifiedName {
                return new StringBuilder(LDAP_).append(name()).toString();
        }
 
+       @Override
+       public final String toString() {
+               // must return the name
+               return name();
+       }
+
 }
index f7a7c6e478ba8197e9ef414e5c7fce8e5a20f8aa..01254b985a64302b84dd22db5e789040143b6461 100644 (file)
@@ -13,8 +13,10 @@ 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;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
@@ -84,6 +86,23 @@ public class AggregatingUserAdmin implements UserAdmin {
                }
                UserAdmin userAdmin = findUserAdmin(user.getName());
                Authorization rawAuthorization = userAdmin.getAuthorization(user);
+               String usernameToUse;
+               String displayNameToUse;
+               if (user instanceof Group) {// tokens
+                       String ownerDn = (String) user.getProperties().get(LdapAttrs.owner.name());
+                       if (ownerDn != null) {
+                               UserAdmin ownerUserAdmin = findUserAdmin(ownerDn);
+                               User ownerUser = (User) ownerUserAdmin.getRole(ownerDn);
+                               usernameToUse = ownerDn;
+                               displayNameToUse = LdifAuthorization.extractDisplayName(ownerUser);
+                       } else {
+                               throw new UserDirectoryException(
+                                               "Cannot get authorization for group " + user.getName() + " without owner");
+                       }
+               } else {// regular users
+                       usernameToUse = rawAuthorization.getName();
+                       displayNameToUse = rawAuthorization.toString();
+               }
                // gather system roles
                Set<String> sysRoles = new HashSet<String>();
                for (String role : rawAuthorization.getRoles()) {
@@ -91,8 +110,8 @@ public class AggregatingUserAdmin implements UserAdmin {
                        sysRoles.addAll(Arrays.asList(auth.getRoles()));
                }
                addAbstractSystemRoles(rawAuthorization, sysRoles);
-               Authorization authorization = new AggregatingAuthorization(rawAuthorization.getName(),
-                               rawAuthorization.toString(), sysRoles, rawAuthorization.getRoles());
+               Authorization authorization = new AggregatingAuthorization(usernameToUse, displayNameToUse, sysRoles,
+                               rawAuthorization.getRoles());
                return authorization;
        }
 
index c92ccf7a77e75918a0ec64b5f7e1090c68920599..354f8c0e224d333f2f55b3903178c1bc285614d6 100644 (file)
@@ -16,25 +16,13 @@ class LdifAuthorization implements Authorization {
        private final String displayName;
        private final List<String> allRoles;
 
-       @SuppressWarnings("unchecked")
        public LdifAuthorization(User user, List<Role> allRoles) {
                if (user == null) {
                        this.name = null;
                        this.displayName = "anonymous";
                } else {
                        this.name = user.getName();
-                       Dictionary<String, Object> props = user.getProperties();
-                       Object displayName = props.get(LdapAttrs.displayName);
-                       if (displayName == null)
-                               displayName = props.get(LdapAttrs.cn);
-                       if (displayName == null)
-                               displayName = props.get(LdapAttrs.uid);
-                       if (displayName == null)
-                               displayName = user.getName();
-                       if (displayName == null)
-                               throw new UserDirectoryException("Cannot set display name for "
-                                               + user);
-                       this.displayName = displayName.toString();
+                       this.displayName = extractDisplayName(user);
                }
                // roles
                String[] roles = new String[allRoles.size()];
@@ -80,4 +68,18 @@ class LdifAuthorization implements Authorization {
        public String toString() {
                return displayName;
        }
+
+       final static String extractDisplayName(User user) {
+               Dictionary<String, Object> props = user.getProperties();
+               Object displayName = props.get(LdapAttrs.displayName);
+               if (displayName == null)
+                       displayName = props.get(LdapAttrs.cn);
+               if (displayName == null)
+                       displayName = props.get(LdapAttrs.uid);
+               if (displayName == null)
+                       displayName = user.getName();
+               if (displayName == null)
+                       throw new UserDirectoryException("Cannot set display name for " + user);
+               return displayName.toString();
+       }
 }