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