diff --git a/.gitattributes b/.gitattributes index 9c2550989518412877ae7ae8bff1266ae1d0e8db..3ade8d4fc524f20243eae28b438ff3e12b93b4cd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1726,6 +1726,7 @@ library/Class/MultiUpload/HandlerFactory.php -text library/Class/MultiUpload/HandlerForm.php -text library/Class/MultiUpload/HandlerXhr.php -text library/Class/Multimedia.php -text +library/Class/Multimedia/AuthenticateRequest.php -text library/Class/Multimedia/Device.php -text library/Class/Multimedia/DeviceGroup.php -text library/Class/Multimedia/DeviceHold.php -text diff --git a/application/modules/opac/controllers/AbonneController.php b/application/modules/opac/controllers/AbonneController.php index a301644dbe8a41a07b61747ecd33b05e087da0ad..811e2904c8a290962d44be9c181599dc6ce616a9 100644 --- a/application/modules/opac/controllers/AbonneController.php +++ b/application/modules/opac/controllers/AbonneController.php @@ -500,39 +500,28 @@ class AbonneController extends Zend_Controller_Action { $response->auth = 0; $response->until = ''; - if (!($login = $this->_getParam('login')) - || !($password = $this->_getParam('password')) - || !($poste = $this->_getParam('poste'))) { - $response->error = 'MissingParameter'; + $request = Class_Multimedia_AuthenticateRequest::newWithRequest($this->_request); + if (!$request->isValid()) { + $response->error = $request->getError(); $this->_response->setBody(json_encode($response)); return; } - - if (!$user = Class_Users::getLoader()->findFirstBy(array('login' => $login))) { - $response->error = 'UserNotFound'; - $this->_response->setBody(json_encode($response)); - return; - } - - if (($user->getPassword() !== $password)) { - $response->error = 'PasswordIsWrong'; - $this->_response->setBody(json_encode($response)); - return; - } - if (!$user->isAbonnementValid()) { - $response->error='SubscriptionExpired'; - $this->_response->setBody(json_encode($response)); - return; - } - - foreach(array('id', 'login', 'password', 'nom', 'prenom') as $attribute) { + $user = $request->getUser(); + foreach (array('id', 'login', 'password', 'nom', 'prenom') as $attribute) { $response->$attribute = $user->$attribute; } $response->groupes = $user->getUserGroupsLabels(); $response->date_naissance = $user->getDateNaissanceIso8601(); + if (null != ($device = $request->getDevice()) + and null != ($hold = Class_Multimedia_DeviceHold::getLoader()->getCurrentHoldOfUserOnDevice($user, $device)) + ) { + $response->auth = 1; + $response->until = date('c', $hold->getEnd()); + } + $this->_response->setBody(json_encode($response)); } diff --git a/library/Class/Multimedia/AuthenticateRequest.php b/library/Class/Multimedia/AuthenticateRequest.php new file mode 100644 index 0000000000000000000000000000000000000000..9397759505400b015acb556fa628da06f6a098fa --- /dev/null +++ b/library/Class/Multimedia/AuthenticateRequest.php @@ -0,0 +1,114 @@ +<?php +/** + * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved. + * + * AFI-OPAC 2.0 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). + * + * AFI-OPAC 2.0 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 AFI-OPAC 2.0; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +class Class_Multimedia_AuthenticateRequest { + /** @var boolean */ + protected $_valid = false; + + /** @var string */ + protected $_error = ''; + + /** @var Class_Users */ + protected $_user; + + /** @var Class_Multimedia_Device */ + protected $_device; + + + /** + * @param Zend_Controller_Request_Abstract + * @return Class_Multimedia_AuthenticateRequest + */ + public static function newWithRequest($request) { + $instance = new self(); + return $instance->validate($request); + } + + + /** + * @param Zend_Controller_Request_Abstract + * @return Class_Multimedia_AuthenticateRequest + */ + public function validate($request) { + if (!($login = $request->getParam('login')) + || !($password = $request->getParam('password')) + || !($poste = $request->getParam('poste')) + || !($site = $request->getParam('site'))) { + $this->_error = 'MissingParameter'; + return $this; + } + + if (!$user = Class_Users::getLoader()->findFirstBy(array('login' => $login))) { + $this->_error = 'UserNotFound'; + return $this; + } + + if (($user->getPassword() !== $password)) { + $this->_error = 'PasswordIsWrong'; + return $this; + } + + if (!$user->isAbonnementValid()) { + $this->_error = 'SubscriptionExpired'; + return $this; + } + + $this->_user = $user; + + if ($location = Class_Multimedia_Location::getLoader()->findByIdOrigine($site)) + $this->_device = Class_Multimedia_Device::getLoader() + ->findByIdOrigineAndLocation($poste, $location); + + return $this->beValid(); + } + + + /** @return boolean */ + public function isValid() { + return $this->_valid; + } + + + /** @return Class_Multimedia_AuthenticateRequest */ + public function beValid() { + $this->_valid = true; + return $this; + } + + + /** @return string */ + public function getError() { + return $this->_error; + } + + + /** @return Class_Users */ + public function getUser() { + return $this->_user; + } + + + /** @return Class_Multimedia_Device */ + public function getDevice() { + return $this->_device; + } +} +?> \ No newline at end of file diff --git a/library/Class/Multimedia/Device.php b/library/Class/Multimedia/Device.php index 4670ad50eb04f29669c12f4177fd0490364b2b4a..e4d1b79898aff07b0e932b8c735f16cb30117ec3 100644 --- a/library/Class/Multimedia/Device.php +++ b/library/Class/Multimedia/Device.php @@ -26,9 +26,8 @@ class Multimedia_DeviceLoader extends Storm_Model_Loader { * @return Class_Multimedia_DeviceGroup */ public function fromJsonModelWithGroup($json_model, $device_group) { - $id_origine = $device_group->getLocation()->getId() . '-' . $json_model->id; - if (!$model = $this->findFirstBy(array('id_origine' => $id_origine))) - $model = $this->newInstance()->setIdOrigine($id_origine); + if (!$model = $this->findByIdOrigineAndLocation($json_model->id, $device_group->getLocation())) + $model = $this->newInstance()->setIdOrigine($this->getIdOrigineWithLocation($json_model->id, $device_group->getLocation())); $model ->setLibelle($json_model->libelle) ->setOs($json_model->os) @@ -37,6 +36,26 @@ class Multimedia_DeviceLoader extends Storm_Model_Loader { ->save(); return $model; } + + + /** + * @param $id int + * @param $location Class_Multimedia_Location + * @return Class_Multimedia_Device + */ + public function findByIdOrigineAndLocation($id, $location) { + return $this->findFirstBy(array('id_origine' => $this->getIdOrigineWithLocation($id, $location))); + } + + + /** + * @param $id int + * @param $location Class_Multimedia_Location + * @return string + */ + public function getIdOrigineWithLocation($id, $location) { + return $location->getId() . '-' . (int)$id; + } } @@ -107,4 +126,10 @@ class Class_Multimedia_Device extends Storm_Model_Abstract { public function getGroupLibelle() { return $this->getGroup()->getLibelle(); } + + + /** @return int */ + public function getAuthDelay() { + return $this->getGroup()->getAuthDelay(); + } } \ No newline at end of file diff --git a/library/Class/Multimedia/DeviceGroup.php b/library/Class/Multimedia/DeviceGroup.php index c4fa27b60decac7d98dfcdcebcf6297ffe3f580c..0988bf516fcec17d21638f4e469530993c19456a 100644 --- a/library/Class/Multimedia/DeviceGroup.php +++ b/library/Class/Multimedia/DeviceGroup.php @@ -79,4 +79,10 @@ class Class_Multimedia_DeviceGroup extends Storm_Model_Abstract { } return $holdables; } + + + /** @return int */ + public function getAuthDelay() { + return $this->getLocation()->getAuthDelay(); + } } \ No newline at end of file diff --git a/library/Class/Multimedia/DeviceHold.php b/library/Class/Multimedia/DeviceHold.php index 30bd68a3cfec323f634bf2f8748b6f746cb47d91..a7d711fb8386d7fa74ebdbe6d4ff6f60ea3cc1ed 100644 --- a/library/Class/Multimedia/DeviceHold.php +++ b/library/Class/Multimedia/DeviceHold.php @@ -69,6 +69,28 @@ class Multimedia_DeviceHoldloader extends Storm_Model_Loader { } + /** + * @param $user Class_Users + * @param $device Class_Multimedia_Device + * @return Class_Multimedia_DeviceHold + */ + public function getCurrentHoldOfUserOnDevice($user, $device) { + $min_start = $start = time(); + $min_start -= 60 * $device->getAuthDelay(); + $holds = $this->findAll($this->getTable()->select() + ->where('id_user = ' . $user->getId()) + ->where('id_device = ' . $device->getId()) + ->where('start >= ' . $min_start) + ->where('start <= ' . $start)); + + if (count($holds) == 0) + return null; + + $this->cacheInstance($holds[0]); + return $holds[0]; + } + + /** * @param $start int * @param $end int diff --git a/library/Class/Multimedia/Location.php b/library/Class/Multimedia/Location.php index a5b136b6f5004bf0ee3846b5b9e96142cad35860..ca9e7eeb49de3549f4a7ffc9685b0d09ad6e73e6 100644 --- a/library/Class/Multimedia/Location.php +++ b/library/Class/Multimedia/Location.php @@ -63,11 +63,20 @@ class Multimedia_LocationLoader extends Storm_Model_Loader { * @return Class_Multimedia_Location */ public function fromJsonModel($json_model) { - if (!$model = $this->findFirstBy(array('id_origine' => (int)$json_model->id))) + if (!$model = $this->findByIdOrigine($json_model->id)) $model = $this->newInstance()->setIdOrigine((int)$json_model->id); $model->setLibelle($json_model->libelle)->save(); return $model; } + + + /** + * @param int + * $return Class_Multimedia_Location + */ + public function findByIdOrigine($id) { + return $this->findFirstBy(array('id_origine' => (int)$id)); + } } diff --git a/tests/application/modules/opac/controllers/AbonneControllerMultimediaTest.php b/tests/application/modules/opac/controllers/AbonneControllerMultimediaTest.php index 5b6575aedcd1c00b3f7e029cec614199f573e145..48d48b2d7cae828b2a4fdcd776cec0a45bc58412 100644 --- a/tests/application/modules/opac/controllers/AbonneControllerMultimediaTest.php +++ b/tests/application/modules/opac/controllers/AbonneControllerMultimediaTest.php @@ -111,9 +111,16 @@ class AbonneControllerMultimediaAuthenticateTest extends AbstractControllerTestC } + /** @test */ + public function withoutSiteShouldReturnErrorMissingParameter() { + $json = $this->getJson('/abonne/authenticate/login/laurent/password/poste/1'); + $this->assertEquals('MissingParameter', $json->error); + } + + /** @test */ public function getAbonneZorkShouldReturnErrorUserNotFound() { - $json= $this->getJson('/abonne/authenticate/login/zork/password/toto/poste/1'); + $json= $this->getJson('/abonne/authenticate/login/zork/password/toto/poste/1/site/1'); $this->assertEquals("UserNotFound", $json->error); } @@ -121,14 +128,26 @@ class AbonneControllerMultimediaAuthenticateTest extends AbstractControllerTestC /** @test */ public function authenticateAbonneLaurentPasswordXXXShouldReturnWrongPassword() { - $json=$this->getJson('/abonne/authenticate/login/laurent/password/xxx/poste/1'); + $json=$this->getJson('/abonne/authenticate/login/laurent/password/xxx/poste/1/site/1'); $this->assertEquals("PasswordIsWrong", $json->error); } /** @test */ public function rightAuthenticationShouldNotReturnError() { - $json = $this->getJson('/abonne/authenticate/login/laurent/password/afi/poste/1'); + Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Multimedia_Location') + ->whenCalled('findByIdOrigine') + ->answers(Class_Multimedia_Location::getLoader()->newInstanceWithId(1)); + + Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Multimedia_Device') + ->whenCalled('findByIdOrigineAndLocation') + ->answers(Class_Multimedia_Device::getLoader()->newInstanceWithId(1)); + + Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Multimedia_DeviceHold') + ->whenCalled('getCurrentHoldOfUserOnDevice') + ->answers(Class_Multimedia_DeviceHold::getLoader()->newInstanceWithId(333) + ->setEnd(strtotime('2012-09-09 16:40:00'))); + $json = $this->getJson('/abonne/authenticate/login/laurent/password/afi/poste/1/site/1'); $this->assertFalse(property_exists($json, 'error')); return $json; } @@ -194,25 +213,43 @@ class AbonneControllerMultimediaAuthenticateTest extends AbstractControllerTestC public function laurentGroupeShoudBeAdulteAbonneAdminAndAgile($json) { $this->assertEquals(array('adulte','abonne','admin_bib', 'Devs agiles'), $json->groupes); } - - + + + /** + * @test + * @depends rightAuthenticationShouldNotReturnError + */ + public function laurentShouldHaveHold($json) { + $this->assertEquals(1, $json->auth); + } + + + /** + * @test + * @depends rightAuthenticationShouldNotReturnError + */ + public function laurentHoldShouldLastUntil16h40($json) { + $this->assertEquals('2012-09-09T16:40:00+02:00', $json->until); + } + + /** @test */ public function baptisteGroupesShouldBeMineurAbonneAndOldSchool(){ - $json = $this->getJson('/abonne/authenticate/login/baptiste/password/afi/poste/1'); + $json = $this->getJson('/abonne/authenticate/login/baptiste/password/afi/poste/1/site/1'); $this->assertEquals(array('mineur','abonne_sigb', 'Devs Oldschool'), $json->groupes); } /** @test */ public function mireilleAuthenticateShouldReturnSubscriptionExpired(){ - $json=$this->getJson('/abonne/authenticate/login/mireille/password/afi/poste/1'); + $json=$this->getJson('/abonne/authenticate/login/mireille/password/afi/poste/1/site/1'); $this->assertEquals('SubscriptionExpired',$json->error); } /** @test */ public function arnaudGroupesShouldBeInviteAndPatrons() { - $json=$this->getJson('/abonne/authenticate/login/arnaud/password/lelache/poste/1'); + $json=$this->getJson('/abonne/authenticate/login/arnaud/password/lelache/poste/1/site/1'); $this->assertEquals(array('invite', 'Patrons'), $json->groupes); }