Files
backend/controllers/OidcController.cc
T

137 lines
4.5 KiB
C++

#include "controllers/OidcController.h"
#include "common/Http.h"
#include "services/OidcRpService.h"
#include <drogon/HttpResponse.h>
using drogon::HttpResponsePtr;
namespace
{
void serviceResponse(Json::Value body,
std::function<void(const HttpResponsePtr &)> &&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<void(const HttpResponsePtr &)> &&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<void(const HttpResponsePtr &)> &&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<std::string>
{
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<void(const HttpResponsePtr &)> &&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<void(const HttpResponsePtr &)> &&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<void(const HttpResponsePtr &)> &&callback)
{
visione::services::OidcRpService service;
const auto subParam = req->getParameter("sub");
const auto anchorParam = req->getParameter("anchor");
const std::optional<std::string> sub =
subParam.empty() ? std::nullopt : std::make_optional(subParam);
const std::optional<std::string> 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<void(const HttpResponsePtr &)> &&callback)
{
visione::services::OidcRpService service;
callback(visione::http::json(service.jwks()));
}