summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorx-yl <kylepereira@mail.com>2021-06-02 18:53:08 +0400
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-06-11 23:58:28 +0430
commit9174fabf05b60abd5435992842db0aff8f615ab9 (patch)
treea5b26378cd9f3d2b6ae72f57c0e59f1280eba74a
parent16995dc3d98e9d3036baae6535a0c7f2fb970d24 (diff)
downloadserenity-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.cpp46
-rw-r--r--Userland/Libraries/LibIMAP/Client.h5
-rw-r--r--Userland/Libraries/LibIMAP/Objects.h36
-rw-r--r--Userland/Libraries/LibIMAP/Parser.cpp6
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); });