def login(user = nil, password = nil)
      if user.to_s.empty? || password.to_s.empty?
        require 'credentials_manager/account_manager'

        puts("Reading keychain entry, because either user or password were empty") if Spaceship::Globals.verbose?

        keychain_entry = CredentialsManager::AccountManager.new(user: user, password: password)
        user ||= keychain_entry.user
        password = keychain_entry.password
      end

      if user.to_s.strip.empty? || password.to_s.strip.empty?
        raise NoUserCredentialsError.new, "No login data provided"
      end

      self.user = user
      @password = password
      begin
        do_login(user, password) # calls `send_login_request` in sub class (which then will redirect back here to `send_shared_login_request`, below)
      rescue InvalidUserCredentialsError => ex
        raise ex unless keychain_entry

        if keychain_entry.invalid_credentials
          login(user)
        else
          raise ex
        end
      end
    end
def login(user = nil, password = nil)
      if user.to_s.empty? || password.to_s.empty?
        require 'credentials_manager/account_manager'

        puts("Reading keychain entry, because either user or password were empty") if Spaceship::Globals.verbose?

        keychain_entry = CredentialsManager::AccountManager.new(user: user, password: password)
        user ||= keychain_entry.user
        password = keychain_entry.password
      end

      if user.to_s.strip.empty? || password.to_s.strip.empty?
        raise NoUserCredentialsError.new, "No login data provided"
      end

      self.user = user
      @password = password
      begin
        do_login(user, password) # calls `send_login_request` in sub class (which then will redirect back here to `send_shared_login_request`, below)
      rescue InvalidUserCredentialsError => ex
        raise ex unless keychain_entry

        if keychain_entry.invalid_credentials
          login(user)
        else
          raise ex
        end
      end
    end
Authenticates with Apple's web services. This method has to be called once
 to generate a valid session. The session will automatically be used from then
 on.

 This method will automatically use the username from the Appfile (if available)
 and fetch the password from the Keychain (if available)

 @param user (String) (optional): The username (usually the email address)
 @param password (String) (optional): The password

 @raise InvalidUserCredentialsError: raised if authentication failed

 @return (Spaceship::Client) The client the login method was called for