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