Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ Allow keyword args on all SASL authenticators #177

Merged
merged 4 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions lib/net/imap/sasl/digest_md5_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class Net::IMAP::SASL::DigestMD5Authenticator
attr_reader :authzid

# :call-seq:
# new(username, password, authzid = nil) -> authenticator
# new(username, password, authzid = nil, **options) -> authenticator
# new(username:, password:, authzid: nil, **options) -> authenticator
#
# Creates an Authenticator for the "+DIGEST-MD5+" SASL mechanism.
#
Expand All @@ -55,7 +56,12 @@ class Net::IMAP::SASL::DigestMD5Authenticator
# * +warn_deprecation+ — Set to +false+ to silence the warning.
#
# See the documentation for each attribute for more details.
def initialize(username, password, authzid = nil, warn_deprecation: true)
def initialize(user = nil, pass = nil, authz = nil,
username: nil, password: nil, authzid: nil,
warn_deprecation: true, **)
username ||= user or raise ArgumentError, "missing username"
password ||= pass or raise ArgumentError, "missing password"
authzid ||= authz
if warn_deprecation
warn "WARNING: DIGEST-MD5 SASL mechanism was deprecated by RFC6331."
# TODO: recommend SCRAM instead.
Expand Down
2 changes: 1 addition & 1 deletion lib/net/imap/sasl/external_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ExternalAuthenticator
# #authzid is an optional identity to act as or on behalf of.
#
# Any other keyword parameters are quietly ignored.
def initialize(authzid: nil)
def initialize(authzid: nil, **)
@authzid = authzid&.to_str&.encode "UTF-8"
if @authzid&.match?(/\u0000/u) # also validates UTF8 encoding
raise ArgumentError, "contains NULL"
Expand Down
14 changes: 9 additions & 5 deletions lib/net/imap/sasl/plain_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class Net::IMAP::SASL::PlainAuthenticator
attr_reader :authzid

# :call-seq:
# new(username, password, authzid: nil) -> authenticator
# new(username, password, authzid: nil, **) -> authenticator
# new(username:, password:, authzid: nil, **) -> authenticator
#
# Creates an Authenticator for the "+PLAIN+" SASL mechanism.
#
Expand All @@ -50,10 +51,13 @@ class Net::IMAP::SASL::PlainAuthenticator
# * #authzid ― Alternate identity to act as or on behalf of. Optional.
#
# See attribute documentation for more details.
def initialize(username, password, authzid: nil)
raise ArgumentError, "username contains NULL" if username&.include?(NULL)
raise ArgumentError, "password contains NULL" if password&.include?(NULL)
raise ArgumentError, "authzid contains NULL" if authzid&.include?(NULL)
def initialize(user = nil, pass = nil,
username: nil, password: nil, authzid: nil, **)
username ||= user or raise ArgumentError, "missing username"
password ||= pass or raise ArgumentError, "missing password"
raise ArgumentError, "username contains NULL" if username.include?(NULL)
raise ArgumentError, "password contains NULL" if password.include?(NULL)
raise ArgumentError, "authzid contains NULL" if authzid&.include?(NULL)
@username = username
@password = password
@authzid = authzid
Expand Down
16 changes: 11 additions & 5 deletions lib/net/imap/sasl/xoauth2_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ class Net::IMAP::SASL::XOAuth2Authenticator
attr_reader :oauth2_token

# :call-seq:
# :call-seq:
# new(username, oauth2_token) -> authenticator
# new(username, oauth2_token, **) -> authenticator
# new(username:, oauth2_token:, **) -> authenticator
#
# Creates an Authenticator for the "+XOAUTH2+" SASL mechanism, as specified by
# Google[https://developers.google.com/gmail/imap/xoauth2-protocol],
Expand All @@ -47,9 +47,15 @@ class Net::IMAP::SASL::XOAuth2Authenticator
# the service for #username.
#
# See the documentation for each attribute for more details.
def initialize(username, oauth2_token)
@username = username
@oauth2_token = oauth2_token
def initialize(user = nil, token = nil, username: nil, oauth2_token: nil, **)
@username = username || user or
raise ArgumentError, "missing username"
@oauth2_token = oauth2_token || token or
raise ArgumentError, "missing oauth2_token"
[username, user].compact.count == 1 or
raise ArgumentError, "conflicting values for username"
[oauth2_token, token].compact.count == 1 or
raise ArgumentError, "conflicting values for oauth2_token"
end

# :call-seq:
Expand Down
11 changes: 11 additions & 0 deletions test/net/imap/test_imap_authenticators.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ def test_xoauth2_response
)
end

def test_xoauth2_kwargs
assert_equal(
"user=arg\1auth=Bearer kwarg\1\1",
xoauth2("arg", oauth2_token: "kwarg").process(nil)
)
assert_equal(
"user=user\1auth=Bearer kwarg\1\1",
xoauth2(username: "user", oauth2_token: "kwarg").process(nil)
)
end

def test_xoauth2_supports_initial_response
assert xoauth2("foo", "bar").initial_response?
assert Net::IMAP::SASL.initial_response?(xoauth2("foo", "bar"))
Expand Down