@@ -462,6 +462,9 @@ module Net
462462 # +LITERAL-+, and +SPECIAL-USE+.</em>
463463 #
464464 # ==== RFC2087: +QUOTA+
465+ # +NOTE:+ Only the +STORAGE+ quota resource type is currently supported.
466+ # - Obsoleted by <tt>QUOTA=RES-*</tt> [RFC9208[https://www.rfc-editor.org/rfc/rfc9208]],
467+ # although the commands are backward compatible.
465468 # - #getquota: returns the resource usage and limits for a quota root
466469 # - #getquotaroot: returns the list of quota roots for a mailbox, as well as
467470 # their resource usage and limits.
@@ -578,6 +581,16 @@ module Net
578581 # See FetchData#emailid and FetchData#emailid.
579582 # - Updates #status with support for the +MAILBOXID+ status attribute.
580583 #
584+ # ==== RFC9208: <tt>QUOTA=RES-*</tt>
585+ # +NOTE:+ Only the +STORAGE+ quota resource type is currently supported.
586+ # - Obsoletes the +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
587+ # extension and provides strict semantics for different resource types.
588+ # - #getquota: returns the resource usage and limits for a quota root
589+ # - #getquotaroot: returns the list of quota roots for a mailbox, as well as
590+ # their resource usage and limits.
591+ # - #setquota: sets the resource limits for a given quota root.
592+ # - Updates #status with <tt>"DELETED"</tt> and +DELETED-STORAGE+ attributes.
593+ #
581594 # ==== RFC9394: +PARTIAL+
582595 # - Updates #search, #uid_search with the +PARTIAL+ return option which adds
583596 # ESearchResult#partial return data.
@@ -698,13 +711,12 @@ module Net
698711 #
699712 # === \IMAP Extensions
700713 #
701- # [QUOTA[https://www.rfc-editor.org/rfc/rfc9208 ]]::
702- # Melnikov, A ., "IMAP QUOTA Extension ", RFC 9208 , DOI 10.17487/RFC9208 ,
703- # March 2022 , <https://www.rfc-editor.org/info/rfc9208 >.
714+ # [QUOTA[https://www.rfc-editor.org/rfc/rfc2087 ]]::
715+ # Myers, J ., "IMAP4 QUOTA extension ", RFC 2087 , DOI 10.17487/RFC2087 ,
716+ # January 1997 , <https://www.rfc-editor.org/info/rfc2087 >.
704717 #
705- # <em>Note: obsoletes</em>
706- # RFC-2087[https://www.rfc-editor.org/rfc/rfc2087]<em> (January 1997)</em>.
707- # <em>Net::IMAP does not fully support the RFC9208 updates yet.</em>
718+ # *NOTE*: _obsoleted_ by RFC9208[https://www.rfc-editor.org/rfc/rfc9208]
719+ # (March 2022).
708720 # [IDLE[https://www.rfc-editor.org/rfc/rfc2177]]::
709721 # Leiba, B., "IMAP4 IDLE command", RFC 2177, DOI 10.17487/RFC2177,
710722 # June 1997, <https://www.rfc-editor.org/info/rfc2177>.
@@ -756,6 +768,11 @@ module Net
756768 # Gondwana, B., Ed., "IMAP Extension for Object Identifiers",
757769 # RFC 8474, DOI 10.17487/RFC8474, September 2018,
758770 # <https://www.rfc-editor.org/info/rfc8474>.
771+ # [{QUOTA=RES-*}[https://www.rfc-editor.org/rfc/rfc9208]]::
772+ # Melnikov, A., "IMAP QUOTA Extension", RFC 9208, DOI 10.17487/RFC9208,
773+ # March 2022, <https://www.rfc-editor.org/info/rfc9208>.
774+ #
775+ # Obsoletes RFC2087[https://www.rfc-editor.org/rfc/rfc2087].
759776 # [PARTIAL[https://www.rfc-editor.org/info/rfc9394]]::
760777 # Melnikov, A., Achuthan, A., Nagulakonda, V., and L. Alves,
761778 # "IMAP PARTIAL Extension for Paged SEARCH and FETCH", RFC 9394,
@@ -769,6 +786,7 @@ module Net
769786 #
770787 # === IANA registries
771788 # * {IMAP Capabilities}[http://www.iana.org/assignments/imap4-capabilities]
789+ # * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
772790 # * {IMAP Response Codes}[https://www.iana.org/assignments/imap-response-codes/imap-response-codes.xhtml]
773791 # * {IMAP Mailbox Name Attributes}[https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml]
774792 # * {IMAP and JMAP Keywords}[https://www.iana.org/assignments/imap-jmap-keywords/imap-jmap-keywords.xhtml]
@@ -779,8 +797,8 @@ module Net
779797 # * {GSSAPI/Kerberos/SASL Service Names}[https://www.iana.org/assignments/gssapi-service-names/gssapi-service-names.xhtml]:
780798 # +imap+
781799 # * {Character sets}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
800+ #
782801 # ==== For currently unsupported features:
783- # * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
784802 # * {LIST-EXTENDED options and responses}[https://www.iana.org/assignments/imap-list-extended/imap-list-extended.xhtml]
785803 # * {IMAP METADATA Server Entry and Mailbox Entry Registries}[https://www.iana.org/assignments/imap-metadata/imap-metadata.xhtml]
786804 # * {IMAP ANNOTATE Extension Entries and Attributes}[https://www.iana.org/assignments/imap-annotate-extension/imap-annotate-extension.xhtml]
@@ -1828,12 +1846,18 @@ def xlist(refname, mailbox)
18281846 # to both admin and user. If this mailbox exists, it returns an array
18291847 # containing objects of type MailboxQuotaRoot and MailboxQuota.
18301848 #
1849+ # *NOTE:* Currently, Net::IMAP only supports +QUOTA+ responses with a single
1850+ # resource type. This is usually +STORAGE+, but you may need to verify this
1851+ # with UntaggedResponse#raw_data.
1852+ #
18311853 # Related: #getquota, #setquota, MailboxQuotaRoot, MailboxQuota
18321854 #
18331855 # ==== Capabilities
18341856 #
1835- # The server's capabilities must include +QUOTA+
1836- # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1857+ # Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1858+ # capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1859+ # {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1860+ # resource type.
18371861 def getquotaroot ( mailbox )
18381862 synchronize do
18391863 send_command ( "GETQUOTAROOT" , mailbox )
@@ -1845,41 +1869,59 @@ def getquotaroot(mailbox)
18451869 end
18461870
18471871 # Sends a {GETQUOTA command [RFC2087 §4.2]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.2]
1848- # along with specified +mailbox+. If this mailbox exists, then an array
1849- # containing a MailboxQuota object is returned. This command is generally
1850- # only available to server admin.
1872+ # for the +quota_root+. If this quota root exists, then an array
1873+ # containing a MailboxQuota object is returned.
1874+ #
1875+ # The names of quota roots that are applicable to a particular mailbox can
1876+ # be discovered with #getquotaroot.
1877+ #
1878+ # *NOTE:* Currently, Net::IMAP only supports +QUOTA+ responses with a single
1879+ # resource type. This is usually +STORAGE+, but you may need to verify this
1880+ # with UntaggedResponse#raw_data.
18511881 #
18521882 # Related: #getquotaroot, #setquota, MailboxQuota
18531883 #
18541884 # ==== Capabilities
18551885 #
1856- # The server's capabilities must include +QUOTA+
1857- # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1858- def getquota ( mailbox )
1886+ # Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1887+ # capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1888+ # {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1889+ # resource type.
1890+ def getquota ( quota_root )
18591891 synchronize do
1860- send_command ( "GETQUOTA" , mailbox )
1892+ send_command ( "GETQUOTA" , quota_root )
18611893 clear_responses ( "QUOTA" )
18621894 end
18631895 end
18641896
18651897 # Sends a {SETQUOTA command [RFC2087 §4.1]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.1]
1866- # along with the specified +mailbox+ and +quota+. If +quota+ is nil, then
1867- # +quota+ will be unset for that mailbox. Typically one needs to be logged
1868- # in as a server admin for this to work.
1898+ # along with the specified +quota_root+ and +storage_limit+. If
1899+ # +storage_limit+ is +nil+, resource limits are unset for that quota root.
1900+ # If +storage_limit+ is a number, it sets the +STORAGE+ resource limit.
1901+ #
1902+ # imap.setquota "#user/alice", 100
1903+ # imap.getquota "#user/alice"
1904+ # # => [#<struct Net::IMAP::MailboxQuota mailbox="#user/alice" usage=54 quota=100>]
1905+ #
1906+ # Typically one needs to be logged in as a server admin for this to work.
1907+ #
1908+ # *NOTE:* Currently, Net::IMAP only supports setting +STORAGE+ quota limits.
18691909 #
18701910 # Related: #getquota, #getquotaroot
18711911 #
18721912 # ==== Capabilities
18731913 #
1874- # The server's capabilities must include +QUOTA+
1875- # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1876- def setquota ( mailbox , quota )
1877- if quota . nil?
1878- data = '()'
1914+ # Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1915+ # capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1916+ # {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1917+ # resource type.
1918+ def setquota ( quota_root , storage_limit )
1919+ if storage_limit . nil?
1920+ list = [ ]
18791921 else
1880- data = '( STORAGE ' + quota . to_s + ')'
1922+ list = [ " STORAGE" , Integer ( storage_limit ) ]
18811923 end
1882- send_command ( "SETQUOTA" , mailbox , RawData . new ( data ) )
1924+ send_command ( "SETQUOTA" , quota_root , list )
18831925 end
18841926
18851927 # Sends a {SETACL command [RFC4314 §3.1]}[https://www.rfc-editor.org/rfc/rfc4314#section-3.1]
@@ -1986,7 +2028,10 @@ def lsub(refname, mailbox)
19862028 # <tt>STATUS=SIZE</tt>
19872029 # {[RFC8483]}[https://www.rfc-editor.org/rfc/rfc8483.html].
19882030 #
1989- # +DELETED+ requires the server's capabilities to include +IMAP4rev2+.
2031+ # +DELETED+ must be supported when the server's capabilities includes
2032+ # +IMAP4rev2+.
2033+ # or <tt>QUOTA=RES-MESSAGES</tt>
2034+ # {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208.html].
19902035 #
19912036 # +HIGHESTMODSEQ+ requires the server's capabilities to include +CONDSTORE+
19922037 # {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
@@ -2267,11 +2312,11 @@ def uid_expunge(uid_set)
22672312 # Encoded as an \IMAP date (see ::encode_date).
22682313 #
22692314 # [When +criteria+ is a String]
2270- # +criteria+ will be sent directly to the server <em>without any
2271- # validation or encoding </em>.
2315+ # +criteria+ will be sent to the server <em>with minimal validation and no
2316+ # encoding or formatting </em>.
22722317 #
2273- # <em>*WARNING:* This is vulnerable to injection attacks when external
2274- # inputs are used.</em>
2318+ # <em>*WARNING:* Although CRLF is prohibited, this is vulnerable to other
2319+ # types of attribute injection attack if unvetted user input is used.</em>
22752320 #
22762321 # ==== Supported return options
22772322 #
@@ -2592,6 +2637,13 @@ def uid_search(...)
25922637 #
25932638 # +attr+ is a list of attributes to fetch; see FetchStruct documentation for
25942639 # a list of supported attributes.
2640+ # >>>
2641+ # When +attr+ is a String, it will be sent <em>with minimal validation and
2642+ # no encoding or formatting</em>. When +attr+ is an Array, each String in
2643+ # +attr+ will be sent this way.
2644+ #
2645+ # <em>*WARNING:* Although CRLF is prohibited, this is vulnerable to other
2646+ # types of attribute injection attack if unvetted user input is used.</em>
25952647 #
25962648 # +changedsince+ is an optional integer mod-sequence. It limits results to
25972649 # messages with a mod-sequence greater than +changedsince+.
@@ -3712,7 +3764,7 @@ def fetch_internal(cmd, set, attr, mod = nil, partial: nil, changedsince: nil)
37123764 end
37133765
37143766 def store_internal ( cmd , set , attr , flags , unchangedsince : nil )
3715- attr = RawData . new ( attr ) if attr . instance_of? ( String )
3767+ attr = Atom . new ( attr ) if attr . instance_of? ( String )
37163768 args = [ SequenceSet . new ( set ) ]
37173769 args << [ "UNCHANGEDSINCE" , Integer ( unchangedsince ) ] if unchangedsince
37183770 args << attr << flags
0 commit comments