Files
openapi-generator/samples/server/petstore/cpp-httplib-server/feature-test/api/SecurityApi.cpp
vasireddyrajesh b96334ffad Add standalone C++ server using cpp-httplib for OpenAPI-based APIs (#21724)
Supports:
All OpenAPI 3.x data types: primitives, arrays, enums, nullable/optional fields, nested objects
All parameter types: path, query, header, cookie, and combinations
Schema composition: allOf (inheritance), oneOf (discriminated unions), anyOf (flexible unions)
Security schemes: API key and bearer token authentication
Discriminator-based polymorphic deserialization and error handling

Provides:
Error handling for invalid JSON, type mismatches, missing/unknown discriminator, and parameter validation
Build system integration (CMake) for easy compilation and linking with required dependencies
Clear build and run instructions for local development and testing
Enables comprehensive, real-world validation of generated C++ server code against OpenAPI specifications
2026-02-12 19:41:05 +08:00

298 lines
10 KiB
C++

/**
* This file is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
// System headers
#include <algorithm>
#include <cctype>
#include <locale>
// Project headers
#include "SecurityApi.h"
#include "AuthenticationManager.h"
constexpr int HTTP_RESPONSE_CODE_TEST_API_KEY_SECURITY200_RESPONSE = 200;
constexpr int HTTP_RESPONSE_CODE_ERROR_RESPONSE = 401;
constexpr int HTTP_RESPONSE_CODE_TEST_BASIC_SECURITY200_RESPONSE = 200;
constexpr int HTTP_RESPONSE_CODE_TEST_BEARER_SECURITY200_RESPONSE = 200;
constexpr int HTTP_RESPONSE_CODE_TEST_O_AUTH2_SECURITY200_RESPONSE = 200;
constexpr int HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR = 500;
namespace api {
using namespace models;
void Security::handleSecurityapikeyGetResponse(const SecurityapikeyGetResponse& result, httplib::Response& res)
{
std::visit([&](const auto& value)
{
using T = std::decay_t<decltype(value)>;
// Success types
if constexpr (std::is_same_v<T, models::TestApiKeySecurity200Response>)
{
res.status = HTTP_RESPONSE_CODE_TEST_API_KEY_SECURITY200_RESPONSE;
nlohmann::json responseJson;
to_json(responseJson, value);
res.set_content(responseJson.dump(), "application/json");
}
// Error types
else if constexpr (std::is_same_v<T, models::ErrorResponse>)
{
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
nlohmann::json errorJson = value;
res.set_content(errorJson.dump(), "application/json");
}
}, result);
}
void Security::handleSecuritybasicGetResponse(const SecuritybasicGetResponse& result, httplib::Response& res)
{
std::visit([&](const auto& value)
{
using T = std::decay_t<decltype(value)>;
// Success types
if constexpr (std::is_same_v<T, models::TestBasicSecurity200Response>)
{
res.status = HTTP_RESPONSE_CODE_TEST_BASIC_SECURITY200_RESPONSE;
nlohmann::json responseJson;
to_json(responseJson, value);
res.set_content(responseJson.dump(), "application/json");
}
// Error types
else if constexpr (std::is_same_v<T, models::ErrorResponse>)
{
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
nlohmann::json errorJson = value;
res.set_content(errorJson.dump(), "application/json");
}
}, result);
}
void Security::handleSecuritybearerGetResponse(const SecuritybearerGetResponse& result, httplib::Response& res)
{
std::visit([&](const auto& value)
{
using T = std::decay_t<decltype(value)>;
// Success types
if constexpr (std::is_same_v<T, models::TestBearerSecurity200Response>)
{
res.status = HTTP_RESPONSE_CODE_TEST_BEARER_SECURITY200_RESPONSE;
nlohmann::json responseJson;
to_json(responseJson, value);
res.set_content(responseJson.dump(), "application/json");
}
// Error types
else if constexpr (std::is_same_v<T, models::ErrorResponse>)
{
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
nlohmann::json errorJson = value;
res.set_content(errorJson.dump(), "application/json");
}
}, result);
}
void Security::handleSecurityoauth2getResponse(const Securityoauth2getResponse& result, httplib::Response& res)
{
std::visit([&](const auto& value)
{
using T = std::decay_t<decltype(value)>;
// Success types
if constexpr (std::is_same_v<T, models::TestOAuth2Security200Response>)
{
res.status = HTTP_RESPONSE_CODE_TEST_O_AUTH2_SECURITY200_RESPONSE;
nlohmann::json responseJson;
to_json(responseJson, value);
res.set_content(responseJson.dump(), "application/json");
}
// Error types
else if constexpr (std::is_same_v<T, models::ErrorResponse>)
{
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
nlohmann::json errorJson = value;
res.set_content(errorJson.dump(), "application/json");
}
}, result);
}
bool Security::performAuthentication(
const httplib::Request& req,
std::shared_ptr<AuthenticationManager> auth,
httplib::Response& res)
{
if (!auth)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "AuthenticationManager not configured";
res.status = HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR;
res.set_content(errorJson.dump(), "application/json");
return false;
}
if (req.has_header("X-API-Key"))
{
if (auth->validateApiKey(req.get_header_value("X-API-Key"))) return true;
}
if (req.has_header("Authorization"))
{
auto authHeader = req.get_header_value("Authorization");
if (authHeader.find("Basic ") == 0)
{
std::string credentials = authHeader.substr(6);
if (auth->validateBasicAuth(credentials, "")) return true;
}
}
if (req.has_header("Authorization"))
{
auto authHeader = req.get_header_value("Authorization");
if (authHeader.find("Bearer ") == 0)
{
std::string token = authHeader.substr(7);
if (auth->validateBearerToken(token)) return true;
}
}
if (req.has_header("Authorization"))
{
auto authHeader = req.get_header_value("Authorization");
if (authHeader.find("Bearer ") == 0)
{
std::string token = authHeader.substr(7);
std::vector<std::string> requiredScopes = { "read:users", "write:users" };
if (auth->validateOAuth2(token, requiredScopes)) return true;
}
}
return false;
}
void Security::handleSecurityapikeyGetRequest([[maybe_unused]] const httplib::Request& req, httplib::Response& res, std::shared_ptr<AuthenticationManager> auth)
{
try
{
if (!performAuthentication(req, auth, res))
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Authentication required";
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
return;
}
auto result = handleGetForSecurityapikey();
handleSecurityapikeyGetResponse(result, res);
}
catch (const std::exception& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Internal error: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR;
res.set_content(errorJson.dump(), "application/json");
}
}
void Security::handleSecuritybasicGetRequest([[maybe_unused]] const httplib::Request& req, httplib::Response& res, std::shared_ptr<AuthenticationManager> auth)
{
try
{
if (!performAuthentication(req, auth, res))
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Authentication required";
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
return;
}
auto result = handleGetForSecuritybasic();
handleSecuritybasicGetResponse(result, res);
}
catch (const std::exception& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Internal error: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR;
res.set_content(errorJson.dump(), "application/json");
}
}
void Security::handleSecuritybearerGetRequest([[maybe_unused]] const httplib::Request& req, httplib::Response& res, std::shared_ptr<AuthenticationManager> auth)
{
try
{
if (!performAuthentication(req, auth, res))
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Authentication required";
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
return;
}
auto result = handleGetForSecuritybearer();
handleSecuritybearerGetResponse(result, res);
}
catch (const std::exception& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Internal error: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR;
res.set_content(errorJson.dump(), "application/json");
}
}
void Security::handleSecurityoauth2GetRequest([[maybe_unused]] const httplib::Request& req, httplib::Response& res, std::shared_ptr<AuthenticationManager> auth)
{
try
{
if (!performAuthentication(req, auth, res))
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Authentication required";
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
return;
}
auto result = handleGetForSecurityoauth2();
handleSecurityoauth2getResponse(result, res);
}
catch (const std::exception& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Internal error: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR;
res.set_content(errorJson.dump(), "application/json");
}
}
void Security::registerRoutes(httplib::Server& svr, std::shared_ptr<AuthenticationManager> auth)
{
svr.Get("/security/apikey", [this, auth]([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
handleSecurityapikeyGetRequest(req, res, auth);
});
svr.Get("/security/basic", [this, auth]([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
handleSecuritybasicGetRequest(req, res, auth);
});
svr.Get("/security/bearer", [this, auth]([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
handleSecuritybearerGetRequest(req, res, auth);
});
svr.Get("/security/oauth2", [this, auth]([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
handleSecurityoauth2GetRequest(req, res, auth);
});
}
} // namespace api