private static CLIExitCode ProcessAddUserOption()

in Configurator/Core/CLI/CommandLine.cs [601:706]


    private static CLIExitCode ProcessAddUserOption(CommandLineOption option, ServerInstallation serverInstallation)
    {
      var result = CommandLineParser.ParseAddUserOption(option.Value, out string[] serverUserItems);
      if (result.ExitCode != ExitCode.Success)
      {
        return result;
      }

      // Process user name.
      var userName = serverUserItems[0].Substring(1, serverUserItems[0].Length - 2);
      var message = MySqlServerInstance.ValidateUserName(userName, false);
      if (!string.IsNullOrEmpty(message))
      {
        return new CLIExitCode(ExitCode.InvalidCustomUserName, userName, CommandLineParser.ADD_USER_OPTION_NAME, message);
      }

      // Process password/Windows Security Token.
      bool mysqlAuthentication = serverUserItems[4].Equals("MYSQL", StringComparison.InvariantCultureIgnoreCase);
      var passwordOrSecurityToken = serverUserItems[1].Substring(1, serverUserItems[1].Length - 2);
      if (mysqlAuthentication)
      {
        message = MySqlServerInstance.ValidatePassword(passwordOrSecurityToken, true);
        if (!string.IsNullOrEmpty(message))
        {
          return new CLIExitCode(ExitCode.InvalidCustomUserPassword, CommandLineParser.ADD_USER_OPTION_NAME, message);
        }
      }
      else
      {
        char[] validSeparators = { ';', ' ', ',' };
        string[] winAuthTokens = passwordOrSecurityToken.Trim().Split(validSeparators);
        foreach (string possibleToken in winAuthTokens)
        {
          bool tokenExists;
          if (possibleToken == string.Empty)
          {
            continue;
          }

          try
          {
            tokenExists = DirectoryServicesWrapper.TokenExists(possibleToken);
            if (!tokenExists)
            {
              return new CLIExitCode(ExitCode.CustomUserSecurityTokenNotFound, possibleToken, CommandLineParser.ADD_USER_OPTION_NAME, message);
            }
          }
          catch (Exception ex)
          {
            tokenExists = false;
            // Attempting to query the Active Directory may raise an error with the "Unspecified error" message
            // which can indicate different issues, in this case a more user friendly error message is required
            var exceptionMessage = ex.Message == Resources.ServerConfigUnspecifiedError
              ? Resources.ServerConfigUserFriendlyUnspecifiedError
              : ex.Message;
            Logger.LogError($"- {possibleToken}: {exceptionMessage}");
          }
        }
      }
      
      // Process host.
      var host = serverUserItems[2].ToLower();
      if (userName.Equals(MySqlServerUser.ROOT_USERNAME, StringComparison.OrdinalIgnoreCase)
          && (host == MySqlServerUser.LOCALHOST
              || host == "::1"
              || host == "127.0.0.1"))
      {
        return new CLIExitCode(ExitCode.InvalidCustomUserRootUser, CommandLineParser.ADD_USER_OPTION_NAME);
      }

      // Process user role.
      var roleString = serverUserItems[3].Substring(1, serverUserItems[3].Length - 2);
      var role = serverInstallation.Controller.RolesDefined.Roles.Find(name => name.ID.Equals(roleString, StringComparison.InvariantCultureIgnoreCase)
                                                                               || name.Display.Equals(roleString, StringComparison.InvariantCultureIgnoreCase));
      if (role == null)
      {
        return new CLIExitCode(ExitCode.InvalidCustomUserRole, roleString, CommandLineParser.ADD_USER_OPTION_NAME);
      }

      // Add user instance to list.
      var user = new MySqlServerUser()
      {
        Username = userName,
        AuthenticationPlugin = serverInstallation.Controller.Settings.DefaultAuthenticationPlugin,
        Host = host,
        UserRole = role
      };
      if (mysqlAuthentication)
      {
        user.Password = passwordOrSecurityToken;
      }
      else
      {
        user.WindowsSecurityTokenList = passwordOrSecurityToken;
      }

      // Validate not repeated user.
      if (serverInstallation.Controller.Settings.NewServerUsers.Any(existingUser => existingUser.Username.Equals(user.Username, StringComparison.InvariantCultureIgnoreCase)
                                                                                    && existingUser.Host.Equals(user.Host, StringComparison.InvariantCultureIgnoreCase)))
      {
        return new CLIExitCode(ExitCode.RepeatedCustomUser, user.Username, user.Host);
      }

      serverInstallation.Controller.Settings.NewServerUsers.Add(user);
      return new CLIExitCode(ExitCode.Success);
    }