Skip to content

Commit 2066e7f

Browse files
committed
πŸ”’πŸ—‘οΈ Deprecate old starttls args, use keyword args
`Net::IMAP#starttls` converts all incoming keyword args in params for `OpenSSL::SSL::SSLContext#set_params`.
1 parent e2e1426 commit 2066e7f

File tree

3 files changed

+82
-9
lines changed

3 files changed

+82
-9
lines changed

β€Žlib/net/imap.rb

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,12 @@ def logout
10751075
# Sends a {STARTTLS command [IMAP4rev1 Β§6.2.1]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.1]
10761076
# to start a TLS session.
10771077
#
1078-
# Any +options+ are forwarded to OpenSSL::SSL::SSLContext#set_params.
1078+
# Any +options+ are forwarded directly to
1079+
# {OpenSSL::SSL::SSLContext#set_params}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-set_params];
1080+
# the keys are names of attribute assignment methods on
1081+
# SSLContext[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html].
1082+
#
1083+
# See DeprecatedClientOptions#starttls for deprecated arguments.
10791084
#
10801085
# This method returns after TLS negotiation and hostname verification are
10811086
# both successful. Any error indicates that the connection has not been
@@ -1097,14 +1102,8 @@ def logout
10971102
# Server capabilities may change after #starttls, #login, and #authenticate.
10981103
# Cached #capabilities will be cleared when this method completes.
10991104
#
1100-
def starttls(options = {}, verify = true)
1101-
begin
1102-
# for backward compatibility
1103-
certs = options.to_str
1104-
options = create_ssl_params(certs, verify)
1105-
rescue NoMethodError
1106-
end
1107-
@ssl_ctx_params, @ssl_ctx = build_ssl_ctx(options || {})
1105+
def starttls(**options)
1106+
@ssl_ctx_params, @ssl_ctx = build_ssl_ctx(options)
11081107
send_command("STARTTLS") do |resp|
11091108
if resp.kind_of?(TaggedResponse) && resp.name == "OK"
11101109
clear_cached_capabilities

β€Žlib/net/imap/deprecated_client_options.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,33 @@ def initialize(host, port_or_options = nil, *deprecated, **options)
9191
end
9292
end
9393

94+
# :call-seq:
95+
# starttls(**options) # standard
96+
# starttls(options = {}) # obsolete
97+
# starttls(certs = nil, verify = true) # deprecated
98+
#
99+
# Translates Net::IMAP#starttls arguments for backward compatibility.
100+
#
101+
# Support for +certs+ and +verify+ will be dropped in a future release.
102+
#
103+
# See ::new for interpretation of +certs+ and +verify+.
104+
def starttls(*deprecated, **options)
105+
if deprecated.empty?
106+
super(**options)
107+
elsif options.any?
108+
# starttls(*__invalid__, **options)
109+
raise ArgumentError, "Do not combine deprecated and keyword options"
110+
elsif deprecated.first.respond_to?(:to_hash) && deprecated.length > 1
111+
# starttls(*__invalid__, **options)
112+
raise ArgumentError, "Do not use deprecated verify param with options hash"
113+
elsif deprecated.first.respond_to?(:to_hash)
114+
super(**Hash.try_convert(deprecated.first))
115+
else
116+
warn "DEPRECATED: Call Net::IMAP#starttls with keyword options", uplevel: 1
117+
super(**create_ssl_params(*deprecated))
118+
end
119+
end
120+
94121
private
95122

96123
def create_ssl_params(certs = nil, verify = true)

β€Žtest/net/imap/test_deprecated_client_options.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,51 @@ class InitializeTests < DeprecatedClientOptionsTest
115115

116116
end
117117

118+
class StartTLSTests < DeprecatedClientOptionsTest
119+
test "Convert obsolete options hash to keywords" do
120+
with_fake_server(preauth: false) do |server, imap|
121+
imap.starttls(ca_file: server.config.tls[:ca_file], min_version: :TLS1_2)
122+
assert_equal(
123+
{ca_file: server.config.tls[:ca_file], min_version: :TLS1_2},
124+
imap.ssl_ctx_params
125+
)
126+
assert imap.ssl_ctx.verify_hostname
127+
assert_equal(server.config.tls[:ca_file], imap.ssl_ctx.ca_file)
128+
end
129+
end
130+
131+
test "Convert deprecated certs, verify with warning" do
132+
with_fake_server(preauth: false) do |server, imap|
133+
assert_deprecated_warning(/Call Net::IMAP#starttls with keyword/i) do
134+
imap.starttls(server.config.tls[:ca_file], false)
135+
end
136+
assert_equal(
137+
{
138+
ca_file: server.config.tls[:ca_file],
139+
verify_mode: OpenSSL::SSL::VERIFY_NONE,
140+
},
141+
imap.ssl_ctx_params
142+
)
143+
assert_equal server.config.tls[:ca_file], imap.ssl_ctx.ca_file
144+
end
145+
end
146+
147+
test "combined options hash and keyword args raises ArgumentError" do
148+
with_fake_server(preauth: false) do |server, imap|
149+
assert_raise(ArgumentError) do
150+
imap.starttls({min_version: :TLS1_2},
151+
ca_file: server.config.tls[:ca_file])
152+
end
153+
end
154+
end
155+
156+
test "combined options hash and ssl args raises ArgumentError" do
157+
with_fake_server(preauth: false) do |server, imap|
158+
assert_raise(ArgumentError) do
159+
imap.starttls({min_version: :TLS1_2}, false)
160+
end
161+
end
162+
end
163+
end
164+
118165
end

0 commit comments

Comments
Β (0)