Skip to content

Commit

Permalink
fix(confighttp): do not return 200 on errors
Browse files Browse the repository at this point in the history
  • Loading branch information
ReenigneArcher committed Jan 9, 2025
1 parent 6a233cb commit 78b043a
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 32 deletions.
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ basic authentication with the admin username and password.
## POST /api/apps
@copydoc confighttp::saveApp()

## DELETE /api/apps{index}
## DELETE /api/apps/{index}
@copydoc confighttp::deleteApp()

## POST /api/covers/upload
Expand Down
112 changes: 81 additions & 31 deletions src/confighttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,65 @@ namespace confighttp {
return true;
}

/**
* @brief Send a 404 Not Found response.
* @param response The original response object.
* @param request The original request object.
*/
void
not_found(resp_https_t response, [[maybe_unused]] req_https_t request) {
pt::ptree tree;

Check warning on line 152 in src/confighttp.cpp

View check run for this annotation

Codecov / codecov/patch

src/confighttp.cpp#L151-L152

Added lines #L151 - L152 were not covered by tests
tree.put("status_code", 404);
tree.put("error", "Not Found");

std::ostringstream data;
pt::write_json(data, tree);

SimpleWeb::CaseInsensitiveMultimap headers;
headers.emplace("Content-Type", "application/json");

response->write(SimpleWeb::StatusCode::client_error_not_found, data.str(), headers);
}

/**
* @brief Send a 400 Bad Request response.
* @param response The original response object.
* @param request The original request object.
*/
void
bad_request_default(resp_https_t response, [[maybe_unused]] req_https_t request) {
pt::ptree tree;

Check warning on line 172 in src/confighttp.cpp

View check run for this annotation

Codecov / codecov/patch

src/confighttp.cpp#L171-L172

Added lines #L171 - L172 were not covered by tests
tree.put("status_code", 400);
tree.put("error", "Invalid Request");

std::ostringstream data;
pt::write_json(data, tree);

SimpleWeb::CaseInsensitiveMultimap headers;
headers.emplace("Content-Type", "application/json");

response->write(SimpleWeb::StatusCode::client_error_bad_request, data.str(), headers);
}

