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