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::requestPrefersHtml(accept))
18     {
19         // If we have a webui installed, redirect to that login page
20         if (hasWebuiRoute)
21         {
22             res.result(boost::beast::http::status::temporary_redirect);
23             res.addHeader("Location",
24                           "/#/login?next=" + http_helpers::urlEncode(url));
25             return;
26         }
27         // If we don't have a webui installed, just return an unauthorized
28         // body
29         res.result(boost::beast::http::status::unauthorized);
30         res.body() = "Unauthorized";
31         return;
32     }
33 
34     res.result(boost::beast::http::status::unauthorized);
35 
36     // XHR requests from a browser will set the X-Requested-With header when
37     // doing their requests, even though they might not be requesting html.
38     if (!xRequestedWith.empty())
39     {
40         return;
41     }
42     // if basic auth is disabled, don't propose it.
43     if (!persistent_data::SessionStore::getInstance()
44              .getAuthMethodsConfig()
45              .basic)
46     {
47         return;
48     }
49     res.addHeader("WWW-Authenticate", "Basic");
50 }
51 } // namespace forward_unauthorized
52