Replace the base authorization manager with an extended one with a runCallback method
This commit is contained in:
94
src/Authorize/AuthorizationManager.php
Normal file
94
src/Authorize/AuthorizationManager.php
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AVSDev UF Organisations (https://avsdev.uk)
|
||||||
|
*
|
||||||
|
* @link https://git.avsdev.uk/avsdev/sprinkle-organisations
|
||||||
|
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace UserFrosting\Sprinkle\Organisations\Authorize;
|
||||||
|
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
use UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface;
|
||||||
|
use UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager as UFAuthorizationManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AuthorizationManager class.
|
||||||
|
*
|
||||||
|
* Extends the authorization manager and allows for running an authorization callback without fetching it from the internal list.
|
||||||
|
*
|
||||||
|
* @author Craig Williams (https://avsdev.uk)
|
||||||
|
*/
|
||||||
|
class AuthorizationManager extends UFAuthorizationManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run a registered callback directly.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param object $user
|
||||||
|
* @param ... $args
|
||||||
|
*/
|
||||||
|
public function runCallback($user, $name, ...$args)
|
||||||
|
{
|
||||||
|
$debug = $this->ci->config['debug.auth'];
|
||||||
|
$logger = $this->ci->authLogger;
|
||||||
|
|
||||||
|
if (is_null($user) || !($user instanceof UserInterface)) {
|
||||||
|
if ($debug) {
|
||||||
|
$this->ci->authLogger->debug('No user defined. Access denied.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The master (root) account has access to everything.
|
||||||
|
// Need to use loose comparison for now, because some DBs return `id` as a string.
|
||||||
|
if ($user->id == $this->ci->config['reserved_user_ids.master']) {
|
||||||
|
if ($debug) {
|
||||||
|
$this->ci->authLogger->debug('User is the master (root) user. Access granted.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($debug) {
|
||||||
|
$trace = array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3), 1);
|
||||||
|
$this->ci->authLogger->debug('Authorization check requested at: ', $trace);
|
||||||
|
$this->ci->authLogger->debug("Checking authorization for user {$user->id} ('{$user->user_name}') against check '$name'...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($name, $this->callbacks) || !isset($this->callbacks[$name])) {
|
||||||
|
if ($debug) {
|
||||||
|
$this->ci->authLogger->debug('No matching callback found. Access denied.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($debug) {
|
||||||
|
$this->ci->authLogger->debug("Calling check '{$name}' with arguments:", $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = call_user_func_array($this->callbacks[$name], $args);
|
||||||
|
|
||||||
|
if ($result === true) {
|
||||||
|
if ($debug) {
|
||||||
|
$this->ci->authLogger->debug("User passed check '{$name}'. Access granted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
if ($this->debug) {
|
||||||
|
$this->logger->debug("Error running check '$name':" . $e->getMessage() . ". Access denied.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ use Psr\Container\ContainerInterface;
|
|||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use UserFrosting\Sprinkle\Organisations\Database\Models\Interfaces\OrganisationInterface as OrganisationInterface;
|
use UserFrosting\Sprinkle\Organisations\Database\Models\Interfaces\OrganisationInterface as OrganisationInterface;
|
||||||
|
use UserFrosting\Sprinkle\Organisations\Authorize\AuthorizationManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers services for the organisation sprinkle.
|
* Registers services for the organisation sprinkle.
|
||||||
@@ -51,6 +52,9 @@ class ServicesProvider
|
|||||||
* @return \UserFrosting\Sprinkle\Core\Util\ClassMapper
|
* @return \UserFrosting\Sprinkle\Core\Util\ClassMapper
|
||||||
*/
|
*/
|
||||||
$container->extend('authorizer', function ($authorizer, $c) {
|
$container->extend('authorizer', function ($authorizer, $c) {
|
||||||
|
|
||||||
|
$new_authorizer = new AuthorizationManager($c, $authorizer->getCallbacks());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if all $user is a member of $organisation.
|
* Check if all $user is a member of $organisation.
|
||||||
*
|
*
|
||||||
@@ -58,7 +62,7 @@ class ServicesProvider
|
|||||||
* @param int $organisation_id the id of the target organisation.
|
* @param int $organisation_id the id of the target organisation.
|
||||||
* @return bool true if $user is a member of $organisation.
|
* @return bool true if $user is a member of $organisation.
|
||||||
*/
|
*/
|
||||||
$authorizer->addCallback('is_organisation_member', function ($user_id, $organisation_id) {
|
$new_authorizer->addCallback('is_organisation_member', function ($user_id, $organisation_id) {
|
||||||
return Capsule::table('organisation_members')
|
return Capsule::table('organisation_members')
|
||||||
->where('user_id', $user_id)
|
->where('user_id', $user_id)
|
||||||
->where('organisation_id', $organisation_id)
|
->where('organisation_id', $organisation_id)
|
||||||
@@ -72,7 +76,7 @@ class ServicesProvider
|
|||||||
* @param int $organisation_id the id of the target organisation.
|
* @param int $organisation_id the id of the target organisation.
|
||||||
* @return bool true if $user is an administrator of $organisation.
|
* @return bool true if $user is an administrator of $organisation.
|
||||||
*/
|
*/
|
||||||
$authorizer->addCallback('is_organisation_admin', function ($user_id, $organisation_id) {
|
$new_authorizer->addCallback('is_organisation_admin', function ($user_id, $organisation_id) {
|
||||||
return Capsule::table('organisation_members')
|
return Capsule::table('organisation_members')
|
||||||
->where('user_id', $user_id)
|
->where('user_id', $user_id)
|
||||||
->where('organisation_id', $organisation_id)
|
->where('organisation_id', $organisation_id)
|
||||||
@@ -80,7 +84,7 @@ class ServicesProvider
|
|||||||
->count() > 0;
|
->count() > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
return $authorizer;
|
return $new_authorizer;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user