net-imap 0.4.17 → 0.5.0
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.
- checksums.yaml +4 -4
- data/Gemfile +7 -1
- data/lib/net/imap/authenticators.rb +2 -2
- data/lib/net/imap/command_data.rb +11 -0
- data/lib/net/imap/config.rb +36 -10
- data/lib/net/imap/data_encoding.rb +3 -3
- data/lib/net/imap/deprecated_client_options.rb +6 -3
- data/lib/net/imap/errors.rb +6 -0
- data/lib/net/imap/response_data.rb +6 -93
- data/lib/net/imap/response_parser.rb +5 -17
- data/lib/net/imap/sasl/authentication_exchange.rb +52 -20
- data/lib/net/imap/sasl/authenticators.rb +8 -4
- data/lib/net/imap/sasl/client_adapter.rb +77 -26
- data/lib/net/imap/sasl/cram_md5_authenticator.rb +1 -1
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +213 -51
- data/lib/net/imap/sasl/login_authenticator.rb +2 -1
- data/lib/net/imap/sasl/protocol_adapters.rb +60 -4
- data/lib/net/imap/sasl.rb +6 -3
- data/lib/net/imap/sasl_adapter.rb +0 -1
- data/lib/net/imap/sequence_set.rb +11 -19
- data/lib/net/imap.rb +28 -46
- data/net-imap.gemspec +1 -1
- metadata +6 -6
@@ -14,13 +14,6 @@ module Net
|
|
14
14
|
# receive a SequenceSet as an argument, for example IMAP#search, IMAP#fetch,
|
15
15
|
# and IMAP#store.
|
16
16
|
#
|
17
|
-
# == EXPERIMENTAL API
|
18
|
-
#
|
19
|
-
# SequenceSet is currently experimental. Only two methods, ::[] and
|
20
|
-
# #valid_string, are considered stable. Although the API isn't expected to
|
21
|
-
# change much, any other methods may be removed or changed without
|
22
|
-
# deprecation.
|
23
|
-
#
|
24
17
|
# == Creating sequence sets
|
25
18
|
#
|
26
19
|
# SequenceSet.new with no arguments creates an empty sequence set. Note
|
@@ -37,7 +30,8 @@ module Net
|
|
37
30
|
#
|
38
31
|
# SequenceSet.new may receive a single optional argument: a non-zero 32 bit
|
39
32
|
# unsigned integer, a range, a <tt>sequence-set</tt> formatted string,
|
40
|
-
# another sequence set,
|
33
|
+
# another sequence set, a Set (containing only numbers or <tt>*</tt>), or an
|
34
|
+
# Array containing any of these (array inputs may be nested).
|
41
35
|
#
|
42
36
|
# set = Net::IMAP::SequenceSet.new(1)
|
43
37
|
# set.valid_string #=> "1"
|
@@ -289,8 +283,7 @@ module Net
|
|
289
283
|
private_constant :STAR_INT, :STARS
|
290
284
|
|
291
285
|
COERCIBLE = ->{ _1.respond_to? :to_sequence_set }
|
292
|
-
|
293
|
-
private_constant :COERCIBLE, :ENUMABLE
|
286
|
+
private_constant :COERCIBLE
|
294
287
|
|
295
288
|
class << self
|
296
289
|
|
@@ -1272,7 +1265,8 @@ module Net
|
|
1272
1265
|
when *STARS, Integer, Range then [input_to_tuple(obj)]
|
1273
1266
|
when String then str_to_tuples obj
|
1274
1267
|
when SequenceSet then obj.tuples
|
1275
|
-
when
|
1268
|
+
when Set then obj.map { [to_tuple_int(_1)] * 2 }
|
1269
|
+
when Array then obj.flat_map { input_to_tuples _1 }
|
1276
1270
|
when nil then []
|
1277
1271
|
else
|
1278
1272
|
raise DataFormatError,
|
@@ -1285,8 +1279,7 @@ module Net
|
|
1285
1279
|
# String, Set, Array, or... any type of object.
|
1286
1280
|
def input_try_convert(input)
|
1287
1281
|
SequenceSet.try_convert(input) ||
|
1288
|
-
|
1289
|
-
input.respond_to?(:to_int) && Integer(input.to_int) ||
|
1282
|
+
Integer.try_convert(input) ||
|
1290
1283
|
String.try_convert(input) ||
|
1291
1284
|
input
|
1292
1285
|
end
|
@@ -1416,12 +1409,11 @@ module Net
|
|
1416
1409
|
end
|
1417
1410
|
|
1418
1411
|
def nz_number(num)
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
num
|
1412
|
+
String === num && !/\A[1-9]\d*\z/.match?(num) and
|
1413
|
+
raise DataFormatError, "%p is not a valid nz-number" % [num]
|
1414
|
+
NumValidator.ensure_nz_number Integer num
|
1415
|
+
rescue TypeError # To catch errors from Integer()
|
1416
|
+
raise DataFormatError, $!.message
|
1425
1417
|
end
|
1426
1418
|
|
1427
1419
|
# intentionally defined after the class implementation
|
data/lib/net/imap.rb
CHANGED
@@ -719,7 +719,7 @@ module Net
|
|
719
719
|
# * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
|
720
720
|
#
|
721
721
|
class IMAP < Protocol
|
722
|
-
VERSION = "0.
|
722
|
+
VERSION = "0.5.0"
|
723
723
|
|
724
724
|
# Aliases for supported capabilities, to be used with the #enable command.
|
725
725
|
ENABLE_ALIASES = {
|
@@ -946,9 +946,6 @@ module Net
|
|
946
946
|
@sock = tcp_socket(@host, @port)
|
947
947
|
start_tls_session if ssl_ctx
|
948
948
|
start_imap_connection
|
949
|
-
|
950
|
-
# DEPRECATED: to remove in next version
|
951
|
-
@client_thread = Thread.current
|
952
949
|
end
|
953
950
|
|
954
951
|
# Returns true after the TLS negotiation has completed and the remote
|
@@ -956,11 +953,6 @@ module Net
|
|
956
953
|
# but peer verification was disabled.
|
957
954
|
def tls_verified?; @tls_verified end
|
958
955
|
|
959
|
-
def client_thread # :nodoc:
|
960
|
-
warn "Net::IMAP#client_thread is deprecated and will be removed soon."
|
961
|
-
@client_thread
|
962
|
-
end
|
963
|
-
|
964
956
|
# Disconnects from the server.
|
965
957
|
#
|
966
958
|
# Related: #logout, #logout!
|
@@ -1244,6 +1236,9 @@ module Net
|
|
1244
1236
|
# +SASL-IR+ capability, below). Defaults to the #config value for
|
1245
1237
|
# {sasl_ir}[rdoc-ref:Config#sasl_ir], which defaults to +true+.
|
1246
1238
|
#
|
1239
|
+
# The +registry+ kwarg can be used to select the mechanism implementation
|
1240
|
+
# from a custom registry. See SASL.authenticator and SASL::Authenticators.
|
1241
|
+
#
|
1247
1242
|
# All other arguments are forwarded to the registered SASL authenticator for
|
1248
1243
|
# the requested mechanism. <em>The documentation for each individual
|
1249
1244
|
# mechanism must be consulted for its specific parameters.</em>
|
@@ -1338,29 +1333,9 @@ module Net
|
|
1338
1333
|
# Previously cached #capabilities will be cleared when this method
|
1339
1334
|
# completes. If the TaggedResponse to #authenticate includes updated
|
1340
1335
|
# capabilities, they will be cached.
|
1341
|
-
def authenticate(
|
1342
|
-
|
1343
|
-
|
1344
|
-
mechanism = mechanism.to_s.tr("_", "-").upcase
|
1345
|
-
authenticator = SASL.authenticator(mechanism, *creds, **props, &callback)
|
1346
|
-
cmdargs = ["AUTHENTICATE", mechanism]
|
1347
|
-
if sasl_ir && capable?("SASL-IR") && auth_capable?(mechanism) &&
|
1348
|
-
authenticator.respond_to?(:initial_response?) &&
|
1349
|
-
authenticator.initial_response?
|
1350
|
-
response = authenticator.process(nil)
|
1351
|
-
cmdargs << (response.empty? ? "=" : [response].pack("m0"))
|
1352
|
-
end
|
1353
|
-
result = send_command_with_continuations(*cmdargs) {|data|
|
1354
|
-
challenge = data.unpack1("m")
|
1355
|
-
response = authenticator.process challenge
|
1356
|
-
[response].pack("m0")
|
1357
|
-
}
|
1358
|
-
if authenticator.respond_to?(:done?) && !authenticator.done?
|
1359
|
-
logout!
|
1360
|
-
raise SASL::AuthenticationIncomplete, result
|
1361
|
-
end
|
1362
|
-
@capabilities = capabilities_from_resp_code result
|
1363
|
-
result
|
1336
|
+
def authenticate(*args, sasl_ir: config.sasl_ir, **props, &callback)
|
1337
|
+
sasl_adapter.authenticate(*args, sasl_ir: sasl_ir, **props, &callback)
|
1338
|
+
.tap { @capabilities = capabilities_from_resp_code _1 }
|
1364
1339
|
end
|
1365
1340
|
|
1366
1341
|
# Sends a {LOGIN command [IMAP4rev1 §6.2.3]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.3]
|
@@ -1380,13 +1355,9 @@ module Net
|
|
1380
1355
|
# ===== Capabilities
|
1381
1356
|
#
|
1382
1357
|
# An IMAP client MUST NOT call #login when the server advertises the
|
1383
|
-
# +LOGINDISABLED+ capability.
|
1384
|
-
#
|
1385
|
-
#
|
1386
|
-
# raise "Remote server has disabled the login command"
|
1387
|
-
# else
|
1388
|
-
# imap.login username, password
|
1389
|
-
# end
|
1358
|
+
# +LOGINDISABLED+ capability. By default, Net::IMAP will raise a
|
1359
|
+
# LoginDisabledError when that capability is present. See
|
1360
|
+
# Config#enforce_logindisabled.
|
1390
1361
|
#
|
1391
1362
|
# Server capabilities may change after #starttls, #login, and #authenticate.
|
1392
1363
|
# Cached capabilities _must_ be invalidated after this method completes.
|
@@ -1394,6 +1365,9 @@ module Net
|
|
1394
1365
|
# ResponseCode.
|
1395
1366
|
#
|
1396
1367
|
def login(user, password)
|
1368
|
+
if enforce_logindisabled? && capability?("LOGINDISABLED")
|
1369
|
+
raise LoginDisabledError
|
1370
|
+
end
|
1397
1371
|
send_command("LOGIN", user, password)
|
1398
1372
|
.tap { @capabilities = capabilities_from_resp_code _1 }
|
1399
1373
|
end
|
@@ -1950,7 +1924,7 @@ module Net
|
|
1950
1924
|
# [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]].
|
1951
1925
|
def uid_expunge(uid_set)
|
1952
1926
|
synchronize do
|
1953
|
-
send_command("UID EXPUNGE",
|
1927
|
+
send_command("UID EXPUNGE", SequenceSet.new(uid_set))
|
1954
1928
|
clear_responses("EXPUNGE")
|
1955
1929
|
end
|
1956
1930
|
end
|
@@ -2608,7 +2582,7 @@ module Net
|
|
2608
2582
|
when :raise
|
2609
2583
|
raise ArgumentError, RESPONSES_DEPRECATION_MSG
|
2610
2584
|
when :warn
|
2611
|
-
warn(RESPONSES_DEPRECATION_MSG, uplevel: 1)
|
2585
|
+
warn(RESPONSES_DEPRECATION_MSG, uplevel: 1, category: :deprecated)
|
2612
2586
|
when :frozen_dup
|
2613
2587
|
synchronize {
|
2614
2588
|
responses = @responses.transform_values(&:freeze)
|
@@ -2957,6 +2931,14 @@ module Net
|
|
2957
2931
|
end
|
2958
2932
|
end
|
2959
2933
|
|
2934
|
+
def enforce_logindisabled?
|
2935
|
+
if config.enforce_logindisabled == :when_capabilities_cached
|
2936
|
+
capabilities_cached?
|
2937
|
+
else
|
2938
|
+
config.enforce_logindisabled
|
2939
|
+
end
|
2940
|
+
end
|
2941
|
+
|
2960
2942
|
def search_internal(cmd, keys, charset)
|
2961
2943
|
if keys.instance_of?(String)
|
2962
2944
|
keys = [RawData.new(keys)]
|
@@ -2990,9 +2972,9 @@ module Net
|
|
2990
2972
|
synchronize do
|
2991
2973
|
clear_responses("FETCH")
|
2992
2974
|
if mod
|
2993
|
-
send_command(cmd,
|
2975
|
+
send_command(cmd, SequenceSet.new(set), attr, mod)
|
2994
2976
|
else
|
2995
|
-
send_command(cmd,
|
2977
|
+
send_command(cmd, SequenceSet.new(set), attr)
|
2996
2978
|
end
|
2997
2979
|
clear_responses("FETCH")
|
2998
2980
|
end
|
@@ -3000,7 +2982,7 @@ module Net
|
|
3000
2982
|
|
3001
2983
|
def store_internal(cmd, set, attr, flags, unchangedsince: nil)
|
3002
2984
|
attr = RawData.new(attr) if attr.instance_of?(String)
|
3003
|
-
args = [
|
2985
|
+
args = [SequenceSet.new(set)]
|
3004
2986
|
args << ["UNCHANGEDSINCE", Integer(unchangedsince)] if unchangedsince
|
3005
2987
|
args << attr << flags
|
3006
2988
|
synchronize do
|
@@ -3011,7 +2993,7 @@ module Net
|
|
3011
2993
|
end
|
3012
2994
|
|
3013
2995
|
def copy_internal(cmd, set, mailbox)
|
3014
|
-
send_command(cmd,
|
2996
|
+
send_command(cmd, SequenceSet.new(set), mailbox)
|
3015
2997
|
end
|
3016
2998
|
|
3017
2999
|
def sort_internal(cmd, sort_keys, search_keys, charset)
|
@@ -3042,7 +3024,7 @@ module Net
|
|
3042
3024
|
keys.collect! do |i|
|
3043
3025
|
case i
|
3044
3026
|
when -1, Range, Array
|
3045
|
-
|
3027
|
+
SequenceSet.new(i)
|
3046
3028
|
else
|
3047
3029
|
i
|
3048
3030
|
end
|
data/net-imap.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.summary = %q{Ruby client api for Internet Message Access Protocol}
|
17
17
|
spec.description = %q{Ruby client api for Internet Message Access Protocol}
|
18
18
|
spec.homepage = "https://github.com/ruby/net-imap"
|
19
|
-
spec.required_ruby_version = Gem::Requirement.new(">=
|
19
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.1.0")
|
20
20
|
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
21
21
|
|
22
22
|
spec.metadata["homepage_uri"] = spec.homepage
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-imap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
8
|
- nicholas a. evans
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-10-
|
12
|
+
date: 2024-10-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-protocol
|
@@ -110,7 +110,7 @@ metadata:
|
|
110
110
|
homepage_uri: https://github.com/ruby/net-imap
|
111
111
|
source_code_uri: https://github.com/ruby/net-imap
|
112
112
|
changelog_uri: https://github.com/ruby/net-imap/releases
|
113
|
-
post_install_message:
|
113
|
+
post_install_message:
|
114
114
|
rdoc_options: []
|
115
115
|
require_paths:
|
116
116
|
- lib
|
@@ -118,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
118
|
requirements:
|
119
119
|
- - ">="
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
version:
|
121
|
+
version: 3.1.0
|
122
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
123
|
requirements:
|
124
124
|
- - ">="
|
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
126
|
version: '0'
|
127
127
|
requirements: []
|
128
128
|
rubygems_version: 3.5.16
|
129
|
-
signing_key:
|
129
|
+
signing_key:
|
130
130
|
specification_version: 4
|
131
131
|
summary: Ruby client api for Internet Message Access Protocol
|
132
132
|
test_files: []
|