Merge "Principal to contain all the user roles"
[controller.git] / opendaylight / usermanager / src / main / java / org / opendaylight / controller / usermanager / internal / UserManagerImpl.java
index 3e57ed846c7861a15bb948988364bb0069a175ae..5ddf6be6c54914e9f0cf0047c0dd272ea7813590 100644 (file)
@@ -82,11 +82,12 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     private static final String authFileName = ROOT + "authorization.conf";
     private ConcurrentMap<String, UserConfig> localUserConfigList;
     private ConcurrentMap<String, ServerConfig> remoteServerConfigList;
-    private ConcurrentMap<String, AuthorizationConfig> authorizationConfList; // local authorization info for remotely authenticated users
+    // local authorization info for remotely authenticated users
+    private ConcurrentMap<String, AuthorizationConfig> authorizationConfList;
     private ConcurrentMap<String, AuthenticatedUser> activeUsers;
     private ConcurrentMap<String, IAAAProvider> authProviders;
     private ConcurrentMap<Long, String> localUserListSaveConfigEvent,
-            remoteServerSaveConfigEvent, authorizationSaveConfigEvent;
+    remoteServerSaveConfigEvent, authorizationSaveConfigEvent;
     private IClusterGlobalServices clusterGlobalService = null;
     private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
     private IContainerAuthorization containerAuthorizationClient;
