Migrating caches to TRANSACTIONAL Caches and enabled use1PcForAutoCommitTransactions.
[controller.git] / opendaylight / usermanager / implementation / src / main / java / org / opendaylight / controller / usermanager / internal / UserManagerImpl.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.usermanager.internal;
10
11 import java.io.FileNotFoundException;
12 import java.io.IOException;
13 import java.io.ObjectInputStream;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.EnumSet;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
24
25 import org.apache.commons.lang3.StringUtils;
26 import org.eclipse.osgi.framework.console.CommandInterpreter;
27 import org.eclipse.osgi.framework.console.CommandProvider;
28 import org.opendaylight.controller.clustering.services.CacheConfigException;
29 import org.opendaylight.controller.clustering.services.CacheExistException;
30 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
31 import org.opendaylight.controller.clustering.services.IClusterServices;
32 import org.opendaylight.controller.configuration.IConfigurationAware;
33 import org.opendaylight.controller.containermanager.IContainerAuthorization;
34 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
35 import org.opendaylight.controller.sal.authorization.IResourceAuthorization;
36 import org.opendaylight.controller.sal.authorization.UserLevel;
37 import org.opendaylight.controller.sal.utils.StatusCode;
38 import org.opendaylight.controller.sal.utils.GlobalConstants;
39 import org.opendaylight.controller.sal.utils.IObjectReader;
40 import org.opendaylight.controller.sal.utils.ObjectReader;
41 import org.opendaylight.controller.sal.utils.ObjectWriter;
42 import org.opendaylight.controller.sal.utils.Status;
43 import org.opendaylight.controller.usermanager.AuthResponse;
44 import org.opendaylight.controller.usermanager.AuthenticatedUser;
45 import org.opendaylight.controller.usermanager.AuthorizationConfig;
46 import org.opendaylight.controller.usermanager.IAAAProvider;
47 import org.opendaylight.controller.usermanager.ISessionManager;
48 import org.opendaylight.controller.usermanager.IUserManager;
49 import org.opendaylight.controller.usermanager.ServerConfig;
50 import org.opendaylight.controller.usermanager.UserConfig;
51 import org.opendaylight.controller.usermanager.security.SessionManager;
52 import org.opendaylight.controller.usermanager.security.UserSecurityContextRepository;
53
54 import org.osgi.framework.BundleContext;
55 import org.osgi.framework.FrameworkUtil;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58 import org.springframework.security.authentication.AuthenticationProvider;
59 import org.springframework.security.authentication.AuthenticationServiceException;
60 import org.springframework.security.authentication.BadCredentialsException;
61 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
62 import org.springframework.security.core.Authentication;
63 import org.springframework.security.core.AuthenticationException;
64 import org.springframework.security.core.userdetails.User;
65 import org.springframework.security.core.userdetails.UserDetails;
66 import org.springframework.security.core.userdetails.UsernameNotFoundException;
67 import org.springframework.security.web.context.SecurityContextRepository;
68
69 /**
70  * The internal implementation of the User Manager.
71  */
72 public class UserManagerImpl implements IUserManager, IObjectReader,
73         IConfigurationAware, CommandProvider, AuthenticationProvider {
74     private static final Logger logger = LoggerFactory
75             .getLogger(UserManagerImpl.class);
76     private static final String defaultAdmin = "admin";
77     private static final String defaultAdminPassword = "admin";
78     private static final String defaultAdminRole = UserLevel.NETWORKADMIN
79             .toString();
80     private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
81     private static final String SAVE = "save";
82     private static final String usersFileName = ROOT + "users.conf";
83     private static final String serversFileName = ROOT + "servers.conf";
84     private static final String authFileName = ROOT + "authorization.conf";
85     private ConcurrentMap<String, UserConfig> localUserConfigList;
86     private ConcurrentMap<String, ServerConfig> remoteServerConfigList;
87     // local authorization info for remotely authenticated users
88     private ConcurrentMap<String, AuthorizationConfig> authorizationConfList;
89     private ConcurrentMap<String, AuthenticatedUser> activeUsers;
90     private ConcurrentMap<String, IAAAProvider> authProviders;
91     private ConcurrentMap<Long, String> localUserListSaveConfigEvent,
92     remoteServerSaveConfigEvent, authorizationSaveConfigEvent;
93     private IClusterGlobalServices clusterGlobalService = null;
94     private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
95     private IContainerAuthorization containerAuthorizationClient;
96     private Set<IResourceAuthorization> applicationAuthorizationClients;
97     private ISessionManager sessionMgr = new SessionManager();
98
99     public boolean addAAAProvider(IAAAProvider provider) {
100         if (provider == null || provider.getName() == null
101                 || provider.getName().trim().isEmpty()) {
102             return false;
103         }
104         if (authProviders.get(provider.getName()) != null) {
105             return false;
106         }
107
108         authProviders.put(provider.getName(), provider);
109         return true;
110     }
111
112     public void removeAAAProvider(IAAAProvider provider) {
113         authProviders.remove(provider.getName());
114     }
115
116     public IAAAProvider getAAAProvider(String name) {
117         return authProviders.get(name);
118     }
119
120     @Override
121     public Set<String> getAAAProviderNames() {
122         return authProviders.keySet();
123     }
124
125     @SuppressWarnings("deprecation")
126     private void allocateCaches() {
127         this.applicationAuthorizationClients = Collections
128                 .synchronizedSet(new HashSet<IResourceAuthorization>());
129         if (clusterGlobalService == null) {
130             logger.error("un-initialized clusterGlobalService, can't create cache");
131             return;
132         }
133
134         try {
135             clusterGlobalService.createCache("usermanager.localUserConfigList",
136                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
137
138             clusterGlobalService.createCache(
139                     "usermanager.remoteServerConfigList",
140                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
141
142             clusterGlobalService.createCache(
143                     "usermanager.authorizationConfList",
144                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
145
146             clusterGlobalService.createCache("usermanager.activeUsers",
147                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
148
149             clusterGlobalService.createCache(
150                     "usermanager.localUserSaveConfigEvent",
151                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
152
153             clusterGlobalService.createCache(
154                     "usermanager.remoteServerSaveConfigEvent",
155                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
156
157             clusterGlobalService.createCache(
158                     "usermanager.authorizationSaveConfigEvent",
159                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
160         } catch (CacheConfigException cce) {
161             logger.error("Cache configuration invalid - check cache mode");
162         } catch (CacheExistException ce) {
163             logger.debug("Skipping cache creation as already present");
164         }
165     }
166
167     @SuppressWarnings({ "unchecked", "deprecation" })
168     private void retrieveCaches() {
169         if (clusterGlobalService == null) {
170             logger.error("un-initialized clusterService, can't retrieve cache");
171             return;
172         }
173
174         activeUsers = (ConcurrentMap<String, AuthenticatedUser>) clusterGlobalService
175                 .getCache("usermanager.activeUsers");
176         if (activeUsers == null) {
177             logger.error("Failed to get cache for activeUsers");
178         }
179
180         localUserConfigList = (ConcurrentMap<String, UserConfig>) clusterGlobalService
181                 .getCache("usermanager.localUserConfigList");
182         if (localUserConfigList == null) {
183             logger.error("Failed to get cache for localUserConfigList");
184         }
185
186         remoteServerConfigList = (ConcurrentMap<String, ServerConfig>) clusterGlobalService
187                 .getCache("usermanager.remoteServerConfigList");
188         if (remoteServerConfigList == null) {
189             logger.error("Failed to get cache for remoteServerConfigList");
190         }
191
192         authorizationConfList = (ConcurrentMap<String, AuthorizationConfig>) clusterGlobalService
193                 .getCache("usermanager.authorizationConfList");
194         if (authorizationConfList == null) {
195             logger.error("Failed to get cache for authorizationConfList");
196         }
197
198         localUserListSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
199                 .getCache("usermanager.localUserSaveConfigEvent");
200         if (localUserListSaveConfigEvent == null) {
201             logger.error("Failed to get cache for localUserSaveConfigEvent");
202         }
203
204         remoteServerSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
205                 .getCache("usermanager.remoteServerSaveConfigEvent");
206         if (remoteServerSaveConfigEvent == null) {
207             logger.error("Failed to get cache for remoteServerSaveConfigEvent");
208         }
209
210         authorizationSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
211                 .getCache("usermanager.authorizationSaveConfigEvent");
212         if (authorizationSaveConfigEvent == null) {
213             logger.error("Failed to get cache for authorizationSaveConfigEvent");
214         }
215     }
216
217     private void loadConfigurations() {
218         // To encode and decode user and server configuration objects
219         loadSecurityKeys();
220
221         /*
222          * Do not load local startup file if we already got the configurations
223          * synced from another cluster node
224          */
225         if (localUserConfigList.isEmpty()) {
226             loadUserConfig();
227         }
228         if (remoteServerConfigList.isEmpty()) {
229             loadServerConfig();
230         }
231         if (authorizationConfList.isEmpty()) {
232             loadAuthConfig();
233         }
234     }
235
236     private void loadSecurityKeys() {
237
238     }
239
240     private void checkDefaultNetworkAdmin() {
241         // If startup config is not there, it's old or it was deleted,
242         // need to add Default Admin
243         if (!localUserConfigList.containsKey(defaultAdmin)) {
244             List<String> roles = new ArrayList<String>(1);
245             roles.add(defaultAdminRole);
246             localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin,
247                     defaultAdminPassword, roles));
248         }
249     }
250
251     @Override
252     public AuthResultEnum authenticate(String userName, String password) {
253         IAAAProvider aaaClient;
254         AuthResponse rcResponse = null;
255         AuthenticatedUser result;
256         boolean remotelyAuthenticated = false;
257         boolean authorizationInfoIsPresent = false;
258         boolean authorized = false;
259
260         /*
261          * Attempt remote authentication first if server is configured
262          */
263         for (ServerConfig aaaServer : remoteServerConfigList.values()) {
264             String protocol = aaaServer.getProtocol();
265             aaaClient = this.getAAAProvider(protocol);
266             if (aaaClient != null) {
267                 rcResponse = aaaClient.authService(userName, password,
268                         aaaServer.getAddress(), aaaServer.getSecret());
269                 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
270                     logger.info(
271                             "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
272                             userName, aaaServer.getAddress());
273                     remotelyAuthenticated = true;
274                     break;
275                 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
276                     logger.info(
277                             "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
278                             new Object[] { userName, aaaServer.getAddress(),
279                                     rcResponse.getStatus().toString() });
280                 } else {
281                     logger.info(
282                             "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
283                             new Object[] { userName, aaaServer.getAddress(),
284                                     rcResponse.getStatus().toString() });
285                 }
286             }
287         }
288
289         if (!remotelyAuthenticated) {
290             UserConfig localUser = this.localUserConfigList.get(userName);
291             if (localUser == null) {
292                 logger.info(
293                         "Local Authentication Failed for User:\"{}\", Reason: "
294                                 + "user not found in Local Database", userName);
295                 return (AuthResultEnum.AUTH_INVALID_LOC_USER);
296             }
297             rcResponse = localUser.authenticate(password);
298             if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
299                 logger.info(
300                         "Local Authentication Failed for User: \"{}\", Reason: {}",
301                         userName, rcResponse.getStatus().toString());
302
303                 return (rcResponse.getStatus());
304             }
305             logger.info("Local Authentication Succeeded for User: \"{}\"",
306                     userName);
307         }
308
309         /*
310          * Authentication succeeded
311          */
312         result = new AuthenticatedUser(userName);
313
314         /*
315          * Extract attributes from response All the information we are
316          * interested in is in the first Cisco VSA (vendor specific attribute).
317          * Just process the first VSA and return
318          */
319         String attributes = (rcResponse.getData() != null && !rcResponse
320                 .getData().isEmpty()) ? rcResponse.getData().get(0) : null;
321
322         /*
323          * Check if the authorization information is present
324          */
325         authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
326
327         /*
328          * The AAA server was only used to perform the authentication Look for
329          * locally stored authorization info for this user If found, add the
330          * data to the rcResponse
331          */
332         if (remotelyAuthenticated && !authorizationInfoIsPresent) {
333             logger.info(
334                     "No Remote Authorization Info provided by Server for User: \"{}\"",
335                     userName);
336             logger.info(
337                     "Looking for Local Authorization Info for User: \"{}\"",
338                     userName);
339
340             AuthorizationConfig resource = authorizationConfList.get(userName);
341             if (resource != null) {
342                 logger.info("Found Local Authorization Info for User: \"{}\"",
343                         userName);
344                 attributes = resource.getRolesString();
345
346             }
347             authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
348         }
349
350         /*
351          * Common response parsing for local & remote authenticated user Looking
352          * for authorized resources, detecting attributes' validity
353          */
354         if (authorizationInfoIsPresent) {
355             // Identifying the administrative role
356             result.setRoleList(attributes.split(" "));
357             authorized = true;
358         } else {
359             logger.info("Not able to find Authorization Info for User: \"{}\"",
360                     userName);
361         }
362
363         /*
364          * Add profile for authenticated user
365          */
366         putUserInActiveList(userName, result);
367         if (authorized) {
368             logger.info("User \"{}\" authorized for the following role(s): {}",
369                     userName, result.getUserRoles());
370         } else {
371             logger.info("User \"{}\" Not Authorized for any role ", userName);
372         }
373
374         return rcResponse.getStatus();
375     }
376
377     // Check in the attributes string whether or not authorization information
378     // is present
379     private boolean checkAuthorizationInfo(String attributes) {
380         return (attributes != null && !attributes.isEmpty());
381     }
382
383     private void putUserInActiveList(String user, AuthenticatedUser result) {
384         activeUsers.put(user, result);
385     }
386
387     private void removeUserFromActiveList(String user) {
388         if (!activeUsers.containsKey(user)) {
389             // as cookie persists in cache, we can get logout for unexisting
390             // active users
391             return;
392         }
393         activeUsers.remove(user);
394     }
395
396     @Override
397     public Status saveLocalUserList() {
398         return saveLocalUserListInternal();
399     }
400
401     private Status saveLocalUserListInternal() {
402         ObjectWriter objWriter = new ObjectWriter();
403         return objWriter.write(new ConcurrentHashMap<String, UserConfig>(
404                 localUserConfigList), usersFileName);
405     }
406
407     @Override
408     public Status saveAAAServerList() {
409         return saveAAAServerListInternal();
410     }
411
412     private Status saveAAAServerListInternal() {
413         ObjectWriter objWriter = new ObjectWriter();
414         return objWriter.write(new ConcurrentHashMap<String, ServerConfig>(
415                 remoteServerConfigList), serversFileName);
416     }
417
418     @Override
419     public Status saveAuthorizationList() {
420         return saveAuthorizationListInternal();
421     }
422
423     private Status saveAuthorizationListInternal() {
424         ObjectWriter objWriter = new ObjectWriter();
425         return objWriter.write(
426                 new ConcurrentHashMap<String, AuthorizationConfig>(
427                         authorizationConfList), authFileName);
428     }
429
430     @Override
431     public Object readObject(ObjectInputStream ois)
432             throws FileNotFoundException, IOException, ClassNotFoundException {
433         // Perform the class deserialization locally, from inside the package
434         // where the class is defined
435         return ois.readObject();
436     }
437
438     @SuppressWarnings("unchecked")
439     private void loadUserConfig() {
440         ObjectReader objReader = new ObjectReader();
441         ConcurrentMap<String, UserConfig> confList = (ConcurrentMap<String, UserConfig>) objReader
442                 .read(this, usersFileName);
443
444         if (confList == null) {
445             return;
446         }
447
448         for (UserConfig conf : confList.values()) {
449             addLocalUser(conf);
450         }
451     }
452
453     @SuppressWarnings("unchecked")
454     private void loadServerConfig() {
455         ObjectReader objReader = new ObjectReader();
456         ConcurrentMap<String, ServerConfig> confList = (ConcurrentMap<String, ServerConfig>) objReader
457                 .read(this, serversFileName);
458
459         if (confList == null) {
460             return;
461         }
462
463         for (ServerConfig conf : confList.values()) {
464             addAAAServer(conf);
465         }
466     }
467
468     @SuppressWarnings("unchecked")
469     private void loadAuthConfig() {
470         ObjectReader objReader = new ObjectReader();
471         ConcurrentMap<String, AuthorizationConfig> confList = (ConcurrentMap<String, AuthorizationConfig>) objReader
472                 .read(this, authFileName);
473
474         if (confList == null) {
475             return;
476         }
477
478         for (AuthorizationConfig conf : confList.values()) {
479             addAuthInfo(conf);
480         }
481     }
482
483     /*
484      * Interaction with GUI START
485      */
486     public Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
487         // UserConfig Validation check
488         Status validCheck = AAAconf.validate();
489         if (!validCheck.isSuccess()) {
490             return validCheck;
491         }
492
493         // Update Config database
494         if (delete) {
495             if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
496                 String msg = "Invalid Request: Default Network Admin  User "
497                         + "cannot be deleted";
498                 logger.debug(msg);
499                 return new Status(StatusCode.NOTALLOWED, msg);
500             }
501             localUserConfigList.remove(AAAconf.getUser());
502             /*
503              * A user account has been removed form local database, we assume
504              * admin does not want this user to stay connected, in case he has
505              * an open session. So we clean the active list as well.
506              */
507             removeUserFromActiveList(AAAconf.getUser());
508         } else {
509             if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
510                 String msg = "Invalid Request: Default Network Admin  User "
511                         + "cannot be added";
512                 logger.debug(msg);
513                 return new Status(StatusCode.NOTALLOWED, msg);
514             }
515             localUserConfigList.put(AAAconf.getUser(), AAAconf);
516         }
517
518         return new Status(StatusCode.SUCCESS, null);
519     }
520
521     private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
522         // Validation check
523         if (!AAAconf.isValid()) {
524             String msg = "Invalid Server configuration";
525             logger.warn(msg);
526             return new Status(StatusCode.BADREQUEST, msg);
527         }
528
529         // Update configuration database
530         if (delete) {
531             remoteServerConfigList.remove(AAAconf.getAddress());
532         } else {
533             remoteServerConfigList.put(AAAconf.getAddress(), AAAconf);
534         }
535
536         return new Status(StatusCode.SUCCESS, null);
537     }
538
539     private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
540         Status configCheck = AAAconf.validate();
541         if (!configCheck.isSuccess()) {
542             String msg = "Invalid Authorization configuration: "
543                     + configCheck.getDescription();
544             logger.warn(msg);
545             return new Status(StatusCode.BADREQUEST, msg);
546         }
547
548         // Update configuration database
549         if (delete) {
550             authorizationConfList.remove(AAAconf.getUser());
551         } else {
552             authorizationConfList.put(AAAconf.getUser(), AAAconf);
553         }
554
555         return new Status(StatusCode.SUCCESS, null);
556     }
557
558     @Override
559     public Status addLocalUser(UserConfig AAAconf) {
560         return addRemoveLocalUser(AAAconf, false);
561     }
562
563     @Override
564     public Status removeLocalUser(UserConfig AAAconf) {
565         return addRemoveLocalUser(AAAconf, true);
566     }
567
568     @Override
569     public Status removeLocalUser(String userName) {
570         if (userName == null || userName.trim().isEmpty()) {
571             return new Status(StatusCode.BADREQUEST, "Invalid user name");
572         }
573         if (!localUserConfigList.containsKey(userName)) {
574             return new Status(StatusCode.NOTFOUND, "User does not exist");
575         }
576         return addRemoveLocalUser(localUserConfigList.get(userName), true);
577     }
578
579     @Override
580     public Status addAAAServer(ServerConfig AAAconf) {
581         return addRemoveAAAServer(AAAconf, false);
582     }
583
584     @Override
585     public Status removeAAAServer(ServerConfig AAAconf) {
586         return addRemoveAAAServer(AAAconf, true);
587     }
588
589     @Override
590     public Status addAuthInfo(AuthorizationConfig AAAconf) {
591         return addRemoveAuthInfo(AAAconf, false);
592     }
593
594     @Override
595     public Status removeAuthInfo(AuthorizationConfig AAAconf) {
596         return addRemoveAuthInfo(AAAconf, true);
597     }
598
599     @Override
600     public List<UserConfig> getLocalUserList() {
601         return new ArrayList<UserConfig>(localUserConfigList.values());
602     }
603
604     @Override
605     public List<ServerConfig> getAAAServerList() {
606         return new ArrayList<ServerConfig>(remoteServerConfigList.values());
607     }
608
609     @Override
610     public List<AuthorizationConfig> getAuthorizationList() {
611         return new ArrayList<AuthorizationConfig>(
612                 authorizationConfList.values());
613     }
614
615     @Override
616     public Status changeLocalUserPassword(String user, String curPassword,
617             String newPassword) {
618         UserConfig targetConfigEntry = null;
619
620         // update configuration entry
621         targetConfigEntry = localUserConfigList.get(user);
622         if (targetConfigEntry == null) {
623             return new Status(StatusCode.NOTFOUND, "User not found");
624         }
625         Status status = targetConfigEntry
626                 .update(curPassword, newPassword, null);
627         if (!status.isSuccess()) {
628             return status;
629         }
630         // Trigger cluster update
631         localUserConfigList.put(user, targetConfigEntry);
632
633         logger.info("Password changed for User \"{}\"", user);
634
635         return status;
636     }
637
638     @Override
639     public void userLogout(String userName) {
640         // TODO: if user was authenticated through AAA server, send
641         // Acct-Status-Type=stop message to server with logout as reason
642         removeUserFromActiveList(userName);
643         logger.info("User \"{}\" logged out", userName);
644     }
645
646     /*
647      * This function will get called by http session mgr when session times out
648      */
649     @Override
650     public void userTimedOut(String userName) {
651         // TODO: if user was authenticated through AAA server, send
652         // Acct-Status-Type=stop message to server with timeout as reason
653         removeUserFromActiveList(userName);
654         logger.info("User \"{}\" timed out", userName);
655     }
656
657     @Override
658     public String getAccessDate(String user) {
659         return this.activeUsers.get(user).getAccessDate();
660     }
661
662     @Override
663     public synchronized Map<String, List<String>> getUserLoggedIn() {
664         Map<String, List<String>> loggedInList = new HashMap<String, List<String>>();
665         for (Map.Entry<String, AuthenticatedUser> user : activeUsers.entrySet()) {
666             String userNameShow = user.getKey();
667             loggedInList.put(userNameShow, user.getValue().getUserRoles());
668         }
669         return loggedInList;
670     }
671
672     public void _umAddUser(CommandInterpreter ci) {
673         String userName = ci.nextArgument();
674         String password = ci.nextArgument();
675         String role = ci.nextArgument();
676
677         List<String> roles = new ArrayList<String>();
678         while (role != null) {
679             if (!role.trim().isEmpty()) {
680                 roles.add(role);
681             }
682             role = ci.nextArgument();
683         }
684
685         if (userName == null || userName.trim().isEmpty() || password == null
686                 || password.trim().isEmpty() || roles == null
687                 || roles.isEmpty()) {
688             ci.println("Invalid Arguments");
689             ci.println("umAddUser <user_name> <password> <user_role>");
690             return;
691         }
692         ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
693     }
694
695     public void _umRemUser(CommandInterpreter ci) {
696         String userName = ci.nextArgument();
697
698         if (userName == null || userName.trim().isEmpty()) {
699             ci.println("Invalid Arguments");
700             ci.println("umRemUser <user_name>");
701             return;
702         }
703         UserConfig target = localUserConfigList.get(userName);
704         if (target == null) {
705             ci.println("User not found");
706             return;
707         }
708         ci.println(this.removeLocalUser(target));
709     }
710
711     public void _umGetUsers(CommandInterpreter ci) {
712         for (UserConfig conf : this.getLocalUserList()) {
713             ci.println(conf.getUser() + " " + conf.getRoles());
714         }
715     }
716
717     public void _addAAAServer(CommandInterpreter ci) {
718         String server = ci.nextArgument();
719         String secret = ci.nextArgument();
720         String protocol = ci.nextArgument();
721
722         if (server == null || secret == null || protocol == null) {
723             ci.println("Usage : addAAAServer <server> <secret> <protocol>");
724             return;
725         }
726         ServerConfig s = new ServerConfig(server, secret, protocol);
727         addAAAServer(s);
728     }
729
730     public void _removeAAAServer(CommandInterpreter ci) {
731         String server = ci.nextArgument();
732         String secret = ci.nextArgument();
733         String protocol = ci.nextArgument();
734
735         if (server == null || secret == null || protocol == null) {
736             ci.println("Usage : addAAAServer <server> <secret> <protocol>");
737             return;
738         }
739         ServerConfig s = new ServerConfig(server, secret, protocol);
740         removeAAAServer(s);
741     }
742
743     public void _printAAAServers(CommandInterpreter ci) {
744         for (ServerConfig aaaServer : remoteServerConfigList.values()) {
745             ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
746         }
747     }
748
749     @Override
750     public String getHelp() {
751         StringBuffer help = new StringBuffer();
752         return help.toString();
753     }
754
755     void setClusterGlobalService(IClusterGlobalServices s) {
756         logger.debug("Cluster Service Global set");
757         this.clusterGlobalService = s;
758     }
759
760     void unsetClusterGlobalService(IClusterGlobalServices s) {
761         if (this.clusterGlobalService == s) {
762             logger.debug("Cluster Service Global removed!");
763             this.clusterGlobalService = null;
764         }
765     }
766
767     void unsetContainerAuthClient(IContainerAuthorization s) {
768         if (this.containerAuthorizationClient == s) {
769             this.containerAuthorizationClient = null;
770         }
771     }
772
773     void setContainerAuthClient(IContainerAuthorization s) {
774         this.containerAuthorizationClient = s;
775     }
776
777     void setAppAuthClient(IResourceAuthorization s) {
778         this.applicationAuthorizationClients.add(s);
779     }
780
781     void unsetAppAuthClient(IResourceAuthorization s) {
782         this.applicationAuthorizationClients.remove(s);
783     }
784
785     /**
786      * Function called by the dependency manager when all the required
787      * dependencies are satisfied
788      *
789      */
790     void init() {
791     }
792
793     /**
794      * Function called by the dependency manager when at least one dependency
795      * become unsatisfied or when the component is shutting down because for
796      * example bundle is being stopped.
797      *
798      */
799     void destroy() {
800     }
801
802     /**
803      * Function called by dependency manager after "init ()" is called and after
804      * the services provided by the class are registered in the service registry
805      *
806      */
807     void start() {
808         authProviders = new ConcurrentHashMap<String, IAAAProvider>();
809         // Instantiate cluster synced variables
810         allocateCaches();
811         retrieveCaches();
812
813         // Read startup configuration and populate databases
814         loadConfigurations();
815
816         // Make sure default Network Admin account is there
817         checkDefaultNetworkAdmin();
818         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
819                 .getBundleContext();
820         bundleContext.registerService(CommandProvider.class.getName(), this,
821                 null);
822     }
823
824     /**
825      * Function called by the dependency manager before the services exported by
826      * the component are unregistered, this will be followed by a "destroy ()"
827      * calls
828      *
829      */
830     void stop() {
831     }
832
833     @Override
834     public List<String> getUserRoles(String userName) {
835         List<String> roles = null;
836         if (userName != null) {
837             /*
838              * First look in active users then in local configured users,
839              * finally in local authorized users
840              */
841             if (activeUsers.containsKey(userName)) {
842                 roles = activeUsers.get(userName).getUserRoles();
843             } else if (localUserConfigList.containsKey(userName)) {
844                 roles = localUserConfigList.get(userName).getRoles();
845             } else if (authorizationConfList.containsKey(userName)) {
846                 roles = authorizationConfList.get(userName).getRoles();
847             }
848         }
849         return (roles == null) ? new ArrayList<String>(0) : roles;
850     }
851
852     @Override
853     public UserLevel getUserLevel(String username) {
854         // Returns the highest controller user level for the passed user
855         List<String> rolesNames = getUserRoles(username);
856
857         if (rolesNames.isEmpty()) {
858             return UserLevel.NOUSER;
859         }
860
861         // Check against the well known controller roles first
862         if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
863             return UserLevel.SYSTEMADMIN;
864         }
865         if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
866             return UserLevel.NETWORKADMIN;
867         }
868         if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
869             return UserLevel.NETWORKOPERATOR;
870         }
871         // Check if container user now
872         if (containerAuthorizationClient != null) {
873             for (String roleName : rolesNames) {
874                 if (containerAuthorizationClient.isApplicationRole(roleName)) {
875                     return UserLevel.CONTAINERUSER;
876                 }
877             }
878         }
879         // Finally check if application user
880         if (applicationAuthorizationClients != null) {
881             for (String roleName : rolesNames) {
882                 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
883                     if (client.isApplicationRole(roleName)) {
884                         return UserLevel.APPUSER;
885                     }
886                 }
887             }
888         }
889         return UserLevel.NOUSER;
890     }
891
892
893     @Override
894     public List<UserLevel> getUserLevels(String username) {
895         // Returns the controller user levels for the passed user
896         List<String> rolesNames =  getUserRoles(username);
897         List<UserLevel> levels = new ArrayList<UserLevel>();
898
899         if (rolesNames.isEmpty()) {
900             return levels;
901         }
902
903         // Check against the well known controller roles first
904         if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
905             levels.add(UserLevel.SYSTEMADMIN);
906         }
907         if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
908             levels.add(UserLevel.NETWORKADMIN);
909         }
910         if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
911             levels.add(UserLevel.NETWORKOPERATOR);
912         }
913         // Check if container user now
914         if (containerAuthorizationClient != null) {
915             for (String roleName : rolesNames) {
916                 if (containerAuthorizationClient.isApplicationRole(roleName)) {
917                     levels.add(UserLevel.CONTAINERUSER);
918                     break;
919                 }
920             }
921         }
922         // Finally check if application user
923         if (applicationAuthorizationClients != null) {
924             for (String roleName : rolesNames) {
925                 for (IResourceAuthorization client : this.applicationAuthorizationClients) {
926                     if (client.isApplicationRole(roleName)) {
927                         levels.add(UserLevel.APPUSER);
928                         break;
929                     }
930                 }
931             }
932         }
933         return levels;
934     }
935
936     @Override
937     public Status saveConfiguration() {
938         boolean success = true;
939         Status ret = saveLocalUserList();
940         if (!ret.isSuccess()) {
941             success = false;
942         }
943         ret = saveAAAServerList();
944         if (!ret.isSuccess()) {
945             success = false;
946         }
947         ret = saveAuthorizationList();
948         if (!ret.isSuccess()) {
949             success = false;
950         }
951
952         if (success) {
953             return new Status(StatusCode.SUCCESS, null);
954         }
955
956         return new Status(StatusCode.INTERNALERROR,
957                 "Failed to save user configurations");
958     }
959
960     @Override
961     public UserDetails loadUserByUsername(String username)
962             throws UsernameNotFoundException {
963         AuthenticatedUser user = activeUsers.get(username);
964
965         if (user != null) {
966             boolean enabled = true;
967             boolean accountNonExpired = true;
968             boolean credentialsNonExpired = true;
969             boolean accountNonLocked = true;
970
971             return new User(username, localUserConfigList.get(username)
972                     .getPassword(), enabled, accountNonExpired,
973                     credentialsNonExpired, accountNonLocked,
974                     user.getGrantedAuthorities(getUserLevel(username)));
975         } else {
976             throw new UsernameNotFoundException("User not found " + username);
977         }
978     }
979
980     @Override
981     public boolean supports(Class<?> authentication) {
982         return UsernamePasswordAuthenticationToken.class
983                 .isAssignableFrom(authentication);
984
985     }
986
987     @Override
988     public SecurityContextRepository getSecurityContextRepo() {
989         return securityContextRepo;
990     }
991
992     public void setSecurityContextRepo(
993             SecurityContextRepository securityContextRepo) {
994         this.securityContextRepo = securityContextRepo;
995     }
996
997     @Override
998     public Authentication authenticate(Authentication authentication)
999             throws AuthenticationException {
1000
1001         if (StringUtils.isBlank((String) authentication.getCredentials())
1002                 || StringUtils.isBlank((String) authentication.getPrincipal())) {
1003             throw new BadCredentialsException(
1004                     "Username or credentials did not match");
1005         }
1006
1007         AuthResultEnum result = authenticate(
1008                 (String) authentication.getPrincipal(),
1009                 (String) authentication.getCredentials());
1010         if (result.equals(AuthResultEnum.AUTHOR_PASS)
1011                 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
1012                 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
1013
1014             AuthenticatedUser user = activeUsers.get(authentication
1015                     .getPrincipal().toString());
1016
1017             if (user == null) {
1018                 throw new AuthenticationServiceException(
1019                         "Authentication Failure");
1020             }
1021
1022             authentication = new UsernamePasswordAuthenticationToken(
1023                     authentication.getPrincipal(),
1024                     authentication.getCredentials(),
1025                     user.getGrantedAuthorities(getUserLevel(authentication
1026                             .getName())));
1027             return authentication;
1028
1029         } else {
1030             throw new BadCredentialsException(
1031                     "Username or credentials did not match");
1032         }
1033
1034     }
1035
1036     // Following are setters for use in unit testing
1037     void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
1038         if (ucl != null) {
1039             this.localUserConfigList = ucl;
1040         }
1041     }
1042
1043     void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
1044         if (scl != null) {
1045             this.remoteServerConfigList = scl;
1046         }
1047     }
1048
1049     void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
1050         if (acl != null) {
1051             this.authorizationConfList = acl;
1052         }
1053     }
1054
1055     void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
1056         if (au != null) {
1057             this.activeUsers = au;
1058         }
1059     }
1060
1061     void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
1062         if (ap != null) {
1063             this.authProviders = ap;
1064         }
1065     }
1066
1067     @Override
1068     public ISessionManager getSessionManager() {
1069         return this.sessionMgr;
1070     }
1071
1072     public void setSessionMgr(ISessionManager sessionMgr) {
1073         this.sessionMgr = sessionMgr;
1074     }
1075
1076     @Override
1077     public String getPassword(String username) {
1078         return localUserConfigList.get(username).getPassword();
1079     }
1080
1081     @Override
1082     public boolean isRoleInUse(String role) {
1083         if (role == null || role.isEmpty()) {
1084             return false;
1085         }
1086         // Check against controller roles
1087         if (role.equals(UserLevel.SYSTEMADMIN.toString())
1088                 || role.equals(UserLevel.NETWORKADMIN.toString())
1089                 || role.equals(UserLevel.NETWORKOPERATOR.toString())) {
1090             return true;
1091         }
1092         // Check if container roles
1093         if (containerAuthorizationClient != null) {
1094             if (containerAuthorizationClient.isApplicationRole(role)) {
1095                 return true;
1096             }
1097         }
1098         // Finally if application role
1099         if (applicationAuthorizationClients != null) {
1100             for (IResourceAuthorization client : this.applicationAuthorizationClients) {
1101                 if (client.isApplicationRole(role)) {
1102                     return true;
1103                 }
1104             }
1105         }
1106         return false;
1107     }
1108 }