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