Objects.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. /*
  2. * Copyright (c) 2021, Kyle Pereira <hey@xylepereira.me>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Function.h>
  8. #include <AK/Tuple.h>
  9. #include <AK/Variant.h>
  10. #include <LibCore/DateTime.h>
  11. #include <LibCore/EventReceiver.h>
  12. namespace IMAP {
  13. enum class CommandType {
  14. Append,
  15. Authenticate,
  16. Capability,
  17. Copy,
  18. Check,
  19. Close,
  20. Create,
  21. Delete,
  22. Examine,
  23. Expunge,
  24. Fetch,
  25. Idle,
  26. List,
  27. ListSub,
  28. Login,
  29. Logout,
  30. Noop,
  31. Rename,
  32. Search,
  33. Select,
  34. Status,
  35. Store,
  36. Subscribe,
  37. UIDCopy,
  38. UIDFetch,
  39. UIDSearch,
  40. UIDStore,
  41. Unsubscribe,
  42. };
  43. enum class MailboxFlag : unsigned {
  44. All = 1u << 0,
  45. Drafts = 1u << 1,
  46. Flagged = 1u << 2,
  47. HasChildren = 1u << 3,
  48. HasNoChildren = 1u << 4,
  49. Important = 1u << 5,
  50. Junk = 1u << 6,
  51. Marked = 1u << 7,
  52. NoInferiors = 1u << 8,
  53. NoSelect = 1u << 9,
  54. Sent = 1u << 10,
  55. Trash = 1u << 11,
  56. Unmarked = 1u << 12,
  57. Unknown = 1u << 13,
  58. };
  59. enum class ResponseType : unsigned {
  60. Capability = 1u << 0,
  61. List = 1u << 1,
  62. Exists = 1u << 2,
  63. Recent = 1u << 3,
  64. Flags = 1u << 4,
  65. UIDNext = 1u << 5,
  66. UIDValidity = 1u << 6,
  67. Unseen = 1u << 7,
  68. PermanentFlags = 1u << 8,
  69. Fetch = 1u << 9,
  70. Search = 1u << 10,
  71. ListSub = 1u << 11,
  72. Expunged = 1u << 12,
  73. Bye = 1u << 13,
  74. Status = 1u << 14
  75. };
  76. enum class FetchResponseType : unsigned {
  77. Body = 1u << 1,
  78. UID = 1u << 2,
  79. InternalDate = 1u << 3,
  80. Envelope = 1u << 4,
  81. Flags = 1u << 5,
  82. BodyStructure = 1u << 6,
  83. };
  84. enum class StatusItemType : unsigned {
  85. Recent = 1u << 1,
  86. UIDNext = 1u << 2,
  87. UIDValidity = 1u << 3,
  88. Unseen = 1u << 4,
  89. Messages = 1u << 5,
  90. };
  91. class Parser;
  92. class StatusItem {
  93. public:
  94. [[nodiscard]] unsigned status_items() const
  95. {
  96. return m_status_items;
  97. }
  98. [[nodiscard]] bool contains_status_item_type(StatusItemType type) const
  99. {
  100. return (static_cast<unsigned>(type) & m_status_items) != 0;
  101. }
  102. void add_status_item_type(StatusItemType type)
  103. {
  104. m_status_items |= static_cast<unsigned>(type);
  105. }
  106. void set_mailbox(ByteString&& mailbox) { m_mailbox = move(mailbox); }
  107. ByteString& mailbox() { return m_mailbox; }
  108. unsigned get(StatusItemType type) const
  109. {
  110. VERIFY(contains_status_item_type(type));
  111. switch (type) {
  112. case StatusItemType::Recent:
  113. return m_recent;
  114. case StatusItemType::UIDNext:
  115. return m_uid_next;
  116. case StatusItemType::UIDValidity:
  117. return m_uid_validity;
  118. case StatusItemType::Unseen:
  119. return m_unseen;
  120. case StatusItemType::Messages:
  121. return m_messages;
  122. }
  123. VERIFY_NOT_REACHED();
  124. }
  125. void set(StatusItemType type, unsigned value)
  126. {
  127. add_status_item_type(type);
  128. switch (type) {
  129. case StatusItemType::Recent:
  130. m_recent = value;
  131. break;
  132. case StatusItemType::UIDNext:
  133. m_uid_next = value;
  134. break;
  135. case StatusItemType::UIDValidity:
  136. m_uid_validity = value;
  137. break;
  138. case StatusItemType::Unseen:
  139. m_unseen = value;
  140. break;
  141. case StatusItemType::Messages:
  142. m_uid_next = value;
  143. break;
  144. }
  145. }
  146. private:
  147. unsigned m_status_items { 0 };
  148. unsigned m_messages { 0 };
  149. unsigned m_recent { 0 };
  150. unsigned m_uid_next { 0 };
  151. unsigned m_uid_validity { 0 };
  152. unsigned m_unseen { 0 };
  153. ByteString m_mailbox;
  154. };
  155. struct Address {
  156. ByteString name;
  157. ByteString source_route;
  158. ByteString mailbox;
  159. ByteString host;
  160. };
  161. struct Envelope {
  162. ByteString date; // Format of date not specified.
  163. ByteString subject;
  164. Vector<Address> from;
  165. Vector<Address> sender;
  166. Vector<Address> reply_to;
  167. Vector<Address> to;
  168. Vector<Address> cc;
  169. Vector<Address> bcc;
  170. ByteString in_reply_to;
  171. ByteString message_id;
  172. };
  173. class BodyStructure;
  174. struct BodyExtension {
  175. AK::Variant<Optional<ByteString>, unsigned, Vector<OwnPtr<BodyExtension>>> data;
  176. };
  177. struct MultiPartBodyStructureData {
  178. Optional<Tuple<ByteString, HashMap<ByteString, ByteString>>> disposition;
  179. Vector<OwnPtr<BodyStructure>> bodies;
  180. Vector<ByteString> langs;
  181. ByteString multipart_subtype;
  182. HashMap<ByteString, ByteString> params;
  183. ByteString location;
  184. Vector<BodyExtension> extensions;
  185. };
  186. struct BodyStructureData {
  187. ByteString type;
  188. ByteString subtype;
  189. ByteString id {};
  190. ByteString desc {};
  191. ByteString encoding;
  192. HashMap<ByteString, ByteString> fields;
  193. unsigned bytes { 0 };
  194. unsigned lines { 0 };
  195. Optional<Tuple<Envelope, NonnullOwnPtr<BodyStructure>>> contanied_message;
  196. ByteString md5 {};
  197. Optional<Tuple<ByteString, HashMap<ByteString, ByteString>>> disposition {};
  198. Optional<Vector<ByteString>> langs {};
  199. ByteString location {};
  200. Vector<BodyExtension> extensions {};
  201. };
  202. class BodyStructure {
  203. friend Parser;
  204. public:
  205. explicit BodyStructure(BodyStructureData&& data)
  206. : m_data(move(data))
  207. {
  208. }
  209. explicit BodyStructure(MultiPartBodyStructureData&& data)
  210. : m_data(move(data))
  211. {
  212. }
  213. AK::Variant<BodyStructureData, MultiPartBodyStructureData> const& data() const { return m_data; }
  214. private:
  215. AK::Variant<BodyStructureData, MultiPartBodyStructureData> m_data;
  216. };
  217. // Set -1 for '*' i.e highest possible value.
  218. struct Sequence {
  219. int start;
  220. int end;
  221. [[nodiscard]] ByteString serialize() const;
  222. };
  223. struct FetchCommand {
  224. enum class DataItemType {
  225. BodyStructure,
  226. Envelope,
  227. Flags,
  228. InternalDate,
  229. UID,
  230. PeekBody,
  231. BodySection
  232. };
  233. struct DataItem {
  234. enum class SectionType {
  235. Header,
  236. HeaderFields,
  237. HeaderFieldsNot,
  238. Text,
  239. Parts
  240. };
  241. struct Section {
  242. SectionType type;
  243. Optional<Vector<unsigned>> parts {};
  244. bool ends_with_mime {};
  245. Optional<Vector<ByteString>> headers {};
  246. [[nodiscard]] ByteString serialize() const;
  247. };
  248. DataItemType type;
  249. Optional<Section> section {};
  250. bool partial_fetch { false };
  251. int start { 0 };
  252. int octets { 0 };
  253. [[nodiscard]] ByteString serialize() const;
  254. };
  255. Vector<Sequence> sequence_set;
  256. Vector<DataItem> data_items;
  257. ByteString serialize();
  258. };
  259. struct Command {
  260. public:
  261. CommandType type;
  262. int tag;
  263. Vector<ByteString> args;
  264. };
  265. enum class ResponseStatus {
  266. Bad,
  267. No,
  268. OK,
  269. };
  270. struct ListItem {
  271. unsigned flags;
  272. ByteString reference;
  273. ByteString name;
  274. };
  275. class FetchResponseData {
  276. public:
  277. [[nodiscard]] unsigned response_type() const
  278. {
  279. return m_response_type;
  280. }
  281. [[nodiscard]] bool contains_response_type(FetchResponseType response_type) const
  282. {
  283. return (static_cast<unsigned>(response_type) & m_response_type) != 0;
  284. }
  285. void add_response_type(FetchResponseType type)
  286. {
  287. m_response_type |= static_cast<unsigned>(type);
  288. }
  289. void add_body_data(FetchCommand::DataItem&& data_item, ByteString&& body)
  290. {
  291. add_response_type(FetchResponseType::Body);
  292. m_bodies.append({ move(data_item), move(body) });
  293. }
  294. Vector<Tuple<FetchCommand::DataItem, ByteString>>& body_data()
  295. {
  296. VERIFY(contains_response_type(FetchResponseType::Body));
  297. return m_bodies;
  298. }
  299. void set_uid(unsigned uid)
  300. {
  301. add_response_type(FetchResponseType::UID);
  302. m_uid = uid;
  303. }
  304. [[nodiscard]] unsigned uid() const
  305. {
  306. VERIFY(contains_response_type(FetchResponseType::UID));
  307. return m_uid;
  308. }
  309. void set_internal_date(Core::DateTime time)
  310. {
  311. add_response_type(FetchResponseType::InternalDate);
  312. m_internal_date = time;
  313. }
  314. Core::DateTime& internal_date()
  315. {
  316. VERIFY(contains_response_type(FetchResponseType::InternalDate));
  317. return m_internal_date;
  318. }
  319. void set_envelope(Envelope&& envelope)
  320. {
  321. add_response_type(FetchResponseType::Envelope);
  322. m_envelope = move(envelope);
  323. }
  324. Envelope& envelope()
  325. {
  326. VERIFY(contains_response_type(FetchResponseType::Envelope));
  327. return m_envelope;
  328. }
  329. void set_flags(Vector<ByteString>&& flags)
  330. {
  331. add_response_type(FetchResponseType::Flags);
  332. m_flags = move(flags);
  333. }
  334. Vector<ByteString>& flags()
  335. {
  336. VERIFY(contains_response_type(FetchResponseType::Flags));
  337. return m_flags;
  338. }
  339. void set_body_structure(BodyStructure&& structure)
  340. {
  341. add_response_type(FetchResponseType::BodyStructure);
  342. m_body_structure = move(structure);
  343. }
  344. BodyStructure& body_structure()
  345. {
  346. VERIFY(contains_response_type(FetchResponseType::BodyStructure));
  347. return m_body_structure;
  348. }
  349. FetchResponseData()
  350. : m_body_structure(BodyStructureData {})
  351. {
  352. }
  353. private:
  354. Vector<ByteString> m_flags;
  355. Vector<Tuple<FetchCommand::DataItem, ByteString>> m_bodies;
  356. Core::DateTime m_internal_date;
  357. Envelope m_envelope;
  358. unsigned m_uid { 0 };
  359. unsigned m_response_type { 0 };
  360. BodyStructure m_body_structure;
  361. };
  362. ByteString serialize_astring(StringView string);
  363. struct SearchKey {
  364. public:
  365. // clang-format off
  366. struct All { };
  367. struct Answered { };
  368. struct Bcc { ByteString bcc; };
  369. struct Cc { ByteString cc; };
  370. struct Deleted { };
  371. struct Draft { };
  372. struct From { ByteString from; };
  373. struct Header { ByteString header; ByteString value; };
  374. struct Keyword { ByteString keyword; };
  375. struct Larger { unsigned number; };
  376. struct New { };
  377. struct Not { OwnPtr<SearchKey> operand; };
  378. struct Old { };
  379. struct On { Core::DateTime date; };
  380. struct Or { OwnPtr<SearchKey> lhs; OwnPtr<SearchKey> rhs; };
  381. struct Recent { };
  382. struct SearchKeys { Vector<OwnPtr<SearchKey>> keys; };
  383. struct Seen { };
  384. struct SentBefore { Core::DateTime date; };
  385. struct SentOn { Core::DateTime date; };
  386. struct SentSince { Core::DateTime date; };
  387. struct SequenceSet { Sequence sequence; };
  388. struct Since { Core::DateTime date; };
  389. struct Smaller { unsigned number; };
  390. struct Subject { ByteString subject; };
  391. struct Text { ByteString text; };
  392. struct To { ByteString to; };
  393. struct UID { unsigned uid; };
  394. struct Unanswered { };
  395. struct Undeleted { };
  396. struct Undraft { };
  397. struct Unkeyword { ByteString flag_keyword; };
  398. struct Unseen { };
  399. // clang-format on
  400. Variant<All, Answered, Bcc, Cc, Deleted, Draft, From, Header, Keyword,
  401. Larger, New, Not, Old, On, Or, Recent, SearchKeys, Seen, SentBefore, SentOn,
  402. SentSince, SequenceSet, Since, Smaller, Subject, Text, To, UID, Unanswered,
  403. Undeleted, Undraft, Unkeyword, Unseen>
  404. data;
  405. SearchKey(SearchKey&& other) noexcept
  406. : data(move(other.data))
  407. {
  408. }
  409. template<typename T>
  410. explicit SearchKey(T&& t)
  411. : data(forward<T>(t))
  412. {
  413. }
  414. SearchKey& operator=(SearchKey&& other) noexcept
  415. {
  416. if (this == &other) {
  417. return *this;
  418. }
  419. this->data = move(other.data);
  420. return *this;
  421. }
  422. [[nodiscard]] ByteString serialize() const;
  423. };
  424. class ResponseData {
  425. public:
  426. [[nodiscard]] unsigned response_type() const
  427. {
  428. return m_response_type;
  429. }
  430. ResponseData()
  431. : m_response_type(0)
  432. {
  433. }
  434. ResponseData(ResponseData&) = delete;
  435. ResponseData(ResponseData&&) = default;
  436. ResponseData& operator=(ResponseData const&) = delete;
  437. ResponseData& operator=(ResponseData&&) = default;
  438. [[nodiscard]] bool contains_response_type(ResponseType response_type) const
  439. {
  440. return (static_cast<unsigned>(response_type) & m_response_type) != 0;
  441. }
  442. void add_response_type(ResponseType response_type)
  443. {
  444. m_response_type = m_response_type | static_cast<unsigned>(response_type);
  445. }
  446. void add_capabilities(Vector<ByteString>&& capabilities)
  447. {
  448. m_capabilities = move(capabilities);
  449. add_response_type(ResponseType::Capability);
  450. }
  451. Vector<ByteString>& capabilities()
  452. {
  453. VERIFY(contains_response_type(ResponseType::Capability));
  454. return m_capabilities;
  455. }
  456. void add_list_item(ListItem&& item)
  457. {
  458. add_response_type(ResponseType::List);
  459. m_list_items.append(move(item));
  460. }
  461. Vector<ListItem>& list_items()
  462. {
  463. VERIFY(contains_response_type(ResponseType::List));
  464. return m_list_items;
  465. }
  466. void add_lsub_item(ListItem&& item)
  467. {
  468. add_response_type(ResponseType::List);
  469. m_lsub_items.append(move(item));
  470. }
  471. Vector<ListItem>& lsub_items()
  472. {
  473. VERIFY(contains_response_type(ResponseType::ListSub));
  474. return m_lsub_items;
  475. }
  476. void set_exists(unsigned exists)
  477. {
  478. add_response_type(ResponseType::Exists);
  479. m_exists = exists;
  480. }
  481. [[nodiscard]] unsigned exists() const
  482. {
  483. VERIFY(contains_response_type(ResponseType::Exists));
  484. return m_exists;
  485. }
  486. void set_recent(unsigned recent)
  487. {
  488. add_response_type(ResponseType::Recent);
  489. m_recent = recent;
  490. }
  491. [[nodiscard]] unsigned recent() const
  492. {
  493. VERIFY(contains_response_type(ResponseType::Recent));
  494. return m_recent;
  495. }
  496. void set_uid_next(unsigned uid_next)
  497. {
  498. add_response_type(ResponseType::UIDNext);
  499. m_uid_next = uid_next;
  500. }
  501. [[nodiscard]] unsigned uid_next() const
  502. {
  503. VERIFY(contains_response_type(ResponseType::UIDNext));
  504. return m_uid_next;
  505. }
  506. void set_uid_validity(unsigned uid_validity)
  507. {
  508. add_response_type(ResponseType::UIDValidity);
  509. m_uid_validity = uid_validity;
  510. }
  511. [[nodiscard]] unsigned uid_validity() const
  512. {
  513. VERIFY(contains_response_type(ResponseType::UIDValidity));
  514. return m_uid_validity;
  515. }
  516. void set_unseen(unsigned unseen)
  517. {
  518. add_response_type(ResponseType::Unseen);
  519. m_unseen = unseen;
  520. }
  521. [[nodiscard]] unsigned unseen() const
  522. {
  523. VERIFY(contains_response_type(ResponseType::Unseen));
  524. return m_unseen;
  525. }
  526. void set_flags(Vector<ByteString>&& flags)
  527. {
  528. m_response_type |= static_cast<unsigned>(ResponseType::Flags);
  529. m_flags = move(flags);
  530. }
  531. Vector<ByteString>& flags()
  532. {
  533. VERIFY(contains_response_type(ResponseType::Flags));
  534. return m_flags;
  535. }
  536. void set_permanent_flags(Vector<ByteString>&& flags)
  537. {
  538. add_response_type(ResponseType::PermanentFlags);
  539. m_permanent_flags = move(flags);
  540. }
  541. Vector<ByteString>& permanent_flags()
  542. {
  543. VERIFY(contains_response_type(ResponseType::PermanentFlags));
  544. return m_permanent_flags;
  545. }
  546. void add_fetch_response(unsigned message, FetchResponseData&& data)
  547. {
  548. add_response_type(ResponseType::Fetch);
  549. m_fetch_responses.append(Tuple<unsigned, FetchResponseData> { move(message), move(data) });
  550. }
  551. Vector<Tuple<unsigned, FetchResponseData>>& fetch_data()
  552. {
  553. VERIFY(contains_response_type(ResponseType::Fetch));
  554. return m_fetch_responses;
  555. }
  556. void set_search_results(Vector<unsigned>&& results)
  557. {
  558. add_response_type(ResponseType::Search);
  559. m_search_results = move(results);
  560. }
  561. Vector<unsigned>& search_results()
  562. {
  563. VERIFY(contains_response_type(ResponseType::Search));
  564. return m_search_results;
  565. }
  566. void add_expunged(unsigned message)
  567. {
  568. add_response_type(ResponseType::Expunged);
  569. m_expunged.append(message);
  570. }
  571. Vector<unsigned>& expunged()
  572. {
  573. VERIFY(contains_response_type(ResponseType::Expunged));
  574. return m_expunged;
  575. }
  576. void set_bye(Optional<ByteString> message)
  577. {
  578. add_response_type(ResponseType::Bye);
  579. m_bye_message = move(message);
  580. }
  581. Optional<ByteString>& bye_message()
  582. {
  583. VERIFY(contains_response_type(ResponseType::Bye));
  584. return m_bye_message;
  585. }
  586. void set_status(StatusItem&& status_item)
  587. {
  588. add_response_type(ResponseType::Status);
  589. m_status_item = move(status_item);
  590. }
  591. StatusItem& status_item()
  592. {
  593. return m_status_item;
  594. }
  595. private:
  596. unsigned m_response_type;
  597. Vector<ByteString> m_capabilities;
  598. Vector<ListItem> m_list_items;
  599. Vector<ListItem> m_lsub_items;
  600. Vector<unsigned> m_expunged;
  601. unsigned m_recent {};
  602. unsigned m_exists {};
  603. unsigned m_uid_next {};
  604. unsigned m_uid_validity {};
  605. unsigned m_unseen {};
  606. Vector<ByteString> m_permanent_flags;
  607. Vector<ByteString> m_flags;
  608. Vector<Tuple<unsigned, FetchResponseData>> m_fetch_responses;
  609. Vector<unsigned> m_search_results;
  610. Optional<ByteString> m_bye_message;
  611. StatusItem m_status_item;
  612. };
  613. enum class StoreMethod {
  614. Replace,
  615. Add,
  616. Remove
  617. };
  618. class SolidResponse {
  619. // Parser is allowed to set up fields
  620. friend class Parser;
  621. public:
  622. ResponseStatus status() { return m_status; }
  623. int tag() const { return m_tag; }
  624. ResponseData& data() { return m_data; }
  625. ByteString response_text() { return m_response_text; }
  626. SolidResponse()
  627. : SolidResponse(ResponseStatus::Bad, -1)
  628. {
  629. }
  630. SolidResponse(ResponseStatus status, int tag)
  631. : m_status(status)
  632. , m_tag(tag)
  633. , m_data(ResponseData())
  634. {
  635. }
  636. private:
  637. ResponseStatus m_status;
  638. ByteString m_response_text;
  639. unsigned m_tag;
  640. ResponseData m_data;
  641. };
  642. struct ContinueRequest {
  643. ByteString data;
  644. };
  645. using Response = Variant<SolidResponse, ContinueRequest>;
  646. }
  647. // An RFC 2822 message
  648. // https://datatracker.ietf.org/doc/html/rfc2822
  649. struct Message {
  650. ByteString data;
  651. };