Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ci/qa/phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,7 @@ parameters:

-
message: "#^Argument of an invalid type Surfnet\\\\Stepup\\\\Identity\\\\Entity\\\\SecondFactorCollection\\|null supplied for foreach, only iterables are supported\\.$#"
count: 8
count: 11
path: ../../src/Surfnet/Stepup/Identity/Identity.php

-
Expand Down Expand Up @@ -1455,6 +1455,11 @@ parameters:
count: 1
path: ../../src/Surfnet/Stepup/Identity/Identity.php

-
message: "#^Cannot call method getType\\(\\) on mixed\\.$#"
count: 3
path: ../../src/Surfnet/Stepup/Identity/Identity.php

-
message: "#^Cannot call method getValues\\(\\) on Surfnet\\\\Stepup\\\\Identity\\\\Entity\\\\RegistrationAuthorityCollection\\|null\\.$#"
count: 1
Expand Down
31 changes: 28 additions & 3 deletions src/Surfnet/Stepup/Identity/Identity.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ public function bootstrapYubikeySecondFactor(
): void {
$this->assertNotForgotten();
$this->assertUserMayAddSecondFactor($maxNumberOfTokens);
$this->assertTokenTypeNotAlreadyRegistered(new SecondFactorType('yubikey'));

$this->apply(
new YubikeySecondFactorBootstrappedEvent(
Expand All @@ -234,6 +235,7 @@ public function provePossessionOfYubikey(
): void {
$this->assertNotForgotten();
$this->assertUserMayAddSecondFactor($maxNumberOfTokens);
$this->assertTokenTypeNotAlreadyRegistered(new SecondFactorType('yubikey'));

if ($emailVerificationRequired) {
$emailVerificationNonce = TokenGenerator::generateNonce();
Expand Down Expand Up @@ -278,6 +280,7 @@ public function provePossessionOfPhone(
): void {
$this->assertNotForgotten();
$this->assertUserMayAddSecondFactor($maxNumberOfTokens);
$this->assertTokenTypeNotAlreadyRegistered(new SecondFactorType('sms'));

if ($emailVerificationRequired) {
$emailVerificationNonce = TokenGenerator::generateNonce();
Expand Down Expand Up @@ -373,6 +376,7 @@ public function provePossessionOfGssf(
): void {
$this->assertNotForgotten();
$this->assertUserMayAddSecondFactor($maxNumberOfTokens);
$this->assertTokenTypeNotAlreadyRegistered(new SecondFactorType($provider->getStepupProvider()));

if ($emailVerificationRequired) {
$emailVerificationNonce = TokenGenerator::generateNonce();
Expand Down Expand Up @@ -422,6 +426,7 @@ public function provePossessionOfU2fDevice(
): void {
$this->assertNotForgotten();
$this->assertUserMayAddSecondFactor($maxNumberOfTokens);
$this->assertTokenTypeNotAlreadyRegistered(new SecondFactorType('u2f'));

if ($emailVerificationRequired) {
$emailVerificationNonce = TokenGenerator::generateNonce();
Expand Down Expand Up @@ -685,6 +690,7 @@ public function migrateVettedSecondFactor(
throw new DomainException("The second factor on the original identity can not be found");
}
$this->assertTokenNotAlreadyRegistered($secondFactor->getType(), $secondFactor->getIdentifier());
$this->assertTokenTypeNotAlreadyRegistered($secondFactor->getType());
if ($sourceIdentity->getInstitution()->equals($this->getInstitution())) {
throw new DomainException("Cannot move the second factor to the same institution");
}
Expand Down Expand Up @@ -1546,21 +1552,40 @@ private function assertTokenNotAlreadyRegistered(SecondFactorType $type, SecondF
{
foreach ($this->unverifiedSecondFactors as $unverified) {
if ($unverified->typeAndIdentifierAreEqual($type, $identifier)) {
throw new DomainException("The second factor was already registered as a unverified second factor");
throw new DomainException("The second factor was already registered as an unverified second factor");
}
}
foreach ($this->verifiedSecondFactors as $verified) {
if ($verified->typeAndIdentifierAreEqual($type, $identifier)) {
throw new DomainException("The second factor was already registered as a verified second factor");
}
}
foreach ($this->vettedSecondFactors as $vettedSecondFactor) {
if ($vettedSecondFactor->typeAndIdentifierAreEqual($type, $identifier)) {
foreach ($this->vettedSecondFactors as $vetted) {
if ($vetted->typeAndIdentifierAreEqual($type, $identifier)) {
throw new DomainException("The second factor was registered as a vetted second factor");
}
}
}

private function assertTokenTypeNotAlreadyRegistered(SecondFactorType $type): void
{
foreach ($this->unverifiedSecondFactors as $unverified) {
if ($unverified->getType()->equals($type)) {
throw new DomainException("This second factor type was already registered as an unverified second factor");
}
}
foreach ($this->verifiedSecondFactors as $verified) {
if ($verified->getType()->equals($type)) {
throw new DomainException("This second factor type was already registered as a verified second factor");
}
}
foreach ($this->vettedSecondFactors as $vetted) {
if ($vetted->getType()->equals($type)) {
throw new DomainException("This second factor type was already registered as a vetted second factor");
}
}
}

private function assertSelfAssertedTokenRegistrationAllowed(): void
{
if ($this->vettedSecondFactors->count() !== 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ public function test_can_not_be_moved_if_already_present_as_verified_token(): vo

public function test_can_not_be_moved_if_already_present_as_unverified_token(): void
{
$this->expectExceptionMessage("The second factor was already registered as a unverified second factor");
$this->expectExceptionMessage("The second factor was already registered as an unverified second factor");
$this->expectException(DomainException::class);

$this->setUpInstitutionConfiguration(2, ['yubikey']);
Expand Down
Loading