Add ACL Manipulator

This commit is contained in:
Nicolas Le Goff
2013-11-05 18:58:44 +01:00
parent db4286c506
commit 4cef82083c
8 changed files with 271 additions and 56 deletions

View File

@@ -64,6 +64,9 @@ class CreateCollection extends Command
}
}
\User_Adapter::reset_sys_admins_rights($this->container);
$app = $this->container;
$this->container['manipulator.acl']->resetAdminRights(array_map(function ($id) use ($app) {
return \User_Adapter::getInstance($id, $app);
}, array_keys(\User_Adapter::get_sys_admins($this->container))));
}
}

View File

@@ -137,7 +137,9 @@ class Dashboard implements ControllerProviderInterface
*/
public function resetAdminRights(Application $app, Request $request)
{
\User_Adapter::reset_sys_admins_rights($app);
$app['manipulator.acl']->resetAdminRights(array_map(function ($id) use ($app) {
return \User_Adapter::getInstance($id, $app);
}, array_keys(\User_Adapter::get_sys_admins($app))));
return $app->redirectPath('admin_dashbord');
}
@@ -159,7 +161,9 @@ class Dashboard implements ControllerProviderInterface
if ($admins > 0) {
\User_Adapter::set_sys_admins($app, array_filter($admins));
\User_Adapter::reset_sys_admins_rights($app);
$app['manipulator.acl']->resetAdminRights(array_map(function ($id) use ($app) {
return \User_Adapter::getInstance($id, $app);
}, array_keys(\User_Adapter::get_sys_admins($app))));
}
}

View File

@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Model\Manipulator\ACLManipulator;
use Alchemy\Phrasea\Model\Manipulator\TaskManipulator;
use Alchemy\Phrasea\Model\Manipulator\UserManipulator;
use Alchemy\Phrasea\Model\Manager\UserManager;
@@ -28,6 +29,11 @@ class ManipulatorServiceProvider implements ServiceProviderInterface
$app['manipulator.user'] = $app->share(function ($app) {
return new UserManipulator($app['model.user-manager'], $app['auth.password-encoder'], $app['geonames.connector']);
});
$app['manipulator.acl'] = $app->share(function ($app) {
return new ACLManipulator($app['acl'], $app['phraseanet.appbox']);
});
$app['model.user-manager'] = $app->share(function ($app) {
return new UserManager($app['EM'], $app['phraseanet.appbox']->get_connection());
});

View File

