aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Matrix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Matrix.cpp')
-rw-r--r--src/plugins/Matrix.cpp82
1 files changed, 30 insertions, 52 deletions
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 8b819a2..d709f73 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -54,7 +54,7 @@ namespace QuickMedia {
char url[512];
if(next_batch.empty())
- snprintf(url, sizeof(url), "%s/_matrix/client/r0/sync?timeout=0", homeserver.c_str());
+ snprintf(url, sizeof(url), "%s/_matrix/client/r0/sync?timeout=0&full_state=true", homeserver.c_str());
else
snprintf(url, sizeof(url), "%s/_matrix/client/r0/sync?timeout=30000&since=%s", homeserver.c_str(), next_batch.c_str());
@@ -831,38 +831,6 @@ namespace QuickMedia {
return post_message(room_id, filename, content_uri_json.asString(), MessageType::IMAGE, &message_info);
}
- static std::string parse_login_error_response(std::string json_str) {
- if(json_str.empty())
- return "Unknown error";
-
- Json::Value json_root;
- Json::CharReaderBuilder json_builder;
- std::unique_ptr<Json::CharReader> json_reader(json_builder.newCharReader());
- std::string json_errors;
- if(!json_reader->parse(&json_str[0], &json_str[json_str.size()], &json_root, &json_errors)) {
- fprintf(stderr, "Matrix login response parse error: %s\n", json_errors.c_str());
- return json_str;
- }
-
- if(!json_root.isObject())
- return json_str;
-
- const Json::Value &errcode_json = json_root["errcode"];
- // Yes, matrix is retarded and returns M_NOT_JSON error code when username/password is incorrect
- if(errcode_json.isString() && strcmp(errcode_json.asCString(), "M_NOT_JSON") == 0)
- return "Incorrect username or password";
-
- return json_str;
- }
-
- // Returns empty string on error
- static std::string extract_homeserver_from_user_id(const std::string &user_id) {
- size_t index = user_id.find(':');
- if(index == std::string::npos)
- return "";
- return user_id.substr(index + 1);
- }
-
PluginResult Matrix::login(const std::string &username, const std::string &password, const std::string &homeserver, std::string &err_msg) {
// TODO: this is deprecated but not all homeservers have the new version.
// When this is removed from future version then switch to the new login method (identifier object with the username).
@@ -882,8 +850,8 @@ namespace QuickMedia {
};
std::string server_response;
- if(download_to_string(homeserver + "/_matrix/client/r0/login", server_response, std::move(additional_args), use_tor, true) != DownloadResult::OK) {
- err_msg = parse_login_error_response(std::move(server_response));
+ if(download_to_string(homeserver + "/_matrix/client/r0/login", server_response, std::move(additional_args), use_tor, true, false) != DownloadResult::OK) {
+ err_msg = std::move(server_response);
return PluginResult::NET_ERR;
}
@@ -904,6 +872,12 @@ namespace QuickMedia {
return PluginResult::ERR;
}
+ const Json::Value &error = json_root["error"];
+ if(error.isString()) {
+ err_msg = error.asString();
+ return PluginResult::ERR;
+ }
+
const Json::Value &user_id_json = json_root["user_id"];
if(!user_id_json.isString()) {
err_msg = "Failed to parse matrix login response";
@@ -916,17 +890,13 @@ namespace QuickMedia {
return PluginResult::ERR;
}
- std::string user_id = user_id_json.asString();
+ // Use the user-provided homeserver instead of the one the server tells us about, otherwise this wont work with a proxy
+ // such as pantalaimon
+ json_root["homeserver"] = homeserver;
- std::string homeserver_response = extract_homeserver_from_user_id(user_id);
- if(homeserver_response.empty()) {
- err_msg = "Missing homeserver in user id, user id: " + user_id;
- return PluginResult::ERR;
- }
-
- this->user_id = std::move(user_id);
+ this->user_id = user_id_json.asString();
this->access_token = access_token_json.asString();
- this->homeserver = "https://" + std::move(homeserver_response);
+ this->homeserver = homeserver;
// TODO: Handle well_known field. The spec says clients SHOULD handle it if its provided
@@ -956,6 +926,13 @@ namespace QuickMedia {
if(download_to_string(homeserver + "/_matrix/client/r0/logout", server_response, std::move(additional_args), use_tor, true) != DownloadResult::OK)
return PluginResult::NET_ERR;
+ // Make sure all fields are reset here!
+ room_data_by_id.clear();
+ user_id.clear();
+ access_token.clear();
+ homeserver.clear();
+ next_batch.clear();
+
return PluginResult::OK;
}
@@ -991,29 +968,30 @@ namespace QuickMedia {
return PluginResult::ERR;
}
- std::string user_id = user_id_json.asString();
- std::string access_token = access_token_json.asString();
-
- std::string homeserver = extract_homeserver_from_user_id(user_id);
- if(homeserver.empty()) {
- fprintf(stderr, "Missing homeserver in user id, user id: %s\n", user_id.c_str());
+ const Json::Value &homeserver_json = json_root["homeserver"];
+ if(!homeserver_json.isString()) {
+ fprintf(stderr, "Failed to parse matrix cached session response\n");
return PluginResult::ERR;
}
+ std::string user_id = user_id_json.asString();
+ std::string access_token = access_token_json.asString();
+ std::string homeserver = homeserver_json.asString();
+
std::vector<CommandArg> additional_args = {
{ "-H", "Authorization: Bearer " + access_token }
};
std::string server_response;
// We want to make any request to the server that can verify that our token is still valid, doesn't matter which call
- if(download_to_string("https://" + homeserver + "/_matrix/client/r0/account/whoami", server_response, std::move(additional_args), use_tor, true) != DownloadResult::OK) {
+ if(download_to_string(homeserver + "/_matrix/client/r0/account/whoami", server_response, std::move(additional_args), use_tor, true) != DownloadResult::OK) {
fprintf(stderr, "Matrix whoami response: %s\n", server_response.c_str());
return PluginResult::NET_ERR;
}
this->user_id = std::move(user_id);
this->access_token = std::move(access_token);
- this->homeserver = "https://" + homeserver;
+ this->homeserver = std::move(homeserver);
return PluginResult::OK;
}