@@ -602,49 +602,55 @@ def starttls(options = {}, verify = true)
602602 end
603603 end
604604
605+ # :call-seq:
606+ # authenticate(mechanism, ...) -> ok_resp
607+ # authenticate(mech, *creds, **props) {|prop, auth| val } -> ok_resp
608+ # authenticate(mechanism, authnid, credentials, authzid=nil) -> ok_resp
609+ # authenticate(mechanism, **properties) -> ok_resp
610+ # authenticate(mechanism) {|propname, authctx| prop_value } -> ok_resp
611+ #
605612 # Sends an {AUTHENTICATE command [IMAP4rev1 §6.2.2]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.2]
606- # to authenticate the client.
607- #
608- # The +auth_type+ parameter is a string that
609- # represents the authentication mechanism to be used. Currently Net::IMAP
610- # supports the following mechanisms:
611- #
612- # PLAIN:: Login using cleartext user and password. Secure with TLS.
613- # See PlainAuthenticator.
614- # CRAM-MD5:: DEPRECATED: Use PLAIN (or DIGEST-MD5) with TLS.
615- # DIGEST-MD5:: DEPRECATED by RFC6331. Must be secured using TLS.
616- # See DigestMD5Authenticator.
617- # LOGIN:: DEPRECATED: Use PLAIN.
618- #
619- # Most mechanisms require two args: authentication identity (e.g. username)
620- # and credentials (e.g. a password). But each mechanism requires and allows
621- # different arguments; please consult the documentation for the specific
622- # mechanisms you are using. <em>Several obsolete mechanisms are available
623- # for backwards compatibility. Using deprecated mechanisms will issue
624- # warnings.</em>
625- #
626- # Servers do not support all mechanisms and clients must not attempt to use
627- # a mechanism unless "AUTH=#{mechanism}" is listed as a #capability.
628- # Clients must not attempt to authenticate or #login when +LOGINDISABLED+ is
629- # listed with the capabilities. Server capabilities, especially auth
630- # mechanisms, do change after calling #starttls so they need to be checked
631- # again.
613+ # to authenticate the client. If successful, the connection enters the
614+ # "_authenticated_" state.
632615 #
633- # For example:
616+ # +mechanism+ is the name of the \SASL authentication mechanism to be used.
617+ # All other arguments are forwarded to the authenticator for the requested
618+ # mechanism. The listed call signatures are suggestions. <em>The
619+ # documentation for each individual mechanism must be consulted for its
620+ # specific parameters.</em>
634621 #
635- # imap.authenticate('PLAIN', user, password)
622+ # An exception Net::IMAP::NoResponseError is raised if authentication fails.
636623 #
637- # A Net::IMAP::NoResponseError is raised if authentication fails.
624+ # Related: #login, #starttls
638625 #
639- # See Net::IMAP::Authenticators for more information on plugging in your
640- # own authenticator.
626+ # ==== Supported SASL Mechanisms
641627 #
642- # Related: #login, #starttls
628+ # +PLAIN+:: See PlainAuthenticator.
629+ # Login using clear-text username and password.
643630 #
644- # ==== Capabilities
631+ # +XOAUTH2+:: See XOauth2Authenticator.
632+ # Login using a username and OAuth2 access token.
633+ # Non-standard and obsoleted by +OAUTHBEARER+, but widely
634+ # supported.
635+ #
636+ # >>>
637+ # *Deprecated:* <em>Obsolete mechanisms are available for backwards
638+ # compatibility.</em>
645639 #
646- # Clients MUST NOT attempt to #authenticate or #login when +LOGINDISABLED+
647- # is listed with the capabilities.
640+ # For +DIGEST-MD5+ see DigestMD5Authenticator.
641+ #
642+ # For +LOGIN+, see LoginAuthenticator.
643+ #
644+ # For +CRAM-MD5+, see CramMD5Authenticator.
645+ #
646+ # <em>Using a deprecated mechanism will print a warning.</em>
647+ #
648+ # See Net::IMAP::Authenticators for information on plugging in
649+ # authenticators for other mechanisms. See the {SASL mechanism
650+ # registry}[https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml]
651+ # for information on these and other SASL mechanisms.
652+ #
653+ # ===== Capabilities
648654 #
649655 # Clients MUST NOT attempt to authenticate with a mechanism unless
650656 # <tt>"AUTH=#{mechanism}"</tt> for that mechanism is a server capability.
@@ -654,9 +660,37 @@ def starttls(options = {}, verify = true)
654660 # The TaggedResponse to #authenticate may include updated capabilities in
655661 # its ResponseCode.
656662 #
657- def authenticate ( auth_type , *args )
658- authenticator = self . class . authenticator ( auth_type , *args )
659- send_command ( "AUTHENTICATE" , auth_type ) do |resp |
663+ # ===== Example
664+ # If the authenticators ignore unhandled keyword arguments, the same config
665+ # can be used for multiple mechanisms:
666+ #
667+ # password = nil # saved locally, so we don't ask more than once
668+ # accesstok = nil # saved locally...
669+ # creds = {
670+ # authcid: username,
671+ # password: proc { password ||= ui.prompt_for_password },
672+ # oauth2_token: proc { accesstok ||= kms.fresh_access_token },
673+ # }
674+ # capa = imap.capability
675+ # if capa.include? "AUTH=OAUTHBEARER"
676+ # imap.authenticate "OAUTHBEARER", **creds # authcid, oauth2_token
677+ # elsif capa.include? "AUTH=XOAUTH2"
678+ # imap.authenticate "XOAUTH2", **creds # authcid, oauth2_token
679+ # elsif capa.include? "AUTH=SCRAM-SHA-256"
680+ # imap.authenticate "SCRAM-SHA-256", **creds # authcid, password
681+ # elsif capa.include? "AUTH=PLAIN"
682+ # imap.authenticate "PLAIN", **creds # authcid, password
683+ # elsif capa.include? "AUTH=DIGEST-MD5"
684+ # imap.authenticate "DIGEST-MD5", **creds # authcid, password
685+ # elsif capa.include? "LOGINDISABLED"
686+ # raise "the server has disabled login"
687+ # else
688+ # imap.login username, password
689+ # end
690+ #
691+ def authenticate ( mechanism , *args , **props , &cb )
692+ authenticator = self . class . authenticator ( mechanism , *args , **props , &cb )
693+ send_command ( "AUTHENTICATE" , mechanism ) do |resp |
660694 if resp . instance_of? ( ContinuationRequest )
661695 data = authenticator . process ( resp . data . text . unpack ( "m" ) [ 0 ] )
662696 s = [ data ] . pack ( "m0" )
@@ -668,16 +702,19 @@ def authenticate(auth_type, *args)
668702
669703 # Sends a {LOGIN command [IMAP4rev1 §6.2.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.3]
670704 # to identify the client and carries the plaintext +password+ authenticating
671- # this +user+. Note that, unlike calling #authenticate with an +auth_type+
672- # of "LOGIN", #login does *not* use the LoginAuthenticator.
705+ # this +user+. If successful, the connection enters the "_authenticated_"
706+ # state.
707+ #
708+ # Using #authenticate is generally preferred over #login. The LOGIN command
709+ # is not the same as #authenticate with the "LOGIN" +mechanism+.
673710 #
674711 # A Net::IMAP::NoResponseError is raised if authentication fails.
675712 #
676713 # Related: #authenticate, #starttls
677714 #
678715 # ==== Capabilities
679- # Clients MUST NOT attempt to #authenticate or # login when +LOGINDISABLED+
680- # is listed with the capabilities.
716+ # Clients MUST NOT call # login if +LOGINDISABLED+ is listed with the
717+ # capabilities.
681718 #
682719 # Server capabilities may change after #starttls, #login, and #authenticate.
683720 # Cached capabilities _must_ be invalidated after this method completes.
0 commit comments