]> git.argeo.org Git - lgpl/argeo-commons.git/blob - src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java
Prepare next development cycle
[lgpl/argeo-commons.git] / src / org / argeo / osgi / useradmin / AggregatingUserAdmin.java
1 package org.argeo.osgi.useradmin;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Set;
10
11 import javax.naming.InvalidNameException;
12 import javax.naming.ldap.LdapName;
13
14 import org.osgi.framework.InvalidSyntaxException;
15 import org.osgi.service.useradmin.Authorization;
16 import org.osgi.service.useradmin.Group;
17 import org.osgi.service.useradmin.Role;
18 import org.osgi.service.useradmin.User;
19 import org.osgi.service.useradmin.UserAdmin;
20
21 /**
22 * Aggregates multiple {@link UserDirectory} and integrates them with system
23 * roles.
24 */
25 public class AggregatingUserAdmin implements UserAdmin {
26 private final LdapName systemRolesBaseDn;
27 private final LdapName tokensBaseDn;
28
29 // DAOs
30 private AbstractUserDirectory systemRoles = null;
31 private AbstractUserDirectory tokens = null;
32 private Map<LdapName, AbstractUserDirectory> businessRoles = new HashMap<LdapName, AbstractUserDirectory>();
33
34 public AggregatingUserAdmin(String systemRolesBaseDn, String tokensBaseDn) {
35 try {
36 this.systemRolesBaseDn = new LdapName(systemRolesBaseDn);
37 if (tokensBaseDn != null)
38 this.tokensBaseDn = new LdapName(tokensBaseDn);
39 else
40 this.tokensBaseDn = null;
41 } catch (InvalidNameException e) {
42 throw new UserDirectoryException("Cannot initialize " + AggregatingUserAdmin.class, e);
43 }
44 }
45
46 @Override
47 public Role createRole(String name, int type) {
48 return findUserAdmin(name).createRole(name, type);
49 }
50
51 @Override
52 public boolean removeRole(String name) {
53 boolean actuallyDeleted = findUserAdmin(name).removeRole(name);
54 systemRoles.removeRole(name);
55 return actuallyDeleted;
56 }
57
58 @Override
59 public Role getRole(String name) {
60 return findUserAdmin(name).getRole(name);
61 }
62
63 @Override
64 public Role[] getRoles(String filter) throws InvalidSyntaxException {
65 List<Role> res = new ArrayList<Role>();
66 for (UserAdmin userAdmin : businessRoles.values()) {
67 res.addAll(Arrays.asList(userAdmin.getRoles(filter)));
68 }
69 res.addAll(Arrays.asList(systemRoles.getRoles(filter)));
70 return res.toArray(new Role[res.size()]);
71 }
72
73 @Override
74 public User getUser(String key, String value) {
75 List<User> res = new ArrayList<User>();
76 for (UserAdmin userAdmin : businessRoles.values()) {
77 User u = userAdmin.getUser(key, value);
78 if (u != null)
79 res.add(u);
80 }
81 // Note: node roles cannot contain users, so it is not searched
82 return res.size() == 1 ? res.get(0) : null;
83 }
84
85 @Override
86 public Authorization getAuthorization(User user) {
87 if (user == null) {// anonymous
88 return systemRoles.getAuthorization(null);
89 }
90 UserAdmin userAdmin = findUserAdmin(user.getName());
91 Authorization rawAuthorization = userAdmin.getAuthorization(user);
92 String usernameToUse;
93 String displayNameToUse;
94 if (user instanceof Group) {
95 String ownerDn = TokenUtils.userDn((Group) user);
96 if (ownerDn != null) {// tokens
97 UserAdmin ownerUserAdmin = findUserAdmin(ownerDn);
98 User ownerUser = (User) ownerUserAdmin.getRole(ownerDn);
99 usernameToUse = ownerDn;
100 displayNameToUse = LdifAuthorization.extractDisplayName(ownerUser);
101 } else {
102 usernameToUse = rawAuthorization.getName();
103 displayNameToUse = rawAuthorization.toString();
104 }
105 } else {// regular users
106 usernameToUse = rawAuthorization.getName();
107 displayNameToUse = rawAuthorization.toString();
108 }
109 // gather system roles
110 Set<String> sysRoles = new HashSet<String>();
111 for (String role : rawAuthorization.getRoles()) {
112 Authorization auth = systemRoles.getAuthorization((User) userAdmin.getRole(role));
113 systemRoles:for(String systemRole:auth.getRoles()) {
114 if(role.equals(systemRole))
115 continue systemRoles;
116 sysRoles.add(systemRole);
117 }
118 // sysRoles.addAll(Arrays.asList(auth.getRoles()));
119 }
120 addAbstractSystemRoles(rawAuthorization, sysRoles);
121 Authorization authorization = new AggregatingAuthorization(usernameToUse, displayNameToUse, sysRoles,
122 rawAuthorization.getRoles());
123 return authorization;
124 }
125
126 /**
127 * Enrich with application-specific roles which are strictly programmatic, such
128 * as anonymous/user semantics.
129 */
130 protected void addAbstractSystemRoles(Authorization rawAuthorization, Set<String> sysRoles) {
131
132 }
133
134 //
135 // USER ADMIN AGGREGATOR
136 //
137 protected void addUserDirectory(AbstractUserDirectory userDirectory) {
138 LdapName baseDn = userDirectory.getBaseDn();
139 if (isSystemRolesBaseDn(baseDn)) {
140 this.systemRoles = userDirectory;
141 systemRoles.setExternalRoles(this);
142 } else if (isTokensBaseDn(baseDn)) {
143 this.tokens = userDirectory;
144 tokens.setExternalRoles(this);
145 } else {
146 if (businessRoles.containsKey(baseDn))
147 throw new UserDirectoryException("There is already a user admin for " + baseDn);
148 businessRoles.put(baseDn, userDirectory);
149 }
150 userDirectory.init();
151 postAdd(userDirectory);
152 }
153
154 /** Called after a new user directory has been added */
155 protected void postAdd(AbstractUserDirectory userDirectory) {
156 }
157
158 private UserAdmin findUserAdmin(String name) {
159 try {
160 UserAdmin userAdmin = findUserAdmin(new LdapName(name));
161 return userAdmin;
162 } catch (InvalidNameException e) {
163 throw new UserDirectoryException("Badly formatted name " + name, e);
164 }
165 }
166
167 private UserAdmin findUserAdmin(LdapName name) {
168 if (name.startsWith(systemRolesBaseDn))
169 return systemRoles;
170 if (tokensBaseDn != null && name.startsWith(tokensBaseDn))
171 return tokens;
172 List<UserAdmin> res = new ArrayList<UserAdmin>(1);
173 for (LdapName baseDn : businessRoles.keySet()) {
174 AbstractUserDirectory ud = businessRoles.get(baseDn);
175 if (name.startsWith(baseDn)) {
176 if (!ud.isDisabled())
177 res.add(ud);
178 }
179 // Object principal = ud.getProperties().get(Context.SECURITY_PRINCIPAL);
180 // if (principal != null) {
181 // try {
182 // LdapName principalLdapName = new LdapName(principal.toString());
183 // if (principalLdapName.equals(name))
184 // res.add(ud);
185 // } catch (InvalidNameException e) {
186 // // silent
187 // }
188 // }
189 }
190 if (res.size() == 0)
191 throw new UserDirectoryException("Cannot find user admin for " + name);
192 if (res.size() > 1)
193 throw new UserDirectoryException("Multiple user admin found for " + name);
194 return res.get(0);
195 }
196
197 protected boolean isSystemRolesBaseDn(LdapName baseDn) {
198 return baseDn.equals(systemRolesBaseDn);
199 }
200
201 protected boolean isTokensBaseDn(LdapName baseDn) {
202 return tokensBaseDn != null && baseDn.equals(tokensBaseDn);
203 }
204
205 // protected Dictionary<String, Object> currentState() {
206 // Dictionary<String, Object> res = new Hashtable<String, Object>();
207 // // res.put(NodeConstants.CN, NodeConstants.DEFAULT);
208 // for (LdapName name : businessRoles.keySet()) {
209 // AbstractUserDirectory userDirectory = businessRoles.get(name);
210 // String uri = UserAdminConf.propertiesAsUri(userDirectory.getProperties()).toString();
211 // res.put(uri, "");
212 // }
213 // return res;
214 // }
215
216 public void destroy() {
217 for (LdapName name : businessRoles.keySet()) {
218 AbstractUserDirectory userDirectory = businessRoles.get(name);
219 destroy(userDirectory);
220 }
221 businessRoles.clear();
222 businessRoles = null;
223 destroy(systemRoles);
224 systemRoles = null;
225 }
226
227 private void destroy(AbstractUserDirectory userDirectory) {
228 preDestroy(userDirectory);
229 userDirectory.destroy();
230 }
231
232 protected void removeUserDirectory(LdapName baseDn) {
233 if (isSystemRolesBaseDn(baseDn))
234 throw new UserDirectoryException("System roles cannot be removed ");
235 if (!businessRoles.containsKey(baseDn))
236 throw new UserDirectoryException("No user directory registered for " + baseDn);
237 AbstractUserDirectory userDirectory = businessRoles.remove(baseDn);
238 destroy(userDirectory);
239 }
240
241 /**
242 * Called before each user directory is destroyed, so that additional actions
243 * can be performed.
244 */
245 protected void preDestroy(AbstractUserDirectory userDirectory) {
246 }
247
248 }