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.

@@ -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, or an enumerable containing any of these.
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
- ENUMABLE = ->{ _1.respond_to?(:each) && _1.respond_to?(:empty?) }
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 ENUMABLE then obj.flat_map { input_to_tuples _1 }
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
- # Integer.try_convert(input) || # ruby 3.1+
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
- case num
1420
- when Integer, /\A[1-9]\d*\z/ then num = Integer(num)
1421
- else raise DataFormatError, "%p is not a valid nz-number" % [num]
1422
- end
1423
- NumValidator.ensure_nz_number(num)
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.4.17"
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(mechanism, *creds,
1342
- sasl_ir: config.sasl_ir,
1343
- **props, &callback)
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
- # if imap.capability? "LOGINDISABLED"
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", MessageSet.new(uid_set))
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, MessageSet.new(set), attr, mod)
2975
+ send_command(cmd, SequenceSet.new(set), attr, mod)
2994
2976
  else
2995
- send_command(cmd, MessageSet.new(set), attr)
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 = [MessageSet.new(set)]
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, MessageSet.new(set), mailbox)
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
- MessageSet.new(i)
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(">= 2.7.3")
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.17
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-13 00:00:00.000000000 Z
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: 2.7.3
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: []