Merge "Principal to contain all the user roles"
[controller.git] / opendaylight / usermanager / src / main / java / org / opendaylight / controller / usermanager / internal / UserManagerImpl.java
index 0397cd4c47766cb9ac07e98aaadd72dcfde7c03a..5ddf6be6c54914e9f0cf0047c0dd272ea7813590 100644 (file)
@@ -82,17 +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;
@@ -120,6 +115,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         return authProviders.get(name);
     }
 
+    @Override
     public Set<String> getAAAProviderNames() {
         return authProviders.keySet();
     }
@@ -243,8 +239,10 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         // If startup config is not there, it's old or it was deleted,
         // need to add Default Admin
         if (!localUserConfigList.containsKey(defaultAdmin)) {
+            List<String> roles = new ArrayList<String>(1);
+            roles.add(defaultAdminRole);
             localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin,
-                    defaultAdminPassword, defaultAdminRole));
+                    defaultAdminPassword, roles));
         }
     }
 
@@ -253,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;
@@ -276,13 +273,13 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                 } else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
                     logger.info(
                             "Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
-                            new Object[] {userName, aaaServer.getAddress(),
-                            rcResponse.getStatus().toString()});
+                            new Object[] { userName, aaaServer.getAddress(),
+                                    rcResponse.getStatus().toString() });
                 } else {
                     logger.info(
                             "Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
-                            new Object[] {userName, aaaServer.getAddress(),
-                            rcResponse.getStatus().toString()});
+                            new Object[] { userName, aaaServer.getAddress(),
+                                    rcResponse.getStatus().toString() });
                 }
             }
         }
@@ -342,7 +339,7 @@ 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);
@@ -354,8 +351,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
          */
         if (authorizationInfoIsPresent) {
             // Identifying the administrative role
-            adminRoles = attributes.split(" ");
-            result.setRoleList(adminRoles);
+            result.setRoleList(attributes.split(" "));
             authorized = true;
         } else {
             logger.info("Not able to find Authorization Info for User: \"{}\"",
@@ -368,7 +364,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         putUserInActiveList(userName, result);
         if (authorized) {
             logger.info("User \"{}\" authorized for the following role(s): {}",
-                        userName, result.getUserRoles());
+                    userName, result.getUserRoles());
         } else {
             logger.info("User \"{}\" Not Authorized for any role ", userName);
         }
@@ -395,6 +391,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         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);
@@ -504,6 +503,12 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                 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 "
@@ -621,16 +626,17 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         if (targetConfigEntry == null) {
             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
@@ -702,34 +708,43 @@ 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());
         }
     }
 
@@ -761,7 +776,6 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
 
     public void _printAAAServers(CommandInterpreter ci) {
         for (ServerConfig aaaServer : remoteServerConfigList.values()) {
-            String protocol = aaaServer.getProtocol();
             ci.println(aaaServer.getAddress() + "-" + aaaServer.getProtocol());
         }
     }
@@ -805,7 +819,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     /**
      * Function called by the dependency manager when all the required
      * dependencies are satisfied
-     * 
+     *
      */
     void init() {
     }
@@ -814,7 +828,7 @@ 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.
-     * 
+     *
      */
     void destroy() {
     }
@@ -822,7 +836,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     /**
      * 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() {
         authProviders = new ConcurrentHashMap<String, IAAAProvider>();
@@ -845,7 +859,7 @@ 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
-     * 
+     *
      */
     void stop() {
     }
@@ -863,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
         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) {
+        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;
@@ -938,8 +1014,9 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                     .getPassword(), enabled, accountNonExpired,
                     credentialsNonExpired, accountNonLocked,
                     user.getGrantedAuthorities(getUserLevel(username)));
-        } else
+        } else {
             throw new UsernameNotFoundException("User not found " + username);
+        }
     }
 
     @Override
@@ -991,9 +1068,10 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
                             .getName())));
             return authentication;
 
-        } else
+        } else {
             throw new BadCredentialsException(
                     "Username or credentials did not match");
+        }
 
     }
 
@@ -1037,6 +1115,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         this.sessionMgr = sessionMgr;
     }
 
+    @Override
     public String getPassword(String username) {
         return localUserConfigList.get(username).getPassword();
     }