Skip to content

Commit

Permalink
test(oidc): add oidc_provider_group tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JMounier committed Aug 1, 2024
1 parent cb4858d commit 30e5dc8
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 23 deletions.
2 changes: 1 addition & 1 deletion modules/admin/include/Tanker/Admin/Client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct App

struct AppUpdateOptions
{
std::optional<OidcConfiguration> oidcProvider;
std::optional<std::vector<OidcConfiguration>> oidcProviders;
std::optional<bool> preverifiedVerification;
std::optional<bool> userEnrollment;
};
Expand Down
23 changes: 14 additions & 9 deletions modules/admin/src/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ void from_json(nlohmann::json const& j, OidcConfiguration& config)
config.clientId = value;
if (auto value = j.at("issuer").get<std::string>(); !value.empty())
config.issuer = value;
if (auto value = j.at("oidc_provider_group_id").get<std::string>(); !value.empty())
config.oidcProviderGroupId = value;
}
void from_json(nlohmann::json const& j, App& app)
{
Expand Down Expand Up @@ -131,16 +133,19 @@ tc::cotask<App> Client::update(Trustchain::TrustchainId const& trustchainId, App
{
TINFO("updating trustchain {:#S}", trustchainId);
auto body = nlohmann::json{};
if (options.oidcProvider)
if (options.oidcProviders)
{
auto const& provider = options.oidcProvider.value();
bool ignoreTokenExpiration = provider.displayName == "pro-sante-bas-no-expiry";
auto providerJson = nlohmann::json{{"client_id", provider.clientId},
{"issuer", provider.issuer},
{"display_name", provider.displayName},
{"oidc_provider_group_id", provider.oidcProviderGroupId},
{"ignore_token_expiration", ignoreTokenExpiration}};
body["oidc_providers"] = nlohmann::json::array({providerJson});
auto providersJson = nlohmann::json::array();
for (auto const& oidcProvider : options.oidcProviders.value()) {
auto const& provider = oidcProvider;
bool ignoreTokenExpiration = provider.displayName == "pro-sante-bas-no-expiry";
providersJson.push_back(nlohmann::json{{"client_id", provider.clientId},
{"issuer", provider.issuer},
{"display_name", provider.displayName},
{"oidc_provider_group_id", provider.oidcProviderGroupId},
{"ignore_token_expiration", ignoreTokenExpiration}});
}
body["oidc_providers"] = providersJson;
}

if (options.preverifiedVerification)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class TrustchainFactory
tc::cotask<Trustchain::Ptr> createTrustchain(std::string const& name);
tc::cotask<Trustchain::Ptr> useTrustchain(std::string configPath);
tc::cotask<void> enableOidc(Tanker::Trustchain::TrustchainId const& id);
tc::cotask<void> enableFakeOidc(Tanker::Trustchain::TrustchainId const& id, std::string const& issuer = "main", std::string const& providerGroupId = "BxFm1n2_wR2V02gbO-tRK68rTiOwPps0L_hGjxkHofM");
tc::cotask<void> enableFakeOidc(Tanker::Trustchain::TrustchainId const& id);
tc::cotask<void> enablePSCOidc(Tanker::Trustchain::TrustchainId const& id, PSCProvider const& provider);
tc::cotask<void> setUserEnrollmentEnabled(Tanker::Trustchain::TrustchainId const& id, bool state = true);

Expand Down
21 changes: 11 additions & 10 deletions modules/functional-helpers/src/TrustchainFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,22 @@ tc::cotask<void> TrustchainFactory::enableOidc(Tanker::Trustchain::TrustchainId
adminOidcConf.oidcProviderGroupId = "qYjh0nn2C5s8mj9d-F4Oy8UhFqVTNZpnuwE55lWHV7Y";

Admin::AppUpdateOptions options{};
options.oidcProvider = adminOidcConf;
options.oidcProviders = {adminOidcConf};
TC_AWAIT(_admin->update(id, options));
}

tc::cotask<void> TrustchainFactory::enableFakeOidc(Tanker::Trustchain::TrustchainId const& id, std::string const& issuer, std::string const& providerGroupId)
tc::cotask<void> TrustchainFactory::enableFakeOidc(Tanker::Trustchain::TrustchainId const& id)
{
auto const& fakeOidcIssuerUrl = TestConstants::oidcConfig().fakeOidcIssuerUrl;
Admin::OidcConfiguration adminOidcConf{};
adminOidcConf.displayName = "fake-oidc";
adminOidcConf.clientId = "tanker";
adminOidcConf.issuer = fakeOidcIssuerUrl + "/" + issuer;
adminOidcConf.oidcProviderGroupId = providerGroupId;

Admin::AppUpdateOptions options{};
options.oidcProvider = adminOidcConf;

auto fakeOidcProviderGroupID = "BxFm1n2_wR2V02gbO-tRK68rTiOwPps0L_hGjxkHofM";
auto wrongFakeOidcProviderGroupID = "s5XXhLYMKOn6aMKmtdu1590Nyri0XEEHyKMWueiieOk";
options.oidcProviders = std::vector<Admin::OidcConfiguration>{
{ "fake-oidc", "tanker", fakeOidcIssuerUrl + "/main", fakeOidcProviderGroupID},
{ "fake-oidc/alt", "tanker", fakeOidcIssuerUrl + "/alt", fakeOidcProviderGroupID},
{ "fake-oidc/wrong-group", "tanker", fakeOidcIssuerUrl + "/wrong-group", wrongFakeOidcProviderGroupID},
};
TC_AWAIT(_admin->update(id, options));
}

Expand All @@ -92,7 +93,7 @@ tc::cotask<void> TrustchainFactory::enablePSCOidc(Tanker::Trustchain::Trustchain
adminOidcConf.oidcProviderGroupId = "m-DsT9cPgBqoQJPFI3IOMBPobofKvjzXEPA6kOfnCuA";

Admin::AppUpdateOptions options{};
options.oidcProvider = adminOidcConf;
options.oidcProviders = {adminOidcConf};
TC_AWAIT(_admin->update(id, options));
}

Expand Down
51 changes: 49 additions & 2 deletions modules/functional-tests/test_verification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,9 +986,9 @@ TEST_CASE_METHOD(TrustchainFixture, "verification by oidc authorization code")
auto martinePhone = martineDevice2.createCore();

auto const subjectCookie = "fake_oidc_subject=martine";
auto const fakeOidcIssuerUrl = TestConstants::oidcConfig().fakeOidcIssuerUrl + "/main";
auto const fakeOidcIssuerUrl = TestConstants::oidcConfig().fakeOidcIssuerUrl;
auto const providerId =
oidcProviderId(martineLaptop->sdkInfo().trustchainId, fakeOidcIssuerUrl, "tanker");
oidcProviderId(martineLaptop->sdkInfo().trustchainId, fakeOidcIssuerUrl + "/main", "tanker");

TC_AWAIT(enableFakeOidc());

Expand Down Expand Up @@ -1039,6 +1039,27 @@ TEST_CASE_METHOD(TrustchainFixture, "verification by oidc authorization code")
REQUIRE_NOTHROW(TC_AWAIT(martinePhone->verifyIdentity(verification2)));
REQUIRE(martinePhone->status() == Status::Ready);
}

SECTION("registers and verifies with different oidc providers from the same provider group")
{
TC_AWAIT(enableFakeOidc());
auto const altProviderId =
oidcProviderId(martineLaptop->sdkInfo().trustchainId, fakeOidcIssuerUrl + "/alt", "tanker");
auto const wrongProviderId =
oidcProviderId(martineLaptop->sdkInfo().trustchainId, fakeOidcIssuerUrl + "/wrong-group", "tanker");

auto const verification1 = TC_AWAIT(martineLaptop->authenticateWithIdp(providerId, subjectCookie));
auto const verification2 = TC_AWAIT(martineLaptop->authenticateWithIdp(wrongProviderId, subjectCookie));
auto const verification3 = TC_AWAIT(martineLaptop->authenticateWithIdp(altProviderId, subjectCookie));

REQUIRE_NOTHROW(TC_AWAIT(martineLaptop->registerIdentity(verification1)));

REQUIRE(TC_AWAIT(martinePhone->start(martine.identity)) == Status::IdentityVerificationNeeded);
TANKER_CHECK_THROWS_WITH_CODE(TC_AWAIT(martinePhone->verifyIdentity(verification2)), Errc::PreconditionFailed);

REQUIRE_NOTHROW(TC_AWAIT(martinePhone->verifyIdentity(verification3)));
REQUIRE(martinePhone->status() == Status::Ready);
}
}

TEST_CASE_METHOD(TrustchainFixture, "Verification with preverified oidc")
Expand Down Expand Up @@ -1104,6 +1125,32 @@ TEST_CASE_METHOD(TrustchainFixture, "Verification with preverified oidc")
REQUIRE_NOTHROW(
checkVerificationMethods(TC_AWAIT(martinePhone->getVerificationMethods()), {Passphrase{}, expectedOidc}));
}

