Skip to content

Commit

Permalink
Get the selfservice.feature back up and running
Browse files Browse the repository at this point in the history
And while at it, increase its test coverage
  • Loading branch information
MKodde committed Jan 24, 2024
1 parent 8d080a7 commit bfd7c7d
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 80 deletions.
11 changes: 8 additions & 3 deletions stepup/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ services:
- selfservice.dev.openconext.local
- middleware.dev.openconext.local
- gateway.dev.openconext.local
- demogssp.dev.openconext.local
- webauthn.dev.openconext.local
- tiqr.dev.openconext.local
- mailcatcher.dev.openconext.local
hostname: haproxy.docker



mariadb:
image: mariadb:10.6
environment:
Expand Down Expand Up @@ -122,7 +127,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
hostname: demogssp.docker

tiqr:
image: ghcr.io/openconext/stepup-tiqr/stepup-tiqr:prod
environment:
Expand All @@ -134,7 +139,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
hostname: tiqr.docker

azuremfa:
image: ghcr.io/openconext/stepup-azuremfa/stepup-azuremfa:${STEPUP_VERSION:-prod}
environment:
Expand All @@ -146,7 +151,7 @@ services:
extra_hosts:
- "host.docker.internal:host-gateway"
hostname: azuremfa.docker

mailcatcher:
image: sj26/mailcatcher:latest
ports:
Expand Down
2 changes: 1 addition & 1 deletion stepup/tests/behat/config/behat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ default:
spTestUrl: 'https://ssp.dev.openconext.local/simplesaml/sp.php'
- SelfServiceContext:
selfServiceUrl: 'https://selfservice.dev.openconext.local'
mailCatcherUrl: 'http://selfservice.dev.openconext.local:1080/messages'
mailCatcherUrl: 'http://mailcatcher:1080/messages'
- RaContext:
raUrl: 'https://ra.dev.openconext.local'
- ApiFeatureContext:
Expand Down
96 changes: 82 additions & 14 deletions stepup/tests/behat/features/bootstrap/RaContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,27 @@ public function gatherContexts(BeforeScenarioScope $scope)
}

/**
* @Given /^I vet my second factor at the information desk$/
* @Given I vet my :tokenType second factor :vettingType
*/
public function iVetMySecondFactorAtTheInformationDesk()
public function iVetMySecondFactor(string $tokenType, string $vettingType)
{
// We visit the RA location url
$this->minkContext->visit($this->raUrl);
switch ($vettingType) {
case "at the information desk":
// We visit the RA location url
$this->minkContext->visit($this->raUrl);

$this->iAmLoggedInIntoTheRaPortalAs('admin', 'yubikey');
$this->iVetASecondFactor($this->selfServiceContext->getVerifiedSecondFactorId(), $this->selfServiceContext->getActivationCode());
$this->iAmLoggedInIntoTheRaPortalAs('admin', 'yubikey');
$this->iVetASpecificSecondFactor(
$tokenType,
$this->selfServiceContext->getVerifiedSecondFactorId(),
$this->selfServiceContext->getActivationCode()
);
break;
case "using self asserted token registration":
break;
default:
throw new Exception(sprintf('The %s vettingType type is not supported', $vettingType));
}
}


Expand All @@ -75,6 +87,29 @@ public function iVetTheLastAddedSecondFactor()
$this->vettingProcessIsCompleted($secondFactorId);
}

public function iVetASpecificSecondFactor($tokenType, $secondFactorId, $activationCode)
{
// We visit the RA location url
$this->minkContext->visit($this->raUrl);

$this->findsTokenForActivation($activationCode);
switch ($tokenType) {
case "Yubikey":
$this->userProvesPosessionOfYubikeyToken($secondFactorId);
break;
case "SMS":
$this->userProvesPosessionOfSmsToken($secondFactorId);
break;
case "Demo GSSP":
$this->userProvesPosessionOfDemoGsspToken($secondFactorId);
break;
default:
throw new Exception(sprintf('The %s token type is not supported', $tokenType));
}
$this->adminVerifiesUserIdentity($secondFactorId);
$this->vettingProcessIsCompleted($secondFactorId);
}

