From f9ee9620626e471a99f25e84175e27380d902957 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Wed, 26 Sep 2018 16:07:18 +0200 Subject: [PATCH] Introduce Tokens and Argeo Studio styling --- org.argeo.cms.ui.theme/rap/argeo-studio.css | 21 ++++++++++ .../src/org/argeo/cms/script/cms.js | 15 +++++++ .../argeo/cms/auth/UserAdminLoginModule.java | 42 +++++++++++++++++++ .../cms/internal/kernel/DeployConfig.java | 3 +- .../argeo/cms/internal/kernel/InitUtils.java | 17 ++++++++ .../internal/kernel/ou=tokens,ou=node.ldif | 4 ++ .../src/org/argeo/naming/LdapAttrs.java | 10 ++++- .../osgi/useradmin/AggregatingUserAdmin.java | 23 +++++++++- .../osgi/useradmin/LdifAuthorization.java | 28 +++++++------ 9 files changed, 145 insertions(+), 18 deletions(-) create mode 100644 org.argeo.cms.ui.theme/rap/argeo-studio.css create mode 100644 org.argeo.cms/src/org/argeo/cms/internal/kernel/ou=tokens,ou=node.ldif 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 index 000000000..2d7555570 --- /dev/null +++ b/org.argeo.cms.ui.theme/rap/argeo-studio.css @@ -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; +} diff --git a/org.argeo.cms.ui/src/org/argeo/cms/script/cms.js b/org.argeo.cms.ui/src/org/argeo/cms/script/cms.js index 1aacd2c4a..2ffcf9e75 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/script/cms.js +++ b/org.argeo.cms.ui/src/org/argeo/cms/script/cms.js @@ -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, '' + text + '') } diff --git a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java index 4862c57ac..16cc7ac19 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java @@ -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; + } } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java index b42220a6c..8ad51fc9f 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java @@ -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); } } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java index 8a22b480f..1efedd759 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java @@ -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 index 000000000..4ae9b88dd --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/ou=tokens,ou=node.ldif @@ -0,0 +1,4 @@ +dn: ou=tokens,ou=node +objectClass: organizationalUnit +objectClass: top +ou: tokens diff --git a/org.argeo.enterprise/src/org/argeo/naming/LdapAttrs.java b/org.argeo.enterprise/src/org/argeo/naming/LdapAttrs.java index fe03e82f3..171b83a0f 100644 --- a/org.argeo.enterprise/src/org/argeo/naming/LdapAttrs.java +++ b/org.argeo.enterprise/src/org/argeo/naming/LdapAttrs.java @@ -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(); + } + } diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java index f7a7c6e47..01254b985 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java @@ -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 sysRoles = new HashSet(); 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; } diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifAuthorization.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifAuthorization.java index c92ccf7a7..354f8c0e2 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifAuthorization.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifAuthorization.java @@ -16,25 +16,13 @@ class LdifAuthorization implements Authorization { private final String displayName; private final List allRoles; - @SuppressWarnings("unchecked") public LdifAuthorization(User user, List allRoles) { if (user == null) { this.name = null; this.displayName = "anonymous"; } else { this.name = user.getName(); - Dictionary 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 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(); + } } -- 2.30.2