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