@@ -94,8 +95,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     private ISessionManager sessionMgr = new SessionManager();
 
     public boolean addAAAProvider(IAAAProvider provider) {
-        if (provider == null
-                       || provider.getName() == null
+        if (provider == null || provider.getName() == null
                 || provider.getName().trim().isEmpty()) {
             return false;
         }
@@ -115,6 +115,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         return authProviders.get(name);
     }
 
+    @Override
     public Set<String> getAAAProviderNames() {
         return authProviders.keySet();
     }
@@ -124,8 +125,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         this.applicationAuthorizationClients = Collections
                 .synchronizedSet(new HashSet<IResourceAuthorization>());
         if (clusterGlobalService == null) {
-            logger
-                    .error("un-initialized clusterGlobalService, can't create cache");
+            logger.error("un-initialized clusterGlobalService, can't create cache");
             return;
         }
 
@@ -134,36 +134,35 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                     EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
 
             clusterGlobalService.createCache(
-                    "usermanager.remoteServerConfigList", EnumSet
-                            .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    "usermanager.remoteServerConfigList",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
 
             clusterGlobalService.createCache(
-                    "usermanager.authorizationConfList", EnumSet
-                            .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    "usermanager.authorizationConfList",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
 
-            clusterGlobalService.createCache("usermanager.activeUsers", EnumSet
-                    .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+            clusterGlobalService.createCache("usermanager.activeUsers",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
 
             clusterGlobalService.createCache(
-                    "usermanager.localUserSaveConfigEvent", EnumSet
-                            .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    "usermanager.localUserSaveConfigEvent",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
 
             clusterGlobalService.createCache(
-                    "usermanager.remoteServerSaveConfigEvent", EnumSet
-                            .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    "usermanager.remoteServerSaveConfigEvent",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
 
             clusterGlobalService.createCache(
-                    "usermanager.authorizationSaveConfigEvent", EnumSet
-                            .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    "usermanager.authorizationSaveConfigEvent",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
         } catch (CacheConfigException cce) {
             logger.error("\nCache configuration invalid - check cache mode");
         } catch (CacheExistException ce) {
-            logger
-                    .error("\nCache already exits - destroy and recreate if needed");
+            logger.error("\nCache already exits - destroy and recreate if needed");
         }
     }
 
-    @SuppressWarnings( { "unchecked", "deprecation" })
+    @SuppressWarnings({ "unchecked", "deprecation" })
     private void retrieveCaches() {
         if (clusterGlobalService == null) {
             logger.error("un-initialized clusterService, can't retrieve cache");
@@ -203,25 +202,23 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         remoteServerSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
                 .getCache("usermanager.remoteServerSaveConfigEvent");
         if (remoteServerSaveConfigEvent == null) {
-            logger
-                    .error("\nFailed to get cache for remoteServerSaveConfigEvent");
+            logger.error("\nFailed to get cache for remoteServerSaveConfigEvent");
         }
 
         authorizationSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
                 .getCache("usermanager.authorizationSaveConfigEvent");
         if (authorizationSaveConfigEvent == null) {
-            logger
-                    .error("\nFailed to get cache for authorizationSaveConfigEvent");
+            logger.error("\nFailed to get cache for authorizationSaveConfigEvent");
         }
     }
 
     private void loadConfigurations() {
-       // To encode and decode user and server configuration objects
-       loadSecurityKeys();
-       
+        // To encode and decode user and server configuration objects
+        loadSecurityKeys();
+
         /*
-         * Do not load local startup file if we already got the
-         * configurations synced from another cluster node
+         * Do not load local startup file if we already got the configurations
+         * synced from another cluster node
          */
         if (localUserConfigList.isEmpty()) {
             loadUserConfig();
@@ -235,17 +232,17 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     }
 
     private void loadSecurityKeys() {
-               
-       }
 
-       private void checkDefaultNetworkAdmin() {
-        // If startup config is not there, it's old or it was deleted, 
-               // need to add Default Admin
+    }
+
+    private void checkDefaultNetworkAdmin() {
+        // If startup config is not there, it's old or it was deleted,
+        // need to add Default Admin
         if (!localUserConfigList.containsKey(defaultAdmin)) {
-               localUserConfigList.put(defaultAdmin,
-                                               new UserConfig(defaultAdmin,
-                                                               defaultAdminPassword,
-                                                       defaultAdminRole));
+            List<String> roles = new ArrayList<String>(1);
+            roles.add(defaultAdminRole);
+            localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin,
+                    defaultAdminPassword, roles));
         }
     }
 
@@ -254,7 +251,6 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         IAAAProvider aaaClient;
         AuthResponse rcResponse = null;
         AuthenticatedUser result;
-        String[] adminRoles = null;
         boolean remotelyAuthenticated = false;
         boolean authorizationInfoIsPresent = false;
         boolean authorized = false;
@@ -269,22 +265,21 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                 rcResponse = aaaClient.authService(userName, password,
                         aaaServer.getAddress(), aaaServer.getSecret());
                 if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
-                    logger
-                            .info(
-                                    "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
-                                    userName, aaaServer.getAddress());
+                    logger.info(
+                            "Remote Authentication Succeeded for User: \"{}\", by Server: {}",
+                            userName, aaaServer.getAddress());
                     remotelyAuthenticated = true;
                     break;
                 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
                     logger.info(
-                            "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason: "
-                                    + rcResponse.getStatus().toString(),
-                            userName, aaaServer.getAddress());
+                            "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
+                            new Object[] { userName, aaaServer.getAddress(),
+                                    rcResponse.getStatus().toString() });
                 } else {
                     logger.info(
-                            "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason: "
-                                    + rcResponse.getStatus().toString(),
-                            userName, aaaServer.getAddress());
+                            "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
+                            new Object[] { userName, aaaServer.getAddress(),
+                                    rcResponse.getStatus().toString() });
                 }
             }
         }
@@ -299,9 +294,10 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
             }
             rcResponse = localUser.authenticate(password);
             if (rcResponse.getStatus() != AuthResultEnum.AUTH_ACCEPT_LOC) {
-                logger.info("Local Authentication Failed for User: \"{}\", Reason: {}",
-                                userName, rcResponse.getStatus().toString());
-                
+                logger.info(
+                        "Local Authentication Failed for User: \"{}\", Reason: {}",
+                        userName, rcResponse.getStatus().toString());
+
                 return (rcResponse.getStatus());
             }
             logger.info("Local Authentication Succeeded for User: \"{}\"",
@@ -314,8 +310,8 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         result = new AuthenticatedUser(userName);
 
         /*
-         * Extract attributes from response
-         * All the information we are interested in is in the first Cisco VSA (vendor specific attribute).
+         * Extract attributes from response All the information we are
+         * interested in is in the first Cisco VSA (vendor specific attribute).
          * Just process the first VSA and return
          */
         String attributes = (rcResponse.getData() != null && !rcResponse
@@ -327,15 +323,14 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
 
         /*
-         * The AAA server was only used to perform the authentication
-         * Look for locally stored authorization info for this user
-         * If found, add the data to the rcResponse
+         * The AAA server was only used to perform the authentication Look for
+         * locally stored authorization info for this user If found, add the
+         * data to the rcResponse
          */
         if (remotelyAuthenticated && !authorizationInfoIsPresent) {
-            logger
-                    .info(
-                            "No Remote Authorization Info provided by Server for User: \"{}\"",
-                            userName);
+            logger.info(
+                    "No Remote Authorization Info provided by Server for User: \"{}\"",
+                    userName);
             logger.info(
                     "Looking for Local Authorization Info for User: \"{}\"",
                     userName);
@@ -344,20 +339,19 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
             if (resource != null) {
                 logger.info("Found Local Authorization Info for User: \"{}\"",
                         userName);
-                attributes = resource.getRolesData();
+                attributes = resource.getRolesString();
 
             }
             authorizationInfoIsPresent = checkAuthorizationInfo(attributes);
         }
 
         /*
-         * Common response parsing for local & remote authenticated user
-         * Looking for authorized resources, detecting attributes' validity
+         * Common response parsing for local & remote authenticated user Looking
+         * for authorized resources, detecting attributes' validity
          */
         if (authorizationInfoIsPresent) {
-               // Identifying the administrative role
-            adminRoles = attributes.split(" ");
-            result.setRoleList(adminRoles);
+            // Identifying the administrative role
+            result.setRoleList(attributes.split(" "));
             authorized = true;
         } else {
             logger.info("Not able to find Authorization Info for User: \"{}\"",
@@ -369,8 +363,8 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
          */
         putUserInActiveList(userName, result);
         if (authorized) {
-            logger.info("User \"{}\" authorized for the following role(s): "
-                    + result.getUserRoles(), userName);
+            logger.info("User \"{}\" authorized for the following role(s): {}",
+                    userName, result.getUserRoles());
         } else {
             logger.info("User \"{}\" Not Authorized for any role ", userName);
         }
@@ -378,7 +372,8 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         return rcResponse.getStatus();
     }
 
-    // Check in the attributes string whether or not authorization information is present
+    // Check in the attributes string whether or not authorization information
+    // is present
     private boolean checkAuthorizationInfo(String attributes) {
         return (attributes != null && !attributes.isEmpty());
     }
@@ -389,12 +384,14 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
 
     private void removeUserFromActiveList(String user) {
         if (!activeUsers.containsKey(user)) {
-            // as cookie persists in cache, we can get logout for unexisting active users
+            // as cookie persists in cache, we can get logout for unexisting
+            // active users
             return;
         }
         activeUsers.remove(user);
     }
 
+    @Override
     public Status saveLocalUserList() {
         // Publish the save config event to the cluster nodes
         localUserListSaveConfigEvent.put(new Date().getTime(), SAVE);
@@ -407,6 +404,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                 localUserConfigList), usersFileName);
     }
 
+    @Override
     public Status saveAAAServerList() {
         // Publish the save config event to the cluster nodes
         remoteServerSaveConfigEvent.put(new Date().getTime(), SAVE);
@@ -419,6 +417,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                 remoteServerConfigList), serversFileName);
     }
 