/**
* @brief Send a 400 Bad Request response.
* @param response The original response object.
* @param request The original request object.
* @param error_message The error message to include in the response.
*/
void
not_found(resp_https_t response, req_https_t request) {
bad_request(resp_https_t response, [[maybe_unused]] req_https_t request, const std::string &error_message) {

Check warning on line 192 in src/confighttp.cpp

View check run for this annotation

Codecov / codecov/patch

src/confighttp.cpp#L192

Added line #L192 was not covered by tests
pt::ptree tree;
tree.put("root.<xmlattr>.status_code", 404);
tree.put("status_code", 400);
tree.put("error", error_message);

std::ostringstream data;
pt::write_json(data, tree);

pt::write_xml(data, tree);
response->write(data.str());
SimpleWeb::CaseInsensitiveMultimap headers;
headers.emplace("Content-Type", "application/json");

*response << "HTTP/1.1 404 NOT FOUND\r\n"
<< data.str();
response->write(SimpleWeb::StatusCode::client_error_bad_request, data.str(), headers);
}

/**
Expand Down Expand Up @@ -360,7 +407,7 @@ namespace confighttp {
}

/**
* @brief Save an application. If the application already exists, it will be updated, otherwise it will be added.
* @brief Save an application. To save a new application the index must be `-1`. To update an existing application, you must provide the current index of the application.
* @param response The HTTP response object.
* @param request The HTTP request object.
* The body for the post request should be JSON serialized in the following format:
Expand All @@ -385,7 +432,7 @@ namespace confighttp {
* "detached": [
* "Detached command"
* ],
* "image-path": "Full path to the application image. Must be a png file.",
* "image-path": "Full path to the application image. Must be a png file."
* }
* @endcode
*/
Expand Down Expand Up @@ -468,8 +515,7 @@ namespace confighttp {
catch (std::exception &e) {
BOOST_LOG(warning) << "SaveApp: "sv << e.what();

outputTree.put("status", "false");
outputTree.put("error", "Invalid Input JSON");
bad_request(response, request, "Invalid Input JSON");
return;
}

Expand Down Expand Up @@ -502,8 +548,7 @@ namespace confighttp {
int index = stoi(request->path_match[1]);

if (index < 0) {
outputTree.put("status", "false");
outputTree.put("error", "Invalid Index");
bad_request(response, request, "Invalid Index");
return;
}
else {
Expand All @@ -522,8 +567,7 @@ namespace confighttp {
}
catch (std::exception &e) {
BOOST_LOG(warning) << "DeleteApp: "sv << e.what();
outputTree.put("status", "false");
outputTree.put("error", "Invalid File JSON");
bad_request(response, request, "Invalid File JSON");
return;
}

Expand All @@ -539,7 +583,7 @@ namespace confighttp {
* @code{.json}
* {
* "key": "igdb_<game_id>",
* "url": "https://images.igdb.com/igdb/image/upload/t_cover_big_2x/<slug>.png",
* "url": "https://images.igdb.com/igdb/image/upload/t_cover_big_2x/<slug>.png"
* }
* @endcode
*/
Expand Down Expand Up @@ -568,8 +612,7 @@ namespace confighttp {
}
catch (std::exception &e) {
BOOST_LOG(warning) << "UploadCover: "sv << e.what();
outputTree.put("status", "false");
outputTree.put("error", e.what());
bad_request(response, request, e.what());
return;
}

Expand Down Expand Up @@ -699,8 +742,7 @@ namespace confighttp {
}
catch (std::exception &e) {
BOOST_LOG(warning) << "SaveConfig: "sv << e.what();
outputTree.put("status", "false");
outputTree.put("error", e.what());
bad_request(response, request, e.what());
return;
}
}
Expand Down Expand Up @@ -757,6 +799,7 @@ namespace confighttp {

print_req(request);

std::vector<std::string> errors = {};
std::stringstream ss;
std::stringstream configStream;
ss << request->content.rdbuf();
Expand All @@ -779,15 +822,13 @@ namespace confighttp {
auto confirmPassword = inputTree.count("confirmNewPassword") > 0 ? inputTree.get<std::string>("confirmNewPassword") : "";
if (newUsername.length() == 0) newUsername = username;
if (newUsername.length() == 0) {
outputTree.put("status", false);
outputTree.put("error", "Invalid Username");
errors.emplace_back("Invalid Username");
}
else {
auto hash = util::hex(crypto::hash(password + config::sunshine.salt)).to_string();
if (config::sunshine.username.empty() || (boost::iequals(username, config::sunshine.username) && hash == config::sunshine.password)) {
if (newPassword.empty() || newPassword != confirmPassword) {
outputTree.put("status", false);
outputTree.put("error", "Password Mismatch");
errors.emplace_back("Password Mismatch");
}
else {
http::save_user_creds(config::sunshine.credentials_file, newUsername, newPassword);
Expand All @@ -796,15 +837,22 @@ namespace confighttp {
}
}
else {
outputTree.put("status", false);
outputTree.put("error", "Invalid Current Credentials");
errors.emplace_back("Invalid Current Credentials");
}
}

if (!errors.empty()) {
// join the errors array
std::string error = std::accumulate(errors.begin(), errors.end(), std::string(),
[](const std::string &a, const std::string &b) {

Check warning on line 847 in src/confighttp.cpp

View check run for this annotation

Codecov / codecov/patch

src/confighttp.cpp#L847

Added line #L847 was not covered by tests
return a.empty() ? b : a + ", " + b;
});
bad_request(response, request, error);
}
}
catch (std::exception &e) {
BOOST_LOG(warning) << "SavePassword: "sv << e.what();
outputTree.put("status", false);
outputTree.put("error", e.what());
bad_request(response, request, e.what());
return;
}
}
Expand Down Expand Up @@ -847,8 +895,7 @@ namespace confighttp {
}
catch (std::exception &e) {
BOOST_LOG(warning) << "SavePin: "sv << e.what();
outputTree.put("status", false);
outputTree.put("error", e.what());
bad_request(response, request, e.what());
return;
}
}
Expand Down Expand Up @@ -912,8 +959,7 @@ namespace confighttp {
}
catch (std::exception &e) {
BOOST_LOG(warning) << "Unpair: "sv << e.what();
outputTree.put("status", false);
outputTree.put("error", e.what());
bad_request(response, request, e.what());
return;
}
}
Expand Down Expand Up @@ -976,7 +1022,11 @@ namespace confighttp {
auto address_family = net::af_from_enum_string(config::sunshine.address_family);

https_server_t server { config::nvhttp.cert, config::nvhttp.pkey };
server.default_resource["DELETE"] = bad_request_default;
server.default_resource["GET"] = not_found;
server.default_resource["PATCH"] = bad_request_default;
server.default_resource["POST"] = bad_request_default;
server.default_resource["PUT"] = bad_request_default;
server.resource["^/$"]["GET"] = getIndexPage;
server.resource["^/pin/?$"]["GET"] = getPinPage;
server.resource["^/apps/?$"]["GET"] = getAppsPage;
Expand Down

0 comments on commit 78b043a

Please sign in to comment.