SECTION("sets a verification method for every oidc provider from the same oidc provider group at once")
{
auto const fakeOidcIssuerUrl = TestConstants::oidcConfig().fakeOidcIssuerUrl;
auto const mainProviderId =
oidcProviderId(martineLaptop->sdkInfo().trustchainId, fakeOidcIssuerUrl + "/main", "tanker");
auto const altProviderId =
oidcProviderId(martineLaptop->sdkInfo().trustchainId, fakeOidcIssuerUrl + "/alt", "tanker");
auto expectedMainOidc = OidcIdToken{
{},
mainProviderId,
"fake-oidc",
};
auto expectedAltOidc = OidcIdToken{
{},
altProviderId,
"fake-oidc/alt",
};

auto const pass = Passphrase{"******"};
REQUIRE_NOTHROW(TC_AWAIT(martineLaptop->registerIdentity(pass)));
REQUIRE_NOTHROW(TC_AWAIT(martineLaptop->setVerificationMethod(PreverifiedOidc{mainProviderId, subject})));

REQUIRE_NOTHROW(
checkVerificationMethods(TC_AWAIT(martineLaptop->getVerificationMethods()), {Passphrase{}, expectedMainOidc, expectedAltOidc}));
}
}

TEST_CASE_METHOD(TrustchainFixture, "User enrollment throws when the feature is not enabled")
Expand Down

0 comments on commit 30e5dc8

Please sign in to comment.