/**
* @Given /^I vet a second factor with id "([^"]*)" and with activation code "([^"]*)"$/
*/
Expand All @@ -97,9 +132,9 @@ public function iAmLoggedInIntoTheRaPortalAs($userName, $tokenType)
{
// Login into RA
$this->iTryToLoginIntoTheRaPortalAs($userName, $tokenType);

// We are now on the RA homepage
$this->minkContext->assertPageAddress('https://ra.dev.openconext.local');
$this->iSwitchLocaleTo('English');
$this->minkContext->assertPageContainsText('RA Management Portal');
$this->minkContext->assertPageContainsText('Token activation');
}
Expand All @@ -110,10 +145,11 @@ public function iAmLoggedInIntoTheRaPortalAs($userName, $tokenType)
public function iTryToLoginIntoTheRaPortalAs($userName, $tokenType)
{
// We visit the RA location url
$this->minkContext->getSession()->reset();
$this->minkContext->visit($this->raUrl);

// The admin user logs in and gives a Yubikey second factor
$this->authContext->authenticateWithIdentityProviderFor($userName);
$this->authContext->authenticateWithIdentityProviderForWithStepup($userName);
switch ($tokenType) {
case "yubikey":
$this->authContext->verifyYuikeySecondFactor();
Expand Down Expand Up @@ -157,24 +193,30 @@ public function iSearchForOnTheTokenActivationPage($registrationCode)

}

private function userProvesPosessionOfDummyToken()
private function userProvesPosessionOfDemoGsspToken(string $secondFactorId)
{
$vettingProcedureUrl = 'https://ra.dev.openconext.local/vetting-procedure/%s/gssf/dummy/initiate-verification';
$vettingProcedureUrl = 'https://ra.dev.openconext.local/vetting-procedure/%s/gssf/demo_gssp/initiate-verification';

$this->minkContext->assertPageAddress(
sprintf(
$vettingProcedureUrl,
$this->selfServiceContext->getVerifiedSecondFactorId()
$secondFactorId
)
);

// Press the initiate vetting procedure button in the search results
$this->minkContext->pressButton('ra_initiate_gssf_submit');
// Press the Authenticate button on the Dummy authentication page

// Ensure we have the english translation
$this->minkContext->clickLink('EN');

// Press the Authenticate button on the Demo authentication page
$this->minkContext->assertPageAddress('https://demogssp.dev.openconext.local/authentication');
$this->minkContext->pressButton('button_authenticate');
// Pass through the Dummy Gssp redirection page.
// Pass through the Demo Gssp redirection page.
$this->minkContext->assertPageAddress('https://demogssp.dev.openconext.local/saml/sso_return');
$this->minkContext->pressButton('Submit');
// Pass through the 'return to sp' redirection page.
$this->minkContext->assertPageAddress('https://gateway.dev.openconext.local/gssp/demo_gssp/consume-assertion');
$this->minkContext->pressButton('Submit');
}

Expand All @@ -196,6 +238,23 @@ private function userProvesPosessionOfSmsToken($secondFactorId)
$this->minkContext->pressButton('Verify code');
}

private function userProvesPosessionOfYubikeyToken($secondFactorId)
{
$vettingProcedureUrl = 'https://ra.dev.openconext.local/vetting-procedure/%s/verify-yubikey';

$this->minkContext->assertPageAddress(
sprintf(
$vettingProcedureUrl,
$secondFactorId
)
);
// Fill the Code field with an arbitrary verification code
$this->minkContext->fillField('ra_verify_yubikey_public_id_otp', '999');
$page = $this->minkContext->getSession()->getPage();
$form = $page->find('css', 'form[name="ra_verify_yubikey_public_id"]');
$form->submit();
}

private function adminVerifiesUserIdentity($verifiedSecondFactorId)
{
$vettingProcedureUrl = 'https://ra.dev.openconext.local/vetting-procedure/%s/verify-identity';
Expand Down Expand Up @@ -640,6 +699,15 @@ public function iVerifyTheUsersIdentityByFillingTheLastCharactersOfTheDocumentNu
$this->minkContext->pressButton('Verify identity');
}

private function iSwitchLocaleTo(string $newLocale): void
{
$page = $this->minkContext->getSession()->getPage();
$selectElement = $page->find('css', '#stepup_switch_locale_locale');
$selectElement->selectOption($newLocale);
$form = $page->find('css', 'form[name="stepup_switch_locale"]');
$form->submit();
}

private function diePrintingContent()
{
echo $this->minkContext->getSession()->getCurrentUrl();
Expand Down
11 changes: 11 additions & 0 deletions stepup/tests/behat/features/bootstrap/SecondFactorAuthContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,17 @@ public function authenticateWithIdentityProviderFor($userName)
$this->minkContext->assertPageNotContainsText('Incorrect username or password');
}

public function authenticateWithIdentityProviderForWithStepup($userName)
{
$this->minkContext->assertPageAddress('https://ssp.dev.openconext.local/simplesaml/module.php/core/loginuserpass');

$this->minkContext->fillField('username', $userName);
$this->minkContext->fillField('password', $userName);

$this->minkContext->pressButton('Login');
$this->minkContext->pressButton('Yes, continue');
}

private function passTroughIdentityProviderAssertionConsumerService()
{
$this->minkContext->assertPageAddress('https://ssp.dev.openconext.local/simplesaml/module.php/core/loginuserpass');
Expand Down
116 changes: 62 additions & 54 deletions stepup/tests/behat/features/bootstrap/SelfServiceContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,63 +83,64 @@ public function iAmLoggedInIntoTheSelfServicePortalAs($userName)
}

