1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.ops4j.pax.useradmin.service.internal;
19
20 import java.security.NoSuchAlgorithmException;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Dictionary;
24 import java.util.Hashtable;
25 import java.util.Map;
26
27 import org.ops4j.pax.useradmin.service.UserAdminConstants;
28 import org.ops4j.pax.useradmin.service.UserAdminTools;
29 import org.ops4j.pax.useradmin.service.spi.StorageException;
30 import org.ops4j.pax.useradmin.service.spi.StorageProvider;
31 import org.ops4j.pax.useradmin.service.spi.UserAdminFactory;
32 import org.osgi.framework.BundleContext;
33 import org.osgi.framework.Constants;
34 import org.osgi.framework.InvalidSyntaxException;
35 import org.osgi.framework.ServiceReference;
36 import org.osgi.service.cm.ConfigurationException;
37 import org.osgi.service.cm.ManagedService;
38 import org.osgi.service.event.Event;
39 import org.osgi.service.event.EventAdmin;
40 import org.osgi.service.log.LogService;
41 import org.osgi.service.useradmin.Authorization;
42 import org.osgi.service.useradmin.Group;
43 import org.osgi.service.useradmin.Role;
44 import org.osgi.service.useradmin.User;
45 import org.osgi.service.useradmin.UserAdmin;
46 import org.osgi.service.useradmin.UserAdminEvent;
47 import org.osgi.service.useradmin.UserAdminListener;
48 import org.osgi.service.useradmin.UserAdminPermission;
49 import org.osgi.util.tracker.ServiceTracker;
50
51
52
53
54
55
56
57
58
59
60
61 public class UserAdminImpl implements UserAdmin, ManagedService, UserAdminUtil, UserAdminFactory {
62
63 private BundleContext m_context = null;
64
65 private UserAdminPermission m_adminPermission = null;
66
67
68
69
70 private ServiceTracker m_storageService = null;
71
72
73
74
75 private ServiceTracker m_logService = null;
76
77
78
79
80 private ServiceTracker m_eventService = null;
81
82
83
84
85 private ServiceTracker m_eventListeners = null;
86
87
88
89
90 private EncryptorImpl m_encryptor = null;
91
92
93
94
95
96
97
98
99
100 protected UserAdminImpl(BundleContext context,
101 ServiceTracker storageService,
102 ServiceTracker logService,
103 ServiceTracker eventService) {
104 if (null == storageService) {
105 throw new IllegalArgumentException("No StorageProvider ServiceTracker specified.");
106 }
107 if (null == logService) {
108 throw new IllegalArgumentException("No LogService ServiceTracker specified.");
109 }
110 if (null == eventService) {
111 throw new IllegalArgumentException("No EventAdmin ServiceTracker specified.");
112 }
113 m_storageService = storageService;
114 m_storageService.open();
115 m_logService = logService;
116 m_logService.open();
117 m_eventService = eventService;
118 m_eventService.open();
119 m_context = context;
120
121 m_eventListeners = new ServiceTracker(context, UserAdminListener.class.getName(), null);
122 m_eventListeners.open();
123
124 m_encryptor = null;
125 }
126
127
128
129
130
131
132
133 private String getEventTypeName(int type) {
134 String typeName = null;
135 switch (type) {
136 case UserAdminEvent.ROLE_CHANGED:
137 typeName = "ROLE_CHANGED";
138 break;
139 case UserAdminEvent.ROLE_CREATED:
140 typeName = "ROLE_CREATED";
141 break;
142 case UserAdminEvent.ROLE_REMOVED:
143 typeName = "ROLE_REMOVED";
144 default:
145 typeName = "Event" + type;
146 }
147 return typeName;
148 }
149
150
151
152
153
154
155
156
157
158 protected void checkAdminPermission() {
159 SecurityManager sm = System.getSecurityManager();
160 if (null != sm) {
161 if (null == m_adminPermission) {
162 m_adminPermission = new UserAdminPermission(UserAdminPermission.ADMIN, null);
163 }
164 sm.checkPermission(m_adminPermission);
165 }
166 }
167
168
169
170
171
172
173
174
175
176
177
178 private EncryptorImpl createEncryptor(String encryptionAlgorithm,
179 String encryptionRandomAlgorithm,
180 String encryptionRandomAlgorithmSaltLength) throws ConfigurationException {
181 EncryptorImpl encryptor = null;
182 try {
183 encryptor = new EncryptorImpl(encryptionAlgorithm,
184 encryptionRandomAlgorithm,
185 encryptionRandomAlgorithmSaltLength);
186 } catch (NoSuchAlgorithmException e) {
187 throw new ConfigurationException(UserAdminConstants.PROP_ENCRYPTION_ALGORITHM
188 + " or " + UserAdminConstants.PROP_ENCRYPTION_RANDOM_ALGORITHM,
189 "Encryption algorithm not supported: " + e.getMessage(), e);
190 }
191 return encryptor;
192 }
193
194
195
196
197
198
199
200
201 @SuppressWarnings(value = "unchecked")
202 public void updated(Dictionary properties) throws ConfigurationException {
203 if (null == properties) {
204
205 return;
206 }
207 String encryptionAlgorithm = UserAdminTools.getOptionalProperty(properties,
208 UserAdminConstants.PROP_ENCRYPTION_ALGORITHM,
209 UserAdminConstants.ENCRYPTION_ALGORITHM_NONE);
210 if (UserAdminConstants.ENCRYPTION_ALGORITHM_NONE.equals(encryptionAlgorithm)) {
211
212 m_encryptor = null;
213 }
214 else {
215
216 String encryptionRandomAlgorithm = UserAdminTools.getOptionalProperty(properties,
217 UserAdminConstants.PROP_ENCRYPTION_RANDOM_ALGORITHM,
218 UserAdminConstants.DEFAULT_ENCRYPTION_RANDOM_ALGORITHM);
219 String encryptionRandomAlgorithmSaltLength = UserAdminTools.getOptionalProperty(properties,
220 UserAdminConstants.PROP_ENCRYPTION_RANDOM_SALTLENGTH,
221 UserAdminConstants.DEFAULT_ENCRYPTION_RANDOM_SALTLENGTH);
222 m_encryptor = createEncryptor(encryptionAlgorithm,
223 encryptionRandomAlgorithm,
224 encryptionRandomAlgorithmSaltLength);
225 }
226 }
227
228
229
230
231
232
233 public Role createRole(String name, int type) {
234 if (null == name) {
235 throw new IllegalArgumentException(UserAdminMessages.MSG_INVALID_NAME);
236 }
237 if ( (type != Role.GROUP)
238 && (type != Role.USER)) {
239 throw new IllegalArgumentException(UserAdminMessages.MSG_INVALID_ROLE_TYPE);
240 }
241 if (null != getRole(name)) {
242 logMessage(this, LogService.LOG_WARNING, "role already exists: " + name);
243 return null;
244 }
245 checkAdminPermission();
246
247 Role role = null;
248 try {
249 StorageProvider storageProvider = getStorageProvider();
250 switch (type) {
251 case Role.USER:
252 role = storageProvider.createUser(this, name);
253 break;
254
255 case Role.GROUP:
256 role = storageProvider.createGroup(this, name);
257 break;
258
259 default:
260
261 break;
262 }
263 fireEvent(UserAdminEvent.ROLE_CREATED, role);
264 } catch (StorageException e) {
265 logMessage(this, LogService.LOG_ERROR, e.getMessage());
266 }
267 return role;
268 }
269
270
271
272
273 public Authorization getAuthorization(User user) {
274 if (null == user) {
275 throw (new IllegalArgumentException(UserAdminMessages.MSG_INVALID_USER));
276 }
277 AuthorizationImpl authorization = new AuthorizationImpl(this, user);
278 return authorization;
279 }
280
281
282
283
284 public Role getRole(String name) {
285 if (null == name) {
286 throw (new IllegalArgumentException(UserAdminMessages.MSG_INVALID_NAME));
287 }
288 if ("".equals(name)) {
289 name = Role.USER_ANYONE;
290 }
291
292 try {
293 StorageProvider storage = getStorageProvider();
294 return storage.getRole(this, name);
295 } catch (StorageException e) {
296 logMessage(this, LogService.LOG_ERROR, e.getMessage());
297 }
298 return null;
299 }
300
301
302
303
304 public Role[] getRoles(String filter) throws InvalidSyntaxException {
305 try {
306 StorageProvider storage = getStorageProvider();
307 Collection<Role> roles = storage.findRoles(this, filter);
308 if (!roles.isEmpty()) {
309 return roles.toArray(new Role[0]);
310 }
311 } catch (StorageException e) {
312 logMessage(this, LogService.LOG_ERROR, e.getMessage());
313 }
314 return null;
315 }
316
317
318
319
320 public User getUser(String key, String value) {
321 if (null == key) {
322 throw new IllegalArgumentException(UserAdminMessages.MSG_INVALID_KEY);
323 }
324 if (null == value) {
325 throw new IllegalArgumentException(UserAdminMessages.MSG_INVALID_VALUE);
326 }
327 try {
328 StorageProvider storage = getStorageProvider();
329 User user = storage.getUser(this, key, value);
330 return user;
331 } catch (StorageException e) {
332 logMessage(this, LogService.LOG_ERROR, e.getMessage());
333 }
334 return null;
335 }
336
337
338
339
340 public boolean removeRole(String name) {
341 if (null == name) {
342 throw (new IllegalArgumentException(UserAdminMessages.MSG_INVALID_NAME));
343 }
344 if (!"".equals(name) && !Role.USER_ANYONE.equals(name)) {
345 Role role = getRole(name);
346 if (null != role) {
347 checkAdminPermission();
348 try {
349 StorageProvider storageProvider = getStorageProvider();
350 if (storageProvider.deleteRole(role)) {
351 fireEvent(UserAdminEvent.ROLE_REMOVED, role);
352 return true;
353 } else {
354 logMessage(this, LogService.LOG_ERROR, "Role '" + name + "' could not be deleted");
355 }
356 } catch (StorageException e) {
357 logMessage(this, LogService.LOG_ERROR, e.getMessage());
358 }
359 } else {
360 logMessage(this, LogService.LOG_ERROR, "Role '" + name + "' does not exist.");
361 }
362 } else {
363 logMessage(this, LogService.LOG_ERROR, "Standard user '" + Role.USER_ANYONE + "' cannot be removed.");
364 }
365 return false;
366 }
367
368
369
370
371
372
373 public StorageProvider getStorageProvider() throws StorageException {
374 StorageProvider storageProvider = (StorageProvider) m_storageService.getService();
375 if (null == storageProvider) {
376 throw new StorageException(UserAdminMessages.MSG_MISSING_STORAGE_SERVICE);
377 }
378 return storageProvider;
379 }
380
381
382
383
384
385
386 public void logMessage(Object source, int level, String message) {
387 LogService log = (LogService) m_logService.getService();
388 if (null != log) {
389 log.log(level, "[" + (source != null ? source.getClass().getName() : "none") + "] " + message);
390 }
391 }
392
393
394
395
396 public void fireEvent(int type, Role role) {
397 if (null == role) {
398 throw new IllegalArgumentException("parameter role must not be null");
399 }
400 ServiceReference ref = m_context.getServiceReference(UserAdmin.class.getName());
401 final UserAdminEvent uaEvent = new UserAdminEvent(ref, type, role);
402
403
404
405 Object[] eventListeners = m_eventListeners.getServices();
406 if (null != eventListeners) {
407 for (Object listenerObject : eventListeners) {
408 final UserAdminListener listener = (UserAdminListener) listenerObject;
409 Thread notifyThread = new Thread() {
410 @Override
411 public void run() {
412 listener.roleChanged(uaEvent);
413 }
414 };
415 notifyThread.start();
416 }
417 }
418
419
420
421 EventAdmin eventAdmin = (EventAdmin) m_eventService.getService();
422 if (null != eventAdmin) {
423 Dictionary<String, Object> properties = new Hashtable<String, Object>();
424 properties.put("event", uaEvent);
425 properties.put("role", role);
426 properties.put("role.name", role.getName());
427 properties.put("role.type", role.getType());
428 properties.put("service", ref);
429 properties.put("service.id", ref.getProperty(Constants.SERVICE_ID));
430 properties.put("service.objectClass", ref.getProperty(Constants.OBJECTCLASS));
431 properties.put("service.pid", ref.getProperty(Constants.SERVICE_PID));
432
433 Event event = new Event(UserAdminConstants.EVENT_TOPIC_PREFIX + getEventTypeName(type), properties);
434 eventAdmin.postEvent(event);
435 } else {
436 String message = "No event service available - cannot send event of type '"
437 + getEventTypeName(type) + "' for role '" + role.getName() + "'";
438 logMessage(this, LogService.LOG_ERROR,
439 message);
440 }
441 }
442
443
444
445
446 public void checkPermission(String name, String action) {
447 SecurityManager sm = System.getSecurityManager();
448 if (null != sm) {
449 sm.checkPermission(new UserAdminPermission(name, action));
450 }
451 }
452
453
454
455
456 public byte[] encrypt(Object value) {
457 byte[] valueBytes = null;
458 if (value instanceof String) {
459 valueBytes = ((String)value).getBytes();
460 } else if (value instanceof byte[]) {
461 valueBytes = (byte[]) value;
462 } else {
463 throw new IllegalArgumentException("Illegal value type: " + value.getClass().getName());
464 }
465
466 if (null != m_encryptor) {
467 valueBytes = m_encryptor.encrypt(valueBytes);
468 }
469 return valueBytes;
470 }
471
472
473
474
475 public boolean compareToEncryptedValue(Object inputValue,
476 byte[] storedValue) {
477 byte[] valueBytes = null;
478 if (inputValue instanceof String) {
479 valueBytes = ((String)inputValue).getBytes();
480 } else if (inputValue instanceof byte[]) {
481 valueBytes = (byte[]) inputValue;
482 } else {
483 throw new IllegalArgumentException("Illegal value type: " + inputValue.getClass().getName());
484 }
485
486 if (null != m_encryptor) {
487 return m_encryptor.compare(valueBytes, storedValue);
488 }
489 return Arrays.equals(valueBytes, storedValue);
490 }
491
492
493
494
495
496
497 public User createUser(String name,
498 Map<String, Object> properties,
499 Map<String, Object> credentials) {
500 UserImpl user = new UserImpl(name, this, properties, credentials);
501 return user;
502 }
503
504
505
506
507 public Group createGroup(String name,
508 Map<String, Object> properties,
509 Map<String, Object> credentials) {
510 GroupImpl group = new GroupImpl(name, this, properties, credentials);
511 return group;
512 }
513 }