Skip to content

Commit c99081c

Browse files
committed
📚🚚 Reorder SASL files and update visibility
The rdoc output is improved simply by making some constants private and `#initialize` public, Except for changing visibility, no code was changed (only rearranged).
1 parent 663147b commit c99081c

8 files changed

+103
-108
lines changed

lib/net/imap/sasl/anonymous_authenticator.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ module SASL
99
# Net::IMAP#authenticate.
1010
class AnonymousAuthenticator
1111

12+
# An optional token sent for the +ANONYMOUS+ mechanism., up to 255 UTF-8
13+
# characters in length.
14+
#
15+
# If it contains an "@" sign, the message must be a valid email address
16+
# (+addr-spec+ from RFC-2822[https://tools.ietf.org/html/rfc2822]).
17+
# Email syntax is _not_ validated by AnonymousAuthenticator.
18+
#
19+
# Otherwise, it can be any UTF8 string which is permitted by the
20+
# StringPrep::Trace profile.
21+
attr_reader :anonymous_message
22+
1223
# :call-seq:
1324
# new(anonymous_message = "", **) -> authenticator
1425
# new(anonymous_message: "", **) -> authenticator
@@ -31,17 +42,6 @@ def initialize(anon_msg = nil, anonymous_message: nil, **)
3142
end
3243
end
3344

34-
# An optional token sent for the +ANONYMOUS+ mechanism., up to 255 UTF-8
35-
# characters in length.
36-
#
37-
# If it contains an "@" sign, the message must be a valid email address
38-
# (+addr-spec+ from RFC-2822[https://tools.ietf.org/html/rfc2822]).
39-
# Email syntax is _not_ validated by AnonymousAuthenticator.
40-
#
41-
# Otherwise, it can be any UTF8 string which is permitted by the
42-
# StringPrep::Trace profile.
43-
attr_reader :anonymous_message
44-
4545
# :call-seq:
4646
# initial_response? -> true
4747
#

lib/net/imap/sasl/cram_md5_authenticator.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,6 @@
1414
# of cleartext and recommends TLS version 1.2 or greater be used for all
1515
# traffic. With TLS +CRAM-MD5+ is okay, but so is +PLAIN+
1616
class Net::IMAP::SASL::CramMD5Authenticator
17-
def process(challenge)
18-
digest = hmac_md5(challenge, @password)
19-
return @user + " " + digest
20-
end
21-
22-
private
23-
2417
def initialize(user, password, warn_deprecation: true, **_ignored)
2518
if warn_deprecation
2619
warn "WARNING: CRAM-MD5 mechanism is deprecated." # TODO: recommend SCRAM
@@ -30,6 +23,13 @@ def initialize(user, password, warn_deprecation: true, **_ignored)
3023
@password = password
3124
end
3225

26+
def process(challenge)
27+
digest = hmac_md5(challenge, @password)
28+
return @user + " " + digest
29+
end
30+
31+
private
32+
3333
def hmac_md5(text, key)
3434
if key.length > 64
3535
key = Digest::MD5.digest(key)

lib/net/imap/sasl/digest_md5_authenticator.rb

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@
99
# {RFC6331}[https://tools.ietf.org/html/rfc6331] and should not be relied on for
1010
# security. It is included for compatibility with existing servers.
1111
class Net::IMAP::SASL::DigestMD5Authenticator
12+
STAGE_ONE = :stage_one
13+
STAGE_TWO = :stage_two
14+
private_constant :STAGE_ONE, :STAGE_TWO
15+
16+
def initialize(user, password, authname = nil, warn_deprecation: true)
17+
if warn_deprecation
18+
warn "WARNING: DIGEST-MD5 SASL mechanism was deprecated by RFC6331."
19+
# TODO: recommend SCRAM instead.
20+
end
21+
require "digest/md5"
22+
require "strscan"
23+
@user, @password, @authname = user, password, authname
24+
@nc, @stage = {}, STAGE_ONE
25+
end
26+
1227
def process(challenge)
1328
case @stage
1429
when STAGE_ONE
@@ -74,23 +89,8 @@ def process(challenge)
7489
end
7590
end
7691

77-
def initialize(user, password, authname = nil, warn_deprecation: true)
78-
if warn_deprecation
79-
warn "WARNING: DIGEST-MD5 SASL mechanism was deprecated by RFC6331."
80-
# TODO: recommend SCRAM instead.
81-
end
82-
require "digest/md5"
83-
require "strscan"
84-
@user, @password, @authname = user, password, authname
85-
@nc, @stage = {}, STAGE_ONE
86-
end
87-
88-
8992
private
9093

