protected function init() { parent::init(); if (!Director::is_cli() && !Permission::check('ADMIN')) { return Security::permissionFailure(); } }
public function init() { parent::init(); if (!Permission::check('ADMIN')) { return Security::permissionFailure($this); } }
public function getEditForm($id = null, $fields = null) { // TODO Duplicate record fetching (see parent implementation) if (!$id) { $id = $this->currentPageID(); } $form = parent::getEditForm($id); // TODO Duplicate record fetching (see parent implementation) $record = $this->getRecord($id); if ($record && !$record->canView()) { return Security::permissionFailure($this); } $memberList = GridField::create('Members', false, Member::get(), $memberListConfig = GridFieldConfig_RecordEditor::create()->addComponent(new GridFieldButtonRow('after'))->addComponent(new GridFieldExportButton('buttons-after-left')))->addExtraClass("members_grid"); if ($record && method_exists($record, 'getValidator')) { $validator = $record->getValidator(); } else { $validator = Member::singleton()->getValidator(); } $memberListConfig->getComponentByType('GridFieldDetailForm')->setValidator($validator); $groupList = GridField::create('Groups', false, Group::get(), GridFieldConfig_RecordEditor::create()); $columns = $groupList->getConfig()->getComponentByType('GridFieldDataColumns'); $columns->setDisplayFields(array('Breadcrumbs' => singleton('SilverStripe\\Security\\Group')->fieldLabel('Title'))); $columns->setFieldFormatting(array('Breadcrumbs' => function ($val, $item) { return Convert::raw2xml($item->getBreadcrumbs(' > ')); })); $fields = new FieldList($root = new TabSet('Root', $usersTab = new Tab('Users', _t('SecurityAdmin.Users', 'Users'), new LiteralField('MembersCautionText', sprintf('<div class="alert alert-warning" role="alert">%s</div>', _t('SecurityAdmin.MemberListCaution', 'Caution: Removing members from this list will remove them from all groups and the database'))), $memberList), $groupsTab = new Tab('Groups', singleton('SilverStripe\\Security\\Group')->i18n_plural_name(), $groupList)), new HiddenField('ID', false, 0)); // Add import capabilities. Limit to admin since the import logic can affect assigned permissions if (Permission::check('ADMIN')) { $fields->addFieldsToTab('Root.Users', array(new HeaderField(_t('SecurityAdmin.IMPORTUSERS', 'Import users'), 3), new LiteralField('MemberImportFormIframe', sprintf('<iframe src="%s" id="MemberImportFormIframe" width="100%%" height="250px" frameBorder="0">' . '</iframe>', $this->Link('memberimport'))))); $fields->addFieldsToTab('Root.Groups', array(new HeaderField(_t('SecurityAdmin.IMPORTGROUPS', 'Import groups'), 3), new LiteralField('GroupImportFormIframe', sprintf('<iframe src="%s" id="GroupImportFormIframe" width="100%%" height="250px" frameBorder="0">' . '</iframe>', $this->Link('groupimport'))))); } // Tab nav in CMS is rendered through separate template $root->setTemplate('CMSTabSet'); // Add roles editing interface if (Permission::check('APPLY_ROLES')) { $rolesField = GridField::create('Roles', false, PermissionRole::get(), GridFieldConfig_RecordEditor::create()); $rolesTab = $fields->findOrMakeTab('Root.Roles', _t('SecurityAdmin.TABROLES', 'Roles')); $rolesTab->push($rolesField); } $actionParam = $this->getRequest()->param('Action'); if ($actionParam == 'groups') { $groupsTab->addExtraClass('ui-state-active'); } elseif ($actionParam == 'users') { $usersTab->addExtraClass('ui-state-active'); } elseif ($actionParam == 'roles') { $rolesTab->addExtraClass('ui-state-active'); } $actions = new FieldList(); $form = Form::create($this, 'EditForm', $fields, $actions)->setHTMLID('Form_EditForm'); $form->addExtraClass('cms-edit-form'); $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); // Tab nav in CMS is rendered through separate template if ($form->Fields()->hasTabset()) { $form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet'); } $form->addExtraClass('center ss-tabset cms-tabset ' . $this->BaseCSSClasses()); $form->setAttribute('data-pjax-fragment', 'CurrentForm'); $this->extend('updateEditForm', $form); return $form; }
public function preRequest(HTTPRequest $request, Session $session, DataModel $model) { // Bootstrap session so that Session::get() accesses the right instance $dummyController = new Controller(); $dummyController->setSession($session); $dummyController->setRequest($request); $dummyController->pushCurrent(); // Block non-authenticated users from setting the stage mode if (!Versioned::can_choose_site_stage($request)) { $permissionMessage = sprintf(_t("ContentController.DRAFT_SITE_ACCESS_RESTRICTION", 'You must log in with your CMS password in order to view the draft or archived content. ' . '<a href="%s">Click here to go back to the published site.</a>'), Convert::raw2xml(Controller::join_links(Director::baseURL(), $request->getURL(), "?stage=Live"))); // Force output since RequestFilter::preRequest doesn't support response overriding $response = Security::permissionFailure($dummyController, $permissionMessage); $session->inst_save(); $dummyController->popCurrent(); // Prevent output in testing if (class_exists('SilverStripe\\Dev\\SapphireTest', false) && SapphireTest::is_running_test()) { throw new HTTPResponse_Exception($response); } $response->output(); die; } Versioned::choose_site_stage(); $dummyController->popCurrent(); return true; }
protected function init() { parent::init(); // Unless called from the command line, all CliControllers need ADMIN privileges if (!Director::is_cli() && !Permission::check("ADMIN")) { return Security::permissionFailure(); } }
public function init() { parent::init(); $canAccess = Director::isDev() || Director::is_cli() || Permission::check("ADMIN"); if (!$canAccess) { return Security::permissionFailure($this); } }
protected function init() { parent::init(); $isRunningTests = class_exists('SilverStripe\\Dev\\SapphireTest', false) && SapphireTest::is_running_test(); $canAccess = Director::isDev() || Director::is_cli() && !$isRunningTests || Permission::check("ADMIN"); if (!$canAccess) { Security::permissionFailure($this); } }
public function run($request) { if (!Permission::check('ADMIN') && !Director::is_cli()) { $response = Security::permissionFailure(); if ($response) { $response->output(); } die; } SapphireTest::delete_all_temp_dbs(); }
protected function init() { parent::init(); // We allow access to this controller regardless of live-status or ADMIN permission only // if on CLI or with the database not ready. The latter makes it less errorprone to do an // initial schema build without requiring a default-admin login. // Access to this controller is always allowed in "dev-mode", or of the user is ADMIN. $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); $canAccess = Director::isDev() || !Security::database_is_ready() || Director::is_cli() && !$isRunningTests || Permission::check("ADMIN"); if (!$canAccess) { return Security::permissionFailure($this, "This page is secured and you need administrator rights to access it. " . "Enter your credentials below and we will send you right along."); } }
protected function init() { parent::init(); // Special case for dev/build: Defer permission checks to DatabaseAdmin->init() (see #4957) $requestedDevBuild = stripos($this->getRequest()->getURL(), 'dev/build') === 0 && stripos($this->getRequest()->getURL(), 'dev/build/defaults') === false; // We allow access to this controller regardless of live-status or ADMIN permission only // if on CLI. Access to this controller is always allowed in "dev-mode", or of the user is ADMIN. $canAccess = $requestedDevBuild || Director::isDev() || Director::is_cli() || Permission::check("ADMIN"); if (!$canAccess) { Security::permissionFailure($this); return; } // check for valid url mapping // lacking this information can cause really nasty bugs, // e.g. when running Director::test() from a FunctionalTest instance global $_FILE_TO_URL_MAPPING; if (Director::is_cli()) { if (isset($_FILE_TO_URL_MAPPING)) { $testPath = BASE_PATH; $matched = false; while ($testPath && $testPath != "/" && !preg_match('/^[A-Z]:\\\\$/', $testPath)) { if (isset($_FILE_TO_URL_MAPPING[$testPath])) { $matched = true; break; } $testPath = dirname($testPath); } if (!$matched) { echo 'Warning: You probably want to define ' . 'an entry in $_FILE_TO_URL_MAPPING that covers "' . Director::baseFolder() . '"' . "\n"; } } else { echo 'Warning: You probably want to define $_FILE_TO_URL_MAPPING in ' . 'your _ss_environment.php as instructed on the "sake" page of the doc.silverstripe.org wiki' . "\n"; } } // Backwards compat: Default to "draft" stage, which is important // for tasks like dev/build which call DataObject->requireDefaultRecords(), // but also for other administrative tasks which have assumptions about the default stage. Versioned::set_stage(Versioned::DRAFT); }
/** * Handles URL requests. * * - ViewableData::handleRequest() iterates through each rule in {@link self::$url_handlers}. * - If the rule matches, the named method will be called. * - If there is still more URL to be processed, then handleRequest() * is called on the object that that method returns. * * Once all of the URL has been processed, the final result is returned. * However, if the final result is an array, this * array is interpreted as being additional template data to customise the * 2nd to last result with, rather than an object * in its own right. This is most frequently used when a Controller's * action will return an array of data with which to * customise the controller. * * @param SS_HTTPRequest $request The object that is reponsible for distributing URL parsing * @param DataModel $model * @return SS_HTTPResponse|RequestHandler|string|array */ public function handleRequest(SS_HTTPRequest $request, DataModel $model) { // $handlerClass is used to step up the class hierarchy to implement url_handlers inheritance $handlerClass = $this->class ? $this->class : get_class($this); if ($this->brokenOnConstruct) { user_error("parent::__construct() needs to be called on {$handlerClass}::__construct()", E_USER_WARNING); } $this->setRequest($request); $this->setDataModel($model); $match = $this->findAction($request); // If nothing matches, return this object if (!$match) { return $this; } // Start to find what action to call. Start by using what findAction returned $action = $match['action']; // We used to put "handleAction" as the action on controllers, but (a) this could only be called when // you had $Action in your rule, and (b) RequestHandler didn't have one. $Action is better if ($action == 'handleAction') { // TODO Fix LeftAndMain usage // Deprecation::notice('3.2.0', 'Calling handleAction directly is deprecated - use $Action instead'); $action = '$Action'; } // Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action', if ($action[0] == '$') { $action = str_replace("-", "_", $request->latestParam(substr($action, 1))); } if (!$action) { if (isset($_REQUEST['debug_request'])) { Debug::message("Action not set; using default action method name 'index'"); } $action = "index"; } else { if (!is_string($action)) { user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR); } } $classMessage = Director::isLive() ? 'on this handler' : 'on class ' . get_class($this); try { if (!$this->hasAction($action)) { return $this->httpError(404, "Action '{$action}' isn't available {$classMessage}."); } if (!$this->checkAccessAction($action) || in_array(strtolower($action), array('run', 'doInit'))) { return $this->httpError(403, "Action '{$action}' isn't allowed {$classMessage}."); } $result = $this->handleAction($request, $action); } catch (SS_HTTPResponse_Exception $e) { return $e->getResponse(); } catch (PermissionFailureException $e) { $result = Security::permissionFailure(null, $e->getMessage()); } if ($result instanceof SS_HTTPResponse && $result->isError()) { if (isset($_REQUEST['debug_request'])) { Debug::message("Rule resulted in HTTP error; breaking"); } return $result; } // If we return a RequestHandler, call handleRequest() on that, even if there is no more URL to // parse. It might have its own handler. However, we only do this if we haven't just parsed an // empty rule ourselves, to prevent infinite loops. Also prevent further handling of controller // actions which return themselves to avoid infinite loops. $matchedRuleWasEmpty = $request->isEmptyPattern($match['rule']); $resultIsRequestHandler = is_object($result) && $result instanceof RequestHandler; if ($this !== $result && !$matchedRuleWasEmpty && $resultIsRequestHandler) { $returnValue = $result->handleRequest($request, $model); // Array results can be used to handle if (is_array($returnValue)) { $returnValue = $this->customise($returnValue); } return $returnValue; // If we return some other data, and all the URL is parsed, then return that } else { if ($request->allParsed()) { return $result; // But if we have more content on the URL and we don't know what to do with it, return an error. } else { return $this->httpError(404, "I can't handle sub-URLs {$classMessage}."); } } return $this; }
/** * Calls {@link SiteTree->getCMSFields()} * * @param Int $id * @param FieldList $fields * @return Form */ public function getEditForm($id = null, $fields = null) { if (!$id) { $id = $this->currentPageID(); } if (is_object($id)) { $record = $id; } else { $record = $this->getRecord($id); if ($record && !$record->canView()) { return Security::permissionFailure($this); } } if ($record) { $fields = $fields ? $fields : $record->getCMSFields(); if ($fields == null) { user_error("getCMSFields() returned null - it should return a FieldList object.\n\t\t\t\t\tPerhaps you forgot to put a return statement at the end of your method?", E_USER_ERROR); } // Add hidden fields which are required for saving the record // and loading the UI state if (!$fields->dataFieldByName('ClassName')) { $fields->push(new HiddenField('ClassName')); } $tree_class = $this->stat('tree_class'); if ($tree_class::has_extension(Hierarchy::class) && !$fields->dataFieldByName('ParentID')) { $fields->push(new HiddenField('ParentID')); } // Added in-line to the form, but plucked into different view by frontend scripts. if ($record instanceof CMSPreviewable) { /** @skipUpgrade */ $navField = new LiteralField('SilverStripeNavigator', $this->getSilverStripeNavigator()); $navField->setAllowHTML(true); $fields->push($navField); } if ($record->hasMethod('getAllCMSActions')) { $actions = $record->getAllCMSActions(); } else { $actions = $record->getCMSActions(); // add default actions if none are defined if (!$actions || !$actions->count()) { if ($record->hasMethod('canEdit') && $record->canEdit()) { $actions->push(FormAction::create('save', _t('CMSMain.SAVE', 'Save'))->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')); } if ($record->hasMethod('canDelete') && $record->canDelete()) { $actions->push(FormAction::create('delete', _t('ModelAdmin.DELETE', 'Delete'))->addExtraClass('ss-ui-action-destructive')); } } } // Use <button> to allow full jQuery UI styling $actionsFlattened = $actions->dataFields(); if ($actionsFlattened) { /** @var FormAction $action */ foreach ($actionsFlattened as $action) { $action->setUseButtonTag(true); } } $negotiator = $this->getResponseNegotiator(); $form = Form::create($this, "EditForm", $fields, $actions)->setHTMLID('Form_EditForm'); $form->addExtraClass('cms-edit-form'); $form->loadDataFrom($record); $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); $form->setAttribute('data-pjax-fragment', 'CurrentForm'); $form->setValidationResponseCallback(function () use($negotiator, $form) { $request = $this->getRequest(); if ($request->isAjax() && $negotiator) { $form->setupFormErrors(); $result = $form->forTemplate(); return $negotiator->respond($request, array('CurrentForm' => function () use($result) { return $result; })); } }); // Announce the capability so the frontend can decide whether to allow preview or not. if ($record instanceof CMSPreviewable) { $form->addExtraClass('cms-previewable'); } $form->addExtraClass('fill-height'); // Set this if you want to split up tabs into a separate header row // if($form->Fields()->hasTabset()) { // $form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet'); // } // Add a default or custom validator. // @todo Currently the default Validator.js implementation // adds javascript to the document body, meaning it won't // be included properly if the associated fields are loaded // through ajax. This means only serverside validation // will kick in for pages+validation loaded through ajax. // This will be solved by using less obtrusive javascript validation // in the future, see http://open.silverstripe.com/ticket/2915 and // http://open.silverstripe.com/ticket/3386 if ($record->hasMethod('getCMSValidator')) { $validator = $record->getCMSValidator(); // The clientside (mainly LeftAndMain*.js) rely on ajax responses // which can be evaluated as javascript, hence we need // to override any global changes to the validation handler. if ($validator != NULL) { $form->setValidator($validator); } } else { $form->unsetValidator(); } if ($record->hasMethod('canEdit') && !$record->canEdit()) { $readonlyFields = $form->Fields()->makeReadonly(); $form->setFields($readonlyFields); } } else { $form = $this->EmptyForm(); } return $form; }
/** * Cleanup function to reset all the Filename fields. Visit File/fixfiles to call. */ public function fixfiles() { if (!Permission::check('ADMIN')) { return Security::permissionFailure($this); } $files = DataObject::get("File"); foreach ($files as $file) { $file->updateFilesystem(); echo "<li>", $file->Filename; $file->write(); } echo "<p>Done!"; }
public function index() { if (!Permission::check('ADMIN')) { return Security::permissionFailure($this); } return 'Success'; }
/** * Cleanup function to reset all the Filename fields. Visit File/fixfiles to call. * * @deprecated 5.0 */ public function fixfiles() { Deprecation::notice('5.0'); if (!Permission::check('ADMIN')) { return Security::permissionFailure($this); } $files = File::get(); foreach ($files as $file) { $file->updateFilesystem(); echo "<li>", $file->Filename; $file->write(); } echo "<p>Done!"; }