net-imap 0.1.1 → 0.2.3

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.

Potentially problematic release.


This version of net-imap might be problematic. Click here for more details.

@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "errors"
4
+
5
+ module Net
6
+ class IMAP < Protocol
7
+
8
+ # Decode a string from modified UTF-7 format to UTF-8.
9
+ #
10
+ # UTF-7 is a 7-bit encoding of Unicode [UTF7]. IMAP uses a
11
+ # slightly modified version of this to encode mailbox names
12
+ # containing non-ASCII characters; see [IMAP] section 5.1.3.
13
+ #
14
+ # Net::IMAP does _not_ automatically encode and decode
15
+ # mailbox names to and from UTF-7.
16
+ def self.decode_utf7(s)
17
+ return s.gsub(/&([^-]+)?-/n) {
18
+ if $1
19
+ ($1.tr(",", "/") + "===").unpack1("m").encode(Encoding::UTF_8, Encoding::UTF_16BE)
20
+ else
21
+ "&"
22
+ end
23
+ }
24
+ end
25
+
26
+ # Encode a string from UTF-8 format to modified UTF-7.
27
+ def self.encode_utf7(s)
28
+ return s.gsub(/(&)|[^\x20-\x7e]+/) {
29
+ if $1
30
+ "&-"
31
+ else
32
+ base64 = [$&.encode(Encoding::UTF_16BE)].pack("m0")
33
+ "&" + base64.delete("=").tr("/", ",") + "-"
34
+ end
35
+ }.force_encoding("ASCII-8BIT")
36
+ end
37
+
38
+ # Formats +time+ as an IMAP-style date.
39
+ def self.format_date(time)
40
+ return time.strftime('%d-%b-%Y')
41
+ end
42
+
43
+ # Formats +time+ as an IMAP-style date-time.
44
+ def self.format_datetime(time)
45
+ return time.strftime('%d-%b-%Y %H:%M %z')
46
+ end
47
+
48
+ # Common validators of number and nz_number types
49
+ module NumValidator # :nodoc
50
+ module_function
51
+
52
+ # Check is passed argument valid 'number' in RFC 3501 terminology
53
+ def valid_number?(num)
54
+ # [RFC 3501]
55
+ # number = 1*DIGIT
56
+ # ; Unsigned 32-bit integer
57
+ # ; (0 <= n < 4,294,967,296)
58
+ num >= 0 && num < 4294967296
59
+ end
60
+
61
+ # Check is passed argument valid 'nz_number' in RFC 3501 terminology
62
+ def valid_nz_number?(num)
63
+ # [RFC 3501]
64
+ # nz-number = digit-nz *DIGIT
65
+ # ; Non-zero unsigned 32-bit integer
66
+ # ; (0 < n < 4,294,967,296)
67
+ num != 0 && valid_number?(num)
68
+ end
69
+
70
+ # Check is passed argument valid 'mod_sequence_value' in RFC 4551 terminology
71
+ def valid_mod_sequence_value?(num)
72
+ # mod-sequence-value = 1*DIGIT
73
+ # ; Positive unsigned 64-bit integer
74
+ # ; (mod-sequence)
75
+ # ; (1 <= n < 18,446,744,073,709,551,615)
76
+ num >= 1 && num < 18446744073709551615
77
+ end
78
+
79
+ # Ensure argument is 'number' or raise DataFormatError
80
+ def ensure_number(num)
81
+ return if valid_number?(num)
82
+
83
+ msg = "number must be unsigned 32-bit integer: #{num}"
84
+ raise DataFormatError, msg
85
+ end
86
+
87
+ # Ensure argument is 'nz_number' or raise DataFormatError
88
+ def ensure_nz_number(num)
89
+ return if valid_nz_number?(num)
90
+
91
+ msg = "nz_number must be non-zero unsigned 32-bit integer: #{num}"
92
+ raise DataFormatError, msg
93
+ end
94
+
95
+ # Ensure argument is 'mod_sequence_value' or raise DataFormatError
96
+ def ensure_mod_sequence_value(num)
97
+ return if valid_mod_sequence_value?(num)
98
+
99
+ msg = "mod_sequence_value must be unsigned 64-bit integer: #{num}"
100
+ raise DataFormatError, msg
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Net
4
+ class IMAP < Protocol
5
+
6
+ # Superclass of IMAP errors.
7
+ class Error < StandardError
8
+ end
9
+
10
+ # Error raised when data is in the incorrect format.
11
+ class DataFormatError < Error
12
+ end
13
+
14
+ # Error raised when a response from the server is non-parseable.
15
+ class ResponseParseError < Error
16
+ end
17
+
18
+ # Superclass of all errors used to encapsulate "fail" responses
19
+ # from the server.
20
+ class ResponseError < Error
21
+
22
+ # The response that caused this error
23
+ attr_accessor :response
24
+
25
+ def initialize(response)
26
+ @response = response
27
+
28
+ super @response.data.text
29
+ end
30
+
31
+ end
32
+
33
+ # Error raised upon a "NO" response from the server, indicating
34
+ # that the client command could not be completed successfully.
35
+ class NoResponseError < ResponseError
36
+ end
37
+
38
+ # Error raised upon a "BAD" response from the server, indicating
39
+ # that the client command violated the IMAP protocol, or an internal
40
+ # server failure has occurred.
41
+ class BadResponseError < ResponseError
42
+ end
43
+
44
+ # Error raised upon a "BYE" response from the server, indicating
45
+ # that the client is not being allowed to login, or has been timed
46
+ # out due to inactivity.
47
+ class ByeResponseError < ResponseError
48
+ end
49
+
50
+ # Error raised upon an unknown response from the server.
51
+ class UnknownResponseError < ResponseError
52
+ end
53
+
54
+ RESPONSE_ERRORS = Hash.new(ResponseError)
55
+ RESPONSE_ERRORS["NO"] = NoResponseError
56
+ RESPONSE_ERRORS["BAD"] = BadResponseError
57
+
58
+ end
59
+ end
@@ -0,0 +1,234 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Net
4
+ class IMAP < Protocol
5
+
6
+ # -------------------------------------------------------------------------
7
+ # :section: Message Flags: system flags
8
+ #
9
+ # A message has a list of zero or more named tokens, known as "flags",
10
+ # associated with it. A flag is set by its addition to this list and is
11
+ # cleared by its removal. There are two types of flags in IMAP4rev2: system
12
+ # flags and keywords. A flag of either type can be permanent or
13
+ # session-only.
14
+ #
15
+ # A "system flag" is a message flag name that is predefined in the IMAP
16
+ # specification and begins with "\". +Net::IMAP+ returns all system flags
17
+ # as symbols, without the "\" prefix.
18
+ #
19
+ # The descriptions here were copied from the IMAP4rev2 specification:
20
+ # [RFC-9051 § 2.3.2](https://www.rfc-editor.org/rfc/rfc9051.html#section-2.3.2)
21
+ #
22
+ # See [RFC-3501 § 2.3.2](https://www.rfc-editor.org/rfc/rfc3501.html#section-2.3.2)
23
+ # for a description of the flags message attribute and system flag semantics
24
+ # in IMAP4rev1.
25
+ # -------------------------------------------------------------------------
26
+
27
+ # Flag indicating a message has been read.
28
+ SEEN = :Seen
29
+
30
+ # Flag indicating a message has been answered.
31
+ ANSWERED = :Answered
32
+
33
+ # A message flag indicating a message has been flagged for special or urgent
34
+ # attention.
35
+ #
36
+ # Also a mailbox special use attribute, which indicates that this mailbox
37
+ # presents all messages marked in some way as "important". When this
38
+ # special use is supported, it is likely to represent a virtual mailbox
39
+ # collecting messages (from other mailboxes) that are marked with the
40
+ # "\Flagged" message flag.
41
+ FLAGGED = :Flagged
42
+
43
+ # Flag indicating a message has been marked for deletion. This
44
+ # will occur when the mailbox is closed or expunged.
45
+ DELETED = :Deleted
46
+
47
+ # Flag indicating a message is only a draft or work-in-progress version.
48
+ DRAFT = :Draft
49
+
50
+ # Flag indicating that the message is "recent," meaning that this
51
+ # session is the first session in which the client has been notified
52
+ # of this message.
53
+ #
54
+ # This flag was defined by
55
+ # IMAP4rev1 [RFC-3501](https://www.rfc-editor.org/rfc/rfc3501.html),
56
+ # and has been deprecated by
57
+ # IMAP4rev2 [RFC-9051](https://www.rfc-editor.org/rfc/rfc9051.html).
58
+ RECENT = :Recent
59
+
60
+ # -------------------------------------------------------------------------
61
+ # :section: Mailbox Name Attributes, Base attributes
62
+ # Mailbox name attributes will be returned in LIST responses. Base
63
+ # attributes must be returned according to the server's capabilities.
64
+ #
65
+ # IMAP4 specifies that all mailbox name attributes, including future
66
+ # extensions, begin with "\". +Net::IMAP+ returns all mailbox attributes as
67
+ # symbols, without the "\" prefix.
68
+ #
69
+ # The descriptions here were copied from the IMAP4rev2 specification:
70
+ # [RFC9051 § 7.3.1](https://www.rfc-editor.org/rfc/rfc9051.html#section-7.3.1).
71
+ #
72
+ # Other mailbox name attributes can be found in the [IANA IMAP Mailbox Name
73
+ # Attributes registry](https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml)].
74
+ # -------------------------------------------------------------------------
75
+
76
+ # The "\NonExistent" attribute indicates that a mailbox name does not refer
77
+ # to an existing mailbox. Note that this attribute is not meaningful by
78
+ # itself, as mailbox names that match the canonical LIST pattern but don't
79
+ # exist must not be returned unless one of the two conditions listed below
80
+ # is also satisfied:
81
+ #
82
+ # 1. The mailbox name also satisfies the selection criteria (for example,
83
+ # it is subscribed and the "SUBSCRIBED" selection option has been
84
+ # specified).
85
+ #
86
+ # 2. "RECURSIVEMATCH" has been specified, and the mailbox name has at least
87
+ # one descendant mailbox name that does not match the LIST pattern and
88
+ # does match the selection criteria.
89
+ #
90
+ # In practice, this means that the "\NonExistent" attribute is usually
91
+ # returned with one or more of "\Subscribed", "\Remote", "\HasChildren", or
92
+ # the CHILDINFO extended data item.
93
+ #
94
+ # The client must treat the presence of the \NonExistent attribute as if the
95
+ # \NoSelect attribute was also sent by the server
96
+ NONEXISTENT = :NonExistent
97
+
98
+ # Mailbox attribute indicating it is not possible for any child levels of
99
+ # hierarchy to exist under this name; no child levels exist now and none can
100
+ # be created in the future children.
101
+ #
102
+ # The client must treat the presence of the \NoInferiors attribute as if the
103
+ # \HasNoChildren attribute was also sent by the server
104
+ NOINFERIORS = :Noinferiors
105
+
106
+ # Mailbox attribute indicating it is not possible to use this name as a
107
+ # selectable mailbox.
108
+ NOSELECT = :Noselect
109
+
110
+ # The presence of this attribute indicates that the mailbox has child
111
+ # mailboxes. A server SHOULD NOT set this attribute if there are child
112
+ # mailboxes and the user does not have permission to access any of them. In
113
+ # this case, \HasNoChildren SHOULD be used. In many cases, however, a server
114
+ # may not be able to efficiently compute whether a user has access to any
115
+ # child mailboxes. Note that even though the \HasChildren attribute for a
116
+ # mailbox must be correct at the time of processing the mailbox, a client
117
+ # must be prepared to deal with a situation when a mailbox is marked with
118
+ # the \HasChildren attribute, but no child mailbox appears in the response
119
+ # to the LIST command. This might happen, for example, due to child
120
+ # mailboxes being deleted or made inaccessible to the user (using access
121
+ # control) by another client before the server is able to list them.
122
+ #
123
+ # It is an error for the server to return both a \HasChildren and a
124
+ # \HasNoChildren attribute in the same LIST response. A client that
125
+ # encounters a LIST response with both \HasChildren and \HasNoChildren
126
+ # attributes present should act as if both are absent in the LIST response.
127
+ HAS_CHILDREN = :HasChildren
128
+
129
+ # The presence of this attribute indicates that the mailbox has NO child
130
+ # mailboxes that are accessible to the currently authenticated user.
131
+ #
132
+ # It is an error for the server to return both a \HasChildren and a
133
+ # \HasNoChildren attribute in the same LIST response. A client that
134
+ # encounters a LIST response with both \HasChildren and \HasNoChildren
135
+ # attributes present should act as if both are absent in the LIST response.
136
+ #
137
+ # Note: the \HasNoChildren attribute should not be confused with the
138
+ # \NoInferiors attribute, which indicates that no child mailboxes exist now
139
+ # and none can be created in the future.
140
+ HAS_NO_CHILDREN = :HasNoChildren
141
+
142
+ # The mailbox has been marked "interesting" by the server; the mailbox
143
+ # probably contains messages that have been added since the last time the
144
+ # mailbox was selected.
145
+ #
146
+ # If it is not feasible for the server to determine whether or not the
147
+ # mailbox is "interesting", the server SHOULD NOT send either \Marked or
148
+ # \Unmarked. The server MUST NOT send more than one of \Marked, \Unmarked,
149
+ # and \Noselect for a single mailbox, and it MAY send none of these.
150
+ MARKED = :Marked
151
+
152
+ # The mailbox does not contain any additional messages since the last time
153
+ # the mailbox was selected.
154
+ #
155
+ # If it is not feasible for the server to determine whether or not the
156
+ # mailbox is "interesting", the server SHOULD NOT send either \Marked or
157
+ # \Unmarked. The server MUST NOT send more than one of \Marked, \Unmarked,
158
+ # and \Noselect for a single mailbox, and it MAY send none of these.
159
+ UNMARKED = :Unmarked
160
+
161
+ # The mailbox name was subscribed to using the SUBSCRIBE command.
162
+ SUBSCRIBED = :Subscribed
163
+
164
+ # The mailbox is a remote mailbox.
165
+ REMOTE = :Remove
166
+
167
+ # -------------------------------------------------------------------------
168
+ # :section: Mailbox Name Attributes, Special Use
169
+ # Mailbox name attributes will be returned in LIST responses. In addition
170
+ # to the base mailbox name attributes defined above, an IMAP server MAY also
171
+ # include any or all of the following attributes that denote "role" (or
172
+ # "special-use") of a mailbox. These attributes are included along with base
173
+ # attributes defined above. A given mailbox may have none, one, or more than
174
+ # one of these attributes. In some cases, a special use is advice to a
175
+ # client about what to put in that mailbox. In other cases, it's advice to a
176
+ # client about what to expect to find there.
177
+ #
178
+ # IMAP4 specifies that all mailbox name attributes, including future
179
+ # extensions, begin with "\". +Net::IMAP+ returns all mailbox attributes as
180
+ # symbols, without the "\" prefix.
181
+ #
182
+ # The descriptions here were copied from the IMAP4rev2 specification:
183
+ # [RFC-9051 § 7.3.1](https://www.rfc-editor.org/rfc/rfc9051.html#section-7.3.1).
184
+ #
185
+ # Other mailbox name attributes can be found in the [IANA IMAP Mailbox Name
186
+ # Attributes registry](https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml)].
187
+ # -------------------------------------------------------------------------
188
+
189
+ # Mailbox attribute indicating that this mailbox presents all messages in
190
+ # the user's message store. Implementations MAY omit some messages, such as,
191
+ # perhaps, those in \Trash and \Junk. When this special use is supported, it
192
+ # is almost certain to represent a virtual mailbox
193
+ ALL = :All
194
+
195
+ # Mailbox attribute indicating that this mailbox is used to archive
196
+ # messages. The meaning of an "archival" mailbox is server dependent;
197
+ # typically, it will be used to get messages out of the inbox, or otherwise
198
+ # keep them out of the user's way, while still making them accessible
199
+ ARCHIVE = :Archive
200
+
201
+ # Mailbox attribute indicating that this mailbox is used to hold draft
202
+ # messages -- typically, messages that are being composed but have not yet
203
+ # been sent. In some server implementations, this might be a virtual
204
+ # mailbox, containing messages from other mailboxes that are marked with the
205
+ # "\Draft" message flag. Alternatively, this might just be advice that a
206
+ # client put drafts here
207
+ DRAFTS = :Drafts
208
+
209
+ # FLAGGED is defined with the system flags section.
210
+
211
+ # Mailbox attribute indicating that this mailbox is where messages deemed to
212
+ # be junk mail are held. Some server implementations might put messages here
213
+ # automatically. Alternatively, this might just be advice to a client-side
214
+ # spam filter.
215
+ JUNK = :Junk
216
+
217
+ # Mailbox attribute indicating that this mailbox is used to hold copies of
218
+ # messages that have been sent. Some server implementations might put
219
+ # messages here automatically. Alternatively, this might just be advice that
220
+ # a client save sent messages here.
221
+ SENT = :Sent
222
+
223
+ # Mailbox attribute indicating that this mailbox is used to hold messages
224
+ # that have been deleted or marked for deletion. In some server
225
+ # implementations, this might be a virtual mailbox, containing messages from
226
+ # other mailboxes that are marked with the "\Deleted" message flag.
227
+ # Alternatively, this might just be advice that a client that chooses not to
228
+ # use the IMAP "\Deleted" model should use as its trash location. In server
229
+ # implementations that strictly expect the IMAP "\Deleted" model, this
230
+ # special use is likely not to be supported.
231
+ TRASH = :Trash
232
+
233
+ end
234
+ end