diff --git a/FEATURES/101989 b/FEATURES/101989 new file mode 100644 index 0000000000000000000000000000000000000000..204911bea37ff2dd51350a4e70a8656ebc2ba321 --- /dev/null +++ b/FEATURES/101989 @@ -0,0 +1,10 @@ + '101989' => + ['Label' => $this->_('SSO avec les portails Archimed Syracuse pour l'accès aux ressources numériques'), + 'Desc' => $this->_('Connecteur de bibliothèque numérique pour accès par exemple aux ressources de la médiathèque départementale si elle utilise le système Syracuse'), + 'Image' => '', + 'Video' => '', + 'Category' => $this->_('Ressources numériques'), + 'Right' => function($feature_description, $user) {return true;}, + 'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php/Syracuse', + 'Test' => '', + 'Date' => '2020-02-06'], \ No newline at end of file diff --git a/VERSIONS_WIP/101989 b/VERSIONS_WIP/101989 new file mode 100644 index 0000000000000000000000000000000000000000..1186e568f7d7d54de80683e8e980f9c6e53f080c --- /dev/null +++ b/VERSIONS_WIP/101989 @@ -0,0 +1 @@ + - ticket #101989 : SSO avec les portails Archimed Syracuse pour l'accès aux ressources numériques \ No newline at end of file diff --git a/library/ZendAfi/Controller/Action/Helper/CasValidResponse.php b/library/ZendAfi/Controller/Action/Helper/CasValidResponse.php index 032902a7ca826a0c03f1497ef02abf3843a8d920..5eedb6b03225607f628a2a7e05dd3e7dc891d0a5 100644 --- a/library/ZendAfi/Controller/Action/Helper/CasValidResponse.php +++ b/library/ZendAfi/Controller/Action/Helper/CasValidResponse.php @@ -22,30 +22,46 @@ class ZendAfi_Controller_Action_Helper_CasValidResponse extends Zend_Controller_Action_Helper_Abstract { - public function direct($user, $ticket, $attributes = []) { $this->getActionController()->getHelper('ViewRenderer')->setNoRender(); $this->getResponse()->setHeader('Content-Type', 'application/xml;charset=utf-8'); - $this->getResponse()->setBody("<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'> - <cas:authenticationSuccess> - <cas:user>".$user->getId()."</cas:user> - <cas:proxyGrantingTicket>".$ticket." - </cas:proxyGrantingTicket>". - $this->renderAttributes($attributes). - "</cas:authenticationSuccess> - </cas:serviceResponse>"); + $this->getResponse() + ->setBody("<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n" + . " <cas:authenticationSuccess>\n" + . " <cas:user>".$user->getId()."</cas:user>\n" + . " <cas:proxyGrantingTicket>".$ticket."</cas:proxyGrantingTicket>\n" + . $this->renderAttributes($attributes) + . " </cas:authenticationSuccess>\n" + . "</cas:serviceResponse>"); } + public function renderAttributes($attributes) { if (!$attributes) return ''; - $xml = ''; - foreach($attributes as $key => $value) { - $xml .= '<cas:'.$key.'>'.$value.'</cas:'.$key.'>'; - } - return '<cas:attributes>'.$xml.'</cas:attributes>'; - } + $cas_attributes = []; + $push_attribute = function($name, $value) use (&$cas_attributes) { + $cas_attributes []= sprintf('<cas:%1$s>%2$s</cas:%1$s>', + $name, + $value); + }; + + array_walk($attributes, + function($value_or_array, $name) use ($push_attribute) + { + if (!is_array($value_or_array)) + return $push_attribute($name, $value_or_array); + + foreach($value_or_array as $value) + $push_attribute($name, $value); + }); + + return + " <cas:attributes>\n " + . implode("\n ", $cas_attributes) + . "\n </cas:attributes>\n"; + } } ?> \ No newline at end of file diff --git a/library/digital_resources/Skilleos/tests/SkilleosTest.php b/library/digital_resources/Skilleos/tests/SkilleosTest.php index 61f9e4f7c52d04407234c3b227bb3d22447a477d..5ecc6de6552eac9415a85b1260a07fb0efb8f9a6 100644 --- a/library/digital_resources/Skilleos/tests/SkilleosTest.php +++ b/library/digital_resources/Skilleos/tests/SkilleosTest.php @@ -93,17 +93,30 @@ class SkilleosModulesControllerUserWithGroupWithRightTest } - /** @test */ - public function validateWithValidUserTicketShouldAnswerSuccessAndLibraryName() { - - $ticket = (new Class_CasTicket())->getTicketForCurrentUser(); - $this->dispatch('/Skilleos_Plugin/auth/servicevalidate/service/skilleos/ticket/' . $ticket, - true); - $this->assertContains('<cas:user>666</cas:user>',$this->_response->getBody()); - $this->assertContains('<cas:sn>jumper</cas:sn><cas:mail>jolly@jumper.com</cas:mail><cas:givenName>jolly</cas:givenName><cas:bibId>Tombouctou</cas:bibId>',$this->_response->getBody()); + public function expectedCasTags() { + return [ + ['user', 666], + ['sn', 'jumper'], + ['givenName', 'jolly'], + ['mail', 'jolly@jumper.com'], + ['bibId', 'Tombouctou'], + ]; } + + /** + * @dataProvider expectedCasTags + * @test + */ + public function validateWithValidUserTicketShouldAnswerSuccessAndAttributes($tag, $value) { + $ticket = (new Class_CasTicket())->getTicketForCurrentUser(); + $this->dispatch('/Skilleos_Plugin/auth/servicevalidate/service/skilleos/ticket/' . $ticket); + $this->assertContains('<cas:' . $tag .'>' + . (is_callable($value) ? $value() : $value) + . '</cas:' . $tag . '>', + $this->_response->getBody()); + } } diff --git a/library/digital_resources/Syracuse/Config.php b/library/digital_resources/Syracuse/Config.php new file mode 100644 index 0000000000000000000000000000000000000000..6965a2b07215a7b9f66174f6acebf29fdc2528f8 --- /dev/null +++ b/library/digital_resources/Syracuse/Config.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright (c) 2012-2020, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class Syracuse_Config extends Class_DigitalResource_Config { + protected function _getConfig() { + return ['Introduction' => $this->_('Connexion avec une médiathèque départementale utilisant Syracuse pour l\'accès aux ressources numériques'), + 'AdminVars' => ['SSO_URL' => Class_AdminVar_Meta::newDefault($this->_('URL du serveur CAS Syracuse')) + ->bePrivate()], + 'PermissionLabel' => $this->_('Bibliothèque numérique: accéder aux ressources Syracuse'), + 'SsoAction' => true, + 'Harvesting' => false, + + 'HelpLink' => 'http://wiki.bokeh-library-portal.org/index.php/Syracuse', + 'Url' => 'https://www.archimed.fr/module-solutions-pour-bibliotheque/bibliotheque-numerique/', + 'Icon' => 'https://www.archimed.fr/wp-content/themes/wp-insita-bibdoc/images/logo.png', + + 'MenuLabel' => $this->_('Lien vers Syracuse'), + 'ModuleMenu' => $this->withNameSpace('ModuleMenu'), + 'NotAllowedMessage' => $this->_('Vous devez être abonné pour accéder à cette ressource.'), + ]; + } + + + public function getSsoUrl($user) { + return $this->getAdminVar('SSO_URL') . '&ticket='.(new Class_CasTicket())->getTicketForUser($user); + } + + + public function isEnabled() { + return '' != $this->getAdminVar('SSO_URL'); + } + + + public function renderCustomDiagOn($view) { + return (new Syracuse_View_Helper_Dashboard) + ->setView($view) + ->dashboard(); + } + + + public function getSsoValidateUrl() { + return Class_Url::absolute(['controller' => 'auth', + 'action' => 'serviceValidate']); + } + + + public function validateUrlFor($user) { + return $this->getSsoValidateUrl() + . '?' + . http_build_query(['service' => 'bokeh-test', + 'ticket' => (new Class_CasTicket())->getTicketForUser($user)]); + } + +} +?> \ No newline at end of file diff --git a/library/digital_resources/Syracuse/ModuleMenu.php b/library/digital_resources/Syracuse/ModuleMenu.php new file mode 100644 index 0000000000000000000000000000000000000000..76f469744bcba4c2465f74e3ff80d6672ee36a5a --- /dev/null +++ b/library/digital_resources/Syracuse/ModuleMenu.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright (c) 2012-2020, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class Syracuse_ModuleMenu extends Class_DigitalResource_ModuleMenu {} diff --git a/library/digital_resources/Syracuse/View/Helper/Dashboard.php b/library/digital_resources/Syracuse/View/Helper/Dashboard.php new file mode 100644 index 0000000000000000000000000000000000000000..d92d22abe6b4d62a37928e2143d4c4c77e591350 --- /dev/null +++ b/library/digital_resources/Syracuse/View/Helper/Dashboard.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright (c) 2012-2020, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class Syracuse_View_Helper_Dashboard extends ZendAfi_View_Helper_BaseHelper { + public function dashboard() { + return + $this->_tag('h3', $this->_('Informations à transmettre à Archimed')) + . + $this->_tag('h4', $this->_('Configuration du serveur CAS')) + . + $this->_tag('dl', + $this->_tag('dt', $this->_('URL d\'authentification')) + . + $this->_tag('dd', + $this->_tag('pre', + Class_Url::absolute(['module' => 'opac', + 'controller' => 'cas-server', + 'action' => 'login']))) + . + $this->_tag('dt', $this->_('URL de validation')) + . + $this->_tag('dd', + $this->_tag('pre', + Class_Url::absolute(['controller' => 'auth', + 'action' => 'serviceValidate'])))); + } +} diff --git a/library/digital_resources/Syracuse/controllers/AuthController.php b/library/digital_resources/Syracuse/controllers/AuthController.php new file mode 100644 index 0000000000000000000000000000000000000000..d7933eb2590464c269ed40411c9128b7321a498e --- /dev/null +++ b/library/digital_resources/Syracuse/controllers/AuthController.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright (c) 2012-2020, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class Syracuse_Plugin_AuthController extends Class_DigitalResource_Controller { + public function servicevalidateAction() { + $service = $this->_request->getParam('service'); + $ticket = $this->_request->getParam('ticket'); + if (strlen($ticket)<1 || strlen($service)<1) { + return $this->_helper->casFailureResponse('INVALID_REQUEST'); + } + + if (!$user = (new Class_CasTicket())->userForTicket($ticket)) + return $this->_helper->casFailureResponse('INVALID_TICKET',$ticket); + + $attributes = ['lastname' => $user->getNom(), + 'firstname' => $user->getPrenom(), + 'mail' => $user->getMail(), + 'expire_at' => $user->getDateFin(), + 'card_number' => $user->getIdabon(), + 'site_code' => $user->getLibraryId(), + 'site_label' => $user->getLibelleBib(), + 'birth_date' => $user->getNaissance(), + 'postal_code' => $user->getCodePostal(), + 'city' => $user->getVille(), + 'affiliation' => array_map( + function($group) { + return $group->getLibelle(); + }, + $user->getUserGroups()) + ]; + + return $this->_helper->casValidResponse($user, $ticket, $attributes); + } +} +?> \ No newline at end of file diff --git a/library/digital_resources/Syracuse/controllers/IndexController.php b/library/digital_resources/Syracuse/controllers/IndexController.php new file mode 100644 index 0000000000000000000000000000000000000000..99a70f0c8697129b6e83e5f59b649e0a602ee47b --- /dev/null +++ b/library/digital_resources/Syracuse/controllers/IndexController.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright (c) 2012-2020, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class Syracuse_Plugin_IndexController extends Class_DigitalResource_Controller {} \ No newline at end of file diff --git a/library/digital_resources/Syracuse/tests/SyracuseTest.php b/library/digital_resources/Syracuse/tests/SyracuseTest.php new file mode 100644 index 0000000000000000000000000000000000000000..507ffcdb0a5afb58641d85dd32497779d05d3493 --- /dev/null +++ b/library/digital_resources/Syracuse/tests/SyracuseTest.php @@ -0,0 +1,245 @@ +<?php +/** + * Copyright (c) 2012-2020, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +abstract class SyracuseModulesControllerTestCase extends AbstractControllerTestCase { + protected + $_storm_default_to_volatile = true, + $_user; + + public function setUp() { + parent::setUp(); + Storm_Cache::beVolatile(); + Class_AdminVar::set('Syracuse_SSO_URL', + 'https://mediatheque.departementale.fr/default.aspx?forceLogon=CG_CAS_BDP'); + + $this->fixture('Class_Bib', + ['id' => 34, + 'libelle' => 'Gresivaudan']); + + $this->_user = $this->fixture('Class_Users', + ['id' => 10, + 'nom' => 'Pouce', + 'prenom' => 'Tom', + 'date_fin' => '2020-02-12', + 'naissance' => '1978-08-02', + 'code_postal' => '38123', + 'ville' => 'Laval', + 'idabon' => '123XPE', + 'id_site' => 34, + 'mail' => 'tom@pouce.fr', + 'login' => 'Tom', + 'password' => 'pwd']); + $this->_user + ->addUserGroup($this->fixture('Class_UserGroup', + ['id' => 1, + 'libelle' => 'supremes'])) + ->addUserGroup($this->fixture('Class_UserGroup', + ['id' => 2, + 'libelle' => 'temptations'])) + ->assertSave(); + + ZendAfi_Auth::getInstance()->logUser($this->_user); + } +} + + + + +class SyracuseModulesControllerTest extends SyracuseModulesControllerTestCase { + + /** @test */ + public function userWithoutSIGBAccountShouldNotHaveAccessToSyracuse() { + $this->dispatch('/opac/modules/syracuse'); + $this->assertFlashMessengerContentContains('Vous devez être abonné pour accéder à cette ressource.'); + } + + + /** @test */ + public function userWithoutRightsShouldBeRedirectedToSyracuse() { + $this->_user + ->beAbonneSIGB() + ->setDateFin('2099-02-12') + ->setIdabon('34245') + ->setBib($this->fixture('Class_Bib', + ['id' => 2, + 'libelle' => 'Chambe'])) + ->assertSave(); + $this->dispatch('/opac/modules/syracuse'); + $this->assertFlashMessengerContentContains('Vous devez être abonné pour accéder à cette ressource.'); + } + + + + /** @test */ + public function userGroupPermissionsShouldContainsSyracuse() { + $this->assertContains('Bibliothèque numérique: accéder aux ressources Syracuse', + Class_DigitalResource::getInstance()->getPermissionsLabel()); + } + + + /** @test */ + public function validateAuthWithoutTicketShouldAnswerError() { + $this->dispatch('/Syracuse_Plugin/auth/servicevalidate'); + $this->assertContains('<cas:authenticationFailure code="INVALID_REQUEST">', + $this->_response->getBody()); + } + + + /** @test */ + public function validateAuthWithValidTicketButNoServiceShouldAnswerErrorINVAID_REQUEST() { + $ticket = (new Class_CasTicket())->getTicketForCurrentUser(); + $this->dispatch('/Syracuse_Plugin/auth/servicevalidate/ticket/' . $ticket); + $this->assertContains('<cas:authenticationFailure code="INVALID_REQUEST">', + $this->_response->getBody()); + } + + + /** @test */ + public function validateAuthWithInvalidTicketShouldAnswerError() { + $this->dispatch('/Syracuse_Plugin/auth/servicevalidate/service/blabla/ticket/666'); + $this->assertContains('<cas:authenticationFailure code="INVALID_TICKET"> Ticket 666 not recognized</cas:authenticationFailure>', + $this->_response->getBody()); + } + + + public function expectedCasTags() { + return [ + ['user', 10], + ['proxyGrantingTicket', function() { return (new Class_CasTicket())->getTicketForCurrentUser(); }], + ['lastname', 'Pouce'], + ['firstname', 'Tom'], + ['mail', 'tom@pouce.fr'], + ['expire_at', '2020-02-12'], + ['card_number', '123XPE'], + ['site_code', 34], + ['site_label', 'Gresivaudan'], + ['birth_date', '1978-08-02'], + ['affiliation', 'supremes'], + ['affiliation', 'temptations'], + ['postal_code', '38123'], + ['city', 'Laval'] + ]; + } + + + /** + * @dataProvider expectedCasTags + * @test + */ + public function validateWithValidUserTicketShouldAnswerSuccessAndAttributes($tag, $value) { + $ticket = (new Class_CasTicket())->getTicketForCurrentUser(); + $this->dispatch('/Syracuse_Plugin/auth/servicevalidate/service/syracuse/ticket/' . $ticket); + $this->assertContains('<cas:' . $tag .'>' + . (is_callable($value) ? $value() : $value) + . '</cas:' . $tag . '>', + $this->_response->getBody()); + } + + + /** @test */ + public function validateWithValidUserTicketShouldContainsFifteenCasAttributes() { + $ticket = (new Class_CasTicket())->getTicketForCurrentUser(); + $this->dispatch('/Syracuse_Plugin/auth/servicevalidate/service/syracuse/ticket/' . $ticket); + + preg_match_all('/<cas:[^ >]+>/', + $this->_response->getBody(), + $matches); + $attributes = array_diff($matches[0], ['<cas:authenticationSuccess>']); + $this->assertCount(15, $attributes); + + } + + + /** @test */ + public function modulesMenuShouldBeAvailable() { + $menu = new Class_Systeme_ModulesMenu; + $this->assertEquals('Syracuse', $menu->getFonction('Syracuse')->getType()); + } + + + /** @test */ + public function dashboardShouldContainsUrlCasServiceValidate() { + $this->dispatch('/Syracuse_Plugin'); + $this->assertXPathContentContains('//dl/dd/pre', + 'http://localhost' . Class_Url::baseUrl() . '/Syracuse_Plugin/auth/serviceValidate', + $this->_response->getBody()); + } + + + /** @test */ + public function dashboardShouldContainsUrlCasLogin() { + $this->dispatch('/Syracuse_Plugin'); + $this->assertXPathContentContains('//dl/dd/pre', + 'http://localhost' . Class_Url::baseUrl() . '/cas-server/login', + $this->_response->getBody()); + } +} + + + + +class SyracuseModulesControllerWithRightsTest extends SyracuseModulesControllerTestCase { + public function setUp() { + parent::setUp(); + $group = $this->fixture('Class_UserGroup', + ['id' => 3, + 'libelle' => 'multimedia']); + + $this->fixture('Class_Permission', + ['id' => 1, + 'code' => 'Syracuse']) + ->permitTo($group, new Class_Entity()); + + $this->_user->beAbonneSIGB() + ->setDateFin('2099-02-12') + ->setIdabon('34245') + ->setBib($this->fixture('Class_Bib', + ['id' => 2, + 'libelle' => 'Gresivaudan'])) + ->addUserGroup($group) + ->assertSave(); + } + + + /** @test */ + public function userWithRightsShouldBeRedirectedToSyracuseWithCasTicket() { + $this->dispatch('/opac/modules/syracuse'); + + $ticket = (new Class_CasTicket())->getTicketForCurrentUser(); + $this->assertXpathContentContains('//script', 'document.location.href="https://mediatheque.departementale.fr/default.aspx?forceLogon=CG_CAS_BDP&ticket=' . $ticket . '";'); + } + + + /** @test */ + public function pageShouldContainsUrlSsoTitle() { + $this->dispatch('/Syracuse_Plugin'); + $this->assertXPathContentContains('//h4', 'URL SSO générée par /modules/syracuse pour l\'utilisateur "Syracuse_test_user"'); + } + + + /** @test */ + public function pageShouldContainsSsoUrlForServiceValidate() { + $this->dispatch('/Syracuse_Plugin'); + $ticket = (new Class_CasTicket())->getTicketForUser(Class_Users::findFirstBy(['login' => 'Syracuse_test_user'])); + $this->assertContains('<pre>http://localhost' . Class_Url::baseUrl() . '/Syracuse_Plugin/auth/serviceValidate?service=bokeh-test&ticket=' . $ticket . '</pre>', + $this->_response->getBody()); + } +} \ No newline at end of file