diff --git a/FEATURES/145530 b/FEATURES/145530 new file mode 100644 index 0000000000000000000000000000000000000000..99673b826022cedd445ab9bec51de786a7f10f3b --- /dev/null +++ b/FEATURES/145530 @@ -0,0 +1,10 @@ + '145530' => + ['Label' => $this->_('Fournisseurs d\'identité : option par fournisseur d\'identité le profil sur lequel basculer après authentification'), + 'Desc' => $this->_('À l\'instar de la boîte de connexion, chaque fournisseur d\'identité peut définir un profil sur lequel l\'utilisateur-trice bascule lorsque l\'authentification est complète. Si c\'est un compte invité et que l\'option de basculer sur la pré-inscription est activée, alors la page de pré-inscription sera affichée dans le contexte du profil sélectionné'), + 'Image' => '', + 'Video' => '', + 'Category' => $this->_('Authentification'), + 'Right' => function($feature_description, $user) {return true;}, + 'Wiki' => 'https://wiki.bokeh-library-portal.org/index.php?title=Fournisseurs_d%27identit%C3%A9s', + 'Test' => '', + 'Date' => '2022-08-01'], \ No newline at end of file diff --git a/VERSIONS_WIP/145530 b/VERSIONS_WIP/145530 new file mode 100644 index 0000000000000000000000000000000000000000..a797146c8bc2069806c8cb1888a89974bd77ebc3 --- /dev/null +++ b/VERSIONS_WIP/145530 @@ -0,0 +1 @@ + - fonctionnalité #145530 : Fournisseurs d'identité : option par fournisseur d'identité le profil sur lequel basculer après authentification \ No newline at end of file diff --git a/library/Class/IdentityProvider.php b/library/Class/IdentityProvider.php index 7f422bd17020c7936d0ab12883b9e0dfd589e75f..c8b970669e9d705758fd1bd9e8aca75ad7b51e0c 100644 --- a/library/Class/IdentityProvider.php +++ b/library/Class/IdentityProvider.php @@ -76,6 +76,7 @@ class Class_IdentityProvider extends Storm_Model_Abstract{ 'associate_on_login', 'auto_create_users', 'redirect_to_preregistration', + 'profil_redirect', 'disable_nonce_check', 'scope'], @@ -263,12 +264,22 @@ class Class_IdentityProvider extends Storm_Model_Abstract{ } - public function loginSuccessRedirectUrl() { + public function loginSuccessRedirectUrl() : string { if ($this->getRedirectToPreregistration() && Class_Users::getIdentity()->isInvite()) - return '/auth/pre-registration'; + return $this->_getPreregistrationUrl(); - return $this->getConnector()->loginSuccessRedirectUrl(); + if ($profil = Class_Profil::find($this->getProfilRedirect())) + return $profil->getUrl(); + + return (string)$this->getConnector()->loginSuccessRedirectUrl(); + } + + + protected function _getPreregistrationUrl() : string { + return Class_Url::relative(array_filter(['controller' => 'auth', + 'action' => 'pre-registration', + 'id_profil' => $this->getProfilRedirect()])); } diff --git a/library/ZendAfi/Form/Admin/IdentityProvider.php b/library/ZendAfi/Form/Admin/IdentityProvider.php index 1cbfd8ecfc157c488e5b1b60498644266f143fd8..aa2c9144eb0929ff1a7754cf2bc1368e0be5229a 100644 --- a/library/ZendAfi/Form/Admin/IdentityProvider.php +++ b/library/ZendAfi/Form/Admin/IdentityProvider.php @@ -96,11 +96,15 @@ class ZendAfi_Form_Admin_IdentityProvider extends ZendAfi_Form { 'auto_create_users', ['label' => $this->_('Création automatique des comptes')]) - ->addElement('checkbox', 'redirect_to_preregistration', ['label' => $this->_('Redirection des invités sur la pré-inscription')]) + ->addElement('comboProfils', + 'profil_redirect', + ['label' => $this->_('À la connexion : basculer automatiquement sur le profil'), + 'empty_option' => true]) + ->addElement('multiInput', 'scopes', ['label' => $this->_('Scopes à transmettre'), 'fields' => [['name' => 'scope']]]) diff --git a/tests/scenarios/IdentityProvider/IdentityProviderAdminTest.php b/tests/scenarios/IdentityProvider/IdentityProviderAdminTest.php index d976cfd4df68f55afc3d65898bc4b97d427432af..fd74aa17e74531b4043b882ff5b401c0b6fa123f 100644 --- a/tests/scenarios/IdentityProvider/IdentityProviderAdminTest.php +++ b/tests/scenarios/IdentityProvider/IdentityProviderAdminTest.php @@ -253,6 +253,12 @@ class IdentityProviderAdminEditTest extends IdentityProviderAdminTestCase { } + /** @test */ + public function formShouldContainsSelectProfilRedirectWithOptionProfileOne() { + $this->assertXPathContentContains('//select[@name="profil_redirect"]/optgroup/option[@value="1"]', + 'portail: Accueil'); + } + /** @test */ public function tableShouldContainsCheckboxCreateAutoAccounts() { @@ -387,8 +393,6 @@ class IdentityProviderAdminPostAddCasTest extends IdentityProviderAdminTestCase class IdentityProviderAdminWidgetTest extends Admin_AbstractControllerTestCase { - protected $_storm_default_to_volatile = true; - public function setUp() { parent::setUp(); $simple_widgets = ['modules' => ['1' => ['division' => '1', @@ -407,6 +411,18 @@ class IdentityProviderAdminWidgetTest extends Admin_AbstractControllerTestCase { public function inputTitleShouldBeSeConnecterAvec() { $this->assertXPath('//input[@name="titre"][@value="Se connecter avec"]'); } + + + /** @test */ + public function inputLoggedTitleValueShouldBeAssocierVotreCompte() { + $this->assertXPath('//input[@name="logged_title"][@value="Associer votre compte à "]'); + } + + + /** @test */ + public function inputProviderLoggedTitleValueShouldBeCompteAssocié() { + $this->assertXPath('//input[@name="provider_logged_title"][@value="Compte associé"]'); + } } diff --git a/tests/scenarios/IdentityProvider/IdentityProviderAuthenticationCasTest.php b/tests/scenarios/IdentityProvider/IdentityProviderAuthenticationCasTest.php index 23a98f595d3740d2d5eef360e9f4fed30f6253ae..27925a7316f1eb2c28781253688d1b23f79dc171 100644 --- a/tests/scenarios/IdentityProvider/IdentityProviderAuthenticationCasTest.php +++ b/tests/scenarios/IdentityProvider/IdentityProviderAuthenticationCasTest.php @@ -55,7 +55,7 @@ class IdentityProviderAuthenticationCasRedirectToLoginTest extends IdentityProviderAuthenticationCasTestCase { /** @test */ - public function shouldRedirectToCasServerLogin() { + public function responseShouldRedirectToCasServerLogin() { $this->dispatch('/identity-providers/authenticate/id/1'); $this->assertRedirectContains('http://moncompte.server.com/login?service='); } @@ -92,7 +92,7 @@ class IdentityProviderAuthenticationCasInvalidTicketNotLoggedNotAssociatedTest /** @test */ - public function shouldNotBeRemotelyLogged() { + public function providerShouldNotBeRemotelyLogged() { $this->assertFalse($this->_provider->isRemotelyLogged()); } } @@ -131,19 +131,19 @@ class IdentityProviderAuthenticationCasValidTicketNotLoggedNotAssociatedTest /** @test */ - public function shouldNotValidateTicketTwice() { + public function providerShouldValidateTicketOnlyOnce() { $this->assertEquals(1, Class_WebService_Cas2::getWebClient()->methodCallCount('getResponse')); } /** @test */ - public function shouldDisplayLoginForm() { + public function pageShouldDisplayLoginForm() { $this->assertXPath('//input[@name="username"]'); } /** @test */ - public function shouldBeRemotlyLogged() { + public function providerShouldBeRemotelyLogged() { $this->assertTrue($this->_provider->isRemotelyLogged()); } @@ -254,20 +254,20 @@ class IdentityProviderAuthenticationCasAuthLoginIdentityAssociatedToAnotherTest /** @test */ - public function shouldRedirect() { - $this->assertRedirect(); + public function responseSouldRedirectToRoot() { + $this->assertRedirectTo('/'); } /** @test */ - public function shouldNotDuplicate() { + public function identityShouldNotBeDuplicated() { $this->assertEquals(1, Class_User_Identity::countBy(['identifier' => 'mysuperid', 'provider_id' => 1])); } /** @test */ - public function shouldNotifyAssociationNotComplete() { + public function responseShouldNotifyAssociationNotComplete() { $this->assertFlashMessengerContentContains('L\'association a échoué, cette identité est déjà associée à un autre compte'); } } @@ -311,22 +311,23 @@ class IdentityProviderAuthenticationCasAuthLoginPostAutoAssociationTest public function setUp() { parent::setUp(); - $this->fixture('Class_Users', ['id' => 999, - 'login' => 'mysuperid', - 'password' => 'infopassword']); + $this->fixture(Class_Users::class, + ['id' => 999, + 'login' => 'mysuperid', + 'password' => 'infopassword']); $this->dispatch('/auth/login/provider/1?ticket=testticket'); } /** @test */ - public function shouldRedirect() { - $this->assertRedirect(); + public function responseShouldRedirectToRoot() { + $this->assertRedirectTo('/'); } /** @test */ - public function shouldAssociateOnLogin() { + public function identityShouldBeAssociatedOnLogin() { $this->assertNotNull(Class_User_Identity::findFirstBy(['provider_id' => 1, 'user_id' => 999, 'identifier' => 'mysuperid'])); @@ -334,7 +335,7 @@ class IdentityProviderAuthenticationCasAuthLoginPostAutoAssociationTest /** @test */ - public function shouldBeConnected() { + public function userShouldBeConnected() { $this->assertNotNull(Class_Users::getIdentity()); } } @@ -342,6 +343,39 @@ class IdentityProviderAuthenticationCasAuthLoginPostAutoAssociationTest +class IdentityProviderAuthenticationCasAuthLoginPostAutoAssociationWithProfilRedirectTest + extends IdentityProviderAuthenticationCasAutoAssociationTestCase { + + public function setUp() { + parent::setUp(); + + $this->fixture(Class_Profil::class, + ['id' => 4, + 'libelle' => 'welcome']); + + + $this + ->_provider + ->setConfigValue('profil_redirect', 4); + + $this->fixture(Class_Users::class, + ['id' => 999, + 'login' => 'mysuperid', + 'password' => 'infopassword']); + + $this->dispatch('/auth/login/provider/1?ticket=testticket'); + } + + + /** @test */ + public function responseShouldRedirectToProfilFour() { + $this->assertRedirectTo(Class_Url::absolute('/index/index/id_profil/4')); + } +} + + + + class IdentityProviderAuthenticationCasAuthLoginPostAutoAssociationWithDuplicateTest extends IdentityProviderAuthenticationCasAutoAssociationTestCase { diff --git a/tests/scenarios/IdentityProvider/IdentityProviderAuthenticationOpenIdConnectTest.php b/tests/scenarios/IdentityProvider/IdentityProviderAuthenticationOpenIdConnectTest.php index 8376a456f585c9e1c050f0f8ec8000eb0ec35f00..f3e97ac07e19c4f8c18aa0251c6bdf7f1dc4c3f7 100644 --- a/tests/scenarios/IdentityProvider/IdentityProviderAuthenticationOpenIdConnectTest.php +++ b/tests/scenarios/IdentityProvider/IdentityProviderAuthenticationOpenIdConnectTest.php @@ -308,9 +308,32 @@ class IdentityProviderOpenIdConnectGitlabTest extends IdentityProviderOpenIdConn class IdentityProviderOpenIdConnectAuthLoginWithRedirectPreregistrationTest extends IdentityProviderOpenIdConnectTestCase { + protected $_captain_flam; + public function setUp() { parent::setUp(); - $this->_provider + + $this->_captain_flam = $this->fixture(Class_Users::class, + ['id' => 33, + 'login' => 'captainflam', + 'password' => 'secret', + 'role_level' => ZendAfi_Acl_AdminControllerRoles::INVITE + ]); + + $this->fixture(Class_User_Identity::class, + ['id' => 1, + 'provider_id' => 1, + 'user_id' => $this->_captain_flam->getId(), + 'identifier' => 2]); + + + $this->fixture(Class_Profil::class, + ['id' => 4, + 'libelle' => 'welcome']); + + + $this + ->_provider ->setConfigValue('redirect_to_preregistration', 1); } @@ -329,41 +352,60 @@ class IdentityProviderOpenIdConnectAuthLoginWithRedirectPreregistrationTest exte } - /** @test */ public function withExistingInviteResponseShouldRedirectToPreRegistration() { - $this->fixture(Class_Users::class, - ['id' => 33, - 'login' => 'captainflam', - 'password' => 'secret', - 'role_level' => ZendAfi_Acl_AdminControllerRoles::INVITE - ]); - - $this->fixture(Class_User_Identity::class, - ['id' => 1, - 'provider_id' => 1, - 'user_id' => 33, - 'identifier' => 2]); $this->_loginAndAssertRedirectTo('/auth/pre-registration'); } /** @test */ public function withExistingAbonneResponseShouldNotRedirectToPreRegistrationButRoot() { - $this->fixture(Class_Users::class, - ['id' => 33, - 'login' => 'captainflam', - 'password' => 'secret', - 'id_site' => 3, - 'idabon' => 'abcd123', - 'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB, - ]); + $this + ->_captain_flam + ->beAbonneSIGB() + ->setIdabon('abon123') + ->save(); - $this->fixture(Class_User_Identity::class, - ['id' => 1, - 'provider_id' => 1, - 'user_id' => 33, - 'identifier' => 2]); + $this->_loginAndAssertRedirectTo('/'); + } + + + /** @test */ + public function withExistingInviteResponseAndProfilRedirectFourShouldRedirectToPreRegistrationIdProfilFour() { + $this + ->_provider + ->setConfigValue('profil_redirect', 4); + $this->_loginAndAssertRedirectTo('/auth/pre-registration/id_profil/4'); + } + + + /** @test */ + public function withExistingAbonneResponseAndProfilRedirectFourShouldNotRedirectToPreRegistrationButProfilFour() { + $this + ->_captain_flam + ->beAbonneSIGB() + ->setIdabon('abon123') + ->save(); + + $this + ->_provider + ->setConfigValue('profil_redirect', 4); + + $this->_loginAndAssertRedirectTo(Class_Url::absolute('/index/index/id_profil/4')); + } + + + /** @test */ + public function withExistingAbonneResponseAndUnknownProfilRedirectFourShouldNotRedirectToPreRegistrationButRoot() { + $this + ->_captain_flam + ->beAbonneSIGB() + ->setIdabon('abon123') + ->save(); + + $this + ->_provider + ->setConfigValue('profil_redirect', 666); $this->_loginAndAssertRedirectTo('/'); }