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

Forward authenticate keyword arguments #74

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
37 changes: 26 additions & 11 deletions lib/net/smtp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ def debug_output=(arg)

#
# :call-seq:
# start(address, port = nil, helo: 'localhost', auth: nil, tls: false, starttls: :auto, tls_verify: true, tls_hostname: nil, ssl_context_params: nil) { |smtp| ... }
# start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls: false, starttls: :auto, tls_verify: true, tls_hostname: nil, ssl_context_params: nil) { |smtp| ... }
# start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
#
Expand Down Expand Up @@ -521,6 +522,8 @@ def debug_output=(arg)
# These will be sent to #authenticate as positional arguments-the exact
# semantics are dependent on the +authtype+.
#
# +auth+ is an optional hash of keyword arguments for #authenticate.
#
# See the discussion of Net::SMTP@SMTP+Authentication in the overview notes.
#
# === Errors
Expand All @@ -538,6 +541,7 @@ def debug_output=(arg)
#
def SMTP.start(address, port = nil, *args, helo: nil,
user: nil, secret: nil, password: nil, authtype: nil,
auth: nil,
tls: false, starttls: :auto,
tls_verify: true, tls_hostname: nil, ssl_context_params: nil,
&block)
Expand All @@ -546,7 +550,8 @@ def SMTP.start(address, port = nil, *args, helo: nil,
user ||= args[1]
secret ||= password || args[2]
authtype ||= args[3]
new(address, port, tls: tls, starttls: starttls, tls_verify: tls_verify, tls_hostname: tls_hostname, ssl_context_params: ssl_context_params).start(helo: helo, user: user, secret: secret, authtype: authtype, &block)
new(address, port, tls: tls, starttls: starttls, tls_verify: tls_verify, tls_hostname: tls_hostname, ssl_context_params: ssl_context_params)
.start(helo: helo, user: user, secret: secret, authtype: authtype, auth: auth, &block)
end

# +true+ if the \SMTP session has been started.
Expand All @@ -558,6 +563,7 @@ def started?
# :call-seq:
# start(helo: 'localhost', user: nil, secret: nil, authtype: nil) { |smtp| ... }
# start(helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
# start(helo = 'localhost', auth: {type: nil, **auth_kwargs}) { |smtp| ... }
#
# Opens a TCP connection and starts the SMTP session.
#
Expand All @@ -578,6 +584,8 @@ def started?
# These will be sent to #authenticate as positional arguments-the exact
# semantics are dependent on the +authtype+.
#
# +auth+ is an optional hash of keyword arguments for #authenticate.
#
# See the discussion of Net::SMTP@SMTP+Authentication in the overview notes.
#
# See also: Net::SMTP.start
Expand Down Expand Up @@ -619,12 +627,15 @@ def started?
# * Net::ReadTimeout
# * IOError
#
def start(*args, helo: nil, user: nil, secret: nil, password: nil, authtype: nil)
def start(*args, helo: nil,
user: nil, secret: nil, password: nil,
authtype: nil, auth: nil)
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..4)" if args.size > 4
helo ||= args[0] || 'localhost'
user ||= args[1]
secret ||= password || args[2]
authtype ||= args[3]
auth ||= {}
if defined?(OpenSSL::VERSION)
ssl_context_params = @ssl_context_params || {}
unless ssl_context_params.has_key?(:verify_mode)
Expand All @@ -639,13 +650,13 @@ def start(*args, helo: nil, user: nil, secret: nil, password: nil, authtype: nil
end
if block_given?
begin
do_start helo, user, secret, authtype
do_start helo, user, secret, authtype, **auth
return yield(self)
ensure
do_finish
end
else
do_start helo, user, secret, authtype
do_start helo, user, secret, authtype, **auth
return self
end
end
Expand All @@ -663,10 +674,10 @@ def tcp_socket(address, port)
TCPSocket.open address, port
end

def do_start(helo_domain, user, secret, authtype)
def do_start(helo_domain, user, secret, authtype, **auth)
raise IOError, 'SMTP session already started' if @started
if user || secret || authtype
check_auth_args authtype, user, secret
if user || secret || authtype || auth.any?
check_auth_args(authtype, user, secret, **auth)
end
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
tcp_socket(@address, @port)
Expand All @@ -684,7 +695,11 @@ def do_start(helo_domain, user, secret, authtype)
# helo response may be different after STARTTLS
do_helo helo_domain
end
authenticate user, secret, (authtype || DEFAULT_AUTH_TYPE) if user
if user or secret
authenticate(user, secret, authtype, **auth)
elsif authtype or auth.any?
authenticate(authtype, **auth)
end
@started = true
ensure
unless @started
Expand Down Expand Up @@ -869,10 +884,10 @@ def open_message_stream(from_addr, *to_addrs, &block) # :yield: stream
# All arguments-other than +authtype+-are forwarded to the authenticator.
# Different authenticators may interpret the +user+ and +secret+
# arguments differently.
def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
check_auth_args authtype, user, secret
def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE, **kwargs, &block)
check_auth_args authtype, user, secret, **kwargs
authenticator = Authenticator.auth_class(authtype).new(self)
authenticator.auth(user, secret)
authenticator.auth(user, secret, **kwargs, &block)
end

private
Expand Down