/** * The main code of the Dispatcher. It spawns the necessary controller and * runs it. * * @return void * * @throws \Exception */ public function dispatch() { try { $result = $this->onBeforeDispatch(); $error = ''; } catch (\Exception $e) { $result = false; $error = $e->getMessage(); } if (!$result) { // For json, don't use normal 403 page, but a json encoded message if ($this->input->get('format', '') == 'json') { echo json_encode(array('code' => '403', 'error' => $error)); $this->container->application->close(); } throw new \Exception(Text::_('AWF_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); } // Get and execute the controller $view = $this->input->getCmd('view', $this->defaultView); $task = $this->input->getCmd('task', 'default'); if (empty($task)) { $task = 'default'; $this->input->set('task', $task); } $controller = Mvc\Controller::getInstance($this->container->application_name, $view, $this->container); $status = $controller->execute($task); if ($status === false) { throw new \Exception(Text::_('AWF_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); } if (!$this->onAfterDispatch()) { throw new \Exception(Text::_('AWF_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); } $controller->redirect(); }
/** * Checks if the current user has enough privileges for the requested ACL * area. * * @param string $area The ACL area, e.g. core.manage. * * @return bool True if the user has the ACL privilege specified */ protected function checkACL($controller_name, $area) { // If the area is one of false, 0, no or 403 we cancel the action if (in_array(strtolower($area), array('false', '0', 'no', '403'))) { return false; } // If the area is one of true, 1, yes we proceed with the action if (in_array(strtolower($area), array('true', '1', 'yes'))) { return true; } // If no ACL area is specified we proceed with the action if (empty($area)) { return true; } // Get the controller, model and table $container = $this->subject->getContainer(); $application_name = $container->application_name; $component_name = 'com_' . strtolower($application_name); /** @var DataController $controller */ $controller = Controller::getInstance($application_name, $controller_name, $container); $model = $controller->getModel(); // If it's not a data model or it's not assets tracked just perform a regular ACL check on the component if (!$model instanceof DataModel || !$model->getState('_isAssetsTracked', false)) { return Helper::authorise($area, $component_name); } // Initialise $ids = null; // Get the IDs in the request $ids = $controller->getIDsFromRequest($model, false); // If there are no IDs there is no asset tracking, fall back to the generic ACL check if (empty($ids)) { return Helper::authorise($area, $component_name); } // This should never happen unless you screw up overriding getIDsFromRequest in your model... if (!is_array($ids)) { $ids = array($ids); } // Check the asset permissions of each record $resource = Inflector::singularize($controller_name); $isEditState = $area == 'core.edit.state'; foreach ($ids as $id) { $asset = $component_name . '.' . $resource . '.' . $id; // Dedicated permission found, check it! if (Helper::authorise($area, $asset)) { return true; } // No dedicated permissions. Fallback on edit.own. if (!$isEditState && Helper::authorise('core.edit.own', $asset) && $model->hasField('created_by')) { // Load the record $model->find(array('id' => $id)); // Make sure the record can be loaded if ($model->getId()) { // Now test the owner is the user. $owner_id = (int) $model->created_by; // If I am the owner the test is successful if ($owner_id == \JFactory::getUser()->id) { return true; } } } } return false; }
/** * Returns a named Model object. Makes sure that the Model is a database-aware model, throwing an exception * otherwise, when $name is null. * * @param string $name The Model name. If null we'll use the modelName * variable or, if it's empty, the same name as * the Controller * @param array $config Configuration parameters to the Model. If skipped * we will use $this->config * * @return DataModel The instance of the Model known to this Controller * * @throws \Exception When the model type doesn't match our expectations */ public function getModel($name = null, $config = array()) { $model = parent::getModel($name, $config); if (is_null($name) && !$model instanceof DataModel) { throw new \Exception('Model ' . get_class($model) . ' is not a database-aware Model'); } return $model; }