@@ -0,0 +1,148 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Model\Manipulator;
use Alchemy\Phrasea\Authentication\ACLProvider;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Exception\LogicException;
class ACLManipulator implements ManipulatorInterface
{
/** @var ACLProvider */
private $ACLProvider;
/** @var \appbox */
private $appbox;
public function __construct(ACLProvider $ACLProvider, \appbox $appbox)
{
$this->ACLProvider = $ACLProvider;
$this->appbox = $appbox;
}
/**
* @throws LogicException
*/
public function getRepository()
{
throw new LogicException('ACL class is not a doctrine entity and therefore it does not have repository.');
}
/**
* Resets rights for users.
*
* @param User_Adapter $user
*
* @throws InvalidArgumentException
*/
public function resetAdminRights($users)
{
foreach($this->makeTraversable($users) as $user) {
$this->doResetAdminRights($user);
}
}
/**
* Resets rights for a user.
*
* @param \User_adapter $user
*/
private function doResetAdminRights(\User_adapter $user)
{
$acl = $this->ACLProvider->get($user);
$databoxes = $this->appbox->get_databoxes();
$acl->give_access_to_sbas(array_map(function (\databox $databox) {
return $databox->get_sbas_id();
}, $databoxes));
foreach ($databoxes as $databox) {
$this->doResetAdminRightsOnDatabox($acl, $databox);
}
}
/**
* Resets admin rights on a databox.
*
* @param \ACL $acl
* @param \databox $databox
*/
private function doResetAdminRightsOnDatabox(\ACL $acl, \databox $databox)
{
$collections = $databox->get_collections();
$acl->update_rights_to_sbas($databox->get_sbas_id(), array(
'bas_manage' => '1',
'bas_modify_struct' => '1',
'bas_modif_th' => '1',
'bas_chupub' => '1'
));
$acl->give_access_to_base(array_map(function (\collection $collection) {
return $collection->get_base_id();
}, $collections));
foreach ($collections as $collection) {
$this->doResetRightsOnCollection($acl, $collection);
}
}
/**
* Resets admin rights on a collection.
*
* @param \ACL $acl
* @param \collection $collection
*/
private function doResetRightsOnCollection(\ACL $acl, \collection $collection)
{
$baseId = $collection->get_base_id();
$acl->set_limits($baseId, false);
$acl->remove_quotas_on_base($baseId);
$acl->set_masks_on_base($baseId, '0', '0', '0', '0');
$acl->update_rights_to_base($baseId, array(
'canputinalbum' => '1',
'candwnldhd' => '1',
'candwnldsubdef' => '1',
'nowatermark' => '1',
'candwnldpreview' => '1',
'cancmd' => '1',
'canadmin' => '1',
'canreport' => '1',
'canpush' => '1',
'creationdate' => '1',
'canaddrecord' => '1',
'canmodifrecord' => '1',
'candeleterecord' => '1',
'chgstatus' => '1',
'imgtools' => '1',
'manage' => '1',
'modify_struct' => '1',
'bas_modify_struct' => '1'
));
}
/**
* Makes given variable traversable.
*
* @param mixed $var
*
* @return array
*/
private function makeTraversable($var)
{
if (!is_array($var) && !$var instanceof \Traversable) {
return array($var);
}
return $var;
}
}

View File

@@ -1224,57 +1224,6 @@ class User_Adapter implements User_Interface, cache_cacheableInterface
return false;
}
public static function reset_sys_admins_rights(Application $app)
{
$users = self::get_sys_admins($app);
foreach ($app['phraseanet.appbox']->get_databoxes() as $databox) {
foreach (array_keys($users) as $usr_id) {
$user = User_Adapter::getInstance($usr_id, $app);
$app['acl']->get($user)->give_access_to_sbas(array($databox->get_sbas_id()));
$rights = array(
'bas_manage' => '1'
, 'bas_modify_struct' => '1'
, 'bas_modif_th' => '1'
, 'bas_chupub' => '1'
);
$app['acl']->get($user)->update_rights_to_sbas($databox->get_sbas_id(), $rights);
foreach ($databox->get_collections() as $collection) {
$app['acl']->get($user)->give_access_to_base(array($collection->get_base_id()));
$rights = array(
'canputinalbum' => '1'
, 'candwnldhd' => '1'
, 'candwnldsubdef' => '1'
, 'nowatermark' => '1'
, 'candwnldpreview' => '1'
, 'cancmd' => '1'
, 'canadmin' => '1'
, 'canreport' => '1'
, 'canpush' => '1'
, 'creationdate' => '1'
, 'canaddrecord' => '1'
, 'canmodifrecord' => '1'
, 'candeleterecord' => '1'
, 'chgstatus' => '1'
, 'imgtools' => '1'
, 'manage' => '1'
, 'modify_struct' => '1'
, 'bas_modify_struct' => '1'
);
$app['acl']->get($user)->update_rights_to_base($collection->get_base_id(), $rights);
$app['acl']->get($user)->set_limits($collection->get_base_id(), false);
}
}
}
return;
}
public function get_locale()
{
return $this->locale ?: $this->app['phraseanet.registry']->get('GV_default_lng', 'en_GB');

View File

@@ -118,8 +118,6 @@ interface User_Interface
public static function set_sys_admins(Application $app, $admins);
public static function reset_sys_admins_rights(Application $app);
public function get_locale();
public static function create(Application $app, $login, $password, $email, $admin, $invite = false);

View File

@@ -12,6 +12,11 @@ class ManipulatorServiceProvidertest extends ServiceProviderTestCase
'manipulator.task',
'Alchemy\Phrasea\Model\Manipulator\TaskManipulator'
),
array(
'Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider',
'manipulator.acl',
'Alchemy\Phrasea\Model\Manipulator\ACLManipulator'
),
);
}
}

View File

@@ -0,0 +1,102 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Tests\Phrasea\Model\Manipulator;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
class ACLManipulatorTest extends \PhraseanetPHPUnitAbstract
{
public function testResetAdminRights()
{
$user = \User_Adapter::create(self::$DI['app'], uniqid('toto'), 'toto', null, true);
$acl = self::$DI['app']['acl']->get($user);
$databoxId = null;
$baseId = null;
foreach(self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$databoxId = $databox->get_sbas_id();
$acl->update_rights_to_sbas($databoxId, array(
'bas_manage' => '0',
'bas_modify_struct' => '0',
'bas_modif_th' => '0',
'bas_chupub' => '0'
));
foreach($databox->get_collections() as $collection) {
$baseId = $collection->get_base_id();
$acl->set_limits($baseId, true);
$acl->set_masks_on_base($baseId, '1', '1', '1', '1');
$acl->update_rights_to_base($baseId, array(
'canputinalbum' => '0',
'candwnldhd' => '0',
'candwnldsubdef' => '0',
'nowatermark' => '0',
'candwnldpreview' => '0',
'cancmd' => '0',
'canadmin' => '0',
'canreport' => '0',
'canpush' => '0',
'creationdate' => '0',
'canaddrecord' => '0',
'canmodifrecord' => '0',
'candeleterecord' => '0',
'chgstatus' => '0',
'imgtools' => '0',
'manage' => '0',
'modify_struct' => '0',
'bas_modify_struct' => '0'
));
break 2;
}
}
self::$DI['app']['manipulator.acl']->resetAdminRights($user);
self::$DI['app']['acl']->purge();
$acl = self::$DI['app']['acl']->get($user);
if ($baseId === null) {
$this->fail("Need at least one collection");
}
$this->assertTrue($acl->has_right_on_sbas($databoxId, 'bas_manage'));
$this->assertTrue($acl->has_right_on_sbas($databoxId, 'bas_modify_struct'));
$this->assertTrue($acl->has_right_on_sbas($databoxId, 'bas_modif_th'));
$this->assertTrue($acl->has_right_on_sbas($databoxId, 'bas_chupub'));
$this->assertTrue($acl->has_right_on_base($baseId, 'canputinalbum'));
$this->assertTrue($acl->has_right_on_base($baseId, 'candwnldhd'));
$this->assertTrue($acl->has_right_on_base($baseId, 'nowatermark'));
$this->assertTrue($acl->has_right_on_base($baseId, 'candwnldpreview'));
$this->assertTrue($acl->has_right_on_base($baseId, 'cancmd'));
$this->assertTrue($acl->has_right_on_base($baseId, 'canadmin'));
$this->assertTrue($acl->has_right_on_base($baseId, 'canreport'));
$this->assertTrue($acl->has_right_on_base($baseId, 'canpush'));
$this->assertTrue($acl->has_right_on_base($baseId, 'canaddrecord'));
$this->assertTrue($acl->has_right_on_base($baseId, 'canmodifrecord'));
$this->assertTrue($acl->has_right_on_base($baseId, 'candeleterecord'));
$this->assertTrue($acl->has_right_on_base($baseId, 'chgstatus'));
$this->assertTrue($acl->has_right_on_base($baseId, 'imgtools'));
$this->assertTrue($acl->has_right_on_base($baseId, 'manage'));
$this->assertTrue($acl->has_right_on_base($baseId, 'modify_struct'));
$this->assertEquals(0, $acl->get_limits($baseId));
$this->assertEquals(0, $acl->get_limits($acl->get_mask_xor($baseId)));
$this->assertEquals(0, $acl->get_limits($acl->get_mask_and($baseId)));
$user->delete();
}
}