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         }
26         else
27         {
28             // If we don't have a webui installed, just return a lame
29             // unauthorized body
30             res.result(boost::beast::http::status::unauthorized);
31             res.body() = "Unauthorized";
32         }
33     }
34     else
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             // Only propose basic auth as an option if it's enabled.
43             if (persistent_data::SessionStore::getInstance()
44                     .getAuthMethodsConfig()
45                     .basic)
46             {
47                 res.addHeader("WWW-Authenticate", "Basic");
48             }
49         }
50     }
51 }
52 } // namespace forward_unauthorized
53