Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F803867
D487.id1248.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Feb 26, 9:00 AM
Size
7 KB
Mime Type
text/x-diff
Expires
Thu, Feb 27, 9:00 AM (10 h, 21 m)
Engine
blob
Format
Raw Data
Handle
576590
Attached To
D487: INP-1877 - Check meta-permissions for "root" user
D487.id1248.diff
View Options
Index: core/kernel/event_handler.php
===================================================================
--- core/kernel/event_handler.php
+++ core/kernel/event_handler.php
@@ -201,26 +201,73 @@
}
/**
- * Checks user permission to execute given $event
+ * Automatically decides what permission checking method to use for a given event/user.
*
- * @param kEvent $event
- * @return bool
- * @access public
+ * @param kEvent $event Event.
+ *
+ * @return boolean
+ */
+ public function AutoCheckPermission(kEvent $event)
+ {
+ if ( $this->Application->permissionCheckingDisabled() ) {
+ return $this->CheckMetaPermission($event);
+ }
+
+ return $this->CheckPermission($event);
+ }
+
+ /**
+ * Checks user static permission to execute given $event.
+ *
+ * @param kEvent $event Event.
+ *
+ * @return boolean
*/
public function CheckPermission(kEvent $event)
{
+ $this->addDynamicPermissionMappings($event);
+
/** @var kPermissionsHelper $perm_helper */
$perm_helper = $this->Application->recallObject('PermissionsHelper');
- if ( !isset($this->permMapping[$event->Name]) ) {
- $ajax_event_name = $this->getAjaxSubEventName($event);
+ return $perm_helper->CheckEventPermission($event, $this->permMapping);
+ }
- if ( $ajax_event_name != '' && isset($this->permMapping[$ajax_event_name]) ) {
- $this->permMapping[$event->Name] = $this->permMapping[$ajax_event_name];
- }
+ /**
+ * Checks user meta-permission to execute given $event.
+ *
+ * @param kEvent $event Event.
+ *
+ * @return boolean
+ */
+ public function CheckMetaPermission(kEvent $event)
+ {
+ $this->addDynamicPermissionMappings($event);
+
+ /** @var kPermissionsHelper $perm_helper */
+ $perm_helper = $this->Application->recallObject('PermissionsHelper');
+
+ return $perm_helper->CheckEventMetaPermission($event, $this->permMapping);
+ }
+
+ /**
+ * Adds dynamic permission mappings.
+ *
+ * @param kEvent $event Event.
+ *
+ * @return void
+ */
+ protected function addDynamicPermissionMappings(kEvent $event)
+ {
+ if ( isset($this->permMapping[$event->Name]) ) {
+ return;
}
- return $perm_helper->CheckEventPermission($event, $this->permMapping);
+ $ajax_event_name = $this->getAjaxSubEventName($event);
+
+ if ( $ajax_event_name != '' && isset($this->permMapping[$ajax_event_name]) ) {
+ $this->permMapping[$event->Name] = $this->permMapping[$ajax_event_name];
+ }
}
/**
@@ -271,4 +318,4 @@
$event->setEventParam('sql', $sql);
}
- }
\ No newline at end of file
+ }
Index: core/kernel/managers/request_manager.php
===================================================================
--- core/kernel/managers/request_manager.php
+++ core/kernel/managers/request_manager.php
@@ -157,7 +157,7 @@
/** @var kEventHandler $event_handler */
$event_handler = $this->Application->recallObject($event->Prefix . '_EventHandler');
- if ( $this->Application->permissionCheckingDisabled() || $event_handler->CheckPermission($event) ) {
+ if ( $event_handler->AutoCheckPermission($event) ) {
$this->Application->HandleEvent($event);
$this->Application->notifyEventSubscribers($event);
}
Index: core/units/helpers/permissions_helper.php
===================================================================
--- core/units/helpers/permissions_helper.php
+++ core/units/helpers/permissions_helper.php
@@ -111,15 +111,15 @@
}
$perm_status = false;
- foreach ($check_perms as $perm_name) {
- // check if at least one of required permissions is set
- if ($perm_name == 'debug' && $this->Application->isDebugMode(false)) {
- // universal "debug" permission
- return true;
- }
- elseif ( $perm_name == 'admin' && $this->Application->isAdminUser ) {
- // any logged-in admin user will suffice
- return true;
+
+ foreach ( $check_perms as $perm_name ) {
+ // Check if at least one of required permissions is set.
+ if ( $this->isMetaPermission($perm_name) ) {
+ if ( $this->checkMetaPermission($perm_name) ) {
+ return true;
+ }
+
+ continue;
}
$perm_name = $section.'.'.$perm_name;
@@ -138,6 +138,78 @@
}
/**
+ * Common event meta-permission checking method.
+ *
+ * @param kEvent $event Event.
+ * @param array $perm_mapping Perm mapping.
+ *
+ * @return boolean
+ */
+ public function CheckEventMetaPermission(kEvent $event, array $perm_mapping)
+ {
+ // This populates "top_prefix" event parameter used in "getPermissionByEvent" method.
+ $event->getSection();
+
+ try {
+ $check_perms = $this->getPermissionByEvent($event, $perm_mapping);
+ }
+ catch ( Exception $e ) {
+ // Permission mapping is absent > grant access.
+ return true;
+ }
+
+ // Event is defined in mapping but is not checked by permissions.
+ if ( $check_perms === true ) {
+ return true;
+ }
+
+ // Event is mapped to a meta-permission > check used meta-permission.
+ foreach ( $check_perms as $perm_name ) {
+ if ( $this->isMetaPermission($perm_name) ) {
+ return $this->finalizePermissionCheck($event, $this->checkMetaPermission($perm_name));
+ }
+ }
+
+ // Event isn't mapped to a meta-permission > grant access.
+ return true;
+ }
+
+ /**
+ * Determines if this is a meta-permission.
+ *
+ * @param string $permission_name Permission name.
+ *
+ * @return boolean
+ */
+ public function isMetaPermission($permission_name)
+ {
+ return $permission_name === 'admin' || $permission_name === 'debug';
+ }
+
+ /**
+ * Determines if this is a meta-permission.
+ *
+ * @param string $permission_name Permission name.
+ *
+ * @return boolean
+ * @throws InvalidArgumentException When a non-meta-permission is given.
+ */
+ public function checkMetaPermission($permission_name)
+ {
+ if ( $permission_name === 'debug' ) {
+ // Universal "debug" permission.
+ return $this->Application->isDebugMode(false);
+ }
+
+ if ( $permission_name === 'admin' ) {
+ // Any logged-in admin user will suffice.
+ return $this->Application->isAdminUser;
+ }
+
+ throw new InvalidArgumentException('The "' . $permission_name . '" permission is not a meta permission.');
+ }
+
+ /**
* Returns owner + primary category for each item (used for permission checking)
*
* @param string $prefix
@@ -260,13 +332,12 @@
continue;
}
- if ( $perm_name == 'debug' && $this->Application->isDebugMode(false) ) {
- // universal "debug" permission
- return true;
- }
- elseif ( $perm_name == 'admin' && $this->Application->isAdminUser ) {
- // any logged-in admin user will suffice
- return true;
+ if ( $this->isMetaPermission($perm_name) ) {
+ if ( $this->checkMetaPermission($perm_name) ) {
+ return true;
+ }
+
+ continue;
}
$perm_name = $item_prefix . '.' . $perm_mapping[$perm_name];
@@ -406,8 +477,8 @@
$permission_groups = getArrayValue($params, 'permissions');
$check_admin = isset($params['admin']) && $params['admin'];
- if ($permission_groups && !$perm_event) {
- // check permissions by permission names in current category
+ if ( $permission_groups && !$perm_event ) {
+ // Check permissions by permission names in current category.
$permission_groups = explode('|', $permission_groups);
$group_has_permission = false;
@@ -444,14 +515,15 @@
}
return false;
}
- elseif ( $perm_event && !$this->Application->permissionCheckingDisabled() ) {
- // check permission by event name
- list ($prefix, ) = explode(':', $perm_event);
+
+ if ( $perm_event ) {
+ // Check permission by event name.
+ list ($prefix,) = explode(':', $perm_event);
/** @var kEventHandler $event_handler */
$event_handler = $this->Application->recallObject($prefix . '_EventHandler');
- return $event_handler->CheckPermission( new kEvent($perm_event) );
+ return $event_handler->AutoCheckPermission(new kEvent($perm_event));
}
return true;
Event Timeline
Log In to Comment