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