Skip to content

Commit

Permalink
Refactor ACL
Browse files Browse the repository at this point in the history
- Replace PermissionAccess trait with AclTrait. This *only* handles injecting the ACL
- Move enabling/disabling custom roles into Acl implementation
- Add default roles+permissions into Acl
  • Loading branch information
rjmackay committed Jul 19, 2017
1 parent 65b9cdf commit 1a6973f
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 96 deletions.
6 changes: 3 additions & 3 deletions application/classes/Ushahidi/Repository/Form/Stage.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
use Ushahidi\Core\Traits\UserContext;

use Ushahidi\Core\Traits\AdminAccess;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;

class Ushahidi_Repository_Form_Stage extends Ushahidi_Repository implements
FormStageRepository
{
use UserContext;

// Provides `hasPermission`
use PermissionAccess;
// Provides `acl`
use AclTrait;

use PostValueRestrictions;

Expand Down
8 changes: 4 additions & 4 deletions application/classes/Ushahidi/Repository/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
use Ushahidi\Core\Usecase\Set\SetPostRepository;
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\Permissions\ManagePosts;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;
use Ushahidi\Core\Traits\AdminAccess;
use Ushahidi\Core\Tool\Permissions\Permissionable;
use Ushahidi\Core\Traits\PostValueRestrictions;
Expand All @@ -48,8 +48,8 @@ class Ushahidi_Repository_Post extends Ushahidi_Repository implements
// Use the JSON transcoder to encode properties
use Ushahidi_JsonTranscodeRepository;

// Provides `hasPermission`
use PermissionAccess;
// Provides `acl`
use AclTrait;

// Checks if user is Admin
use AdminAccess;
Expand Down Expand Up @@ -492,7 +492,7 @@ protected function setSearchConditions(SearchData $search)
if (!$user->id) {
$query->where("$table.status", '=', 'published');
} elseif (!$this->isUserAdmin($user) and
!$this->hasPermission($user, Permission::MANAGE_POSTS)) {
!$this->acl->hasPermission($user, Permission::MANAGE_POSTS)) {
$query
->and_where_open()
->where("$table.status", '=', 'published')
Expand Down
8 changes: 4 additions & 4 deletions application/classes/Ushahidi/Validator/Post/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Ushahidi\Core\Entity\PostSearchData;
use Ushahidi\Core\Tool\Validator;
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;
use Ushahidi\Core\Traits\AdminAccess;
use Ushahidi\Core\Traits\Permissions\ManagePosts;
use Ushahidi\Core\Usecase\Post\UpdatePostRepository;
Expand All @@ -30,8 +30,8 @@ class Ushahidi_Validator_Post_Create extends Validator
{
use UserContext;

// Provides `hasPermission`
use PermissionAccess;
// Provides `acl`
use AclTrait;

// Checks if user is Admin
use AdminAccess;
Expand Down Expand Up @@ -189,7 +189,7 @@ public function checkApprovalRequired (Validation $validation, $status, $fullDat

$user = $this->getUser();
// Do we have permission to publish this post?
$userCanChangeStatus = ($this->isUserAdmin($user) or $this->hasPermission($user, Permission::MANAGE_POSTS));
$userCanChangeStatus = ($this->isUserAdmin($user) or $this->acl->hasPermission($user, Permission::MANAGE_POSTS));
// .. if yes, any status is ok.
if ($userCanChangeStatus) {
return;
Expand Down
46 changes: 46 additions & 0 deletions src/App/Acl.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,73 @@

use Ushahidi\Core\Tool\Permissions\Acl as AclInterface;
use Ushahidi\Core\Entity\User;
use Ushahidi\Core\Entity\Permission;
use Ushahidi\Core\Entity\RoleRepository;

class Acl implements AclInterface
{
protected $role_repo;
protected $roles_enabled = false;
const DEFAULT_ROLES = [
'user' => [Permission::EDIT_OWN_POSTS]
];

public function setRoleRepo(RoleRepository $role_repo)
{
$this->role_repo = $role_repo;
}

public function setRolesEnabled($roles_enabled)
{
$this->roles_enabled = $roles_enabled;
}

/**
* Check if custom roles are enabled for this deployment
* @return boolean
*/
protected function hasRolesEnabled()
{
return (bool) $this->roles_enabled;
}

// Acl interface
public function hasPermission(User $user, $permission)
{
// If the user has no role, they have no permissions
if (!$user->role) {
return false;
}

// Don't check for permissions if we don't have the
// roles feature enabled
if ($this->hasRolesEnabled()) {
return $this->customRoleHasPermission($user, $permission);
} else {
return $this->defaultHasPermission($user, $permission);
}
}

protected function customRoleHasPermission(User $user, $permission)
{
$role = $this->role_repo->getByName($user->role);

// Does the user have the permission?
return in_array($permission, $role->permissions);
}

protected function defaultHasPermission(User $user, $permission)
{
// Admin has all permissions
// This is probably never actually run, but here just in case
if ($user->role === 'admin') {
return true;
}

$defaultRoles = static::DEFAULT_ROLES;
$rolePermissions = isset($defaultRoles[$user->role]) ? $defaultRoles[$user->role] : [];

// Does the user have the permission?
return in_array($permission, $rolePermissions);
}
}
1 change: 1 addition & 0 deletions src/App/Init.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// Helpers, tools, etc
$di->set('tool.acl', $di->lazyNew('Ushahidi\App\Acl'));
$di->setter['Ushahidi\App\Acl']['setRoleRepo'] = $di->lazyGet('repository.role');
$di->setter['Ushahidi\App\Acl']['setRolesEnabled'] = $di->lazyGet('roles.enabled');

$di->set('tool.hasher.password', $di->lazyNew('Ushahidi\App\Hasher\Password'));
$di->set('tool.authenticator.password', $di->lazyNew('Ushahidi\App\Authenticator\Password'));
Expand Down
6 changes: 3 additions & 3 deletions src/Core/Tool/Authorizer/CSVAuthorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use Ushahidi\Core\Traits\AdminAccess;
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\PrivAccess;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;
use Ushahidi\Core\Traits\DataImportAccess;

class CSVAuthorizer implements Authorizer
Expand All @@ -33,7 +33,7 @@ class CSVAuthorizer implements Authorizer

// Check that the user has the necessary permissions
// if roles are available for this deployment.
use PermissionAccess;
use AclTrait;

// Check if the user can import data
use DataImportAccess;
Expand All @@ -50,7 +50,7 @@ public function isAllowed(Entity $entity, $privilege)
$user = $this->getUser();

// Allow role with the right permissions
if ($this->hasPermission($user, Permission::DATA_IMPORT)) {
if ($this->acl->hasPermission($user, Permission::DATA_IMPORT)) {
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Core/Tool/Authorizer/ConfigAuthorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Ushahidi\Core\Traits\AdminAccess;
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\PrivAccess;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;

// The `ConfigAuthorizer` class is responsible for access checks on `Config` Entities
class ConfigAuthorizer implements Authorizer
Expand All @@ -36,7 +36,7 @@ class ConfigAuthorizer implements Authorizer

// Check that the user has the necessary permissions
// if roles are available for this deployment.
use PermissionAccess;
use AclTrait;

/**
* Public config groups
Expand All @@ -62,7 +62,7 @@ public function isAllowed(Entity $entity, $privilege)
}

// Allow role with the right permissions to do everything else
if ($this->hasPermission($user, Permission::MANAGE_SETTINGS)) {
if ($this->acl->hasPermission($user, Permission::MANAGE_SETTINGS)) {
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Core/Tool/Authorizer/DataProviderAuthorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\AdminAccess;
use Ushahidi\Core\Traits\PrivAccess;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;

// The `DataProviderAuthorizer` class is responsible for access checks on `DataProvider` Entities
class DataProviderAuthorizer implements Authorizer
Expand All @@ -33,7 +33,7 @@ class DataProviderAuthorizer implements Authorizer

// Check that the user has the necessary permissions
// if roles are available for this deployment.
use PermissionAccess;
use AclTrait;

// Authorizer
public function isAllowed(Entity $entity, $privilege)
Expand All @@ -42,7 +42,7 @@ public function isAllowed(Entity $entity, $privilege)
$user = $this->getUser();

// Allow role with the right permissions
if ($this->hasPermission($user, Permission::MANAGE_SETTINGS)) {
if ($this->acl->hasPermission($user, Permission::MANAGE_SETTINGS)) {
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Core/Tool/Authorizer/FormAuthorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
use Ushahidi\Core\Traits\ParentAccess;
use Ushahidi\Core\Traits\PrivAccess;
use Ushahidi\Core\Traits\PrivateDeployment;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;

// The `FormAuthorizer` class is responsible for access checks on `Forms`
class FormAuthorizer implements Authorizer
Expand All @@ -41,7 +41,7 @@ class FormAuthorizer implements Authorizer
use PrivateDeployment;

// Check that the user has the necessary permissions
use PermissionAccess;
use AclTrait;

// It requires a `FormRepository` to load parent posts too.
protected $form_repo;
Expand All @@ -66,7 +66,7 @@ public function isAllowed(Entity $entity, $privilege)
}

// Allow role with the right permissions
if ($this->hasPermission($user, Permission::MANAGE_SETTINGS)) {
if ($this->acl->hasPermission($user, Permission::MANAGE_SETTINGS)) {
return true;
}

Expand Down
8 changes: 4 additions & 4 deletions src/Core/Tool/Authorizer/PostAuthorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
use Ushahidi\Core\Traits\PrivAccess;
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\PrivateDeployment;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;

// The `PostAuthorizer` class is responsible for access checks on `Post` Entities
class PostAuthorizer implements Authorizer
Expand All @@ -47,7 +47,7 @@ class PostAuthorizer implements Authorizer

// Check that the user has the necessary permissions
// if roles are available for this deployment.
use PermissionAccess;
use AclTrait;

/**
* Get a list of all possible privilges.
Expand Down Expand Up @@ -87,7 +87,7 @@ public function isAllowed(Entity $entity, $privilege)
}

// First check whether there is a role with the right permissions
if ($this->hasPermission($user, Permission::MANAGE_POSTS)) {
if ($this->acl->hasPermission($user, Permission::MANAGE_POSTS)) {
return true;
}

Expand Down Expand Up @@ -150,7 +150,7 @@ public function isAllowed(Entity $entity, $privilege)
// ownership but those are already checked above
if ($this->isUserOwner($entity, $user)
&& in_array($privilege, ['update', 'delete'])
&& $this->hasPermission($user, Permission::EDIT_OWN_POSTS)) {
&& $this->acl->hasPermission($user, Permission::EDIT_OWN_POSTS)) {
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Core/Tool/Authorizer/SetAuthorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\PrivAccess;
use Ushahidi\Core\Traits\PrivateDeployment;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;

// The `SetAuthorizer` class is responsible for access checks on `Sets`
class SetAuthorizer implements Authorizer
Expand All @@ -42,7 +42,7 @@ class SetAuthorizer implements Authorizer

// Check that the user has the necessary permissions
// if roles are available for this deployment.
use PermissionAccess;
use AclTrait;

protected function isVisibleToUser(Set $entity, $user)
{
Expand All @@ -66,7 +66,7 @@ public function isAllowed(Entity $entity, $privilege)
}

// First check whether there is a role with the right permissions
if ($this->hasPermission($user, Permission::MANAGE_POSTS)) {
if ($this->acl->hasPermission($user, Permission::MANAGE_POSTS)) {
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Core/Tool/Authorizer/TagAuthorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\PrivAccess;
use Ushahidi\Core\Traits\PrivateDeployment;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;

// The `TagAuthorizer` class is responsible for access checks on `Tags`
class TagAuthorizer implements Authorizer
Expand All @@ -39,7 +39,7 @@ class TagAuthorizer implements Authorizer

// Check that the user has the necessary permissions
// if roles are available for this deployment.
use PermissionAccess;
use AclTrait;

protected function isUserOfRole(Tag $entity, $user)
{
Expand All @@ -63,7 +63,7 @@ public function isAllowed(Entity $entity, $privilege)
}

// First check whether there is a role with the right permissions
if ($this->hasPermission($user, Permission::MANAGE_SETTINGS)) {
if ($this->acl->hasPermission($user, Permission::MANAGE_SETTINGS)) {
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Core/Tool/Authorizer/UserAuthorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use Ushahidi\Core\Traits\UserContext;
use Ushahidi\Core\Traits\PrivAccess;
use Ushahidi\Core\Traits\PrivateDeployment;
use Ushahidi\Core\Traits\PermissionAccess;
use Ushahidi\Core\Tool\Permissions\AclTrait;

// The `UserAuthorizer` class is responsible for access checks on `Users`
class UserAuthorizer implements Authorizer
Expand All @@ -37,7 +37,7 @@ class UserAuthorizer implements Authorizer
use PrivateDeployment;

// Check that the user has the necessary permissions
use PermissionAccess;
use AclTrait;

/**
* Get a list of all possible privilges.
Expand Down Expand Up @@ -66,7 +66,7 @@ public function isAllowed(Entity $entity, $privilege)
}

// Role with the Manage Users permission can manage all users
if ($this->hasPermission($user, Permission::MANAGE_USERS)) {
if ($this->acl->hasPermission($user, Permission::MANAGE_USERS)) {
return true;
}

Expand Down
Loading

0 comments on commit 1a6973f

Please sign in to comment.