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