]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/osgi/useradmin/LdapUserAdmin.java
Rename into CMS Context
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / osgi / useradmin / LdapUserAdmin.java
1 package org.argeo.osgi.useradmin;
2
3 import static org.argeo.util.naming.LdapAttrs.objectClass;
4
5 import java.util.ArrayList;
6 import java.util.Dictionary;
7 import java.util.List;
8
9 import javax.naming.AuthenticationNotSupportedException;
10 import javax.naming.Binding;
11 import javax.naming.Context;
12 import javax.naming.InvalidNameException;
13 import javax.naming.NameNotFoundException;
14 import javax.naming.NamingEnumeration;
15 import javax.naming.NamingException;
16 import javax.naming.directory.Attribute;
17 import javax.naming.directory.Attributes;
18 import javax.naming.directory.SearchControls;
19 import javax.naming.directory.SearchResult;
20 import javax.naming.ldap.LdapName;
21
22 import org.osgi.framework.Filter;
23 import org.osgi.service.useradmin.Role;
24 import org.osgi.service.useradmin.User;
25
26 /** A user admin based on a LDAP server. */
27 public class LdapUserAdmin extends AbstractUserDirectory {
28 private LdapConnection ldapConnection;
29
30 public LdapUserAdmin(Dictionary<String, ?> properties) {
31 this(properties, false);
32 }
33
34 public LdapUserAdmin(Dictionary<String, ?> properties, boolean scoped) {
35 super(null, properties, scoped);
36 ldapConnection = new LdapConnection(getUri().toString(), properties);
37 }
38
39 public void destroy() {
40 ldapConnection.destroy();
41 }
42
43 @Override
44 protected AbstractUserDirectory scope(User user) {
45 Dictionary<String, Object> credentials = user.getCredentials();
46 String username = (String) credentials.get(SHARED_STATE_USERNAME);
47 if (username == null)
48 username = user.getName();
49 Dictionary<String, Object> properties = cloneProperties();
50 properties.put(Context.SECURITY_PRINCIPAL, username.toString());
51 Object pwdCred = credentials.get(SHARED_STATE_PASSWORD);
52 byte[] pwd = (byte[]) pwdCred;
53 if (pwd != null) {
54 char[] password = DigestUtils.bytesToChars(pwd);
55 properties.put(Context.SECURITY_CREDENTIALS, new String(password));
56 } else {
57 properties.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
58 }
59 return new LdapUserAdmin(properties, true);
60 }
61
62 // protected InitialLdapContext getLdapContext() {
63 // return initialLdapContext;
64 // }
65
66 @Override
67 protected Boolean daoHasRole(LdapName dn) {
68 try {
69 return daoGetRole(dn) != null;
70 } catch (NameNotFoundException e) {
71 return false;
72 }
73 }
74
75 @Override
76 protected DirectoryUser daoGetRole(LdapName name) throws NameNotFoundException {
77 try {
78 Attributes attrs = ldapConnection.getAttributes(name);
79 if (attrs.size() == 0)
80 return null;
81 int roleType = roleType(name);
82 LdifUser res;
83 if (roleType == Role.GROUP)
84 res = new LdifGroup(this, name, attrs);
85 else if (roleType == Role.USER)
86 res = new LdifUser(this, name, attrs);
87 else
88 throw new UserDirectoryException("Unsupported LDAP type for " + name);
89 return res;
90 } catch (NameNotFoundException e) {
91 throw e;
92 } catch (NamingException e) {
93 return null;
94 }
95 }
96
97 @Override
98 protected List<DirectoryUser> doGetRoles(Filter f) {
99 ArrayList<DirectoryUser> res = new ArrayList<DirectoryUser>();
100 try {
101 String searchFilter = f != null ? f.toString()
102 : "(|(" + objectClass + "=" + getUserObjectClass() + ")(" + objectClass + "="
103 + getGroupObjectClass() + "))";
104 SearchControls searchControls = new SearchControls();
105 searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
106
107 LdapName searchBase = getBaseDn();
108 NamingEnumeration<SearchResult> results = ldapConnection.search(searchBase, searchFilter, searchControls);
109
110 results: while (results.hasMoreElements()) {
111 SearchResult searchResult = results.next();
112 Attributes attrs = searchResult.getAttributes();
113 Attribute objectClassAttr = attrs.get(objectClass.name());
114 LdapName dn = toDn(searchBase, searchResult);
115 LdifUser role;
116 if (objectClassAttr.contains(getGroupObjectClass())
117 || objectClassAttr.contains(getGroupObjectClass().toLowerCase()))
118 role = new LdifGroup(this, dn, attrs);
119 else if (objectClassAttr.contains(getUserObjectClass())
120 || objectClassAttr.contains(getUserObjectClass().toLowerCase()))
121 role = new LdifUser(this, dn, attrs);
122 else {
123 // log.warn("Unsupported LDAP type for " + searchResult.getName());
124 continue results;
125 }
126 res.add(role);
127 }
128 return res;
129 } catch (AuthenticationNotSupportedException e) {
130 // ignore (typically an unsupported anonymous bind)
131 // TODO better logging
132 return res;
133 } catch (Exception e) {
134 e.printStackTrace();
135 throw new UserDirectoryException("Cannot get roles for filter " + f, e);
136 }
137 }
138
139 private LdapName toDn(LdapName baseDn, Binding binding) throws InvalidNameException {
140 return new LdapName(binding.isRelative() ? binding.getName() + "," + baseDn : binding.getName());
141 }
142
143 @Override
144 protected List<LdapName> getDirectGroups(LdapName dn) {
145 List<LdapName> directGroups = new ArrayList<LdapName>();
146 try {
147 String searchFilter = "(&(" + objectClass + "=" + getGroupObjectClass() + ")(" + getMemberAttributeId()
148 + "=" + dn + "))";
149
150 SearchControls searchControls = new SearchControls();
151 searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
152
153 LdapName searchBase = getBaseDn();
154 NamingEnumeration<SearchResult> results = ldapConnection.search(searchBase, searchFilter, searchControls);
155
156 while (results.hasMoreElements()) {
157 SearchResult searchResult = (SearchResult) results.nextElement();
158 directGroups.add(toDn(searchBase, searchResult));
159 }
160 return directGroups;
161 } catch (Exception e) {
162 throw new UserDirectoryException("Cannot populate direct members of " + dn, e);
163 }
164 }
165
166 @Override
167 protected void prepare(UserDirectoryWorkingCopy wc) {
168 try {
169 ldapConnection.prepareChanges(wc);
170 } catch (NamingException e) {
171 throw new UserDirectoryException("Cannot prepare LDAP", e);
172 }
173 }
174
175 @Override
176 protected void commit(UserDirectoryWorkingCopy wc) {
177 try {
178 ldapConnection.commitChanges(wc);
179 } catch (NamingException e) {
180 throw new UserDirectoryException("Cannot commit LDAP", e);
181 }
182 }
183
184 @Override
185 protected void rollback(UserDirectoryWorkingCopy wc) {
186 // prepare not impacting
187 }
188
189 }