/**
* @When I register a new Dummy token
* @When I register a new :tokenType token
*/
public function registerNewToken()
{
// Click 'add token' on the overview page
$this->minkContext->clickLink('Add token');

$this->minkContext->assertPageAddress('/registration/select-token');

// Select the dummy second factor type
$this->minkContext->getSession()
->getPage()
->find('css', '[href="/registration/gssf/dummy/initiate"]')->click();

$this->minkContext->assertPageAddress('/registration/gssf/dummy/initiate');

// Start registration
$this->minkContext->assertPageContainsText('Register with Dummy');
$this->minkContext->pressButton('Register with Dummy');

// Register onthe dummy application
$this->minkContext->assertPageAddress('http://localhost:1234/app_dev.php/registration');
$this->minkContext->pressButton('Register user');

// Pass trough GSSP return action
$this->minkContext->pressButton('Submit');

// Pass trough gateway
$this->authContext->passTroughGatewayProxyAssertionConsumerService();

$this->minkContext->assertPageContainsText('Verify your e-mail');
$this->minkContext->assertPageContainsText('Check your inbox');
}

/**
* @When I register a new SMS token
*/
public function registerNewSmsToken()
public function registerNewToken(string $tokenType)
{
$this->minkContext->assertPageAddress('/registration/select-token');

// Select the SMS second factor type
$this->minkContext->getSession()
->getPage()
->find('css', '[href="/registration/sms/send-challenge"]')->click();

$this->minkContext->assertPageAddress('/registration/sms/send-challenge');
// Start registration
$this->minkContext->assertPageContainsText('Send SMS code');
$this->minkContext->fillField('ss_send_sms_challenge_subscriber', '612345678');
$this->minkContext->pressButton('Send code');
// Now we should be on the prove possession page where we enter our OTP
$this->minkContext->assertPageAddress('/registration/sms/prove-possession');
$this->minkContext->assertPageContainsText('Enter SMS code');
$this->minkContext->fillField('ss_verify_sms_challenge_challenge', '999');

$this->minkContext->pressButton('Verify');
switch ($tokenType) {
case 'Yubikey':
$this->minkContext->getSession()
->getPage()
->find('css', '[href="/registration/yubikey/prove-possession"]')->click();
$this->minkContext->assertPageAddress('/registration/yubikey/prove-possession');
$this->minkContext->assertPageContainsText('Link your YubiKey');
$this->minkContext->fillField('ss_prove_yubikey_possession_otp', 'ccccccdhgrbtfddefpkffhkkukbgfcdilhiltrrncmig');
$page = $this->minkContext->getSession()->getPage();
$form = $page->find('css', 'form[name="ss_prove_yubikey_possession"]');
$form->submit();
break;
case 'SMS':
// Select the SMS second factor type
$this->minkContext->getSession()
->getPage()
->find('css', '[href="/registration/sms/send-challenge"]')->click();

$this->minkContext->assertPageAddress('/registration/sms/send-challenge');
// Start registration
$this->minkContext->assertPageContainsText('Send SMS code');
$this->minkContext->fillField('ss_send_sms_challenge_subscriber', '612345678');
$this->minkContext->pressButton('Send code');
// Now we should be on the prove possession page where we enter our OTP
$this->minkContext->assertPageAddress('/registration/sms/prove-possession');
$this->minkContext->assertPageContainsText('Enter SMS code');
$this->minkContext->fillField('ss_verify_sms_challenge_challenge', '999');

$this->minkContext->pressButton('Verify');
break;
case 'Demo GSSP':
// Select the SMS second factor type
$page = $this->minkContext->getSession()->getPage();
$form = $page->find('css', 'form[action="/registration/gssf/demo_gssp/authenticate"]');
$form->submit();

$this->minkContext->assertPageAddress('https://demogssp.dev.openconext.local/registration');
// Start registration
$this->minkContext->assertPageContainsText('Register user');
$this->minkContext->pressButton('Register user');

// Pass through the demogssp
$this->minkContext->assertPageAddress('https://demogssp.dev.openconext.local/saml/sso_return');
$this->minkContext->pressButton('Submit');
// Pass through the gateway
$this->minkContext->assertPageAddress('https://gateway.dev.openconext.local/gssp/demo_gssp/consume-assertion');
$this->minkContext->pressButton('Submit');
// Now we should be back at the SelfService
break;
default:
throw new Exception(sprintf('The %s token type is not supported', $tokenType));
}

## And we should now be on the mail verification page
$this->minkContext->assertPageContainsText('Verify your e-mail');
Expand Down Expand Up @@ -231,7 +232,7 @@ public function verifyEmailAddress()
$this->minkContext->visit(
$this->getEmailVerificationUrl()
);

$this->iChooseToActivateMyTokenUsingServiceDeskVetting();
$this->minkContext->printCurrentUrl();
$this->minkContext->assertPageContainsText('Thank you for registering your token.');

Expand All @@ -255,6 +256,13 @@ public function verifyEmailAddress()
}
}

public function iChooseToActivateMyTokenUsingServiceDeskVetting()
{
$this->minkContext->assertPageContainsText('Activate your token');
$this->minkContext->pressButton('ra-vetting-button');
}


/**
* @Given /^I visit the "([^"]*)" page in the selfservice portal$/
*/
Expand Down
Loading

0 comments on commit bfd7c7d

Please sign in to comment.