+    @Override
     public Status saveAuthorizationList() {
         // Publish the save config event to the cluster nodes
         authorizationSaveConfigEvent.put(new Date().getTime(), SAVE);
@@ -435,7 +434,8 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     @Override
     public Object readObject(ObjectInputStream ois)
             throws FileNotFoundException, IOException, ClassNotFoundException {
-        // Perform the class deserialization locally, from inside the package where the class is defined
+        // Perform the class deserialization locally, from inside the package
+        // where the class is defined
         return ois.readObject();
     }
 
@@ -488,29 +488,34 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
      * Interaction with GUI START
      */
     public Status addRemoveLocalUser(UserConfig AAAconf, boolean delete) {
-        // Validation check
-        if (!AAAconf.isValid()) {
-               String msg = "Invalid Local User configuration";
-            logger.warn(msg);
-            return new Status(StatusCode.BADREQUEST, msg);
+        // UserConfig Validation check
+        Status validCheck = AAAconf.validate();
+        if (!validCheck.isSuccess()) {
+            return validCheck;
         }
 
         // Update Config database
         if (delete) {
-               if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
-                       String msg = "Invalid Request: Default Network Admin  User " +
-                                       "cannot be deleted";
-                       logger.debug(msg);
-                       return new Status(StatusCode.NOTALLOWED, msg);
-               }
+            if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
+                String msg = "Invalid Request: Default Network Admin  User "
+                        + "cannot be deleted";
+                logger.debug(msg);
+                return new Status(StatusCode.NOTALLOWED, msg);
+            }
             localUserConfigList.remove(AAAconf.getUser());
+            /*
+             * A user account has been removed form local database, we assume
+             * admin does not want this user to stay connected, in case he has
+             * an open session. So we clean the active list as well.
+             */
+            removeUserFromActiveList(AAAconf.getUser());
         } else {
-               if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
-                       String msg = "Invalid Request: Default Network Admin  User " +
-                                       "cannot be added";
-                       logger.debug(msg);
-                       return new Status(StatusCode.NOTALLOWED, msg);
-               }
+            if (AAAconf.getUser().equals(UserManagerImpl.defaultAdmin)) {
+                String msg = "Invalid Request: Default Network Admin  User "
+                        + "cannot be added";
+                logger.debug(msg);
+                return new Status(StatusCode.NOTALLOWED, msg);
+            }
             localUserConfigList.put(AAAconf.getUser(), AAAconf);
         }
 
