xref: /openbmc/bmcweb/include/forward_unauthorized.hpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3d4b6c660SEd Tanous #pragma once
43ccb3adbSEd Tanous #include "http_request.hpp"
53ccb3adbSEd Tanous #include "http_response.hpp"
63ccb3adbSEd Tanous #include "http_utility.hpp"
7d4b6c660SEd Tanous 
8c51a58eeSEd Tanous #include <boost/url/format.hpp>
9c51a58eeSEd Tanous #include <boost/url/url.hpp>
10c51a58eeSEd Tanous 
11d4b6c660SEd Tanous namespace forward_unauthorized
12d4b6c660SEd Tanous {
13d4b6c660SEd Tanous 
14cf9e417dSEd Tanous // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
154f48d5f6SEd Tanous static bool hasWebuiRoute = false;
16d4b6c660SEd Tanous 
sendUnauthorized(std::string_view url,std::string_view xRequestedWith,std::string_view accept,crow::Response & res)17c127a0f4SEd Tanous inline void sendUnauthorized(std::string_view url,
18c127a0f4SEd Tanous                              std::string_view xRequestedWith,
1959b98b22SJohn Edward Broadbent                              std::string_view accept, crow::Response& res)
20d4b6c660SEd Tanous {
21d4b6c660SEd Tanous     // If it's a browser connecting, don't send the HTTP authenticate
22d4b6c660SEd Tanous     // header, to avoid possible CSRF attacks with basic auth
234a0e1a0cSEd Tanous     if (http_helpers::isContentTypeAllowed(
244a0e1a0cSEd Tanous             accept, http_helpers::ContentType::HTML, false /*allowWildcard*/))
25d4b6c660SEd Tanous     {
26d4b6c660SEd Tanous         // If we have a webui installed, redirect to that login page
27d4b6c660SEd Tanous         if (hasWebuiRoute)
28d4b6c660SEd Tanous         {
29bd79bce8SPatrick Williams             boost::urls::url forward =
30bd79bce8SPatrick Williams                 boost::urls::format("/?next={}#/login", url);
31d4b6c660SEd Tanous             res.result(boost::beast::http::status::temporary_redirect);
32d9f6c621SEd Tanous             res.addHeader(boost::beast::http::field::location,
33c51a58eeSEd Tanous                           forward.buffer());
34347d1a19SEd Tanous             return;
35d4b6c660SEd Tanous         }
36347d1a19SEd Tanous         // If we don't have a webui installed, just return an unauthorized
37347d1a19SEd Tanous         // body
38d4b6c660SEd Tanous         res.result(boost::beast::http::status::unauthorized);
3927b0cf90SEd Tanous         res.write(
4027b0cf90SEd Tanous             "No authentication provided, and no login UI present to forward to.");
41347d1a19SEd Tanous         return;
42d4b6c660SEd Tanous     }
43347d1a19SEd Tanous 
44d4b6c660SEd Tanous     res.result(boost::beast::http::status::unauthorized);
45c127a0f4SEd Tanous 
46c127a0f4SEd Tanous     // XHR requests from a browser will set the X-Requested-With header when
47c127a0f4SEd Tanous     // doing their requests, even though they might not be requesting html.
48c127a0f4SEd Tanous     if (!xRequestedWith.empty())
49c127a0f4SEd Tanous     {
50347d1a19SEd Tanous         return;
51347d1a19SEd Tanous     }
52347d1a19SEd Tanous     // if basic auth is disabled, don't propose it.
53347d1a19SEd Tanous     if (!persistent_data::SessionStore::getInstance()
54c127a0f4SEd Tanous              .getAuthMethodsConfig()
55c127a0f4SEd Tanous              .basic)
56d4b6c660SEd Tanous     {
57347d1a19SEd Tanous         return;
58347d1a19SEd Tanous     }
59d9f6c621SEd Tanous     res.addHeader(boost::beast::http::field::www_authenticate, "Basic");
60d4b6c660SEd Tanous }
61d4b6c660SEd Tanous } // namespace forward_unauthorized
62