1
1
# frozen_string_literal: true
2
2
3
+ require "forwardable"
4
+
3
5
module Net
4
6
class IMAP
5
7
module SASL
@@ -8,18 +10,28 @@ module SASL
8
10
#
9
11
# TODO: use with more clients, to verify the API can accommodate them.
10
12
#
11
- # An abstract base class for implementing a SASL authentication exchange.
12
- # Different clients will each have their own adapter subclass, overridden
13
- # to match their needs.
13
+ # Represents the client to a SASL::AuthenticationExchange. By default,
14
+ # most methods simply delegate to #client. Clients should subclass
15
+ # SASL::ClientAdapter and override methods as needed to match the
16
+ # semantics of this API to their API.
14
17
#
15
- # Although the default implementations _may_ be sufficient, subclasses
16
- # will probably need to override some methods. Additionally, subclasses
17
- # may need to include a protocol adapter mixin, if the default
18
+ # Subclasses should also include a protocol adapter mixin when the default
18
19
# ProtocolAdapters::Generic isn't sufficient.
20
+ #
21
+ # === Protocol Requirements
22
+ #
23
+ # {RFC4422 §4}[https://www.rfc-editor.org/rfc/rfc4422.html#section-4]
24
+ # lists requirements for protocol specifications to offer SASL. Where
25
+ # possible, ClientAdapter delegates the handling of these requirements to
26
+ # SASL::ProtocolAdapters.
19
27
class ClientAdapter
28
+ extend Forwardable
29
+
20
30
include ProtocolAdapters ::Generic
21
31
22
32
# The client that handles communication with the protocol server.
33
+ #
34
+ # Most ClientAdapter methods are simply delegated to #client by default.
23
35
attr_reader :client
24
36
25
37
# +command_proc+ can used to avoid exposing private methods on #client.
@@ -51,15 +63,17 @@ def initialize(client, &command_proc)
51
63
# AuthenticationExchange.authenticate.
52
64
def authenticate ( ...) AuthenticationExchange . authenticate ( self , ...) end
53
65
66
+ ##
67
+ # method: sasl_ir_capable?
54
68
# Do the protocol, server, and client all support an initial response?
55
- #
56
- # By default, this simply delegates to <tt>client.sasl_ir_capable?</tt>.
57
- def sasl_ir_capable? ; client . sasl_ir_capable? end
69
+ def_delegator :client , :sasl_ir_capable?
58
70
59
- # Does the server advertise support for the mechanism?
71
+ ##
72
+ # method: auth_capable?
73
+ # call-seq: auth_capable?(mechanism)
60
74
#
61
- # By default, this simply delegates to <tt>client.auth_capable?</tt>.
62
- def auth_capable? ( mechanism ) ; client . auth_capable? ( mechanism ) end
75
+ # Does the server advertise support for the +mechanism+?
76
+ def_delegator : client, : auth_capable?
63
77
64
78
# Calls command_proc with +command_name+ (see
65
79
# SASL::ProtocolAdapters::Generic#command_name),
@@ -79,19 +93,30 @@ def run_command(mechanism, initial_response = nil, &continuations_handler)
79
93
command_proc . call ( *args , &continuations_handler )
80
94
end
81
95
96
+ ##
97
+ # method: host
98
+ # The hostname to which the client connected.
99
+ def_delegator :client , :host
100
+
101
+ ##
102
+ # method: port
103
+ # The destination port to which the client connected.
104
+ def_delegator :client , :port
105
+
82
106
# Returns an array of server responses errors raised by run_command.
83
107
# Exceptions in this array won't drop the connection.
84
108
def response_errors ; [ ] end
85
109
86
- # Drop the connection gracefully.
87
- #
88
- # By default, this simply delegates to <tt>client.drop_connection</tt>.
89
- def drop_connection ; client . drop_connection end
110
+ ##
111
+ # method: drop_connection
112
+ # Drop the connection gracefully, sending a "LOGOUT" command as needed.
113
+ def_delegator :client , :drop_connection
114
+
115
+ ##
116
+ # method: drop_connection!
117
+ # Drop the connection abruptly, closing the socket without logging out.
118
+ def_delegator :client , :drop_connection!
90
119
91
- # Drop the connection abruptly.
92
- #
93
- # By default, this simply delegates to <tt>client.drop_connection!</tt>.
94
- def drop_connection! ; client . drop_connection! end
95
120
end
96
121
end
97
122
end
0 commit comments