class Net::IMAP::SASL::AuthenticationExchange


end
.authenticate
.new(sasl_adapter, mechanism, authenticator)
SASL::AuthenticationExchange
authenticator = SASL.authenticator(mechanism, …)
sasl_adapter = MyClient::SASLAdapter.new(self)
def authenticate(mechanism, …)
And ::build delegates to SASL.authenticator and ::new, like so:
end
.authenticate
.build(sasl_adapter, …)
SASL::AuthenticationExchange
sasl_adapter = MyClient::SASLAdapter.new(self)
def authenticate(…)
::authenticate simply delegates to ::build and #authenticate, like so:
end
SASL::AuthenticationExchange.authenticate(sasl_adapter, …)
sasl_adapter = MyClient::SASLAdapter.new(self)
def authenticate(…)
SASL::ClientAdapter#authenticate delegates to ::authenticate, like so:
end
MyClient::SASLAdapter.new(self).authenticate(…)
def authenticate(…)
custom client adapter is probably the best place for that code.
SASL::ClientAdapter#authenticate. If customizations are needed, the
SASL::AuthenticationExchange directly at all. Instead, use
In most cases, the client will not need to use
failure.
returning the client response on success and raising an exception on
called, it will send the appropriate authenticate command to the server,
mechanism name, and a mechanism authenticator. When #authenticate is
a SASL client to a SASL server. It is created from a client adapter, a
An AuthenticationExchange represents a single attempt to authenticate
TODO: pass ClientAdapter#service to SASL.authenticator
TODO: use with more clients, to verify the API can accommodate them.
TODO: raise an error if the command succeeds after being canceled.
TODO: catch exceptions in #process and send #cancel_response.
But the API is still experimental, and may change.
AuthenticationExchange is used internally by Net::IMAP#authenticate.

def self.authenticate(...) build(...).authenticate end

See also: SASL::ClientAdapter#authenticate

Convenience method for build(...).authenticate
def self.authenticate(...) build(...).authenticate end

def self.build(client, mechanism, *args, sasl_ir: true, **kwargs, &block)

SASL::Authenticators registry.
SASL.authenticator. Use the +registry+ kwarg to override the global
+mechanism+, +args+, +kwargs+, and +block+ are all forwarded to

client adapter all support it. Defaults to +true+.
also on whether the server capabilities, mechanism authenticator, and
+sasl_ir+ allows or disallows sending an "initial response", depending

+mechanism+ must be a SASL mechanism name, as a string or symbol.

+client+ must be an instance of SASL::ClientAdapter.

a new Authentication exchange.
Convenience method to combine the creation of a new authenticator and
def self.build(client, mechanism, *args, sasl_ir: true, **kwargs, &block)
  authenticator = SASL.authenticator(mechanism, *args, **kwargs, &block)
  new(client, mechanism, authenticator, sasl_ir: sasl_ir)
end

def authenticate

drop the connection.
exception. Any exceptions other than those in RESPONSE_ERRORS will
using #authenticator. Authentication failures will raise an
Call #authenticate to execute an authentication exchange for #client
def authenticate
  client.run_command(mechanism, initial_response) { process _1 }
    .tap { raise AuthenticationIncomplete, _1 unless done? }
rescue *client.response_errors
  raise # but don't drop the connection
rescue
  client.drop_connection
  raise
rescue Exception # rubocop:disable Lint/RescueException
  client.drop_connection!
  raise
end

def done?

def done?
  authenticator.respond_to?(:done?) ? authenticator.done? : @processed
end

def initial_response

def initial_response
  return unless send_initial_response?
  client.encode_ir authenticator.process nil
end

def initialize(client, mechanism, authenticator, sasl_ir: true)

def initialize(client, mechanism, authenticator, sasl_ir: true)
  @client = client
  @mechanism = Authenticators.normalize_name(mechanism)
  @authenticator = authenticator
  @sasl_ir = sasl_ir
  @processed = false
end

def process(challenge)

def process(challenge)
  client.encode authenticator.process client.decode challenge
ensure
  @processed = true
end

def send_initial_response?

def send_initial_response?
  @sasl_ir &&
    authenticator.respond_to?(:initial_response?) &&
    authenticator.initial_response? &&
    client.sasl_ir_capable? &&
    client.auth_capable?(mechanism)
end