]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.enterprise/src/org/argeo/osgi/useradmin/AggregatingUserAdmin.java
Improve CMS UI framework.
[lgpl/argeo-commons.git] / org.argeo.enterprise / 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 sysRoles.addAll(Arrays.asList(auth.getRoles()));
114 }
115 addAbstractSystemRoles(rawAuthorization, sysRoles);
116 Authorization authorization = new AggregatingAuthorization(usernameToUse, displayNameToUse, sysRoles,
117 rawAuthorization.getRoles());
118 return authorization;
119 }
120
121 /**
122 * Enrich with application-specific roles which are strictly programmatic, such
123 * as anonymous/user semantics.
124 */
125 protected void addAbstractSystemRoles(Authorization rawAuthorization, Set<String> sysRoles) {
126
127 }
128
129 //
130 // USER ADMIN AGGREGATOR
131 //
132 protected void addUserDirectory(AbstractUserDirectory userDirectory) {
133 LdapName baseDn = userDirectory.getBaseDn();
134 if (isSystemRolesBaseDn(baseDn)) {
135 this.systemRoles = userDirectory;
136 systemRoles.setExternalRoles(this);
137 } else if (isTokensBaseDn(baseDn)) {
138 this.tokens = userDirectory;
139 tokens.setExternalRoles(this);
140 } else {
141 if (businessRoles.containsKey(baseDn))
142 throw new UserDirectoryException("There is already a user admin for " + baseDn);
143 businessRoles.put(baseDn, userDirectory);
144 }
145 userDirectory.init();
146 postAdd(userDirectory);
147 }
148
149 /** Called after a new user directory has been added */
150 protected void postAdd(AbstractUserDirectory userDirectory) {
151 }
152
153 private UserAdmin findUserAdmin(String name) {
154 try {
155 UserAdmin userAdmin = findUserAdmin(new LdapName(name));
156 return userAdmin;
157 } catch (InvalidNameException e) {
158 throw new UserDirectoryException("Badly formatted name " + name, e);
159 }
160 }
161
162 private UserAdmin findUserAdmin(LdapName name) {
163 if (name.startsWith(systemRolesBaseDn))
164 return systemRoles;
165 if (tokensBaseDn != null && name.startsWith(tokensBaseDn))
166 return tokens;
167 List<UserAdmin> res = new ArrayList<UserAdmin>(1);
168 for (LdapName baseDn : businessRoles.keySet()) {
169 AbstractUserDirectory ud = businessRoles.get(baseDn);
170 if (name.startsWith(baseDn)) {
171 if (!ud.isDisabled())
172 res.add(ud);
173 }
174 // Object principal = ud.getProperties().get(Context.SECURITY_PRINCIPAL);
175 // if (principal != null) {
176 // try {
177 // LdapName principalLdapName = new LdapName(principal.toString());
178 // if (principalLdapName.equals(name))
179 // res.add(ud);
180 // } catch (InvalidNameException e) {
181 // // silent
182 // }
183 // }
184 }
185 if (res.size() == 0)
186 throw new UserDirectoryException("Cannot find user admin for " + name);
187 if (res.size() > 1)
188 throw new UserDirectoryException("Multiple user admin found for " + name);
189 return res.get(0);
190 }
191
192 protected boolean isSystemRolesBaseDn(LdapName baseDn) {
193 return baseDn.equals(systemRolesBaseDn);
194 }
195
196 protected boolean isTokensBaseDn(LdapName baseDn) {
197 return tokensBaseDn != null && baseDn.equals(tokensBaseDn);
198 }
199
200 // protected Dictionary<String, Object> currentState() {
201 // Dictionary<String, Object> res = new Hashtable<String, Object>();
202 // // res.put(NodeConstants.CN, NodeConstants.DEFAULT);
203 // for (LdapName name : businessRoles.keySet()) {
204 // AbstractUserDirectory userDirectory = businessRoles.get(name);
205 // String uri = UserAdminConf.propertiesAsUri(userDirectory.getProperties()).toString();
206 // res.put(uri, "");
207 // }
208 // return res;
209 // }
210
211 public void destroy() {
212 for (LdapName name : businessRoles.keySet()) {
213 AbstractUserDirectory userDirectory = businessRoles.get(name);
214 destroy(userDirectory);
215 }
216 businessRoles.clear();
217 businessRoles = null;
218 destroy(systemRoles);
219 systemRoles = null;
220 }
221
222 private void destroy(AbstractUserDirectory userDirectory) {
223 preDestroy(userDirectory);
224 userDirectory.destroy();
225 }
226
227 protected void removeUserDirectory(LdapName baseDn) {
228 if (isSystemRolesBaseDn(baseDn))
229 throw new UserDirectoryException("System roles cannot be removed ");
230 if (!businessRoles.containsKey(baseDn))
231 throw new UserDirectoryException("No user directory registered for " + baseDn);
232 AbstractUserDirectory userDirectory = businessRoles.remove(baseDn);
233 destroy(userDirectory);
234 }
235
236 /**
237 * Called before each user directory is destroyed, so that additional actions
238 * can be performed.
239 */
240 protected void preDestroy(AbstractUserDirectory userDirectory) {
241 }
242
243 }