diff --git a/FEATURES/150688 b/FEATURES/150688 new file mode 100644 index 0000000000000000000000000000000000000000..686ec4812096c4f6115ac4d9b8bdbb082beeb7a5 --- /dev/null +++ b/FEATURES/150688 @@ -0,0 +1,10 @@ + '150688' => + ['Label' => $this->_('SIGB Koha - Récupération des catégories d\'adhérents du SIGB'), + 'Desc' => $this->_('Lors de sa connexion à Bokeh, les groupes de l\'utilisateurs sont mis à jour pour refléter la catégorie d\'adhérent dans Koha. Si le groupe n\'existe pas, Bokeh le créé automatiquement dans la catégorie de groupes "Koha"') + 'Image' => '', + 'Video' => '', + 'Category' => '', + 'Right' => function($feature_description, $user) {return true;}, + 'Wiki' => 'https://wiki.bokeh-library-portal.org/index.php?title=SIGB_Koha#Cr.C3.A9ation_des_groupes_Koha_dans_Bokeh', + 'Test' => '', + 'Date' => '2022-02-07'], \ No newline at end of file diff --git a/VERSIONS_WIP/150688 b/VERSIONS_WIP/150688 new file mode 100644 index 0000000000000000000000000000000000000000..0650177455c68e797679dfc85c4408b160df9a1f --- /dev/null +++ b/VERSIONS_WIP/150688 @@ -0,0 +1 @@ + - fonctionnalité #150688 : SIGB Koha - Lors de la connexion de l'utilisateur, sa catégorie d'adhérent dans Koha est créé sous la forme d'un groupe dans Bokeh. \ No newline at end of file diff --git a/cosmogramme/php/fonctions/objets_saisie.php b/cosmogramme/php/fonctions/objets_saisie.php index 9f87adcdc0e7b2bd992383f1e991673510fb2d14..957581db9aa69ffb98bbb0ec841bce2ff73d97c0 100644 --- a/cosmogramme/php/fonctions/objets_saisie.php +++ b/cosmogramme/php/fonctions/objets_saisie.php @@ -138,6 +138,9 @@ function getBlocsParams($id_bib, $type, $valeurs) { ['pre-registration' => function($id, $valeur) { return getOuiNon($id, $valeur); }], + ['create_category_usergroup' => function($id, $valeur) { + return getOuiNon($id, $valeur); + }], 'Interdire_reservation_doc_dispo', 'use_card_number', 'loans_per_page', diff --git a/library/Class/UserGroup.php b/library/Class/UserGroup.php index d048eb52c0db038b5a8f922ded68e67ace83ad19..1152306afce51704dfa8ef0e29a6bc245a3b51d8 100644 --- a/library/Class/UserGroup.php +++ b/library/Class/UserGroup.php @@ -25,6 +25,24 @@ class UserGroupLoader extends Storm_Model_Loader { protected $_dynamics_of_user_cache = []; + public function getOrCreate(Class_UserGroupCategorie $category, + string $label, + Class_Users $user) : Class_UserGroup { + $group = ($group = Class_UserGroup::findFirstBy(['id_cat' => $category->getId(), + 'libelle' => $label])) + ? $group + : ((new Class_UserGroup) + ->setLibelle($label) + ->setIdCat($category->getId())); + + $group + ->addUser($user) + ->save(); + + return $group; + } + + public function save($model) { $result = parent::save($model); if ($model->isDynamic()) diff --git a/library/Class/UserGroupCategorie.php b/library/Class/UserGroupCategorie.php index c402e5f1f0b3283b6d46a275b071012af960ad55..00c6f0ae522fc4f6bbb83d0f52de0cadf46622cb 100644 --- a/library/Class/UserGroupCategorie.php +++ b/library/Class/UserGroupCategorie.php @@ -19,6 +19,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class UserGroupCategorieLoader extends Storm_Model_Loader{ + + + public function getOrCreateByLabel(string $label) : Class_UserGroupCategorie { + if ($categorie = Class_UserGroupCategorie::findFirstBy(['libelle' => $label])) + return $categorie; + + $categorie = (new Class_UserGroupCategorie) + ->setLibelle($label); + + $categorie->save(); + + return $categorie; + } + + public static function getBibRootCategories($bib=null) { return Class_UserGroupCategorie::getTopCategories(); } diff --git a/library/Class/WebService/SIGB/AbstractRESTService.php b/library/Class/WebService/SIGB/AbstractRESTService.php index f2af41d2e3694be46f3ede5f05c0bfb2d1864d64..f1562ea28ecbb44a77df23cfc77fb9b6e3ab778a 100644 --- a/library/Class/WebService/SIGB/AbstractRESTService.php +++ b/library/Class/WebService/SIGB/AbstractRESTService.php @@ -208,7 +208,7 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic * @return Class_WebService_SIGB_Emprunteur */ public function ilsdiGetPatronInfo($params, $reader, $error_tag='error') { - $emprunteur = Class_WebService_SIGB_Emprunteur::newInstance()->setService($this); + $emprunteur = $this->_newEmprunteur()->setService($this); $params = array_merge(array('service' => 'GetPatronInfo'), $params); $xml = $this->httpGet($params); @@ -225,6 +225,11 @@ abstract class Class_WebService_SIGB_AbstractRESTService extends Class_WebServic } + protected function _newEmprunteur() : Class_WebService_SIGB_Emprunteur { + return Class_WebService_SIGB_Emprunteur::newInstance(); + } + + public function ilsdiGetLoansPage($params, $reader, $error_tag='error') { $params = array_merge(array('service' => 'GetPatronInfo'), $params); $xml = $this->httpGet($params); diff --git a/library/Class/WebService/SIGB/Emprunteur.php b/library/Class/WebService/SIGB/Emprunteur.php index 08d7af403b475f4cdf5a3bcef558f155c162a72a..bb3cdbb07ef0c02347c1a014d4d1897024699489 100644 --- a/library/Class/WebService/SIGB/Emprunteur.php +++ b/library/Class/WebService/SIGB/Emprunteur.php @@ -92,7 +92,7 @@ class Class_WebService_SIGB_Emprunteur { * @return Class_WebService_SIGB_Emprunteur */ public static function newInstance($id = '', $name = '') { - return new self($id, $name); + return new static($id, $name); } @@ -114,6 +114,10 @@ class Class_WebService_SIGB_Emprunteur { $this->_name = $name; } + + public function updateUserRelations(Class_Users $user) {} + + /** * @param string $id * @return Class_WebService_SIGB_Emprunteur diff --git a/library/Class/WebService/SIGB/Koha.php b/library/Class/WebService/SIGB/Koha.php index c67a04f72c0c80d3a9565a5fe085298a5e5b984d..0978a718c845dc02ce568faa2dd21705381b07b1 100644 --- a/library/Class/WebService/SIGB/Koha.php +++ b/library/Class/WebService/SIGB/Koha.php @@ -37,6 +37,7 @@ class Class_WebService_SIGB_Koha { 'restful' => '', 'api_community' => '', 'pre-registration' => '', + 'create_category_usergroup' => 0, 'use_card_number' => '', 'loans_per_page' => 0, 'withdrawn_mapping' => '', diff --git a/library/Class/WebService/SIGB/Koha/Emprunteur.php b/library/Class/WebService/SIGB/Koha/Emprunteur.php new file mode 100644 index 0000000000000000000000000000000000000000..42217bd8fbd0fa14a759f4433c834c545416c04b --- /dev/null +++ b/library/Class/WebService/SIGB/Koha/Emprunteur.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright (c) 2012-2022, 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 Class_WebService_SIGB_Koha_Emprunteur extends Class_WebService_SIGB_Emprunteur { + const CATEGORY_KOHA = 'Koha'; + + public function updateUserRelations(Class_Users $user) { + if ( ! $user->getId()) + return; + + if ( ! $this->_service->getCreateCategoryUsergroup() ) + return; + + $category = Class_UserGroupCategorie::getOrCreateByLabel(static::CATEGORY_KOHA); + + foreach($category->getUserGroups() as $group) + $group->removeUser($user)->save(); + + foreach($this->_subscriptions as $label) + Class_UserGroup::getOrCreate($category, $label, $user); + } +} diff --git a/library/Class/WebService/SIGB/Koha/PatronInfoReader.php b/library/Class/WebService/SIGB/Koha/PatronInfoReader.php index b4517b61192fc96b5283a4c4cca2997b072d7c89..3feedac08c66d0f1f2700190bcfb3397d90f8049 100644 --- a/library/Class/WebService/SIGB/Koha/PatronInfoReader.php +++ b/library/Class/WebService/SIGB/Koha/PatronInfoReader.php @@ -110,7 +110,8 @@ class Class_WebService_SIGB_Koha_PatronInfoReader public function endCategorycode($data) { - $this->_emprunteur->subscriptionAdd($data,$data); + $this->_emprunteur->subscriptionAdd($data, + $data); } diff --git a/library/Class/WebService/SIGB/Koha/Service.php b/library/Class/WebService/SIGB/Koha/Service.php index eb8492f2d2b5cedc4da4ab2f6cf664bc31493325..6accb488d400a627f4aa6a7e6903d32b998a192f 100644 --- a/library/Class/WebService/SIGB/Koha/Service.php +++ b/library/Class/WebService/SIGB/Koha/Service.php @@ -27,6 +27,7 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR $restful = false, $api_community = false, $codification_disponibilites = [], + $create_category_usergroup = 0, $loans_per_page = 0, $_withdrawn_mapping = [], $_grouped_holds_itypes = [], @@ -41,7 +42,8 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR ->setRestful($params['restful']==='1') ->setApiCommunity($params['api_community']==='1') ->setPreRegistration($params['pre-registration'] === '1') - ->setLoansPerPage($params['loans_per_page']); + ->setLoansPerPage($params['loans_per_page']) + ->setCreateCategoryUsergroup($params['create_category_usergroup']); } @@ -133,6 +135,17 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR } + public function setCreateCategoryUsergroup($should_create) { + $this->create_category_usergroup = $should_create; + return $this; + } + + + public function getCreateCategoryUsergroup() { + return $this->create_category_usergroup; + } + + public function setLoansPerPage($loans_per_page) { $this->loans_per_page = $loans_per_page; return $this; @@ -180,6 +193,12 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR } + protected function _newEmprunteur() : Class_WebService_SIGB_Emprunteur { + return Class_WebService_SIGB_Koha_Emprunteur::newInstance(); + } + + + protected function getEmprunteurFor($patron_id) { return $this->ilsdiGetPatronInfo(['patron_id' => $patron_id, 'show_contact' => 1, diff --git a/library/ZendAfi/Auth/Adapter/CommSigb.php b/library/ZendAfi/Auth/Adapter/CommSigb.php index 69b925d9e75a402e2d86618d628f3978af6ec939..513eca67ff23423f06238d5be68d5b41a68f9ba4 100644 --- a/library/ZendAfi/Auth/Adapter/CommSigb.php +++ b/library/ZendAfi/Auth/Adapter/CommSigb.php @@ -20,7 +20,11 @@ */ class ZendAfi_Auth_Adapter_CommSigb extends ZendAfi_Auth_Adapter_Abstract { - protected $_called_services; + + protected + $_called_services, + $_loaner; + public function __construct() { $this->_called_services = new Storm_Collection; @@ -146,7 +150,7 @@ class ZendAfi_Auth_Adapter_CommSigb extends ZendAfi_Auth_Adapter_Abstract { if (!$loaner->isValid()) return; - if(!$loaner = $this->_loanerWithValidPassword($user, $loaner)) + if( !$loaner = $this->_loaner = $this->_loanerWithValidPassword($user, $loaner)) return; $loaner->updateUser($user); @@ -195,10 +199,14 @@ class ZendAfi_Auth_Adapter_CommSigb extends ZendAfi_Auth_Adapter_Abstract { if(!$user) return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND, $this->_identity); - if(!$user->save()) + if ( !$user->save()) $result = new Zend_Auth_Result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND, $this->_identity); $this->_authenticated_user = $user; + + if ( $this->_loaner ) + $this->_loaner->updateUserRelations($user); + return $result; } } diff --git a/tests/library/Class/WebService/SIGB/KohaTest.php b/tests/library/Class/WebService/SIGB/KohaTest.php index 07e2742fa88e005f561651909f3ae414d374f69b..be06685f367ff105b2830da412a9811147334d06 100644 --- a/tests/library/Class/WebService/SIGB/KohaTest.php +++ b/tests/library/Class/WebService/SIGB/KohaTest.php @@ -459,6 +459,8 @@ class KohaGetEmprunteurErrorTest extends KohaTestCase { class KohaGetEmprunteurLaureAfondTest extends KohaTestCase { + protected $_group; + public function setUp() { parent::setUp(); @@ -493,20 +495,12 @@ class KohaGetEmprunteurLaureAfondTest extends KohaTestCase { ->with('http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl?service=GetPatronInfo&patron_id=572&show_contact=0&show_loans=1&show_holds=0') ->answers(KohaFixtures::xmlGetPatronInfoLaureLoans()) ->beStrict(); -; - - $this->laurent = $this->service - ->getEmprunteur(Class_Users::newInstance() - ->setLogin('lafond') - ->setPassword('afi') - ->setIdabon('012345')); + $user_laurent = Class_Users::newInstance(['login' => 'lafond', + 'password' => 'afi', + 'idabon' => '012345']); - $this->pierre = $this->service - ->getEmprunteur(Class_Users::newInstance() - ->setLogin('pierre') - ->setPassword('toto') - ->setIdabon('9865')); + $this->laurent = $this->service->getEmprunteur($user_laurent); } @@ -517,20 +511,27 @@ class KohaGetEmprunteurLaureAfondTest extends KohaTestCase { /** @test */ - public function subscriptionShouldBeINDIVIDU() { - $this->assertEquals(['INDIVIDU' => 'INDIVIDU'], $this->laurent->getSubscriptions()); + public function getIdShouldReturn572() { + $this->assertEquals(572, $this->laurent->getId()); } /** @test */ - public function getIdShouldReturn572() { - $this->assertEquals(572, $this->laurent->getId()); + public function subscriptionShouldBeINDIVIDU() { + $this->assertEquals(['INDIVIDU' => 'INDIVIDU'], + $this->laurent->getSubscriptions()); } /** @test */ public function getHoldsWaitingToBePulledForPierreShouldReturn0Holds() { - $this->assertCount(0, $this->pierre->getHoldsWaitingToBePulled()); + $pierre = $this->service + ->getEmprunteur(Class_Users::newInstance() + ->setLogin('pierre') + ->setPassword('toto') + ->setIdabon('9865')); + + $this->assertCount(0, $pierre->getHoldsWaitingToBePulled()); } @@ -1997,3 +1998,196 @@ class KohaGetEmprunteurLisianneWithPagedLoansAndIdSIGBTest extends KohaTestCase $this->assertEquals("Malte",$this->lisianne->getEmpruntAt(1)->getTitre()); } } + + + + +abstract class KohaAuthenticationGroupsTestCase extends ModelTestCase { + protected $_comm_params = ['url_serveur' => 'http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl', + 'id_bib' => 74, + 'type' => Class_IntBib::COM_KOHA, + 'create_category_usergroup' => 1]; + + public function setUp() { + parent::setUp(); + + $this->fixture(Class_Bib::class, ['id' => 74, + 'libelle' => 'KohaBib']); + + $this->fixture(Class_IntBib::class, + ['id' => 74, + 'comm_sigb' => Class_IntBib::COM_KOHA, + 'nom_court' => 'KohaCity', + 'comm_params' => $this->_comm_params]); + + Class_WebService_SIGB_Koha::getService($this->_comm_params) + ->setWebClient($mock_web_client = $this->mock()); + + $mock_web_client + ->whenCalled('postData') + ->with('http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl', + ['service' => 'AuthenticatePatron', + 'username' => 'lafond', + 'password' => 'afi']) + ->answers(KohaFixtures::xmlLookupPatronLaure()) + + ->whenCalled('open_url') + ->with('http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl?service=GetPatronInfo&patron_id=572&show_contact=1&show_loans=0&show_holds=1') + ->answers(KohaFixtures::xmlGetPatronInfoLaure()) + + ->whenCalled('open_url') + ->with('http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl?service=GetPatronInfo&patron_id=572&show_contact=0&show_loans=1&show_holds=0') + ->answers(KohaFixtures::xmlGetPatronInfoLaureLoans()) + ->beStrict(); + } +} + + + + +class KohaAuthenticationGroupsNewUserTest extends KohaAuthenticationGroupsTestCase { + public function setUp() { + parent::setUp(); + + $adapter = (new ZendAfi_Auth_Adapter_CommSigb()) + ->setIdentity('lafond') + ->setCredential('afi'); + + $this->_result = $adapter->authenticate(); + + $this->_group = Class_UserGroup::findFirstBy(['libelle' => 'INDIVIDU']); + } + + + /** @test */ + public function resultShouldBeValid() { + $this->assertTrue($this->_result->isValid()); + } + + + /** @test */ + public function dbShouldContainsUserWithLoginLafond() { + $this->assertNotNull(Class_Users::findFirstBy(['login' => 'lafond'])); + } + + + /** @test */ + public function groupIndividuShouldHaveBeenCreated() { + $this->assertNotNull($this->_group); + } + + + /** @test */ + public function groupIndividuShouldHaveParentGroupesKoha() { + $this->assertEquals($this->_group->getIdCat(), + Class_UserGroupCategorie::findFirstBy(['libelle' => 'Koha'])->getId()); + } + + + /** @test */ + public function userLafondShouldBelongToGroupLecteurIndividuel() { + $this->assertContains(Class_Users::findFirstBy(['login' => 'lafond'])->getId(), + $this->_group->getUsersIds()); + } +} + + + + +class KohaAuthenticationGroupsExistingUserTest extends KohaAuthenticationGroupsTestCase { + public function setUp() { + parent::setUp(); + + $category_koha = $this->fixture(Class_UserGroupCategorie::class, + ['id' => 9, + 'libelle' => 'Koha']); + + $this->fixture(Class_UserGroup::class, + ['id' => 2, + 'libelle' => 'INDIVIDU', + 'categorie' => $category_koha]); + + $user = $this->fixture(Class_Users::class, + ['id' => 5, + 'login' => 'lafond', + 'password' => 'afi', + 'id_sigb' => 572, + 'id_int_bib' => 74, + 'id_site' => 74, + 'idabon' => '10002000', + 'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB, + 'user_groups' => [$this->fixture(Class_UserGroup::class, + ['id' => 7, + 'libelle' => 'Enfant', + 'categorie' => $category_koha])]]); + + (new ZendAfi_Auth_Adapter_CommSigb()) + ->setIdentity('lafond') + ->setCredential('afi') + ->authenticate(); + } + + + /** @test */ + public function groupEnfantShouldBeEmpty() { + $this->assertEmpty(Class_UserGroup::findFirstBy(['libelle' => 'Enfant']) + ->getUsers()); + } + + + /** @test */ + public function groupIndividuShouldBeUnique() { + $this->assertCount(1, Class_UserGroup::findAllBy(['libelle' => 'INDIVIDU'])); + } + + + /** @test */ + public function groupIndividuShouldContainUserLafond() { + $this->assertContains(Class_Users::find(5), + Class_UserGroup::findFirstBy(['libelle' => 'INDIVIDU'])->getUsers()); + } +} + + + + +class KohaAuthenticationNoGroupsTestCase extends KohaAuthenticationGroupsTestCase { + protected $_comm_params = ['url_serveur' => 'http://cat-aficg55.biblibre.com/cgi-bin/koha/ilsdi.pl', + 'id_bib' => 74, + 'type' => Class_IntBib::COM_KOHA, + 'create_category_usergroup' => 0]; + + protected $_storm_default_to_volatile = true; + + + public function setUp() { + parent::setUp(); + + $user = $this->fixture(Class_Users::class, + ['id' => 5, + 'login' => 'lafond', + 'password' => 'afi', + 'id_sigb' => 572, + 'id_int_bib' => 74, + 'id_site' => 74, + 'idabon' => '10002000', + 'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB]); + + (new ZendAfi_Auth_Adapter_CommSigb()) + ->setIdentity('lafond') + ->setCredential('afi') + ->authenticate(); + } + + + /** @test */ + public function groupCategoryKohaShouldNotBe() { + $this->assertEmpty(Class_UserGroupCategorie::findFirstBy(['libelle' => 'Koha'])); + } + + + /** @test */ + public function groupIndividuShouldNotBe() { + $this->assertNull(Class_UserGroup::findFirstBy(['libelle' => 'INDIVIDU'])); + } +} \ No newline at end of file