Class: Net::IMAP::SASL::AuthenticationExchange
- Inherits:
-
Object
- Object
- Net::IMAP::SASL::AuthenticationExchange
- Defined in:
- lib/net/imap/sasl/authentication_exchange.rb
Overview
AuthenticationExchange is used internally by Net::IMAP#authenticate. But the API is still experimental, and may change.
TODO: catch exceptions in #process and send #cancel_response. TODO: raise an error if the command succeeds after being canceled. TODO: use with more clients, to verify the API can accommodate them. TODO: pass ClientAdapter#service to SASL.authenticator
An AuthenticationExchange represents a single attempt to authenticate a SASL client to a SASL server. It is created from a client adapter, a mechanism name, and a mechanism authenticator. When #authenticate is called, it will send the appropriate authenticate command to the server, returning the client response on success and raising an exception on failure.
In most cases, the client will not need to use SASL::AuthenticationExchange directly at all. Instead, use SASL::ClientAdapter#authenticate. If customizations are needed, the custom client adapter is probably the best place for that code.
def authenticate(...)
MyClient::SASLAdapter.new(self).authenticate(...)
end
SASL::ClientAdapter#authenticate delegates to ::authenticate, like so:
def authenticate(...)
sasl_adapter = MyClient::SASLAdapter.new(self)
SASL::AuthenticationExchange.authenticate(sasl_adapter, ...)
end
::authenticate simply delegates to ::build and #authenticate, like so:
def authenticate(...)
sasl_adapter = MyClient::SASLAdapter.new(self)
SASL::AuthenticationExchange
.build(sasl_adapter, ...)
.authenticate
end
And ::build delegates to SASL.authenticator and ::new, like so:
def authenticate(mechanism, ...)
sasl_adapter = MyClient::SASLAdapter.new(self)
authenticator = SASL.authenticator(mechanism, ...)
SASL::AuthenticationExchange
.new(sasl_adapter, mechanism, authenticator)
.authenticate
end
Instance Attribute Summary collapse
-
#authenticator ⇒ Object
readonly
Returns the value of attribute authenticator.
-
#mechanism ⇒ Object
readonly
Returns the value of attribute mechanism.
Class Method Summary collapse
-
.authenticate ⇒ Object
Convenience method for
build(...).authenticate
. -
.build(client, mechanism, *args, sasl_ir: true, **kwargs, &block) ⇒ Object
Convenience method to combine the creation of a new authenticator and a new Authentication exchange.
Instance Method Summary collapse
-
#authenticate ⇒ Object
Call #authenticate to execute an authentication exchange for #client using #authenticator.
- #done? ⇒ Boolean
-
#initialize(client, mechanism, authenticator, sasl_ir: true) ⇒ AuthenticationExchange
constructor
A new instance of AuthenticationExchange.
- #send_initial_response? ⇒ Boolean
Constructor Details
#initialize(client, mechanism, authenticator, sasl_ir: true) ⇒ AuthenticationExchange
Returns a new instance of AuthenticationExchange.
84 85 86 87 88 89 90 |
# File 'lib/net/imap/sasl/authentication_exchange.rb', line 84 def initialize(client, mechanism, authenticator, sasl_ir: true) @client = client @mechanism = Authenticators.normalize_name(mechanism) @authenticator = authenticator @sasl_ir = sasl_ir @processed = false end |
Instance Attribute Details
#authenticator ⇒ Object (readonly)
Returns the value of attribute authenticator.
82 83 84 |
# File 'lib/net/imap/sasl/authentication_exchange.rb', line 82 def authenticator @authenticator end |
#mechanism ⇒ Object (readonly)
Returns the value of attribute mechanism.
82 83 84 |
# File 'lib/net/imap/sasl/authentication_exchange.rb', line 82 def mechanism @mechanism end |
Class Method Details
.authenticate ⇒ Object
Convenience method for build(...).authenticate
See also: SASL::ClientAdapter#authenticate
61 |
# File 'lib/net/imap/sasl/authentication_exchange.rb', line 61 def self.authenticate(...) build(...).authenticate end |
.build(client, mechanism, *args, sasl_ir: true, **kwargs, &block) ⇒ Object
Convenience method to combine the creation of a new authenticator and a new Authentication exchange.
client
must be an instance of SASL::ClientAdapter.
mechanism
must be a SASL mechanism name, as a string or symbol.
sasl_ir
allows or disallows sending an “initial response”, depending also on whether the server capabilities, mechanism authenticator, and client adapter all support it. Defaults to true
.
mechanism
, args
, kwargs
, and block
are all forwarded to SASL.authenticator. Use the registry
kwarg to override the global SASL::Authenticators registry.
77 78 79 80 |
# File 'lib/net/imap/sasl/authentication_exchange.rb', line 77 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 |
Instance Method Details
#authenticate ⇒ Object
Call #authenticate to execute an authentication exchange for #client using #authenticator. Authentication failures will raise an exception. Any exceptions other than those in RESPONSE_ERRORS will drop the connection.
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/net/imap/sasl/authentication_exchange.rb', line 96 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 |
#done? ⇒ Boolean
117 118 119 |
# File 'lib/net/imap/sasl/authentication_exchange.rb', line 117 def done? authenticator.respond_to?(:done?) ? authenticator.done? : @processed end |
#send_initial_response? ⇒ Boolean
109 110 111 112 113 114 115 |
# File 'lib/net/imap/sasl/authentication_exchange.rb', line 109 def send_initial_response? @sasl_ir && authenticator.respond_to?(:initial_response?) && authenticator.initial_response? && client.sasl_ir_capable? && client.auth_capable?(mechanism) end |