91-
STAGE_ONE = :stage_one
92-
STAGE_TWO = :stage_two
93-
9494
def nc(nonce)
9595
if @nc.has_key? nonce
9696
@nc[nonce] = @nc[nonce] + 1

lib/net/imap/sasl/external_authenticator.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ module SASL
1212
# established external to SASL, for example by TLS certificate or IPsec.
1313
class ExternalAuthenticator
1414

15+
# Authorization identity: an identity to act as or on behalf of.
16+
#
17+
# If not explicitly provided, the server defaults to using the identity
18+
# that was authenticated by the external credentials.
19+
attr_reader :authzid
20+
1521
# :call-seq:
1622
# new(authzid: nil, **) -> authenticator
1723
#
@@ -30,12 +36,6 @@ def initialize(authzid: nil)
3036
end
3137
end
3238

33-
# Authorization identity: an identity to act as or on behalf of.
34-
#
35-
# If not explicitly provided, the server defaults to using the identity
36-
# that was authenticated by the external credentials.
37-
attr_reader :authzid
38-
3939
# :call-seq:
4040
# initial_response? -> true
4141
#

lib/net/imap/sasl/login_authenticator.rb

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,9 @@
1818
# {draft-murchison-sasl-login}[https://www.iana.org/go/draft-murchison-sasl-login]
1919
# for both specification and deprecation.
2020
class Net::IMAP::SASL::LoginAuthenticator
21-
def process(data)
22-
case @state
23-
when STATE_USER
24-
@state = STATE_PASSWORD
25-
return @user
26-
when STATE_PASSWORD
27-
return @password
28-
end
29-
end
30-
31-
private
32-
3321
STATE_USER = :USER
3422
STATE_PASSWORD = :PASSWORD
23+
private_constant :STATE_USER, :STATE_PASSWORD
3524

3625
def initialize(user, password, warn_deprecation: true, **_ignored)
3726
if warn_deprecation
@@ -42,4 +31,13 @@ def initialize(user, password, warn_deprecation: true, **_ignored)
4231
@state = STATE_USER
4332
end
4433

34+
def process(data)
35+
case @state
36+
when STATE_USER
37+
@state = STATE_PASSWORD
38+
return @user
39+
when STATE_PASSWORD
40+
return @password
41+
end
42+
end
4543
end

lib/net/imap/sasl/oauthbearer_authenticator.rb

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,6 @@ module SASL
1414
class OAuthAuthenticator
1515
include GS2Header
1616

