Page MenuHomeIn-Portal Phabricator

D487.id1253.diff
No OneTemporary

File Metadata

Created
Wed, Feb 26, 8:58 AM

D487.id1253.diff

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,84 @@
}
/**
+ * 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)
+ {
+ // For a non-root user a "kEventHandler::CheckPermission" method is overridden to fix below issues.
+ try {
+ /*
+ * Exception will be thrown, when "PermSection" isn't defined.
+ *
+ * This populates "top_prefix" event parameter used in "getPermissionByEvent" method.
+ */
+ $event->getSection();
+
+ // Exception will be thrown if a permission mapping is absent.
+ $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 +338,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 +483,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 +521,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