Skip to content

Commit 0d8db36

Browse files
committed
Add auth keyword arg to start methods
This adds a new `auth` keyword param to `Net::SMTP.start` and `#start` that can be used to pass any arbitrary keyword parameters to `#authenticate`. The pre-existing `username`, `secret`, etc keyword params will retain their existing behavior as positional arguments to `#authenticate`.
1 parent 7ad42ef commit 0d8db36

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

lib/net/smtp.rb

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ def debug_output=(arg)
458458

459459
#
460460
# :call-seq:
461+
# start(address, port = nil, helo: 'localhost', auth: nil, tls: false, starttls: :auto, tls_verify: true, tls_hostname: nil, ssl_context_params: nil) { |smtp| ... }
461462
# start(address, port = nil, helo: 'localhost', username: nil, secret: nil, authtype: nil, tls: false, starttls: :auto, tls_verify: true, tls_hostname: nil, ssl_context_params: nil) { |smtp| ... }
462463
# start(address, port = nil, helo = 'localhost', username = nil, secret = nil, authtype = nil) { |smtp| ... }
463464
#
@@ -520,6 +521,8 @@ def debug_output=(arg)
520521
# These will be sent to #authenticate as positional arguments—the exact
521522
# semantics are dependent on the +authtype+.
522523
#
524+
# +auth+ is a hash of arbitrary keyword arguments for #authenticate.
525+
#
523526
# See the discussion of Net::SMTP@SMTP+Authentication in the overview notes.
524527
#
525528
# === Errors
@@ -537,7 +540,7 @@ def debug_output=(arg)
537540
#
538541
def SMTP.start(address, port = nil, *args, helo: nil,
539542
user: nil, secret: nil, password: nil, authtype: nil,
540-
username: nil,
543+
username: nil, auth: nil,
541544
tls: false, starttls: :auto,
542545
tls_verify: true, tls_hostname: nil, ssl_context_params: nil,
543546
&block)
@@ -546,7 +549,8 @@ def SMTP.start(address, port = nil, *args, helo: nil,
546549
username ||= user || args[1]
547550
secret ||= password || args[2]
548551
authtype ||= args[3]
549-
new(address, port, tls: tls, starttls: starttls, tls_verify: tls_verify, tls_hostname: tls_hostname, ssl_context_params: ssl_context_params).start(helo: helo, username: username, secret: secret, authtype: authtype, &block)
552+
new(address, port, tls: tls, starttls: starttls, tls_verify: tls_verify, tls_hostname: tls_hostname, ssl_context_params: ssl_context_params)
553+
.start(helo: helo, username: username, secret: secret, authtype: authtype, auth: auth, &block)
550554
end
551555

552556
# +true+ if the \SMTP session has been started.
@@ -558,6 +562,7 @@ def started?
558562
# :call-seq:
559563
# start(helo: 'localhost', username: nil, secret: nil, authtype: nil) { |smtp| ... }
560564
# start(helo = 'localhost', username = nil, secret = nil, authtype = nil) { |smtp| ... }
565+
# start(helo = 'localhost', auth: {type: nil, **auth_kwargs}) { |smtp| ... }
561566
#
562567
# Opens a TCP connection and starts the SMTP session.
563568
#
@@ -578,6 +583,8 @@ def started?
578583
# These will be sent to #authenticate as positional arguments—the exact
579584
# semantics are dependent on the +authtype+.
580585
#
586+
# +auth+ is an optional hash of keyword arguments for #authenticate.
587+
#
581588
# See the discussion of Net::SMTP@SMTP+Authentication in the overview notes.
582589
#
583590
# See also: Net::SMTP.start
@@ -619,13 +626,15 @@ def started?
619626
# * Net::ReadTimeout
620627
# * IOError
621628
#
622-
def start(*args, helo: nil, user: nil, secret: nil, password: nil, authtype: nil,
623-
username: nil)
629+
def start(*args, helo: nil,
630+
user: nil, username: nil, secret: nil, password: nil,
631+
authtype: nil, auth: nil)
624632
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..4)" if args.size > 4
625633
helo ||= args[0] || 'localhost'
626634
username ||= user || args[1]
627635
secret ||= password || args[2]
628636
authtype ||= args[3]
637+
auth ||= {}
629638
if defined?(OpenSSL::VERSION)
630639
ssl_context_params = @ssl_context_params || {}
631640
unless ssl_context_params.has_key?(:verify_mode)
@@ -640,13 +649,13 @@ def start(*args, helo: nil, user: nil, secret: nil, password: nil, authtype: nil
640649
end
641650
if block_given?
642651
begin
643-
do_start helo, username, secret, authtype
652+
do_start helo, username, secret, authtype, **auth
644653
return yield(self)
645654
ensure
646655
do_finish
647656
end
648657
else
649-
do_start helo, username, secret, authtype
658+
do_start helo, username, secret, authtype, **auth
650659
return self
651660
end
652661
end
@@ -664,9 +673,9 @@ def tcp_socket(address, port)
664673
TCPSocket.open address, port
665674
end
666675

667-
def do_start(helo_domain, user, secret, authtype)
676+
def do_start(helo_domain, user, secret, authtype, **auth)
668677
raise IOError, 'SMTP session already started' if @started
669-
check_auth_args authtype, user, secret
678+
check_auth_args(authtype, user, secret, **auth)
670679
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
671680
tcp_socket(@address, @port)
672681
end
@@ -683,7 +692,11 @@ def do_start(helo_domain, user, secret, authtype)
683692
# helo response may be different after STARTTLS
684693
do_helo helo_domain
685694
end
686-
authenticate user, secret, (authtype || DEFAULT_AUTH_TYPE) if user
695+
if user or secret
696+
authenticate(user, secret, authtype, **auth)
697+
elsif authtype or auth.any?
698+
authenticate(authtype, **auth)
699+
end
687700
@started = true
688701
ensure
689702
unless @started

test/net/smtp/test_smtp.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,15 @@ def test_start_auth_plain
455455
port = fake_server_start(auth: 'plain')
456456
Net::SMTP.start('localhost', port, user: 'account', password: 'password', authtype: :plain){}
457457

458+
port = fake_server_start(auth: 'plain')
459+
Net::SMTP.start('localhost', port, authtype: :plain,
460+
auth: {username: 'account', password: 'password'}){}
461+
462+
port = fake_server_start(auth: 'plain')
463+
Net::SMTP.start('localhost', port, auth: {username: 'account',
464+
password: 'password',
465+
type: :plain}){}
466+
458467
port = fake_server_start(auth: 'plain')
459468
assert_raise Net::SMTPAuthenticationError do
460469
Net::SMTP.start('localhost', port, user: 'account', password: 'invalid', authtype: :plain){}

0 commit comments

Comments
 (0)