net-imap 0.4.17 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -1
  3. data/README.md +10 -4
  4. data/docs/styles.css +75 -14
  5. data/lib/net/imap/authenticators.rb +2 -2
  6. data/lib/net/imap/command_data.rb +59 -46
  7. data/lib/net/imap/config.rb +109 -13
  8. data/lib/net/imap/data_encoding.rb +3 -3
  9. data/lib/net/imap/data_lite.rb +226 -0
  10. data/lib/net/imap/deprecated_client_options.rb +6 -3
  11. data/lib/net/imap/errors.rb +6 -0
  12. data/lib/net/imap/esearch_result.rb +180 -0
  13. data/lib/net/imap/fetch_data.rb +126 -47
  14. data/lib/net/imap/response_data.rb +124 -237
  15. data/lib/net/imap/response_parser/parser_utils.rb +5 -0
  16. data/lib/net/imap/response_parser.rb +183 -34
  17. data/lib/net/imap/sasl/anonymous_authenticator.rb +3 -3
  18. data/lib/net/imap/sasl/authentication_exchange.rb +52 -20
  19. data/lib/net/imap/sasl/authenticators.rb +8 -4
  20. data/lib/net/imap/sasl/client_adapter.rb +77 -26
  21. data/lib/net/imap/sasl/cram_md5_authenticator.rb +4 -4
  22. data/lib/net/imap/sasl/digest_md5_authenticator.rb +218 -56
  23. data/lib/net/imap/sasl/external_authenticator.rb +2 -2
  24. data/lib/net/imap/sasl/gs2_header.rb +7 -7
  25. data/lib/net/imap/sasl/login_authenticator.rb +4 -3
  26. data/lib/net/imap/sasl/oauthbearer_authenticator.rb +6 -6
  27. data/lib/net/imap/sasl/plain_authenticator.rb +7 -7
  28. data/lib/net/imap/sasl/protocol_adapters.rb +60 -4
  29. data/lib/net/imap/sasl/scram_authenticator.rb +8 -8
  30. data/lib/net/imap/sasl.rb +7 -4
  31. data/lib/net/imap/sasl_adapter.rb +0 -1
  32. data/lib/net/imap/search_result.rb +2 -2
  33. data/lib/net/imap/sequence_set.rb +211 -81
  34. data/lib/net/imap/stringprep/nameprep.rb +1 -1
  35. data/lib/net/imap/stringprep/trace.rb +4 -4
  36. data/lib/net/imap/uidplus_data.rb +244 -0
  37. data/lib/net/imap/vanished_data.rb +56 -0
  38. data/lib/net/imap.rb +831 -279
  39. data/net-imap.gemspec +1 -1
  40. data/rakelib/rfcs.rake +2 -0
  41. data/rakelib/string_prep_tables_generator.rb +2 -0
  42. metadata +8 -7
