#include "controllers/OidcController.h" #include "common/Http.h" #include "services/OidcRpService.h" #include using drogon::HttpResponsePtr; namespace { void serviceResponse(Json::Value body, std::function &&callback, drogon::HttpStatusCode failureStatus = drogon::k400BadRequest) { if (body.get("ok", false).asBool()) { callback(visione::http::json(std::move(body))); return; } callback(visione::http::json(std::move(body), failureStatus)); } } // namespace void OidcController::startCieLogin( const drogon::HttpRequestPtr &req, std::function &&callback) { const auto body = visione::http::requireJson(req); if (body.isNull()) { callback(visione::http::error("invalid_json", drogon::k400BadRequest)); return; } visione::services::OidcRpService service; serviceResponse(service.startLogin(body), std::move(callback)); } void OidcController::cieCallback( const drogon::HttpRequestPtr &req, std::function &&callback) { visione::services::OidcRpService service; auto body = service.callback(req->getParameter("state"), req->getParameter("code"), req->getParameter("error"), req->getParameter("error_description"), [&req]() -> std::optional { const auto issuer = req->getParameter("iss"); if (issuer.empty()) { return std::nullopt; } return issuer; }()); if (body.isMember("redirect_url") && body["redirect_url"].isString()) { callback(visione::http::redirect(body["redirect_url"].asString())); return; } serviceResponse(std::move(body), std::move(callback), drogon::k400BadRequest); } void OidcController::cieSessionStatus( const drogon::HttpRequestPtr & /*req*/, std::function &&callback, std::string state) { visione::services::OidcRpService service; serviceResponse(service.sessionStatus(state), std::move(callback), drogon::k404NotFound); } void OidcController::entityConfiguration( const drogon::HttpRequestPtr &req, std::function &&callback) { visione::services::OidcRpService service; if (req->getParameter("format") == "json") { callback(visione::http::json(service.entityConfigurationDocument())); return; } auto response = drogon::HttpResponse::newHttpResponse(); response->setStatusCode(drogon::k200OK); response->setContentTypeString("application/entity-statement+jwt"); response->setBody(service.entityConfigurationJwt()); callback(response); } void OidcController::resolveEntityStatement( const drogon::HttpRequestPtr &req, std::function &&callback) { visione::services::OidcRpService service; const auto subParam = req->getParameter("sub"); const auto anchorParam = req->getParameter("anchor"); const std::optional sub = subParam.empty() ? std::nullopt : std::make_optional(subParam); const std::optional anchor = anchorParam.empty() ? std::nullopt : std::make_optional(anchorParam); if (req->getParameter("format") == "json") { serviceResponse(service.resolveDocument(sub, anchor), std::move(callback), drogon::k404NotFound); return; } auto jwt = service.resolveJwt(sub, anchor); if (jwt.empty()) { callback(visione::http::error("not_found", drogon::k404NotFound)); return; } auto response = drogon::HttpResponse::newHttpResponse(); response->setStatusCode(drogon::k200OK); response->setContentTypeString("application/resolve-response+jwt"); response->setBody(std::move(jwt)); callback(response); } void OidcController::jwks( const drogon::HttpRequestPtr & /*req*/, std::function &&callback) { visione::services::OidcRpService service; callback(visione::http::json(service.jwks())); }