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
;
8 import java
.util
.ArrayList
;
9 import java
.util
.Dictionary
;
10 import java
.util
.Hashtable
;
11 import java
.util
.List
;
12 import java
.util
.SortedMap
;
13 import java
.util
.TreeMap
;
15 import javax
.naming
.NamingEnumeration
;
16 import javax
.naming
.directory
.Attributes
;
17 import javax
.naming
.ldap
.LdapName
;
18 import javax
.transaction
.TransactionManager
;
20 import org
.apache
.commons
.io
.IOUtils
;
21 import org
.osgi
.framework
.Filter
;
22 import org
.osgi
.service
.useradmin
.Role
;
25 * A user admin based on a LDIF files. Requires a {@link TransactionManager} and
26 * an open transaction for write access.
28 public class LdifUserAdmin
extends AbstractUserDirectory
{
29 private SortedMap
<LdapName
, DirectoryUser
> users
= new TreeMap
<LdapName
, DirectoryUser
>();
30 private SortedMap
<LdapName
, DirectoryGroup
> groups
= new TreeMap
<LdapName
, DirectoryGroup
>();
32 public LdifUserAdmin(String uri
, String baseDn
) {
33 this(fromUri(uri
, baseDn
));
36 public LdifUserAdmin(Dictionary
<String
, ?
> properties
) {
40 public LdifUserAdmin(InputStream in
) {
41 super(new Hashtable
<String
, Object
>());
45 private static Dictionary
<String
, Object
> fromUri(String uri
, String baseDn
) {
46 Hashtable
<String
, Object
> res
= new Hashtable
<String
, Object
>();
47 res
.put(UserAdminConf
.uri
.property(), uri
);
48 res
.put(UserAdminConf
.baseDn
.property(), baseDn
);
54 if (getUri().getScheme().equals("file")) {
55 File file
= new File(getUri());
59 load(getUri().toURL().openStream());
60 } catch (Exception e
) {
61 throw new UserDirectoryException("Cannot open URL " + getUri(), e
);
67 throw new UserDirectoryException(
68 "Cannot save LDIF user admin: no URI is set");
70 throw new UserDirectoryException("Cannot save LDIF user admin: "
71 + getUri() + " is read-only");
72 try (FileOutputStream out
= new FileOutputStream(new File(getUri()))) {
74 } catch (IOException e
) {
75 throw new UserDirectoryException("Cannot save user admin to "
80 public void save(OutputStream out
) throws IOException
{
82 LdifWriter ldifWriter
= new LdifWriter(out
);
83 for (LdapName name
: groups
.keySet())
84 ldifWriter
.writeEntry(name
, groups
.get(name
).getAttributes());
85 for (LdapName name
: users
.keySet())
86 ldifWriter
.writeEntry(name
, users
.get(name
).getAttributes());
88 IOUtils
.closeQuietly(out
);
92 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(this, key
, attributes
));
108 } else if (objectClass
.equals("groupOfNames")) {
109 groups
.put(key
, new LdifGroup(this, key
, attributes
));
114 } catch (Exception e
) {
115 throw new UserDirectoryException(
116 "Cannot load user admin service from LDIF", e
);
120 public void destroy() {
127 protected DirectoryUser
daoGetRole(LdapName key
) {
128 if (groups
.containsKey(key
))
129 return groups
.get(key
);
130 if (users
.containsKey(key
))
131 return users
.get(key
);
135 protected Boolean
daoHasRole(LdapName dn
) {
136 return users
.containsKey(dn
) || groups
.containsKey(dn
);
139 @SuppressWarnings("unchecked")
140 protected List
<DirectoryUser
> doGetRoles(Filter f
) {
141 ArrayList
<DirectoryUser
> res
= new ArrayList
<DirectoryUser
>();
143 res
.addAll(users
.values());
144 res
.addAll(groups
.values());
146 // Filter f = FrameworkUtil.createFilter(filter);
147 for (DirectoryUser user
: users
.values())
148 if (f
.match(user
.getProperties()))
150 for (DirectoryUser group
: groups
.values())
151 if (f
.match(group
.getProperties()))
158 protected List
<LdapName
> getDirectGroups(LdapName dn
) {
159 List
<LdapName
> directGroups
= new ArrayList
<LdapName
>();
160 for (LdapName name
: groups
.keySet()) {
161 DirectoryGroup group
= groups
.get(name
);
162 if (group
.getMemberNames().contains(dn
))
163 directGroups
.add(group
.getDn());
169 protected void prepare(UserDirectoryWorkingCopy wc
) {
171 for (LdapName dn
: wc
.getDeletedUsers().keySet()) {
172 if (users
.containsKey(dn
))
174 else if (groups
.containsKey(dn
))
177 throw new UserDirectoryException("User to delete no found "
181 for (LdapName dn
: wc
.getNewUsers().keySet()) {
182 DirectoryUser user
= wc
.getNewUsers().get(dn
);
183 if (Role
.USER
== user
.getType())
185 else if (Role
.GROUP
== user
.getType())
186 groups
.put(dn
, (DirectoryGroup
) user
);
188 throw new UserDirectoryException("Unsupported role type "
189 + user
.getType() + " for new user " + dn
);
192 for (LdapName dn
: wc
.getModifiedUsers().keySet()) {
193 Attributes modifiedAttrs
= wc
.getModifiedUsers().get(dn
);
195 if (users
.containsKey(dn
))
196 user
= users
.get(dn
);
197 else if (groups
.containsKey(dn
))
198 user
= groups
.get(dn
);
200 throw new UserDirectoryException("User to modify no found "
202 user
.publishAttributes(modifiedAttrs
);
207 protected void commit(UserDirectoryWorkingCopy wc
) {
212 protected void rollback(UserDirectoryWorkingCopy wc
) {