@@ -520,7 +525,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     private Status addRemoveAAAServer(ServerConfig AAAconf, boolean delete) {
         // Validation check
         if (!AAAconf.isValid()) {
-               String msg = "Invalid Server configuration";
+            String msg = "Invalid Server configuration";
             logger.warn(msg);
             return new Status(StatusCode.BADREQUEST, msg);
         }
@@ -535,10 +540,11 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         return new Status(StatusCode.SUCCESS, null);
     }
 
-    private Status addRemoveAuthInfo(AuthorizationConfig AAAconf,
-            boolean delete) {
-        if (!AAAconf.isValid()) {
-               String msg = "Invalid Authorization configuration";
+    private Status addRemoveAuthInfo(AuthorizationConfig AAAconf, boolean delete) {
+        Status configCheck = AAAconf.validate();
+        if (!configCheck.isSuccess()) {
+            String msg = "Invalid Authorization configuration: "
+                    + configCheck.getDescription();
             logger.warn(msg);
             return new Status(StatusCode.BADREQUEST, msg);
         }
@@ -565,14 +571,15 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
 
     @Override
     public Status removeLocalUser(String userName) {
-       if (userName == null || userName.trim().isEmpty()) {
-               return new Status(StatusCode.BADREQUEST, "Invalid user name");
-       }
-       if (!localUserConfigList.containsKey(userName)) {
-               return new Status(StatusCode.NOTFOUND, "User does not exist");
-       }       
+        if (userName == null || userName.trim().isEmpty()) {
+            return new Status(StatusCode.BADREQUEST, "Invalid user name");
+        }
+        if (!localUserConfigList.containsKey(userName)) {
+            return new Status(StatusCode.NOTFOUND, "User does not exist");
+        }
         return addRemoveLocalUser(localUserConfigList.get(userName), true);
     }
+
     @Override
     public Status addAAAServer(ServerConfig AAAconf) {
         return addRemoveAAAServer(AAAconf, false);
@@ -605,8 +612,8 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
 
     @Override
     public List<AuthorizationConfig> getAuthorizationList() {
-        return new ArrayList<AuthorizationConfig>(authorizationConfList
-                .values());
+        return new ArrayList<AuthorizationConfig>(
+                authorizationConfList.values());
     }
 
     @Override
@@ -617,21 +624,25 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         // update configuration entry
         targetConfigEntry = localUserConfigList.get(user);
         if (targetConfigEntry == null) {
-               return new Status(StatusCode.NOTFOUND, "User not found");
+            return new Status(StatusCode.NOTFOUND, "User not found");
         }
-        if (false == targetConfigEntry.update(curPassword, newPassword, null)) {
-               return new Status(StatusCode.BADREQUEST, "Current password is incorrect");
+        Status status = targetConfigEntry
+                .update(curPassword, newPassword, null);
+        if (!status.isSuccess()) {
+            return status;
         }
-        localUserConfigList.put(user, targetConfigEntry); // trigger cluster update
+        // Trigger cluster update
+        localUserConfigList.put(user, targetConfigEntry);
 
         logger.info("Password changed for User \"{}\"", user);
 
-        return new Status(StatusCode.SUCCESS, null);
+        return status;
     }
 
     @Override
     public void userLogout(String userName) {
-        // TODO: if user was authenticated through AAA server, send Acct-Status-Type=stop message to server with logout as reason
+        // TODO: if user was authenticated through AAA server, send
+        // Acct-Status-Type=stop message to server with logout as reason
         removeUserFromActiveList(userName);
         logger.info("User \"{}\" logged out", userName);
     }
@@ -641,7 +652,8 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
      */
     @Override
     public void userTimedOut(String userName) {
-        // TODO: if user was authenticated through AAA server, send Acct-Status-Type=stop message to server with timeout as reason
+        // TODO: if user was authenticated through AAA server, send
+        // Acct-Status-Type=stop message to server with timeout as reason
         removeUserFromActiveList(userName);
         logger.info("User \"{}\" timed out", userName);
     }
@@ -696,66 +708,74 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         String password = ci.nextArgument();
         String role = ci.nextArgument();
 
+        List<String> roles = new ArrayList<String>();
+        while (role != null) {
+            if (!role.trim().isEmpty()) {
+                roles.add(role);
+            }
+            role = ci.nextArgument();
+        }
+
         if (userName == null || userName.trim().isEmpty() || password == null
-                || password.trim().isEmpty() || role == null
-                || role.trim().isEmpty()) {
+                || password.trim().isEmpty() || roles == null
+                || roles.isEmpty()) {
             ci.println("Invalid Arguments");
             ci.println("umAddUser <user_name> <password> <user_role>");
             return;
         }
-        this.addLocalUser(new UserConfig(userName, password, role));
+        ci.print(this.addLocalUser(new UserConfig(userName, password, roles)));
     }
 
     public void _umRemUser(CommandInterpreter ci) {
         String userName = ci.nextArgument();
-        String password = ci.nextArgument();
-        String role = ci.nextArgument();
 
-        if (userName == null || userName.trim().isEmpty() || password == null
-                || password.trim().isEmpty() || role == null
-                || role.trim().isEmpty()) {
+        if (userName == null || userName.trim().isEmpty()) {
             ci.println("Invalid Arguments");
-            ci.println("umRemUser <user_name> <password> <user_role>");
+            ci.println("umRemUser <user_name>");
+            return;
+        }
+        UserConfig target = localUserConfigList.get(userName);
+        if (target == null) {
+            ci.println("User not found");
             return;
         }
-        this.removeLocalUser(new UserConfig(userName, password, role));
+        ci.println(this.removeLocalUser(target));
     }
 
     public void _umGetUsers(CommandInterpreter ci) {
         for (UserConfig conf : this.getLocalUserList()) {
-            ci.println(conf.getUser() + " " + conf.getRole());
+            ci.println(conf.getUser() + " " + conf.getRoles());
         }
     }
-    
-    public void _addAAAServer (CommandInterpreter ci) {
+
+    public void _addAAAServer(CommandInterpreter ci) {
         String server = ci.nextArgument();
         String secret = ci.nextArgument();
         String protocol = ci.nextArgument();
-        
+
         if (server == null || secret == null || protocol == null) {
-               ci.println("Usage : addAAAServer <server> <secret> <protocol>");
-               return;
+            ci.println("Usage : addAAAServer <server> <secret> <protocol>");
+            return;
         }
         ServerConfig s = new ServerConfig(server, secret, protocol);
         addAAAServer(s);
     }
-    
-    public void _removeAAAServer (CommandInterpreter ci) {
+
+    public void _removeAAAServer(CommandInterpreter ci) {
         String server = ci.nextArgument();
         String secret = ci.nextArgument();
         String protocol = ci.nextArgument();
-        
+
         if (server == null || secret == null || protocol == null) {
-               ci.println("Usage : addAAAServer <server> <secret> <protocol>");
-               return;
+            ci.println("Usage : addAAAServer <server> <secret> <protocol>");
+            return;
         }
         ServerConfig s = new ServerConfig(server, secret, protocol);
         removeAAAServer(s);
     }
 
-    public void _printAAAServers (CommandInterpreter ci) {
+    public void _printAAAServers(CommandInterpreter ci) {
         for (ServerConfig aaaServer : remoteServerConfigList.values()) {
-            String protocol = aaaServer.getProtocol();
             ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
         }
     }
@@ -805,18 +825,17 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     }
 
     /**
-     * Function called by the dependency manager when at least one
-     * dependency become unsatisfied or when the component is shutting
-     * down because for example bundle is being stopped.
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
      *
      */
     void destroy() {
     }
 
     /**
-     * Function called by dependency manager after "init ()" is called
-     * and after the services provided by the class are registered in
-     * the service registry
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
      *
      */
     void start() {
@@ -837,9 +856,9 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     }
 
     /**
-     * Function called by the dependency manager before the services
-     * exported by the component are unregistered, this will be
-     * followed by a "destroy ()" calls
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
      *
      */
     void stop() {
@@ -858,42 +877,104 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     @Override
     public UserLevel getUserLevel(String username) {
         // Returns the controller well-know user level for the passed user
-       String roleName = null;
+        List<String> rolesNames = null;
 
-       // First check in active users then in local configured users
+        // First check in active users then in local configured users
         if (activeUsers.containsKey(username)) {
-               roleName = activeUsers.get(username).getUserRoles().get(0);
+            List<String> roles = activeUsers.get(username).getUserRoles();
+            rolesNames = (roles == null || roles.isEmpty()) ? null : roles;
         } else if (localUserConfigList.containsKey(username)) {
-               roleName = localUserConfigList.get(username).getRole();
+            UserConfig config = localUserConfigList.get(username);
+            rolesNames = (config == null) ? null : config.getRoles();
         }
-        
-        if (roleName == null) {
-               return UserLevel.NOUSER;
+
+        if (rolesNames == null) {
+            return UserLevel.NOUSER;
         }
-        
-        // For now only one role per user is allowed
-        if (roleName.equals(UserLevel.SYSTEMADMIN.toString())) {
+
+        // Check against the well known controller roles first
+        if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
             return UserLevel.SYSTEMADMIN;
         }
-        if (roleName.equals(UserLevel.NETWORKADMIN.toString())) {
+        if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
             return UserLevel.NETWORKADMIN;
         }
-        if (roleName.equals(UserLevel.NETWORKOPERATOR.toString())) {
+        if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
             return UserLevel.NETWORKOPERATOR;
         }
-        if (this.containerAuthorizationClient != null
-                && this.containerAuthorizationClient
-                        .isApplicationRole(roleName)) {
-            return UserLevel.CONTAINERUSER;
+        // Check if container user now
+        if (containerAuthorizationClient != null) {
+            for (String roleName : rolesNames) {
+                if (containerAuthorizationClient.isApplicationRole(roleName)) {
+                    return UserLevel.CONTAINERUSER;
+                }
+            }
         }
-        for (IResourceAuthorization client : this.applicationAuthorizationClients) {
-            if (client.isApplicationRole(roleName)) {
-                return UserLevel.APPUSER;
+        // Finally check if application user
+        if (applicationAuthorizationClients != null) {
+            for (String roleName : rolesNames) {
+                for (IResourceAuthorization client : this.applicationAuthorizationClients) {
+                    if (client.isApplicationRole(roleName)) {
+                        return UserLevel.APPUSER;
+                    }
+                }
             }
         }
         return UserLevel.NOUSER;
     }
 
+
+    @Override
+    public List<UserLevel> getUserLevels(String username) {
+        // Returns the controller well-know user levels for the passed user
+        List<String> rolesNames = null;
+        List<UserLevel> levels = new ArrayList<UserLevel>();
+
+        if (activeUsers.containsKey(username)) {
+            List<String> roles = activeUsers.get(username).getUserRoles();
+            rolesNames = (roles == null || roles.isEmpty()) ? null : roles;
+        } else if (localUserConfigList.containsKey(username)) {
+            UserConfig config = localUserConfigList.get(username);
+            rolesNames = (config == null) ? null : config.getRoles();
+        }
+
+        if (rolesNames == null) {
+            return levels;
+        }
+
+        // Check against the well known controller roles first
+        if (rolesNames.contains(UserLevel.SYSTEMADMIN.toString())) {
+            levels.add(UserLevel.SYSTEMADMIN);
+        }
+        if (rolesNames.contains(UserLevel.NETWORKADMIN.toString())) {
+            levels.add(UserLevel.NETWORKADMIN);
+        }
+        if (rolesNames.contains(UserLevel.NETWORKOPERATOR.toString())) {
+            levels.add(UserLevel.NETWORKOPERATOR);
+        }
+        // Check if container user now
+        if (containerAuthorizationClient != null) {
+            for (String roleName : rolesNames) {
+                if (containerAuthorizationClient.isApplicationRole(roleName)) {
+                    levels.add(UserLevel.CONTAINERUSER);
+                    break;
+                }
+            }
+        }
+        // Finally check if application user
+        if (applicationAuthorizationClients != null) {
+            for (String roleName : rolesNames) {
+                for (IResourceAuthorization client : this.applicationAuthorizationClients) {
+                    if (client.isApplicationRole(roleName)) {
+                        levels.add(UserLevel.APPUSER);
+                        break;
+                    }
+                }
+            }
+        }
+        return levels;
+    }
+
     @Override
     public Status saveConfiguration() {
         boolean success = true;
@@ -915,7 +996,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         }
 
         return new Status(StatusCode.INTERNALERROR,
-                       "Failed to save user configurations");
+                "Failed to save user configurations");
     }
 
     @Override
@@ -931,10 +1012,11 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
 
             return new User(username, localUserConfigList.get(username)
                     .getPassword(), enabled, accountNonExpired,
-                    credentialsNonExpired, accountNonLocked, user
-                            .getGrantedAuthorities(getUserLevel(username)));
-        } else
+                    credentialsNonExpired, accountNonLocked,
+                    user.getGrantedAuthorities(getUserLevel(username)));
+        } else {
             throw new UsernameNotFoundException("User not found " + username);
+        }
     }
 
     @Override
@@ -964,8 +1046,9 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                     "Username or credentials did not match");
         }
 
-        AuthResultEnum result = authenticate((String) authentication
-                .getPrincipal(), (String) authentication.getCredentials());
+        AuthResultEnum result = authenticate(
+                (String) authentication.getPrincipal(),
+                (String) authentication.getCredentials());
         if (result.equals(AuthResultEnum.AUTHOR_PASS)
                 || result.equals(AuthResultEnum.AUTH_ACCEPT_LOC)
                 || result.equals(AuthResultEnum.AUTH_ACCEPT)) {
@@ -979,46 +1062,60 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
             }
 
             authentication = new UsernamePasswordAuthenticationToken(
-                    authentication.getPrincipal(), authentication
-                            .getCredentials(), user
-                            .getGrantedAuthorities(getUserLevel(authentication
-                                    .getName())));
+                    authentication.getPrincipal(),
+                    authentication.getCredentials(),
+                    user.getGrantedAuthorities(getUserLevel(authentication
+                            .getName())));
             return authentication;
 
-        } else
+        } else {
             throw new BadCredentialsException(
                     "Username or credentials did not match");
+        }
 
     }
 
