ENH add DevAdminConfirmationMiddleware

This commit is contained in:
Andrew Paxley 2023-10-31 17:20:58 +13:00
parent 3244b44a54
commit 78444a44ca
5 changed files with 80 additions and 6 deletions

View File

@ -87,7 +87,7 @@ SilverStripe\Core\Injector\Injector:
DevUrlsConfirmationMiddleware: '%$DevUrlsConfirmationMiddleware'
DevUrlsConfirmationMiddleware:
class: SilverStripe\Control\Middleware\PermissionAwareConfirmationMiddleware
class: SilverStripe\Control\Middleware\DevelopmentAdminConfirmationMiddleware
constructor:
- '%$SilverStripe\Control\Middleware\ConfirmationMiddleware\UrlPathStartswith("dev")'
properties:
@ -97,8 +97,6 @@ SilverStripe\Core\Injector\Injector:
- '%$SilverStripe\Control\Middleware\ConfirmationMiddleware\CliBypass'
- '%$SilverStripe\Control\Middleware\ConfirmationMiddleware\EnvironmentBypass("dev")'
EnforceAuthentication: false
AffectedPermissions:
- ADMIN
---
Name: dev_urls-confirmation-exceptions

View File

@ -0,0 +1,58 @@
<?php
namespace SilverStripe\Control\Middleware;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\DevelopmentAdmin;
use SilverStripe\Security\Permission;
/**
* Extends the PermissionAwareConfirmationMiddleware with checks for user permissions
*
* Respects users who don't have enough access and does not
* ask them for confirmation
*
* By default it enforces authentication by redirecting users to a login page.
*
* How it works:
* - if user can bypass the middleware, then pass request further
* - if there are no confirmation items, then pass request further
* - if user is not authenticated and enforceAuthentication is false, then pass request further
* - if user does not have at least one of the affected permissions, then pass request further
* - otherwise, pass handling to the parent (ConfirmationMiddleware)
*/
class DevelopmentAdminConfirmationMiddleware extends PermissionAwareConfirmationMiddleware
{
/**
* Check whether the user has permissions to perform the target operation
* Otherwise we may want to skip the confirmation dialog.
*
* WARNING! The user has to be authenticated beforehand
*
* @param HTTPRequest $request
*
* @return bool
*/
public function hasAccess(HTTPRequest $request)
{
$action = $request->remaining();
if (empty($action)) {
return false;
}
$registeredRoutes = DevelopmentAdmin::config()->get('registered_controllers');
if (isset($registeredRoutes[$action]['controller'])) {
$initPermissions = Config::forClass($registeredRoutes[$action]['controller'])->get('init_permissions');
foreach ($initPermissions as $permission) {
if (Permission::check($permission)) {
return true;
}
}
}
return false;
}
}

View File

@ -22,6 +22,12 @@ class DevBuildController extends Controller implements PermissionProvider
'build'
];
private static $init_permissions = [
'ADMIN',
'ALL_DEV_ADMIN',
'CAN_DEV_BUILD',
];
protected function init(): void
{
parent::init();
@ -59,7 +65,7 @@ class DevBuildController extends Controller implements PermissionProvider
// We need to ensure that DevelopmentAdminTest can simulate permission failures when running
// "dev/tasks" from CLI.
|| (Director::is_cli() && DevelopmentAdmin::config()->get('allow_all_cli'))
|| Permission::check(['ADMIN', 'ALL_DEV_ADMIN', 'CAN_DEV_BUILD'])
|| Permission::check(static::config()->get('init_permissions'))
);
}

View File

@ -35,6 +35,12 @@ class DevConfigController extends Controller implements PermissionProvider
'audit',
];
private static $init_permissions = [
'ADMIN',
'ALL_DEV_ADMIN',
'CAN_DEV_CONFIG',
];
protected function init(): void
{
parent::init();
@ -148,7 +154,7 @@ class DevConfigController extends Controller implements PermissionProvider
// We need to ensure that DevelopmentAdminTest can simulate permission failures when running
// "dev/tasks" from CLI.
|| (Director::is_cli() && DevelopmentAdmin::config()->get('allow_all_cli'))
|| Permission::check(['ADMIN', 'ALL_DEV_ADMIN', 'CAN_DEV_CONFIG'])
|| Permission::check(static::config()->get('init_permissions'))
);
}

View File

@ -33,6 +33,12 @@ class TaskRunner extends Controller implements PermissionProvider
'runTask',
];
private static $init_permissions = [
'ADMIN',
'ALL_DEV_ADMIN',
'BUILDTASK_CAN_RUN',
];
/**
* @var array
*/
@ -206,7 +212,7 @@ class TaskRunner extends Controller implements PermissionProvider
// We need to ensure that DevelopmentAdminTest can simulate permission failures when running
// "dev/tasks" from CLI.
|| (Director::is_cli() && DevelopmentAdmin::config()->get('allow_all_cli'))
|| Permission::check(['ADMIN', 'ALL_DEV_ADMIN', 'BUILDTASK_CAN_RUN'])
|| Permission::check(static::config()->get('init_permissions'))
);
}