]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java
Fix automated Kerberos config
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / NodeUserAdmin.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.net.URI;
4 import java.net.URISyntaxException;
5 import java.util.Dictionary;
6 import java.util.HashMap;
7 import java.util.Hashtable;
8 import java.util.Map;
9
10 import javax.naming.ldap.LdapName;
11 import javax.transaction.TransactionManager;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.argeo.cms.CmsException;
16 import org.argeo.node.NodeConstants;
17 import org.argeo.osgi.useradmin.AbstractUserDirectory;
18 import org.argeo.osgi.useradmin.AggregatingUserAdmin;
19 import org.argeo.osgi.useradmin.LdapUserAdmin;
20 import org.argeo.osgi.useradmin.LdifUserAdmin;
21 import org.argeo.osgi.useradmin.UserAdminConf;
22 import org.argeo.osgi.useradmin.UserDirectory;
23 import org.osgi.framework.BundleContext;
24 import org.osgi.framework.Constants;
25 import org.osgi.framework.FrameworkUtil;
26 import org.osgi.framework.ServiceRegistration;
27 import org.osgi.service.cm.ConfigurationException;
28 import org.osgi.service.cm.ManagedServiceFactory;
29 import org.osgi.service.useradmin.UserAdmin;
30 import org.osgi.util.tracker.ServiceTracker;
31
32 import bitronix.tm.BitronixTransactionManager;
33 import bitronix.tm.resource.ehcache.EhCacheXAResourceProducer;
34
35 /**
36 * Aggregates multiple {@link UserDirectory} and integrates them with system
37 * roles.
38 */
39 class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactory, KernelConstants {
40 private final static Log log = LogFactory.getLog(NodeUserAdmin.class);
41 private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
42
43 // OSGi
44 private Map<String, LdapName> pidToBaseDn = new HashMap<>();
45 private Map<String, ServiceRegistration<UserDirectory>> pidToServiceRegs = new HashMap<>();
46 private ServiceRegistration<UserAdmin> userAdminReg;
47
48 // JTA
49 private final ServiceTracker<TransactionManager, TransactionManager> tmTracker;
50 private final String cacheName = UserDirectory.class.getName();
51
52 public NodeUserAdmin(String systemRolesBaseDn) {
53 super(systemRolesBaseDn);
54 tmTracker = new ServiceTracker<>(bc, TransactionManager.class, null);
55 tmTracker.open();
56 }
57
58 @Override
59 public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
60 String uri = (String) properties.get(UserAdminConf.uri.name());
61 URI u;
62 try {
63 u = new URI(uri);
64 } catch (URISyntaxException e) {
65 throw new CmsException("Badly formatted URI " + uri, e);
66 }
67
68 // Create
69 AbstractUserDirectory userDirectory = u.getScheme().equals("ldap") ? new LdapUserAdmin(properties)
70 : new LdifUserAdmin(properties);
71 addUserDirectory(userDirectory);
72
73 // OSGi
74 LdapName baseDn = userDirectory.getBaseDn();
75 Dictionary<String, Object> regProps = new Hashtable<>();
76 regProps.put(Constants.SERVICE_PID, pid);
77 if(isSystemRolesBaseDn(baseDn))
78 regProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
79 regProps.put(UserAdminConf.baseDn.name(), baseDn);
80 ServiceRegistration<UserDirectory> reg = bc.registerService(UserDirectory.class, userDirectory, regProps);
81 pidToBaseDn.put(pid, baseDn);
82 pidToServiceRegs.put(pid, reg);
83
84 if (log.isDebugEnabled())
85 log.debug("User directory " + userDirectory.getBaseDn() + " [" + u.getScheme() + "] enabled.");
86
87 if (!isSystemRolesBaseDn(baseDn)) {
88 if (userAdminReg != null)
89 userAdminReg.unregister();
90 // register self as main user admin
91 Dictionary<String, Object> userAdminregProps = currentState();
92 userAdminregProps.put(NodeConstants.CN, NodeConstants.DEFAULT);
93 userAdminregProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
94 userAdminReg = bc.registerService(UserAdmin.class, this, userAdminregProps);
95 }
96 }
97
98 @Override
99 public void deleted(String pid) {
100 assert pidToServiceRegs.get(pid) != null;
101 assert pidToBaseDn.get(pid) != null;
102 pidToServiceRegs.remove(pid).unregister();
103 LdapName baseDn = pidToBaseDn.remove(pid);
104 removeUserDirectory(baseDn);
105 }
106
107 @Override
108 public String getName() {
109 return "Node User Admin";
110 }
111
112 protected void postAdd(AbstractUserDirectory userDirectory) {
113 // JTA
114 TransactionManager tm = tmTracker.getService();
115 if (tm == null)
116 throw new CmsException("A JTA transaction manager must be available.");
117 userDirectory.setTransactionManager(tm);
118 if (tmTracker.getService() instanceof BitronixTransactionManager)
119 EhCacheXAResourceProducer.registerXAResource(cacheName, userDirectory.getXaResource());
120 }
121
122 protected void preDestroy(UserDirectory userDirectory) {
123 if (tmTracker.getService() instanceof BitronixTransactionManager)
124 EhCacheXAResourceProducer.unregisterXAResource(cacheName, userDirectory.getXaResource());
125 }
126
127 }