]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - useradmin/LdifUserAdmin.java
1 package org
.argeo
.osgi
.useradmin
;
4 import java
.io
.FileOutputStream
;
5 import java
.io
.IOException
;
6 import java
.io
.InputStream
;
7 import java
.io
.OutputStream
;
9 import java
.net
.URISyntaxException
;
10 import java
.util
.ArrayList
;
11 import java
.util
.Dictionary
;
12 import java
.util
.LinkedHashMap
;
13 import java
.util
.List
;
15 import java
.util
.SortedMap
;
16 import java
.util
.TreeMap
;
18 import javax
.naming
.InvalidNameException
;
19 import javax
.naming
.NamingEnumeration
;
20 import javax
.naming
.directory
.Attributes
;
21 import javax
.naming
.directory
.BasicAttributes
;
22 import javax
.naming
.ldap
.LdapName
;
23 import javax
.naming
.ldap
.Rdn
;
25 import org
.apache
.commons
.io
.IOUtils
;
26 import org
.osgi
.framework
.Filter
;
27 import org
.osgi
.framework
.FrameworkUtil
;
28 import org
.osgi
.framework
.InvalidSyntaxException
;
29 import org
.osgi
.service
.useradmin
.Authorization
;
30 import org
.osgi
.service
.useradmin
.Role
;
31 import org
.osgi
.service
.useradmin
.User
;
33 /** User admin implementation using LDIF file(s) as backend. */
34 public class LdifUserAdmin
extends AbstractLdapUserAdmin
{
35 SortedMap
<LdapName
, LdifUser
> users
= new TreeMap
<LdapName
, LdifUser
>();
36 SortedMap
<LdapName
, LdifGroup
> groups
= new TreeMap
<LdapName
, LdifGroup
>();
38 private Map
<String
, Map
<String
, LdifUser
>> userIndexes
= new LinkedHashMap
<String
, Map
<String
, LdifUser
>>();
40 public LdifUserAdmin(String uri
) {
44 public LdifUserAdmin(String uri
, boolean isReadOnly
) {
45 setReadOnly(isReadOnly
);
48 } catch (URISyntaxException e
) {
49 throw new ArgeoUserAdminException("Invalid URI " + uri
, e
);
52 if (!isReadOnly
&& !getUri().getScheme().equals("file:"))
53 throw new UnsupportedOperationException(getUri().getScheme()
54 + "not supported read-write.");
58 public LdifUserAdmin(InputStream in
) {
66 load(getUri().toURL().openStream());
67 } catch (Exception e
) {
68 throw new ArgeoUserAdminException("Cannot open URL " + getUri(), e
);
73 if (getUri() == null || isReadOnly())
74 throw new ArgeoUserAdminException("Cannot save LDIF user admin");
75 try (FileOutputStream out
= new FileOutputStream(new File(getUri()))) {
77 } catch (IOException e
) {
78 throw new ArgeoUserAdminException("Cannot save user admin to "
83 public void save(OutputStream out
) throws IOException
{
85 LdifWriter ldifWriter
= new LdifWriter(out
);
86 for (LdapName name
: groups
.keySet())
87 ldifWriter
.writeEntry(name
, groups
.get(name
).getAttributes());
88 for (LdapName name
: users
.keySet())
89 ldifWriter
.writeEntry(name
, users
.get(name
).getAttributes());
91 IOUtils
.closeQuietly(out
);
95 protected void load(InputStream in
) {
97 LdifParser ldifParser
= new LdifParser();
98 SortedMap
<LdapName
, Attributes
> allEntries
= ldifParser
.read(in
);
99 for (LdapName key
: allEntries
.keySet()) {
100 Attributes attributes
= allEntries
.get(key
);
101 NamingEnumeration
<?
> objectClasses
= attributes
.get(
102 "objectClass").getAll();
103 objectClasses
: while (objectClasses
.hasMore()) {
104 String objectClass
= objectClasses
.next().toString();
105 if (objectClass
.equals("inetOrgPerson")) {
106 users
.put(key
, new LdifUser(key
, attributes
));
108 } else if (objectClass
.equals("groupOfNames")) {
109 groups
.put(key
, new LdifGroup(key
, attributes
));
116 for (LdifGroup group
: groups
.values())
120 for (String attr
: getIndexedUserProperties())
121 userIndexes
.put(attr
, new TreeMap
<String
, LdifUser
>());
123 for (LdifUser user
: users
.values()) {
124 Dictionary
<String
, Object
> properties
= user
.getProperties();
125 for (String attr
: getIndexedUserProperties()) {
126 Object value
= properties
.get(attr
);
128 LdifUser otherUser
= userIndexes
.get(attr
).put(
129 value
.toString(), user
);
130 if (otherUser
!= null)
131 throw new ArgeoUserAdminException("User " + user
132 + " and user " + otherUser
133 + " both have property " + attr
134 + " set to " + value
);
138 } catch (Exception e
) {
139 throw new ArgeoUserAdminException(
140 "Cannot load user admin service from LDIF", e
);
144 public void destroy() {
152 public Role
getRole(String name
) {
155 key
= new LdapName(name
);
156 } catch (InvalidNameException e
) {
157 // TODO implements default base DN
158 throw new IllegalArgumentException("Badly formatted role name: "
162 if (groups
.containsKey(key
))
163 return groups
.get(key
);
164 if (users
.containsKey(key
))
165 return users
.get(key
);
170 public Authorization
getAuthorization(User user
) {
171 return new LdifAuthorization((LdifUser
) user
);
175 public Role
createRole(String name
, int type
) {
177 LdapName dn
= new LdapName(name
);
178 if (users
.containsKey(dn
) || groups
.containsKey(dn
))
179 throw new ArgeoUserAdminException("Already a role " + name
);
181 BasicAttributes attrs
= new BasicAttributes();
182 attrs
.put("dn", dn
.toString());
183 Rdn nameRdn
= dn
.getRdn(dn
.size() - 1);
184 // TODO deal with multiple attr RDN
185 attrs
.put(nameRdn
.getType(), nameRdn
.getValue());
187 if (type
== Role
.USER
) {
188 newRole
= new LdifUser(dn
, attrs
);
189 users
.put(dn
, newRole
);
190 } else if (type
== Role
.GROUP
) {
191 newRole
= new LdifGroup(dn
, attrs
);
192 groups
.put(dn
, (LdifGroup
) newRole
);
194 throw new ArgeoUserAdminException("Unsupported type " + type
);
196 } catch (InvalidNameException e
) {
197 throw new ArgeoUserAdminException("Cannot create role " + name
, e
);
202 public boolean removeRole(String name
) {
204 LdapName dn
= new LdapName(name
);
205 LdifUser role
= null;
206 if (users
.containsKey(dn
))
207 role
= users
.remove(dn
);
208 else if (groups
.containsKey(dn
))
209 role
= groups
.remove(dn
);
211 throw new ArgeoUserAdminException("There is no role " + name
);
214 for (LdifGroup group
: role
.directMemberOf
) {
215 group
.directMembers
.remove(role
);
216 group
.getAttributes().get(group
.getMemberAttrName())
217 .remove(dn
.toString());
219 if (role
instanceof LdifGroup
) {
220 LdifGroup group
= (LdifGroup
) role
;
221 for (Role user
: group
.directMembers
) {
222 if (user
instanceof LdifUser
)
223 ((LdifUser
) user
).directMemberOf
.remove(group
);
227 } catch (InvalidNameException e
) {
228 throw new ArgeoUserAdminException("Cannot create role " + name
, e
);
233 public Role
[] getRoles(String filter
) throws InvalidSyntaxException
{
234 ArrayList
<Role
> res
= new ArrayList
<Role
>();
235 if (filter
== null) {
236 res
.addAll(users
.values());
237 res
.addAll(groups
.values());
239 Filter f
= FrameworkUtil
.createFilter(filter
);
240 for (LdifUser user
: users
.values())
241 if (f
.match(user
.getProperties()))
243 for (LdifUser group
: groups
.values())
244 if (f
.match(group
.getProperties()))
247 return res
.toArray(new Role
[res
.size()]);
251 public User
getUser(String key
, String value
) {
252 // TODO check value null or empty
254 if (!userIndexes
.containsKey(key
))
256 return userIndexes
.get(key
).get(value
);
260 List
<LdifUser
> collectedUsers
= new ArrayList
<LdifUser
>(
261 getIndexedUserProperties().size());
263 LdifUser user
= null;
265 user
= (LdifUser
) getRole(value
);
267 collectedUsers
.add(user
);
268 } catch (Exception e
) {
271 for (String attr
: userIndexes
.keySet()) {
272 user
= userIndexes
.get(attr
).get(value
);
274 collectedUsers
.add(user
);
277 if (collectedUsers
.size() == 1)
278 return collectedUsers
.get(0);
280 // throw new UnsupportedOperationException();
283 protected void loadMembers(LdifGroup group
) {
284 group
.directMembers
= new ArrayList
<Role
>();
285 for (LdapName ldapName
: group
.getMemberNames()) {
286 LdifUser role
= null;
287 if (groups
.containsKey(ldapName
))
288 role
= groups
.get(ldapName
);
289 else if (users
.containsKey(ldapName
))
290 role
= users
.get(ldapName
);
292 if (getExternalRoles() != null)
293 role
= (LdifUser
) getExternalRoles().getRole(
294 ldapName
.toString());
296 throw new ArgeoUserAdminException("No role found for "
299 role
.directMemberOf
.add(group
);
300 group
.directMembers
.add(role
);