-    //following are setters for use in unit testing
+    // following are setters for use in unit testing
     void setLocalUserConfigList(ConcurrentMap<String, UserConfig> ucl) {
-       if (ucl != null) { this.localUserConfigList = ucl; }
+        if (ucl != null) {
+            this.localUserConfigList = ucl;
+        }
     }
-    void setRemoteServerConfigList (ConcurrentMap<String, ServerConfig> scl) {
-       if (scl != null) { this.remoteServerConfigList = scl; }
+
+    void setRemoteServerConfigList(ConcurrentMap<String, ServerConfig> scl) {
+        if (scl != null) {
+            this.remoteServerConfigList = scl;
+        }
     }
-    void setAuthorizationConfList (ConcurrentMap<String, AuthorizationConfig> acl) {
-       if (acl != null) { this.authorizationConfList = acl; }
+
+    void setAuthorizationConfList(ConcurrentMap<String, AuthorizationConfig> acl) {
+        if (acl != null) {
+            this.authorizationConfList = acl;
+        }
     }
-    void setActiveUsers (ConcurrentMap<String, AuthenticatedUser> au) {
-        if (au != null) { this.activeUsers = au; }
+
+    void setActiveUsers(ConcurrentMap<String, AuthenticatedUser> au) {
+        if (au != null) {
+            this.activeUsers = au;
+        }
     }
-    void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap ) {
-        if (ap != null){ 
+
+    void setAuthProviders(ConcurrentMap<String, IAAAProvider> ap) {
+        if (ap != null) {
             this.authProviders = ap;
         }
     }
-    
+
     @Override
     public ISessionManager getSessionManager() {
         return this.sessionMgr;
     }
-    
+
     public void setSessionMgr(ISessionManager sessionMgr) {
         this.sessionMgr = sessionMgr;
     }
-    
+
+    @Override
     public String getPassword(String username) {
         return localUserConfigList.get(username).getPassword();
     }