From 9ec85110269f8be5c83ea26e283359bb451a67b7 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 27 Feb 2021 13:05:48 +0100 Subject: [PATCH] Better deal with multiple user directories. --- .../org/argeo/cms/auth/UserAdminUtils.java | 3 +- .../cms/internal/kernel/DeployConfig.java | 39 +++++++++++++++++-- .../argeo/cms/internal/kernel/InitUtils.java | 6 +-- .../osgi/useradmin/AggregatingUserAdmin.java | 34 ++++++++-------- 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java index 8fe042653..ad53086f5 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java @@ -147,7 +147,8 @@ public class UserAdminUtils { int i = 0; loop: while (i < rdns.size()) { Rdn currrRdn = rdns.get(i); - if (!LdapAttrs.dc.name().equals(currrRdn.getType())) + if (LdapAttrs.uid.name().equals(currrRdn.getType()) || LdapAttrs.cn.name().equals(currrRdn.getType()) + || LdapAttrs.ou.name().equals(currrRdn.getType())) break loop; else { String currVal = (String) currrRdn.getValue(); 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 228ccbb4a..f481f3fa1 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 @@ -12,6 +12,7 @@ import java.util.SortedMap; import java.util.TreeMap; import javax.naming.InvalidNameException; +import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttributes; import javax.naming.ldap.LdapName; @@ -43,6 +44,8 @@ class DeployConfig implements ConfigurationListener { private boolean isFirstInit = false; + private final static String ROLES = "roles"; + public DeployConfig(ConfigurationAdmin configurationAdmin, DataModels dataModels, boolean isClean) { this.dataModels = dataModels; // ConfigurationAdmin configurationAdmin = @@ -99,7 +102,12 @@ class DeployConfig implements ConfigurationListener { List activeCns = new ArrayList<>(); for (int i = 0; i < userDirectoryConfigs.size(); i++) { Dictionary userDirectoryConfig = userDirectoryConfigs.get(i); - String cn = UserAdminConf.baseDnHash(userDirectoryConfig); + String baseDn = (String) userDirectoryConfig.get(UserAdminConf.baseDn.name()); + String cn; + if (NodeConstants.ROLES_BASEDN.equals(baseDn)) + cn = ROLES; + else + cn = UserAdminConf.baseDnHash(userDirectoryConfig); activeCns.add(cn); userDirectoryConfig.put(NodeConstants.CN, cn); putFactoryDeployConfig(NodeConstants.NODE_USER_ADMIN_PID, userDirectoryConfig); @@ -189,7 +197,17 @@ class DeployConfig implements ConfigurationListener { if (log.isDebugEnabled()) log.debug("Clean state, loading from framework properties..."); setFromFrameworkProperties(isFirstInit); - for (LdapName dn : deployConfigs.keySet()) { + + // FIXME make it more robust + Configuration systemRolesConf = null; + LdapName systemRolesDn; + try { + // FIXME make it more robust + systemRolesDn = new LdapName("cn=roles,ou=org.argeo.api.userAdmin,ou=deploy,ou=node"); + } catch (InvalidNameException e) { + throw new IllegalArgumentException(e); + } + deployConfigs: for (LdapName dn : deployConfigs.keySet()) { Rdn lastRdn = dn.getRdn(dn.size() - 1); LdapName prefix = (LdapName) dn.getPrefix(dn.size() - 1); if (prefix.toString().equals(NodeConstants.DEPLOY_BASEDN)) { @@ -203,15 +221,28 @@ class DeployConfig implements ConfigurationListener { // service factory definition } } else { + Attributes config = deployConfigs.get(dn); + Attribute disabled = config.get(UserAdminConf.disabled.name()); + if (disabled != null) + continue deployConfigs; // service factory service Rdn beforeLastRdn = dn.getRdn(dn.size() - 2); assert beforeLastRdn.getType().equals(NodeConstants.OU); String factoryPid = beforeLastRdn.getValue().toString(); Configuration conf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null); - AttributesDictionary dico = new AttributesDictionary(deployConfigs.get(dn)); - conf.update(dico); + if (systemRolesDn.equals(dn)) { + systemRolesConf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null); + } else { + AttributesDictionary dico = new AttributesDictionary(config); + conf.update(dico); + } } } + + // system roles must be last since it triggers node user admin publication + if (systemRolesConf == null) + throw new IllegalStateException("System roles are not configured."); + systemRolesConf.update(new AttributesDictionary(deployConfigs.get(systemRolesDn))); } // TODO check consistency if not clean } 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 156ebc5f9..011d3856a 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 @@ -167,11 +167,11 @@ class InitUtils { String baseNodeTokensDn = NodeConstants.TOKENS_BASEDN; if (nodeTokensUri == null) { nodeTokensUri = baseNodeTokensDn + ".ldif"; - File nodeRolesFile = new File(nodeBaseDir, nodeRolesUri); - if (!nodeRolesFile.exists()) + File nodeTokensFile = new File(nodeBaseDir, nodeTokensUri); + if (!nodeTokensFile.exists()) try { FileUtils.copyInputStreamToFile(InitUtils.class.getResourceAsStream(baseNodeTokensDn + ".ldif"), - nodeRolesFile); + nodeTokensFile); } catch (IOException e) { throw new RuntimeException("Cannot copy demo resource", e); } 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 f3e51804a..66d46d4e9 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java @@ -110,8 +110,8 @@ public class AggregatingUserAdmin implements UserAdmin { Set sysRoles = new HashSet(); for (String role : rawAuthorization.getRoles()) { Authorization auth = systemRoles.getAuthorization((User) userAdmin.getRole(role)); - systemRoles:for(String systemRole:auth.getRoles()) { - if(role.equals(systemRole)) + systemRoles: for (String systemRole : auth.getRoles()) { + if (role.equals(systemRole)) continue systemRoles; sysRoles.add(systemRole); } @@ -169,23 +169,23 @@ public class AggregatingUserAdmin implements UserAdmin { return systemRoles; if (tokensBaseDn != null && name.startsWith(tokensBaseDn)) return tokens; - List res = new ArrayList(1); - for (LdapName baseDn : businessRoles.keySet()) { - AbstractUserDirectory ud = businessRoles.get(baseDn); + List res = new ArrayList<>(1); + userDirectories: for (LdapName baseDn : businessRoles.keySet()) { + AbstractUserDirectory userDirectory = businessRoles.get(baseDn); if (name.startsWith(baseDn)) { - if (!ud.isDisabled()) - res.add(ud); - } -// Object principal = ud.getProperties().get(Context.SECURITY_PRINCIPAL); -// if (principal != null) { -// try { -// LdapName principalLdapName = new LdapName(principal.toString()); -// if (principalLdapName.equals(name)) -// res.add(ud); -// } catch (InvalidNameException e) { -// // silent + if (userDirectory.isDisabled()) + continue userDirectories; +// if (res.isEmpty()) { + res.add(userDirectory); +// } else { +// for (AbstractUserDirectory ud : res) { +// LdapName bd = ud.getBaseDn(); +// if (userDirectory.getBaseDn().startsWith(bd)) { +// // child user directory +// } +// } // } -// } + } } if (res.size() == 0) throw new UserDirectoryException("Cannot find user admin for " + name); -- 2.30.2