@@ -0,0 +1,244 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Net
4
+ class IMAP < Protocol
5
+
6
+ # *NOTE:* <em>UIDPlusData is deprecated and will be removed in the +0.6.0+
7
+ # release.</em> To use AppendUIDData and CopyUIDData before +0.6.0+, set
8
+ # Config#parser_use_deprecated_uidplus_data to +false+.
9
+ #
10
+ # UIDPlusData represents the ResponseCode#data that accompanies the
11
+ # +APPENDUID+ and +COPYUID+ {response codes}[rdoc-ref:ResponseCode].
12
+ #
13
+ # A server that supports +UIDPLUS+ should send UIDPlusData in response to
14
+ # the append[rdoc-ref:Net::IMAP#append], copy[rdoc-ref:Net::IMAP#copy],
15
+ # move[rdoc-ref:Net::IMAP#move], {uid copy}[rdoc-ref:Net::IMAP#uid_copy],
16
+ # and {uid move}[rdoc-ref:Net::IMAP#uid_move] commands---unless the
17
+ # destination mailbox reports +UIDNOTSTICKY+.
18
+ #
19
+ # Note that append[rdoc-ref:Net::IMAP#append], copy[rdoc-ref:Net::IMAP#copy]
20
+ # and {uid_copy}[rdoc-ref:Net::IMAP#uid_copy] return UIDPlusData in their
21
+ # TaggedResponse. But move[rdoc-ref:Net::IMAP#copy] and
22
+ # {uid_move}[rdoc-ref:Net::IMAP#uid_move] _should_ send UIDPlusData in an
23
+ # UntaggedResponse response before sending their TaggedResponse. However
24
+ # some servers do send UIDPlusData in the TaggedResponse for +MOVE+
25
+ # commands---this complies with the older +UIDPLUS+ specification but is
26
+ # discouraged by the +MOVE+ extension and disallowed by +IMAP4rev2+.
27
+ #
28
+ # == Required capability
29
+ # Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]]
30
+ # or +IMAP4rev2+ capability.
31
+ #
32
+ class UIDPlusData < Struct.new(:uidvalidity, :source_uids, :assigned_uids)
33
+ ##
34
+ # method: uidvalidity
35
+ # :call-seq: uidvalidity -> nonzero uint32
36
+ #
37
+ # The UIDVALIDITY of the destination mailbox.
38
+
39
+ ##
40
+ # method: source_uids
41
+ # :call-seq: source_uids -> nil or an array of nonzero uint32
42
+ #
43
+ # The UIDs of the copied or moved messages.
44
+ #
45
+ # Note:: Returns +nil+ for Net::IMAP#append.
46
+
47
+ ##
48
+ # method: assigned_uids
49
+ # :call-seq: assigned_uids -> an array of nonzero uint32
50
+ #
51
+ # The newly assigned UIDs of the copied, moved, or appended messages.
52
+ #
53
+ # Note:: This always returns an array, even when it contains only one UID.
54
+
55
+ ##
56
+ # :call-seq: uid_mapping -> nil or a hash
57
+ #
58
+ # Returns a hash mapping each source UID to the newly assigned destination
59
+ # UID.
60
+ #
61
+ # Note:: Returns +nil+ for Net::IMAP#append.
62
+ def uid_mapping
63
+ source_uids&.zip(assigned_uids)&.to_h
64
+ end
65
+ end
66
+
67
+ # >>>
68
+ # *NOTE:* <em>AppendUIDData will replace UIDPlusData for +APPENDUID+ in the
69
+ # +0.6.0+ release.</em> To use AppendUIDData before +0.6.0+, set
70
+ # Config#parser_use_deprecated_uidplus_data to +false+.
71
+ #
72
+ # AppendUIDData represents the ResponseCode#data that accompanies the
73
+ # +APPENDUID+ {response code}[rdoc-ref:ResponseCode].
74
+ #
75
+ # A server that supports +UIDPLUS+ (or +IMAP4rev2+) should send
76
+ # AppendUIDData inside every TaggedResponse returned by the
77
+ # append[rdoc-ref:Net::IMAP#append] command---unless the target mailbox
78
+ # reports +UIDNOTSTICKY+.
79
+ #
80
+ # == Required capability
81
+ # Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]]
82
+ # or +IMAP4rev2+ capability.
83
+ class AppendUIDData < Data.define(:uidvalidity, :assigned_uids)
84
+ def initialize(uidvalidity:, assigned_uids:)
85
+ uidvalidity = Integer(uidvalidity)
86
+ assigned_uids = SequenceSet[assigned_uids]
87
+ NumValidator.ensure_nz_number(uidvalidity)
88
+ if assigned_uids.include_star?
89
+ raise DataFormatError, "uid-set cannot contain '*'"
90
+ end
91
+ super
92
+ end
93
+
94
+ ##
95
+ # attr_reader: uidvalidity
96
+ # :call-seq: uidvalidity -> nonzero uint32
97
+ #
98
+ # The UIDVALIDITY of the destination mailbox.
99
+
100
+ ##
101
+ # attr_reader: assigned_uids
102
+ #
103
+ # A SequenceSet with the newly assigned UIDs of the appended messages.
104
+
105
+ # Returns the number of messages that have been appended.
106
+ def size
107
+ assigned_uids.count_with_duplicates
108
+ end
109
+ end
110
+
111
+ # >>>
112
+ # *NOTE:* <em>CopyUIDData will replace UIDPlusData for +COPYUID+ in the
113
+ # +0.6.0+ release.</em> To use CopyUIDData before +0.6.0+, set
114
+ # Config#parser_use_deprecated_uidplus_data to +false+.
115
+ #
116
+ # CopyUIDData represents the ResponseCode#data that accompanies the
117
+ # +COPYUID+ {response code}[rdoc-ref:ResponseCode].
118
+ #
119
+ # A server that supports +UIDPLUS+ (or +IMAP4rev2+) should send CopyUIDData
120
+ # in response to
121
+ # copy[rdoc-ref:Net::IMAP#copy], {uid_copy}[rdoc-ref:Net::IMAP#uid_copy],
122
+ # move[rdoc-ref:Net::IMAP#copy], and {uid_move}[rdoc-ref:Net::IMAP#uid_move]
123
+ # commands---unless the destination mailbox reports +UIDNOTSTICKY+.
124
+ #
125
+ # Note that copy[rdoc-ref:Net::IMAP#copy] and
126
+ # {uid_copy}[rdoc-ref:Net::IMAP#uid_copy] return CopyUIDData in their
127
+ # TaggedResponse. But move[rdoc-ref:Net::IMAP#copy] and
128
+ # {uid_move}[rdoc-ref:Net::IMAP#uid_move] _should_ send CopyUIDData in an
129
+ # UntaggedResponse response before sending their TaggedResponse. However
130
+ # some servers do send CopyUIDData in the TaggedResponse for +MOVE+
131
+ # commands---this complies with the older +UIDPLUS+ specification but is
132
+ # discouraged by the +MOVE+ extension and disallowed by +IMAP4rev2+.
133
+ #
134
+ # == Required capability
135
+ # Requires either +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315]]
136
+ # or +IMAP4rev2+ capability.
137
+ class CopyUIDData < Data.define(:uidvalidity, :source_uids, :assigned_uids)
138
+ def initialize(uidvalidity:, source_uids:, assigned_uids:)
139
+ uidvalidity = Integer(uidvalidity)
140
+ source_uids = SequenceSet[source_uids]
141
+ assigned_uids = SequenceSet[assigned_uids]
142
+ NumValidator.ensure_nz_number(uidvalidity)
143
+ if source_uids.include_star? || assigned_uids.include_star?
144
+ raise DataFormatError, "uid-set cannot contain '*'"
145
+ elsif source_uids.count_with_duplicates != assigned_uids.count_with_duplicates
146
+ raise DataFormatError, "mismatched uid-set sizes for %s and %s" % [
147
+ source_uids, assigned_uids
148
+ ]
149
+ end
150
+ super
151
+ end
152
+
153
+ ##
154
+ # attr_reader: uidvalidity
155
+ #
156
+ # The +UIDVALIDITY+ of the destination mailbox (a nonzero unsigned 32 bit
157
+ # integer).
158
+
159
+ ##
160
+ # attr_reader: source_uids
161
+ #
162
+ # A SequenceSet with the original UIDs of the copied or moved messages.
163
+
164
+ ##
165
+ # attr_reader: assigned_uids
166
+ #
167
+ # A SequenceSet with the newly assigned UIDs of the copied or moved
168
+ # messages.
169
+
170
+ # Returns the number of messages that have been copied or moved.
171
+ # source_uids and the assigned_uids will both the same number of UIDs.
172
+ def size
173
+ assigned_uids.count_with_duplicates
174
+ end
175
+
176
+ # :call-seq:
177
+ # assigned_uid_for(source_uid) -> uid
178
+ # self[source_uid] -> uid
179
+ #
180
+ # Returns the UID in the destination mailbox for the message that was
181
+ # copied from +source_uid+ in the source mailbox.
182
+ #
183
+ # This is the reverse of #source_uid_for.
184
+ #
185
+ # Related: source_uid_for, each_uid_pair, uid_mapping
186
+ def assigned_uid_for(source_uid)
187
+ idx = source_uids.find_ordered_index(source_uid) and
188
+ assigned_uids.ordered_at(idx)
189
+ end
190
+ alias :[] :assigned_uid_for
191
+
192
+ # :call-seq:
193
+ # source_uid_for(assigned_uid) -> uid
194
+ #
195
+ # Returns the UID in the source mailbox for the message that was copied to
196
+ # +assigned_uid+ in the source mailbox.
197
+ #
198
+ # This is the reverse of #assigned_uid_for.
199
+ #
200
+ # Related: assigned_uid_for, each_uid_pair, uid_mapping
201
+ def source_uid_for(assigned_uid)
202
+ idx = assigned_uids.find_ordered_index(assigned_uid) and
203
+ source_uids.ordered_at(idx)
204
+ end
205
+
206
+ # Yields a pair of UIDs for each copied message. The first is the
207
+ # message's UID in the source mailbox and the second is the UID in the
208
+ # destination mailbox.
209
+ #
210
+ # Returns an enumerator when no block is given.
211
+ #
212
+ # Please note the warning on uid_mapping before calling methods like
213
+ # +to_h+ or +to_a+ on the returned enumerator.
214
+ #
215
+ # Related: uid_mapping, assigned_uid_for, source_uid_for
216
+ def each_uid_pair
217
+ return enum_for(__method__) unless block_given?
218
+ source_uids.each_ordered_number.lazy
219
+ .zip(assigned_uids.each_ordered_number.lazy) do
220
+ |source_uid, assigned_uid|
221
+ yield source_uid, assigned_uid
222
+ end
223
+ end
224
+ alias each_pair each_uid_pair
225
+ alias each each_uid_pair
226
+
227
+ # :call-seq: uid_mapping -> hash
228
+ #
229
+ # Returns a hash mapping each source UID to the newly assigned destination
230
+ # UID.
231
+ #
232
+ # <em>*Warning:*</em> The hash that is created may consume _much_ more
233
+ # memory than the data used to create it. When handling responses from an
234
+ # untrusted server, check #size before calling this method.
235
+ #
236
+ # Related: each_uid_pair, assigned_uid_for, source_uid_for
237
+ def uid_mapping
238
+ each_uid_pair.to_h
239
+ end
240
+
241
+ end
242
+
243
+ end
244
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Net
4
+ class IMAP < Protocol
5
+
6
+ # Net::IMAP::VanishedData represents the contents of a +VANISHED+ response,
7
+ # which is described by the
8
+ # {QRESYNC}[https://www.rfc-editor.org/rfc/rfc7162.html] extension.
9
+ # [{RFC7162 §3.2.10}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.2.10]].
10
+ #
11
+ # +VANISHED+ responses replace +EXPUNGE+ responses when either the
12
+ # {QRESYNC}[https://www.rfc-editor.org/rfc/rfc7162.html] or the
13
+ # {UIDONLY}[https://www.rfc-editor.org/rfc/rfc9586.html] extension has been
14
+ # enabled.
15
+ class VanishedData < Data.define(:uids, :earlier)
16
+
17
+ # Returns a new VanishedData object.
18
+ #
19
+ # * +uids+ will be converted by SequenceSet.[].
20
+ # * +earlier+ will be converted to +true+ or +false+
21
+ def initialize(uids:, earlier:)
22
+ uids = SequenceSet[uids]
23
+ earlier = !!earlier
24
+ super
25
+ end
26
+
27
+ ##
28
+ # :attr_reader: uids
29
+ #
30
+ # SequenceSet of UIDs that have been permanently removed from the mailbox.
31
+
32
+ ##
33
+ # :attr_reader: earlier
34
+ #
35
+ # +true+ when the response was caused by Net::IMAP#uid_fetch with
36
+ # <tt>vanished: true</tt> or Net::IMAP#select/Net::IMAP#examine with
37
+ # <tt>qresync: true</tt>.
38
+ #
39
+ # +false+ when the response is used to announce message removals within an
40
+ # already selected mailbox.
41
+
42
+ # rdoc doesn't handle attr aliases nicely. :(
43
+ alias earlier? earlier # :nodoc:
44
+ ##
45
+ # :attr_reader: earlier?
46
+ #
47
+ # Alias for #earlier.
48
+
49
+ # Returns an Array of all of the UIDs in #uids.
50
+ #
51
+ # See SequenceSet#numbers.
52
+ def to_a; uids.numbers end
53
+
54
+ end
55
+ end
56
+ end