Files
backend/common/OidcUserClaims.cc
T

111 lines
2.9 KiB
C++

#include "common/OidcUserClaims.h"
#include <algorithm>
namespace visione::oidc
{
namespace
{
std::string claimString(const Json::Value &value,
const char *primary,
const char *secondary = nullptr)
{
const auto primaryValue = value.get(primary, "");
if (primaryValue.isString() && !primaryValue.asString().empty())
{
return primaryValue.asString();
}
if (secondary)
{
const auto secondaryValue = value.get(secondary, "");
if (secondaryValue.isString())
{
return secondaryValue.asString();
}
}
return {};
}
std::string trimFiscalPrefix(std::string value)
{
const std::string prefix = "TINIT-";
if (value.rfind(prefix, 0) == 0)
{
value.erase(0, prefix.size());
}
std::transform(value.begin(),
value.end(),
value.begin(),
[](unsigned char ch) { return static_cast<char>(std::toupper(ch)); });
return value;
}
} // namespace
std::optional<NormalizedUserClaims> normalizeIdTokenClaims(
const std::string &issuer,
const Json::Value &claims)
{
if (!claims.isObject())
{
return std::nullopt;
}
const auto subject = claims.get("sub", "").asString();
const auto fiscal = trimFiscalPrefix(
claims.get("fiscal_number",
claims.get("https://attributes.eid.gov.it/fiscal_number", ""))
.asString());
if (subject.empty() || fiscal.empty())
{
return std::nullopt;
}
NormalizedUserClaims user;
user.issuer = issuer;
user.subject = subject;
user.firstName = claims.get("given_name", "").asString();
user.lastName = claims.get("family_name", "").asString();
user.email = claims.get("email", "").asString();
user.fiscalCode = fiscal;
user.rawClaims = claims;
return user;
}
std::optional<NormalizedUserClaims> mergeUserClaims(
const std::string &issuer,
const Json::Value &idTokenClaims,
const Json::Value &userinfoClaims)
{
if (!idTokenClaims.isObject() || !userinfoClaims.isObject())
{
return std::nullopt;
}
Json::Value merged = idTokenClaims;
for (const auto &name : userinfoClaims.getMemberNames())
{
merged[name] = userinfoClaims[name];
}
const auto subject = claimString(merged, "sub");
const auto fiscal = trimFiscalPrefix(claimString(
merged,
"fiscal_number",
"https://attributes.eid.gov.it/fiscal_number"));
if (subject.empty() || fiscal.empty())
{
return std::nullopt;
}
NormalizedUserClaims user;
user.issuer = issuer;
user.subject = subject;
user.firstName = claimString(merged, "given_name");
user.lastName = claimString(merged, "family_name");
user.email = claimString(merged, "email");
user.fiscalCode = fiscal;
user.rawClaims = merged;
return user;
}
} // namespace visione::oidc