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.write( 38 "No authentication provided, and no login UI present to forward to."); 39 return; 40 } 41 42 res.result(boost::beast::http::status::unauthorized); 43 44 // XHR requests from a browser will set the X-Requested-With header when 45 // doing their requests, even though they might not be requesting html. 46 if (!xRequestedWith.empty()) 47 { 48 return; 49 } 50 // if basic auth is disabled, don't propose it. 51 if (!persistent_data::SessionStore::getInstance() 52 .getAuthMethodsConfig() 53 .basic) 54 { 55 return; 56 } 57 res.addHeader(boost::beast::http::field::www_authenticate, "Basic"); 58 } 59 } // namespace forward_unauthorized 60