1 package org
.argeo
.cms
.internal
.kernel
;
4 import java
.io
.IOException
;
6 import java
.net
.URISyntaxException
;
7 import java
.util
.ArrayList
;
8 import java
.util
.Arrays
;
9 import java
.util
.Dictionary
;
10 import java
.util
.HashMap
;
11 import java
.util
.HashSet
;
12 import java
.util
.Hashtable
;
13 import java
.util
.List
;
17 import javax
.naming
.InvalidNameException
;
18 import javax
.naming
.ldap
.LdapName
;
19 import javax
.transaction
.TransactionManager
;
21 import org
.apache
.commons
.io
.FileUtils
;
22 import org
.apache
.commons
.logging
.Log
;
23 import org
.apache
.commons
.logging
.LogFactory
;
24 import org
.argeo
.cms
.CmsException
;
25 import org
.argeo
.cms
.KernelHeader
;
26 import org
.argeo
.osgi
.useradmin
.UserDirectory
;
27 import org
.argeo
.osgi
.useradmin
.UserAdminConf
;
28 import org
.argeo
.osgi
.useradmin
.LdapUserAdmin
;
29 import org
.argeo
.osgi
.useradmin
.LdifUserAdmin
;
30 import org
.argeo
.osgi
.useradmin
.UserDirectoryException
;
31 import org
.osgi
.framework
.InvalidSyntaxException
;
32 import org
.osgi
.service
.useradmin
.Authorization
;
33 import org
.osgi
.service
.useradmin
.Role
;
34 import org
.osgi
.service
.useradmin
.User
;
35 import org
.osgi
.service
.useradmin
.UserAdmin
;
37 public class NodeUserAdmin
implements UserAdmin
{
38 private final static Log log
= LogFactory
.getLog(NodeUserAdmin
.class);
39 final static LdapName ROLES_BASE
;
42 ROLES_BASE
= new LdapName(KernelHeader
.ROLES_BASEDN
);
43 } catch (InvalidNameException e
) {
44 throw new UserDirectoryException("Cannot initialize "
45 + NodeUserAdmin
.class, e
);
49 private UserAdmin nodeRoles
= null;
50 private Map
<LdapName
, UserAdmin
> userAdmins
= new HashMap
<LdapName
, UserAdmin
>();
52 public NodeUserAdmin() {
53 File osgiInstanceDir
= KernelUtils
.getOsgiInstanceDir();
54 File nodeBaseDir
= new File(osgiInstanceDir
, "node");
57 String userAdminUri
= KernelUtils
58 .getFrameworkProp(KernelConstants
.USERADMIN_URIS
);
59 if (userAdminUri
== null) {
60 String demoBaseDn
= "dc=example,dc=com";
61 File businessRolesFile
= new File(nodeBaseDir
, demoBaseDn
+ ".ldif");
62 if (!businessRolesFile
.exists())
64 FileUtils
.copyInputStreamToFile(getClass()
65 .getResourceAsStream(demoBaseDn
+ ".ldif"),
67 } catch (IOException e
) {
68 throw new CmsException("Cannot copy demo resource", e
);
70 userAdminUri
= businessRolesFile
.toURI().toString();
73 String
[] uris
= userAdminUri
.split(" ");
74 for (String uri
: uris
) {
78 if (u
.getScheme() == null) {
79 if (uri
.startsWith("/"))
80 u
= new File(uri
).getAbsoluteFile().toURI();
81 else if (!uri
.contains("/"))
82 u
= new File(nodeBaseDir
, uri
).getAbsoluteFile()
85 throw new CmsException("Cannot interpret " + uri
88 } catch (URISyntaxException e
) {
89 throw new CmsException(
90 "Cannot interpret " + uri
+ " as an uri", e
);
92 Dictionary
<String
, ?
> properties
= UserAdminConf
.uriAsProperties(u
94 UserDirectory businessRoles
;
95 if (u
.getScheme().startsWith("ldap")) {
96 businessRoles
= new LdapUserAdmin(properties
);
98 businessRoles
= new LdifUserAdmin(properties
);
100 businessRoles
.init();
101 addUserAdmin(businessRoles
.getBaseDn(), (UserAdmin
) businessRoles
);
102 if (log
.isDebugEnabled())
103 log
.debug("User directory " + businessRoles
.getBaseDn() + " ["
104 + u
.getScheme() + "] enabled.");
108 String nodeRolesUri
= KernelUtils
109 .getFrameworkProp(KernelConstants
.ROLES_URI
);
110 String baseNodeRoleDn
= KernelHeader
.ROLES_BASEDN
;
111 if (nodeRolesUri
== null) {
112 File nodeRolesFile
= new File(nodeBaseDir
, baseNodeRoleDn
+ ".ldif");
113 if (!nodeRolesFile
.exists())
115 FileUtils
.copyInputStreamToFile(getClass()
116 .getResourceAsStream("demo.ldif"), nodeRolesFile
);
117 } catch (IOException e
) {
118 throw new CmsException("Cannot copy demo resource", e
);
120 nodeRolesUri
= nodeRolesFile
.toURI().toString();
123 Dictionary
<String
, ?
> nodeRolesProperties
= UserAdminConf
124 .uriAsProperties(nodeRolesUri
);
125 if (!nodeRolesProperties
.get(UserAdminConf
.baseDn
.property()).equals(
127 throw new CmsException("Invalid base dn for node roles");
128 // TODO deal with "mounted" roles with a different baseDN
130 UserDirectory nodeRoles
;
131 if (nodeRolesUri
.startsWith("ldap")) {
132 nodeRoles
= new LdapUserAdmin(nodeRolesProperties
);
134 nodeRoles
= new LdifUserAdmin(nodeRolesProperties
);
136 nodeRoles
.setExternalRoles(this);
138 addUserAdmin(baseNodeRoleDn
, (UserAdmin
) nodeRoles
);
139 if (log
.isTraceEnabled())
140 log
.trace("Node roles enabled.");
143 Dictionary
<String
, ?
> currentState() {
144 Dictionary
<String
, Object
> res
= new Hashtable
<String
, Object
>();
145 for (LdapName name
: userAdmins
.keySet()) {
146 StringBuilder buf
= new StringBuilder();
147 if (userAdmins
.get(name
) instanceof UserDirectory
) {
148 UserDirectory userDirectory
= (UserDirectory
) userAdmins
150 String uri
= UserAdminConf
.propertiesAsUri(
151 userDirectory
.getProperties()).toString();
154 buf
.append('/').append(name
.toString())
155 .append("?readOnly=true");
161 public void destroy() {
162 for (LdapName name
: userAdmins
.keySet()) {
163 if (userAdmins
.get(name
) instanceof UserDirectory
) {
164 UserDirectory userDirectory
= (UserDirectory
) userAdmins
166 userDirectory
.destroy();
172 public Role
createRole(String name
, int type
) {
173 return findUserAdmin(name
).createRole(name
, type
);
177 public boolean removeRole(String name
) {
178 boolean actuallyDeleted
= findUserAdmin(name
).removeRole(name
);
179 nodeRoles
.removeRole(name
);
180 return actuallyDeleted
;
184 public Role
getRole(String name
) {
185 return findUserAdmin(name
).getRole(name
);
189 public Role
[] getRoles(String filter
) throws InvalidSyntaxException
{
190 List
<Role
> res
= new ArrayList
<Role
>();
191 for (UserAdmin userAdmin
: userAdmins
.values()) {
192 res
.addAll(Arrays
.asList(userAdmin
.getRoles(filter
)));
194 res
.addAll(Arrays
.asList(nodeRoles
.getRoles(filter
)));
195 return res
.toArray(new Role
[res
.size()]);
199 public User
getUser(String key
, String value
) {
200 List
<User
> res
= new ArrayList
<User
>();
201 for (UserAdmin userAdmin
: userAdmins
.values()) {
202 User u
= userAdmin
.getUser(key
, value
);
206 // Note: node roles cannot contain users, so it is not searched
207 return res
.size() == 1 ? res
.get(0) : null;
211 public Authorization
getAuthorization(User user
) {
213 return nodeRoles
.getAuthorization(null);
215 UserAdmin userAdmin
= findUserAdmin(user
.getName());
216 Authorization rawAuthorization
= userAdmin
.getAuthorization(user
);
217 // gather system roles
218 Set
<String
> systemRoles
= new HashSet
<String
>();
219 for (String role
: rawAuthorization
.getRoles()) {
220 Authorization auth
= nodeRoles
.getAuthorization((User
) userAdmin
222 systemRoles
.addAll(Arrays
.asList(auth
.getRoles()));
224 return new NodeAuthorization(rawAuthorization
.getName(),
225 rawAuthorization
.toString(), systemRoles
,
226 rawAuthorization
.getRoles());
230 // USER ADMIN AGGREGATOR
232 public synchronized void addUserAdmin(String baseDn
, UserAdmin userAdmin
) {
233 if (baseDn
.equals(KernelHeader
.ROLES_BASEDN
)) {
234 nodeRoles
= userAdmin
;
238 if (userAdmins
.containsKey(baseDn
))
239 throw new UserDirectoryException(
240 "There is already a user admin for " + baseDn
);
242 userAdmins
.put(new LdapName(baseDn
), userAdmin
);
243 } catch (InvalidNameException e
) {
244 throw new UserDirectoryException("Badly formatted base DN "
249 public synchronized void removeUserAdmin(String baseDn
) {
250 if (baseDn
.equals(KernelHeader
.ROLES_BASEDN
))
251 throw new UserDirectoryException("Node roles cannot be removed.");
254 base
= new LdapName(baseDn
);
255 } catch (InvalidNameException e
) {
256 throw new UserDirectoryException("Badly formatted base DN "
259 if (!userAdmins
.containsKey(base
))
260 throw new UserDirectoryException("There is no user admin for "
262 userAdmins
.remove(base
);
265 private UserAdmin
findUserAdmin(String name
) {
267 return findUserAdmin(new LdapName(name
));
268 } catch (InvalidNameException e
) {
269 throw new UserDirectoryException("Badly formatted name " + name
, e
);
273 private UserAdmin
findUserAdmin(LdapName name
) {
274 if (name
.startsWith(ROLES_BASE
))
276 List
<UserAdmin
> res
= new ArrayList
<UserAdmin
>(1);
277 for (LdapName baseDn
: userAdmins
.keySet()) {
278 if (name
.startsWith(baseDn
))
279 res
.add(userAdmins
.get(baseDn
));
282 throw new UserDirectoryException("Cannot find user admin for "
285 throw new UserDirectoryException("Multiple user admin found for "
290 public void setTransactionManager(TransactionManager transactionManager
) {
291 if (nodeRoles
instanceof UserDirectory
)
292 ((UserDirectory
) nodeRoles
)
293 .setTransactionManager(transactionManager
);
294 for (UserAdmin userAdmin
: userAdmins
.values()) {
295 if (userAdmin
instanceof UserDirectory
)
296 ((UserDirectory
) userAdmin
)
297 .setTransactionManager(transactionManager
);