diff options
author | x-yl <kylepereira@mail.com> | 2021-06-02 18:53:08 +0400 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-06-11 23:58:28 +0430 |
commit | 9174fabf05b60abd5435992842db0aff8f615ab9 (patch) | |
tree | a5b26378cd9f3d2b6ae72f57c0e59f1280eba74a | |
parent | 16995dc3d98e9d3036baae6535a0c7f2fb970d24 (diff) | |
download | serenity-9174fabf05b60abd5435992842db0aff8f615ab9.zip |
LibIMAP: Support for remaining IMAP commands
These include APPEND, AUTHENTICATE, CHECK, CLOSE, EXAMINE, EXPUNGE,
LSUB, SUBSCRIBE, UNSUBSCRIBE
-rw-r--r-- | Userland/Libraries/LibIMAP/Client.cpp | 46 | ||||
-rw-r--r-- | Userland/Libraries/LibIMAP/Client.h | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibIMAP/Objects.h | 36 | ||||
-rw-r--r-- | Userland/Libraries/LibIMAP/Parser.cpp | 6 |
4 files changed, 93 insertions, 0 deletions
diff --git a/Userland/Libraries/LibIMAP/Client.cpp b/Userland/Libraries/LibIMAP/Client.cpp index 37bf28f46a..4f0c2e795d 100644 --- a/Userland/Libraries/LibIMAP/Client.cpp +++ b/Userland/Libraries/LibIMAP/Client.cpp @@ -146,6 +146,22 @@ static ReadonlyBytes command_byte_buffer(CommandType command) return "UID SEARCH"sv.bytes(); case CommandType::Append: return "APPEND"sv.bytes(); + case CommandType::Examine: + return "EXAMINE"sv.bytes(); + case CommandType::ListSub: + return "LSUB"sv.bytes(); + case CommandType::Expunge: + return "EXPUNGE"sv.bytes(); + case CommandType::Subscribe: + return "SUBSCRIBE"sv.bytes(); + case CommandType::Unsubscribe: + return "UNSUBSCRIBE"sv.bytes(); + case CommandType::Authenticate: + return "AUTHENTICATE"sv.bytes(); + case CommandType::Check: + return "CHECK"sv.bytes(); + case CommandType::Close: + return "CLOSE"sv.bytes(); case CommandType::Rename: return "RENAME"sv.bytes(); case CommandType::Status: @@ -203,6 +219,14 @@ RefPtr<Promise<Optional<SolidResponse>>> Client::list(StringView reference_name, return cast_promise<SolidResponse>(send_command(move(command))); } +RefPtr<Promise<Optional<SolidResponse>>> Client::lsub(StringView reference_name, StringView mailbox) +{ + auto command = Command { CommandType::ListSub, m_current_command, + { String::formatted("\"{}\"", reference_name), + String::formatted("\"{}\"", mailbox) } }; + return cast_promise<SolidResponse>(send_command(move(command))); +} + RefPtr<Promise<Optional<SolidResponse>>> Client::fetch(FetchCommand request, bool uid) { auto command = Command { uid ? CommandType::UIDFetch : CommandType::Fetch, m_current_command, { request.serialize() } }; @@ -266,6 +290,13 @@ void Client::send_next_command() send_raw(buffer); m_expecting_response = true; } + +RefPtr<Promise<Optional<SolidResponse>>> Client::examine(StringView string) +{ + auto command = Command { CommandType::Examine, m_current_command, { string } }; + return cast_promise<SolidResponse>(send_command(move(command))); +} + RefPtr<Promise<Optional<SolidResponse>>> Client::create_mailbox(StringView name) { auto command = Command { CommandType::Create, m_current_command, { name } }; @@ -393,6 +424,21 @@ RefPtr<Promise<Optional<SolidResponse>>> Client::append(StringView mailbox, Mess return cast_promise<SolidResponse>(response_promise); } +RefPtr<Promise<Optional<SolidResponse>>> Client::subscribe(StringView mailbox) +{ + auto command = Command { CommandType::Subscribe, m_current_command, { mailbox } }; + return cast_promise<SolidResponse>(send_command(move(command))); +} +RefPtr<Promise<Optional<SolidResponse>>> Client::unsubscribe(StringView mailbox) +{ + auto command = Command { CommandType::Unsubscribe, m_current_command, { mailbox } }; + return cast_promise<SolidResponse>(send_command(move(command))); +} +RefPtr<Promise<Optional<Response>>> Client::authenticate(StringView method) +{ + auto command = Command { CommandType::Authenticate, m_current_command, { method } }; + return send_command(move(command)); +} RefPtr<Promise<Optional<SolidResponse>>> Client::rename(StringView from, StringView to) { auto command = Command { CommandType::Rename, m_current_command, { from, to } }; diff --git a/Userland/Libraries/LibIMAP/Client.h b/Userland/Libraries/LibIMAP/Client.h index a1b2f46c1b..b61ad1d609 100644 --- a/Userland/Libraries/LibIMAP/Client.h +++ b/Userland/Libraries/LibIMAP/Client.h @@ -23,14 +23,19 @@ public: void send_raw(StringView data); RefPtr<Promise<Optional<SolidResponse>>> login(StringView username, StringView password); RefPtr<Promise<Optional<SolidResponse>>> list(StringView reference_name, StringView mailbox_name); + RefPtr<Promise<Optional<SolidResponse>>> lsub(StringView reference_name, StringView mailbox_name); RefPtr<Promise<Optional<SolidResponse>>> select(StringView string); + RefPtr<Promise<Optional<SolidResponse>>> examine(StringView string); RefPtr<Promise<Optional<SolidResponse>>> search(Optional<String> charset, Vector<SearchKey>&& search_keys, bool uid); RefPtr<Promise<Optional<SolidResponse>>> fetch(FetchCommand request, bool uid); RefPtr<Promise<Optional<SolidResponse>>> store(StoreMethod, Sequence, bool silent, Vector<String> const& flags, bool uid); RefPtr<Promise<Optional<SolidResponse>>> copy(Sequence sequence_set, StringView name, bool uid); RefPtr<Promise<Optional<SolidResponse>>> create_mailbox(StringView name); RefPtr<Promise<Optional<SolidResponse>>> delete_mailbox(StringView name); + RefPtr<Promise<Optional<SolidResponse>>> subscribe(StringView mailbox); + RefPtr<Promise<Optional<SolidResponse>>> unsubscribe(StringView mailbox); RefPtr<Promise<Optional<SolidResponse>>> rename(StringView from, StringView to); + RefPtr<Promise<Optional<Response>>> authenticate(StringView method); RefPtr<Promise<Optional<ContinueRequest>>> idle(); RefPtr<Promise<Optional<SolidResponse>>> finish_idle(); RefPtr<Promise<Optional<SolidResponse>>> status(StringView mailbox, Vector<StatusItemType> const& types); diff --git a/Userland/Libraries/LibIMAP/Objects.h b/Userland/Libraries/LibIMAP/Objects.h index 9f9b926caa..127c825674 100644 --- a/Userland/Libraries/LibIMAP/Objects.h +++ b/Userland/Libraries/LibIMAP/Objects.h @@ -18,13 +18,19 @@ namespace IMAP { enum class CommandType { Append, + Authenticate, Capability, Copy, + Check, + Close, Create, Delete, + Examine, + Expunge, Fetch, Idle, List, + ListSub, Login, Logout, Noop, @@ -33,10 +39,12 @@ enum class CommandType { Select, Status, Store, + Subscribe, UIDCopy, UIDFetch, UIDSearch, UIDStore, + Unsubscribe, }; enum class MailboxFlag : unsigned { @@ -68,6 +76,8 @@ enum class ResponseType : unsigned { PermanentFlags = 1u << 8, Fetch = 1u << 9, Search = 1u << 10, + ListSub = 1u << 11, + Expunged = 1u << 12, Bye = 1u << 13, Status = 1u << 14 }; @@ -532,6 +542,18 @@ public: return m_list_items; } + void add_lsub_item(ListItem&& item) + { + add_response_type(ResponseType::List); + m_lsub_items.append(move(item)); + } + + Vector<ListItem>& lsub_items() + { + VERIFY(contains_response_type(ResponseType::ListSub)); + return m_lsub_items; + } + void set_exists(unsigned exists) { add_response_type(ResponseType::Exists); @@ -640,6 +662,18 @@ public: return m_search_results; } + void add_expunged(unsigned message) + { + add_response_type(ResponseType::Expunged); + m_expunged.append(message); + } + + Vector<unsigned>& expunged() + { + VERIFY(contains_response_type(ResponseType::Expunged)); + return m_expunged; + } + void set_bye(Optional<String> message) { add_response_type(ResponseType::Bye); @@ -668,6 +702,8 @@ private: Vector<String> m_capabilities; Vector<ListItem> m_list_items; + Vector<ListItem> m_lsub_items; + Vector<unsigned> m_expunged; unsigned m_recent {}; unsigned m_exists {}; diff --git a/Userland/Libraries/LibIMAP/Parser.cpp b/Userland/Libraries/LibIMAP/Parser.cpp index c00383f711..b2b06ecfe3 100644 --- a/Userland/Libraries/LibIMAP/Parser.cpp +++ b/Userland/Libraries/LibIMAP/Parser.cpp @@ -140,6 +140,9 @@ void Parser::parse_untagged() } else if (data_type.matches("FETCH")) { auto fetch_response = parse_fetch_response(); m_response.data().add_fetch_response(number.value(), move(fetch_response)); + } else if (data_type.matches("EXPUNGE")) { + m_response.data().add_expunged(number.value()); + consume("\r\n"); } return; } @@ -149,6 +152,9 @@ void Parser::parse_untagged() } else if (try_consume("LIST")) { auto item = parse_list_item(); m_response.data().add_list_item(move(item)); + } else if (try_consume("LSUB")) { + auto item = parse_list_item(); + m_response.data().add_lsub_item(move(item)); } else if (try_consume("FLAGS")) { consume(" "); auto flags = parse_list(+[](StringView x) { return String(x); }); |