17-
# Creates an RFC7628[https://tools.ietf.org/html/rfc7628] OAuth
18-
# authenticator.
19-
#
20-
# === Options
21-
#
22-
# See child classes for required configuration parameter(s). The
23-
# following parameters are all optional, but protocols or servers may
24-
# add requirements for #authzid, #host, #port, or any other parameter.
25-
#
26-
# * #authzid ― Identity to act as or on behalf of.
27-
# * #host — Hostname to which the client connected.
28-
# * #port — Service port to which the client connected.
29-
# * #mthd — HTTP method
30-
# * #path — HTTP path data
31-
# * #post — HTTP post data
32-
# * #qs — HTTP query string
33-
#
34-
def initialize(authzid: nil, host: nil, port: nil,
35-
mthd: nil, path: nil, post: nil, qs: nil, **)
36-
@authzid = authzid
37-
@host = host
38-
@port = port
39-
@mthd = mthd
40-
@path = path
41-
@post = post
42-
@qs = qs
43-
@done = false
44-
end
45-
4617
# Authorization identity: an identity to act as or on behalf of.
4718
#
4819
# If no explicit authorization identity is provided, it is usually
@@ -73,6 +44,45 @@ def initialize(authzid: nil, host: nil, port: nil,
7344
# this may hold information about the failure reason, as JSON.
7445
attr_reader :last_server_response
7546

47+
# Creates an RFC7628[https://tools.ietf.org/html/rfc7628] OAuth
48+
# authenticator.
49+
#
50+
# === Options
51+
#
52+
# See child classes for required configuration parameter(s). The
53+
# following parameters are all optional, but protocols or servers may
54+
# add requirements for #authzid, #host, #port, or any other parameter.
55+
#
56+
# * #authzid ― Identity to act as or on behalf of.
57+
# * #host — Hostname to which the client connected.
58+
# * #port — Service port to which the client connected.
59+
# * #mthd — HTTP method
60+
# * #path — HTTP path data
61+
# * #post — HTTP post data
62+
# * #qs — HTTP query string
63+
#
64+
def initialize(authzid: nil, host: nil, port: nil,
65+
mthd: nil, path: nil, post: nil, qs: nil, **)
66+
@authzid = authzid
67+
@host = host
68+
@port = port
69+
@mthd = mthd
70+
@path = path
71+
@post = post
72+
@qs = qs
73+
@done = false
74+
end
75+
76+
# The {RFC7628 §3.1}[https://www.rfc-editor.org/rfc/rfc7628#section-3.1]
77+
# formatted response.
78+
def initial_client_response
79+
kv_pairs = {
80+
host: host, port: port, mthd: mthd, path: path, post: post, qs: qs,
81+
auth: authorization, # authorization is implemented by subclasses
82+
}.compact
83+
[gs2_header, *kv_pairs.map {|kv| kv.join("=") }, "\1"].join("\1")
84+
end
85+
7686
# Returns initial_client_response the first time, then "<tt>^A</tt>".
7787
def process(data)
7888
@last_server_response = data
@@ -87,16 +97,6 @@ def process(data)
8797
# does *not* indicate success.
8898
def done?; @done end
8999

90-
# The {RFC7628 §3.1}[https://www.rfc-editor.org/rfc/rfc7628#section-3.1]
91-
# formatted response.
92-
def initial_client_response
93-
kv_pairs = {
94-
host: host, port: port, mthd: mthd, path: path, post: post, qs: qs,
95-
auth: authorization, # authorization is implemented by subclasses
96-
}.compact
97-
[gs2_header, *kv_pairs.map {|kv| kv.join("=") }, "\1"].join("\1")
98-
end
99-
100100
# Value of the HTTP Authorization header
101101
#
102102
# <b>Implemented by subclasses.</b>
@@ -116,6 +116,9 @@ def authorization; raise "must be implemented by subclass" end
116116
# the bearer token.
117117
class OAuthBearerAuthenticator < OAuthAuthenticator
118118

119+
# An OAuth2 bearer token, generally the access token.
120+
attr_reader :oauth2_token
121+
119122
# :call-seq:
120123
# new(oauth2_token, **options) -> authenticator
121124
# new(oauth2_token:, **options) -> authenticator
@@ -145,9 +148,6 @@ def initialize(oauth2_token_arg = nil, oauth2_token: nil, **args, &blk)
145148
raise ArgumentError, "missing oauth2_token"
146149
end
147150

148-
# An OAuth2 bearer token, generally the access token.
149-
attr_reader :oauth2_token
150-
151151
# :call-seq:
152152
# initial_response? -> true
153153
#

lib/net/imap/sasl/plain_authenticator.rb

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,8 @@
1010
# greater be used for all traffic, and deprecate cleartext access ASAP. +PLAIN+
1111
# can be secured by TLS encryption.
1212
class Net::IMAP::SASL::PlainAuthenticator
13-
14-
def initial_response?; true end
15-
16-
def process(data)
17-
return "#@authzid\0#@username\0#@password"
18-
end
19-
20-
# :nodoc:
2113
NULL = -"\0".b
22-
23-
private
14+
private_constant :NULL
2415

2516
# +username+ is the authentication identity, the identity whose +password+ is
2617
# used. +username+ is referred to as +authcid+ by
@@ -39,4 +30,10 @@ def initialize(username, password, authzid: nil)
3930
@authzid = authzid
4031
end
4132

33+
def initial_response?; true end
34+
35+
def process(data)
36+
return "#@authzid\0#@username\0#@password"
37+
end
38+
4239
end

lib/net/imap/sasl/xoauth2_authenticator.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
class Net::IMAP::SASL::XOAuth2Authenticator
44

5+
def initialize(user, oauth2_token)
6+
@user = user
7+
@oauth2_token = oauth2_token
8+
end
9+
510
def initial_response?; true end
611

712
def process(_data)
@@ -10,11 +15,6 @@ def process(_data)
1015

1116
private
1217

13-
def initialize(user, oauth2_token)
14-
@user = user
15-
@oauth2_token = oauth2_token
16-
end
17-
1818
def build_oauth2_string(user, oauth2_token)
1919
format("user=%s\1auth=Bearer %s\1\1", user, oauth2_token)
2020
end

0 commit comments

Comments
 (0)