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, std::string_view userAgent,
12                              std::string_view accept, crow::Response& res)
13 {
14     // If it's a browser connecting, don't send the HTTP authenticate
15     // header, to avoid possible CSRF attacks with basic auth
16     if (http_helpers::requestPrefersHtml(accept))
17     {
18         // If we have a webui installed, redirect to that login page
19         if (hasWebuiRoute)
20         {
21             res.result(boost::beast::http::status::temporary_redirect);
22             res.addHeader("Location",
23                           "/#/login?next=" + http_helpers::urlEncode(url));
24         }
25         else
26         {
27             // If we don't have a webui installed, just return a lame
28             // unauthorized body
29             res.result(boost::beast::http::status::unauthorized);
30             res.body() = "Unauthorized";
31         }
32     }
33     else
34     {
35         res.result(boost::beast::http::status::unauthorized);
36         // only send the WWW-authenticate header if this isn't a xhr
37         // from the browser.  Most scripts, tend to not set a user-agent header.
38         // So key off that to know whether or not we need to suggest basic auth
39         if (userAgent.empty())
40         {
41             res.addHeader("WWW-Authenticate", "Basic");
42         }
43     }
44 }
45 } // namespace forward_unauthorized
46