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
.List
;
16 import javax
.naming
.InvalidNameException
;
17 import javax
.naming
.ldap
.LdapName
;
18 import javax
.transaction
.TransactionManager
;
20 import org
.apache
.commons
.io
.FileUtils
;
21 import org
.apache
.commons
.logging
.Log
;
22 import org
.apache
.commons
.logging
.LogFactory
;
23 import org
.argeo
.cms
.CmsException
;
24 import org
.argeo
.cms
.KernelHeader
;
25 import org
.argeo
.osgi
.useradmin
.AbstractUserDirectory
;
26 import org
.argeo
.osgi
.useradmin
.LdapProperties
;
27 import org
.argeo
.osgi
.useradmin
.LdapUserAdmin
;
28 import org
.argeo
.osgi
.useradmin
.LdifUserAdmin
;
29 import org
.argeo
.osgi
.useradmin
.UserAdminAggregator
;
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
, UserAdminAggregator
{
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 private TransactionManager transactionManager
;
54 public NodeUserAdmin() {
55 File osgiInstanceDir
= KernelUtils
.getOsgiInstanceDir();
56 File nodeBaseDir
= new File(osgiInstanceDir
, "node");
59 String userAdminUri
= KernelUtils
60 .getFrameworkProp(KernelConstants
.USERADMIN_URI
);
61 if (userAdminUri
== null) {
62 String demoBaseDn
= "dc=example,dc=com";
63 File businessRolesFile
= new File(nodeBaseDir
, demoBaseDn
+ ".ldif");
64 if (!businessRolesFile
.exists())
66 FileUtils
.copyInputStreamToFile(getClass()
67 .getResourceAsStream(demoBaseDn
+ ".ldif"),
69 } catch (IOException e
) {
70 throw new CmsException("Cannot copy demo resource", e
);
72 userAdminUri
= businessRolesFile
.toURI().toString();
75 String
[] uris
= userAdminUri
.split(" ");
76 for (String uri
: uris
) {
80 if (u
.getScheme() == null) {
81 if (uri
.startsWith("/"))
82 u
= new File(uri
).getAbsoluteFile().toURI();
83 else if (!uri
.contains("/"))
84 u
= new File(nodeBaseDir
, uri
).getAbsoluteFile()
87 throw new CmsException("Cannot interpret " + uri
90 } catch (URISyntaxException e
) {
91 throw new CmsException(
92 "Cannot interpret " + uri
+ " as an uri", e
);
94 Dictionary
<String
, ?
> properties
= LdapProperties
.uriAsProperties(u
96 AbstractUserDirectory businessRoles
;
97 if (u
.getScheme().startsWith("ldap")) {
98 businessRoles
= new LdapUserAdmin(properties
);
100 businessRoles
= new LdifUserAdmin(properties
);
102 businessRoles
.init();
103 addUserAdmin(businessRoles
.getBaseDn(), businessRoles
);
104 if (log
.isDebugEnabled())
105 log
.debug("User directory " + businessRoles
.getBaseDn() + " ["
106 + u
.getScheme() + "] enabled.");
110 String nodeRolesUri
= KernelUtils
111 .getFrameworkProp(KernelConstants
.ROLES_URI
);
112 String baseNodeRoleDn
= KernelHeader
.ROLES_BASEDN
;
113 if (nodeRolesUri
== null) {
114 File nodeRolesFile
= new File(nodeBaseDir
, baseNodeRoleDn
+ ".ldif");
115 if (!nodeRolesFile
.exists())
117 FileUtils
.copyInputStreamToFile(getClass()
118 .getResourceAsStream("demo.ldif"), nodeRolesFile
);
119 } catch (IOException e
) {
120 throw new CmsException("Cannot copy demo resource", e
);
122 nodeRolesUri
= nodeRolesFile
.toURI().toString();
125 Dictionary
<String
, ?
> nodeRolesProperties
= LdapProperties
126 .uriAsProperties(nodeRolesUri
);
127 if (!nodeRolesProperties
.get(LdapProperties
.baseDn
.getFullName())
128 .equals(baseNodeRoleDn
)) {
129 throw new CmsException("Invalid base dn for node roles");
130 // TODO deal with "mounted" roles with a different baseDN
132 AbstractUserDirectory nodeRoles
;
133 if (nodeRolesUri
.startsWith("ldap")) {
134 nodeRoles
= new LdapUserAdmin(nodeRolesProperties
);
136 nodeRoles
= new LdifUserAdmin(nodeRolesProperties
);
138 nodeRoles
.setExternalRoles(this);
140 addUserAdmin(baseNodeRoleDn
, nodeRoles
);
141 if (log
.isTraceEnabled())
142 log
.trace("Node roles enabled.");
145 String
asConfigUris() {
146 StringBuilder buf
= new StringBuilder();
147 for (LdapName name
: userAdmins
.keySet()) {
148 buf
.append('/').append(name
.toString());
149 if (userAdmins
.get(name
) instanceof AbstractUserDirectory
) {
150 AbstractUserDirectory userDirectory
= (AbstractUserDirectory
) userAdmins
152 if (userDirectory
.isReadOnly())
153 buf
.append('?').append(LdapProperties
.readOnly
.name())
158 return buf
.toString();
161 public void destroy() {
162 for (LdapName name
: userAdmins
.keySet()) {
163 if (userAdmins
.get(name
) instanceof AbstractUserDirectory
) {
164 AbstractUserDirectory userDirectory
= (AbstractUserDirectory
) 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 return findUserAdmin(name
).removeRole(name
);
182 public Role
getRole(String name
) {
183 return findUserAdmin(name
).getRole(name
);
187 public Role
[] getRoles(String filter
) throws InvalidSyntaxException
{
188 List
<Role
> res
= new ArrayList
<Role
>();
189 for (UserAdmin userAdmin
: userAdmins
.values()) {
190 res
.addAll(Arrays
.asList(userAdmin
.getRoles(filter
)));
192 res
.addAll(Arrays
.asList(nodeRoles
.getRoles(filter
)));
193 return res
.toArray(new Role
[res
.size()]);
197 public User
getUser(String key
, String value
) {
198 List
<User
> res
= new ArrayList
<User
>();
199 for (UserAdmin userAdmin
: userAdmins
.values()) {
200 User u
= userAdmin
.getUser(key
, value
);
204 // Note: node roles cannot contain users, so it is not searched
205 return res
.size() == 1 ? res
.get(0) : null;
209 public Authorization
getAuthorization(User user
) {
210 UserAdmin userAdmin
= findUserAdmin(user
.getName());
211 Authorization rawAuthorization
= userAdmin
.getAuthorization(user
);
212 // gather system roles
213 Set
<String
> systemRoles
= new HashSet
<String
>();
214 for (String role
: rawAuthorization
.getRoles()) {
215 Authorization auth
= nodeRoles
.getAuthorization((User
) userAdmin
217 systemRoles
.addAll(Arrays
.asList(auth
.getRoles()));
219 return new NodeAuthorization(rawAuthorization
.getName(),
220 rawAuthorization
.toString(), systemRoles
,
221 rawAuthorization
.getRoles());
225 // USER ADMIN AGGREGATOR
228 public synchronized void addUserAdmin(String baseDn
, UserAdmin userAdmin
) {
229 if (baseDn
.equals(KernelHeader
.ROLES_BASEDN
)) {
230 nodeRoles
= userAdmin
;
234 if (userAdmins
.containsKey(baseDn
))
235 throw new UserDirectoryException(
236 "There is already a user admin for " + baseDn
);
238 userAdmins
.put(new LdapName(baseDn
), userAdmin
);
239 } catch (InvalidNameException e
) {
240 throw new UserDirectoryException("Badly formatted base DN "
246 public synchronized void removeUserAdmin(String baseDn
) {
247 if (baseDn
.equals(KernelHeader
.ROLES_BASEDN
))
248 throw new UserDirectoryException("Node roles cannot be removed.");
251 base
= new LdapName(baseDn
);
252 } catch (InvalidNameException e
) {
253 throw new UserDirectoryException("Badly formatted base DN "
256 if (!userAdmins
.containsKey(base
))
257 throw new UserDirectoryException("There is no user admin for "
259 userAdmins
.remove(base
);
262 private UserAdmin
findUserAdmin(String name
) {
264 return findUserAdmin(new LdapName(name
));
265 } catch (InvalidNameException e
) {
266 throw new UserDirectoryException("Badly formatted name " + name
, e
);
270 private UserAdmin
findUserAdmin(LdapName name
) {
271 if (name
.startsWith(ROLES_BASE
))
273 List
<UserAdmin
> res
= new ArrayList
<UserAdmin
>(1);
274 for (LdapName baseDn
: userAdmins
.keySet()) {
275 if (name
.startsWith(baseDn
))
276 res
.add(userAdmins
.get(baseDn
));
279 throw new UserDirectoryException("Cannot find user admin for "
282 throw new UserDirectoryException("Multiple user admin found for "
287 public void setTransactionManager(TransactionManager transactionManager
) {
288 this.transactionManager
= transactionManager
;
289 if (nodeRoles
instanceof AbstractUserDirectory
)
290 ((AbstractUserDirectory
) nodeRoles
)
291 .setTransactionManager(transactionManager
);
292 for (UserAdmin userAdmin
: userAdmins
.values()) {
293 if (userAdmin
instanceof AbstractUserDirectory
)
294 ((AbstractUserDirectory
) userAdmin
)
295 .setTransactionManager(transactionManager
);