111 lines
2.9 KiB
C++
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
|