Skip to content

Instantly share code, notes, and snippets.

@statikstasis
Forked from PeeHaa/Action.php
Last active September 3, 2020 18:06
Show Gist options
  • Save statikstasis/68e64b752d1ab7869cf1e03ca2be93eb to your computer and use it in GitHub Desktop.
Save statikstasis/68e64b752d1ab7869cf1e03ca2be93eb to your computer and use it in GitHub Desktop.
RBAC
<?php
namespace Project\Permission;
class Action
{
public const VIEW_SOMETHING = 'view_something';
public const DELETE_SOMETHING = 'delete_something';
private $value;
public function __construct(string $value)
{
$reflection = new \ReflectionClass($this);
if (!in_array($value, $reflection->getConstants(), true) {
throw new Exception('Invalid enum value');
}
$this->value = $value;
}
public function getValue(): string
{
return $this->value;
}
public function isEqualTo(Action $action): bool
{
return $this->value == $action->getValue();
}
}
<?php
namespace Project;
$config = include '../config.file.php';
require_once __DIR__ . '/vendor/autoload.php';
try {
$db = new PDO('mysql:host='.$config['dbhost'].';dbname='.$config['dbname'].';charset=utf8mb4', $config['dbusername'], $config['dbpass']);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch(PDOException $ex) {
echo $ex->getMessage();
}
<?php
namespace Project\Entity;
class Role
{
private $actions;
public function __construct(Action ...$actions)
{
$this->actions = $actions;
}
public function isEntitledTo(Action $action): bool
{
foreach ($this->actions as $allowedAction) {
if ($action->isEqualTo($allowedAction)) {
return true;
}
}
return false;
}
}
<?php
require_once __DIR__ . '/bootstrap.php';
$userRepository = new \Project\Storage\UserRepository($db);
$user = $userRepository->getByUsername('TheUsername');
if ($u->isEntitledTo(new Action(Action::VIEW_SOMETHING))) {
echo "You have permission to view somethin.<br />";
}
<?php
namespace Project\Entity;
class User
{
private $id;
private $name;
private $roles;
public function __construct(int $id, string $name, Role ...$roles)
{
$this->id = $id;
$this->name = $name;
$this->roles = $roles;
}
public function isEntitledTo(Action $action): bool
{
foreach ($this->roles as $role) {
if ($role->isEntitledTo($action)) {
return true;
}
}
return false;
}
}
<?php
namespace Project\Storage;
use Project\Entity\User;
class UserRepository
{
private $db;
public function __construct(PDO $db) {
$this->db = $db;
}
public function getByUsername(string $username)
{
$sql = '
SELECT
rbac_user_roles.USERname,
rbac_user_roles.role_id,
rbac_roles.role_name,
rbac_permissions.permission_id,
rbac_permissions.permission_description
FROM
authorized_users,
rbac_user_roles,
rbac_roles,
rbac_role_permissions,
rbac_permissions
WHERE
authorized_users.USERname = rbac_user_roles.USERname
AND
rbac_user_roles.role_id = rbac_roles.role_id
AND
rbac_role_permissions.permission_id = rbac_permissions.permission_id
AND
rbac_roles.role_id = rbac_role_permissions.role_id
AND
authorized_users.USERname = :username
';
$stmt = $this-db->prepare($sql);
$stmt->execute([
'username' => $username
]);
// build the complete User object including roles etc
return User(/* pass in the data to build the user entity*/);
}
}
@PeeHaa
Copy link

PeeHaa commented Sep 1, 2020

UserRepository::17

$stmt = ' should be $sql = '

And between lines UserRepository::40-UserRepository::42 you need to add:

$stmt = $this-db->prepare($sql);

Role::16-17 should be

         foreach ($this->actions as $allowedAction) {
             if ($action->isEqualTo($allowedAction)) {

User::13 should be:

    public function __construct(int $id, string $name, Role ...$roles)

To see it in action: https://3v4l.org/AuQBn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment