1 #pragma once
2 #include "http_request.hpp"
3 #include "http_response.hpp"
4 #include "http_utility.hpp"
5 
6 namespace forward_unauthorized
7 {
8 
9 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
10 static bool hasWebuiRoute = false;
11 
12 inline void sendUnauthorized(std::string_view url,
13                              std::string_view xRequestedWith,
14                              std::string_view accept, crow::Response& res)
15 {
16     // If it's a browser connecting, don't send the HTTP authenticate
17     // header, to avoid possible CSRF attacks with basic auth
18     if (http_helpers::isContentTypeAllowed(
19             accept, http_helpers::ContentType::HTML, false /*allowWildcard*/))
20     {
21         // If we have a webui installed, redirect to that login page
22         if (hasWebuiRoute)
23         {
24             res.result(boost::beast::http::status::temporary_redirect);
25             res.addHeader(boost::beast::http::field::location,
26                           "/#/login?next=" + http_helpers::urlEncode(url));
27             return;
28         }
29         // If we don't have a webui installed, just return an unauthorized
30         // body
31         res.result(boost::beast::http::status::unauthorized);
32         res.body() = "Unauthorized";
33         return;
34     }
35 
36     res.result(boost::beast::http::status::unauthorized);
37 
38     // XHR requests from a browser will set the X-Requested-With header when
39     // doing their requests, even though they might not be requesting html.
40     if (!xRequestedWith.empty())
41     {
42         return;
43     }
44     // if basic auth is disabled, don't propose it.
45     if (!persistent_data::SessionStore::getInstance()
46              .getAuthMethodsConfig()
47              .basic)
48     {
49         return;
50     }
51     res.addHeader(boost::beast::http::field::www_authenticate, "Basic");
52 }
53 } // namespace forward_unauthorized
54