@@ -602,49 +602,55 @@ def starttls(options = {}, verify = true)
602
602
end
603
603
end
604
604
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
+ #
605
612
# 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.
632
615
#
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>
634
621
#
635
- # imap.authenticate('PLAIN', user, password)
622
+ # An exception Net::IMAP::NoResponseError is raised if authentication fails.
636
623
#
637
- # A Net::IMAP::NoResponseError is raised if authentication fails.
624
+ # Related: #login, #starttls
638
625
#
639
- # See Net::IMAP::Authenticators for more information on plugging in your
640
- # own authenticator.
626
+ # ==== Supported SASL Mechanisms
641
627
#
642
- # Related: #login, #starttls
628
+ # +PLAIN+:: See PlainAuthenticator.
629
+ # Login using clear-text username and password.
643
630
#
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>
645
639
#
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
648
654
#
649
655
# Clients MUST NOT attempt to authenticate with a mechanism unless
650
656
# <tt>"AUTH=#{mechanism}"</tt> for that mechanism is a server capability.
@@ -654,9 +660,37 @@ def starttls(options = {}, verify = true)
654
660
# The TaggedResponse to #authenticate may include updated capabilities in
655
661
# its ResponseCode.
656
662
#
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 |
660
694
if resp . instance_of? ( ContinuationRequest )
661
695
data = authenticator . process ( resp . data . text . unpack ( "m" ) [ 0 ] )
662
696
s = [ data ] . pack ( "m0" )
@@ -668,16 +702,19 @@ def authenticate(auth_type, *args)
668
702
669
703
# Sends a {LOGIN command [IMAP4rev1 §6.2.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.3]
670
704
# 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+.
673
710
#
674
711
# A Net::IMAP::NoResponseError is raised if authentication fails.
675
712
#
676
713
# Related: #authenticate, #starttls
677
714
#
678
715
# ==== 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.
681
718
#
682
719
# Server capabilities may change after #starttls, #login, and #authenticate.
683
720
# Cached capabilities _must_ be invalidated after this method completes.
0 commit comments