public function testClearAllElements() { Session::set('Test', 'Test'); Session::set('Test-1', 'Test-1'); Session::clear_all(); // should session get return null? The array key should probably be // unset from the data array $this->assertEquals(Session::get('Test'), ''); $this->assertEquals(Session::get('Test-1'), ''); }
/** * Gets the current state of this form as a nested array. * * @param Form $form * @return array */ public function getState(Form $form) { // Ensure that session errors are populated within form field messages $form->setupFormErrors(); // @todo - Replace with ValidationResult handling // Currently tri-state; null (unsubmitted), true (submitted-valid), false (submitted-invalid) $errors = Session::get("FormInfo.{$form->FormName()}.errors"); $valid = isset($errors) ? empty($errors) : null; $state = ['id' => $form->FormName(), 'fields' => [], 'valid' => $valid, 'messages' => []]; // flattened nested fields are returned, rather than only top level fields. $state['fields'] = array_merge($this->getFieldStates($form->Fields()), $this->getFieldStates($form->Actions())); if ($message = $form->Message()) { $state['messages'][] = ['value' => ['html' => $message], 'type' => $form->MessageType()]; } return $state; }
/** * Determine if a grant exists for the given FileID * * @param string $fileID * @return bool */ protected function isGranted($fileID) { // Since permissions are applied to the non-variant only, // map back to the original file before checking $originalID = $this->removeVariant($fileID); $granted = Session::get(self::GRANTS_SESSION) ?: array(); return !empty($granted[$originalID]); }
/** * @return string */ protected function getMessageFromSession() { if ($this->message || $this->messageType) { return $this->message; } else { $this->message = Session::get("FormInfo.{$this->FormName()}.formError.message"); $this->messageType = Session::get("FormInfo.{$this->FormName()}.formError.type"); return $this->message; } }
/** * Change the password * * @param array $data The user submitted data * @return HTTPResponse */ public function doChangePassword(array $data) { if ($member = Member::currentUser()) { // The user was logged in, check the current password if (empty($data['OldPassword']) || !$member->checkPassword($data['OldPassword'])->valid()) { $this->clearMessage(); $this->sessionMessage(_t('Member.ERRORPASSWORDNOTMATCH', "Your current password does not match, please try again"), "bad"); // redirect back to the form, instead of using redirectBack() which could send the user elsewhere. return $this->controller->redirect($this->controller->Link('changepassword')); } } if (!$member) { if (Session::get('AutoLoginHash')) { $member = Member::member_from_autologinhash(Session::get('AutoLoginHash')); } // The user is not logged in and no valid auto login hash is available if (!$member) { Session::clear('AutoLoginHash'); return $this->controller->redirect($this->controller->Link('login')); } } // Check the new password if (empty($data['NewPassword1'])) { $this->clearMessage(); $this->sessionMessage(_t('Member.EMPTYNEWPASSWORD', "The new password can't be empty, please try again"), "bad"); // redirect back to the form, instead of using redirectBack() which could send the user elsewhere. return $this->controller->redirect($this->controller->Link('changepassword')); } else { if ($data['NewPassword1'] == $data['NewPassword2']) { $isValid = $member->changePassword($data['NewPassword1']); if ($isValid->valid()) { // Clear locked out status $member->LockedOutUntil = null; $member->FailedLoginCount = null; $member->write(); if ($member->canLogIn()->valid()) { $member->logIn(); } // TODO Add confirmation message to login redirect Session::clear('AutoLoginHash'); if (!empty($_REQUEST['BackURL']) && Director::is_site_url($_REQUEST['BackURL'])) { $url = Director::absoluteURL($_REQUEST['BackURL']); return $this->controller->redirect($url); } else { // Redirect to default location - the login form saying "You are logged in as..." $redirectURL = HTTP::setGetVar('BackURL', Director::absoluteBaseURL(), $this->controller->Link('login')); return $this->controller->redirect($redirectURL); } } else { $this->clearMessage(); $this->sessionMessage(_t('Member.INVALIDNEWPASSWORD', "We couldn't accept that password: {password}", array('password' => nl2br("\n" . Convert::raw2xml($isValid->starredList())))), "bad", false); // redirect back to the form, instead of using redirectBack() which could send the user elsewhere. return $this->controller->redirect($this->controller->Link('changepassword')); } } else { $this->clearMessage(); $this->sessionMessage(_t('Member.ERRORNEWPASSWORD', "You have entered your new password differently, try again"), "bad"); // redirect back to the form, instead of using redirectBack() which could send the user elsewhere. return $this->controller->redirect($this->controller->Link('changepassword')); } } }
/** * Identifier for the currently shown record, * in most cases a database ID. Inspects the following * sources (in this order): * - GET/POST parameter named 'ID' * - URL parameter named 'ID' * - Session value namespaced by classname, e.g. "CMSMain.currentPage" * * @return int */ public function currentPageID() { if ($this->getRequest()->requestVar('ID') && is_numeric($this->getRequest()->requestVar('ID'))) { return $this->getRequest()->requestVar('ID'); } elseif ($this->getRequest()->requestVar('CMSMainCurrentPageID') && is_numeric($this->getRequest()->requestVar('CMSMainCurrentPageID'))) { // see GridFieldDetailForm::ItemEditForm return $this->getRequest()->requestVar('CMSMainCurrentPageID'); } elseif (isset($this->urlParams['ID']) && is_numeric($this->urlParams['ID'])) { return $this->urlParams['ID']; } elseif (Session::get($this->sessionNamespace() . ".currentPage")) { return Session::get($this->sessionNamespace() . ".currentPage"); } else { return null; } }
/** * Show the "change password" page. * This page can either be called directly by logged-in users * (in which case they need to provide their old password), * or through a link emailed through {@link lostpassword()}. * In this case no old password is required, authentication is ensured * through the Member.AutoLoginHash property. * * @see ChangePasswordForm * * @return string|HTTPRequest Returns the "change password" page as HTML code, or a redirect response */ public function changepassword() { $controller = $this->getResponseController(_t('Security.CHANGEPASSWORDHEADER', 'Change your password')); // if the controller calls Director::redirect(), this will break early if (($response = $controller->getResponse()) && $response->isFinished()) { return $response; } // Extract the member from the URL. /** @var Member $member */ $member = null; if (isset($_REQUEST['m'])) { $member = Member::get()->filter('ID', (int) $_REQUEST['m'])->first(); } // Check whether we are merely changin password, or resetting. if (isset($_REQUEST['t']) && $member && $member->validateAutoLoginToken($_REQUEST['t'])) { // On first valid password reset request redirect to the same URL without hash to avoid referrer leakage. // if there is a current member, they should be logged out if ($curMember = Member::currentUser()) { $curMember->logOut(); } // Store the hash for the change password form. Will be unset after reload within the ChangePasswordForm. Session::set('AutoLoginHash', $member->encryptWithUserSettings($_REQUEST['t'])); return $this->redirect($this->Link('changepassword')); } elseif (Session::get('AutoLoginHash')) { // Subsequent request after the "first load with hash" (see previous if clause). $customisedController = $controller->customise(array('Content' => '<p>' . _t('Security.ENTERNEWPASSWORD', 'Please enter a new password.') . '</p>', 'Form' => $this->ChangePasswordForm())); } elseif (Member::currentUser()) { // Logged in user requested a password change form. $customisedController = $controller->customise(array('Content' => '<p>' . _t('Security.CHANGEPASSWORDBELOW', 'You can change your password below.') . '</p>', 'Form' => $this->ChangePasswordForm())); } else { // Show friendly message if it seems like the user arrived here via password reset feature. if (isset($_REQUEST['m']) || isset($_REQUEST['t'])) { $customisedController = $controller->customise(array('Content' => _t('Security.NOTERESETLINKINVALID', '<p>The password reset link is invalid or expired.</p>' . '<p>You can request a new one <a href="{link1}">here</a> or change your password after' . ' you <a href="{link2}">logged in</a>.</p>', array('link1' => $this->Link('lostpassword'), 'link2' => $this->Link('login'))))); } else { return self::permissionFailure($this, _t('Security.ERRORPASSWORDPERMISSION', 'You must be logged in in order to change your password!')); } } return $customisedController->renderWith($this->getTemplatesFor('changepassword')); }
public function testPermissionFailureSetsCorrectFormMessages() { Config::nest(); // Controller that doesn't attempt redirections $controller = new SecurityTest_NullController(); $controller->setResponse(new HTTPResponse()); Security::permissionFailure($controller, array('default' => 'Oops, not allowed')); $this->assertEquals('Oops, not allowed', Session::get('Security.Message.message')); // Test that config values are used correctly Config::inst()->update('SilverStripe\\Security\\Security', 'default_message_set', 'stringvalue'); Security::permissionFailure($controller); $this->assertEquals('stringvalue', Session::get('Security.Message.message'), 'Default permission failure message value was not present'); Config::inst()->remove('SilverStripe\\Security\\Security', 'default_message_set'); Config::inst()->update('SilverStripe\\Security\\Security', 'default_message_set', array('default' => 'arrayvalue')); Security::permissionFailure($controller); $this->assertEquals('arrayvalue', Session::get('Security.Message.message'), 'Default permission failure message value was not present'); // Test that non-default messages work. // NOTE: we inspect the response body here as the session message has already // been fetched and output as part of it, so has been removed from the session $this->logInWithPermission('EDITOR'); Config::inst()->update('SilverStripe\\Security\\Security', 'default_message_set', array('default' => 'default', 'alreadyLoggedIn' => 'You are already logged in!')); Security::permissionFailure($controller); $this->assertContains('You are already logged in!', $controller->getResponse()->getBody(), 'Custom permission failure message was ignored'); Security::permissionFailure($controller, array('default' => 'default', 'alreadyLoggedIn' => 'One-off failure message')); $this->assertContains('One-off failure message', $controller->getResponse()->getBody(), "Message set passed to Security::permissionFailure() didn't override Config values"); Config::unnest(); }
/** * Get the ID of the current logged in user * * @return int Returns the ID of the current logged in user or 0. */ public static function currentUserID() { $id = Session::get("loggedInAs"); if (!$id && !self::$_already_tried_to_auto_log_in) { self::autoLogin(); $id = Session::get("loggedInAs"); } return is_numeric($id) ? $id : 0; }
/** * @return String */ public function getValue() { $value = Session::get($this->getName()); // only regenerate if the token isn't already set in the session if (!$value) { $value = $this->generate(); $this->setValue($value); } return $value; }
/** * Get message from session */ protected function getMessageFromSession() { $forceMessage = Session::get('MemberLoginForm.force_message'); if (($member = Member::currentUser()) && !$forceMessage) { $this->message = _t('Member.LOGGEDINAS', "You're logged in as {name}.", array('name' => $member->{$this->loggedInAsField})); } // Reset forced message if ($forceMessage) { Session::set('MemberLoginForm.force_message', false); } return parent::getMessageFromSession(); }
/** * Given a successful login, tell the parent frame to close the dialog * * @return HTTPResponse|DBField */ public function success() { // Ensure member is properly logged in if (!Member::currentUserID()) { return $this->redirectToExternalLogin(); } // Get redirect url $controller = $this->getResponseController(_t('CMSSecurity.SUCCESS', 'Success')); $backURLs = array($this->getRequest()->requestVar('BackURL'), Session::get('BackURL'), Director::absoluteURL(AdminRootController::config()->url_base, true)); $backURL = null; foreach ($backURLs as $backURL) { if ($backURL && Director::is_site_url($backURL)) { break; } } // Show login $controller = $controller->customise(array('Content' => _t('CMSSecurity.SUCCESSCONTENT', '<p>Login success. If you are not automatically redirected ' . '<a target="_top" href="{link}">click here</a></p>', 'Login message displayed in the cms popup once a user has re-authenticated themselves', array('link' => $backURL)))); return $controller->renderWith($this->getTemplatesFor('success')); }
/** * This is the action that gets executed when a GridField_AlterAction gets clicked. * * @param array $data * @param Form $form * @param HTTPRequest $request * * @return string */ public function gridFieldAlterAction($data, $form, HTTPRequest $request) { $data = $request->requestVars(); // Protection against CSRF attacks $token = $this->getForm()->getSecurityToken(); if (!$token->checkRequest($request)) { $this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE", "There seems to have been a technical problem. Please click the back button, " . "refresh your browser, and try again.")); } $name = $this->getName(); $fieldData = null; if (isset($data[$name])) { $fieldData = $data[$name]; } $state = $this->getState(false); /** @skipUpgrade */ if (isset($fieldData['GridState'])) { $state->setValue($fieldData['GridState']); } foreach ($data as $dataKey => $dataValue) { if (preg_match('/^action_gridFieldAlterAction\\?StateID=(.*)/', $dataKey, $matches)) { $stateChange = Session::get($matches[1]); $actionName = $stateChange['actionName']; $arguments = array(); if (isset($stateChange['args'])) { $arguments = $stateChange['args']; } $html = $this->handleAlterAction($actionName, $arguments, $data); if ($html) { return $html; } } } if ($request->getHeader('X-Pjax') === 'CurrentField') { return $this->FieldHolder(); } return $form->forTemplate(); }
/** * Choose the stage the site is currently on. * * If $_GET['stage'] is set, then it will use that stage, and store it in * the session. * * if $_GET['archiveDate'] is set, it will use that date, and store it in * the session. * * If neither of these are set, it checks the session, otherwise the stage * is set to 'Live'. */ public static function choose_site_stage() { // Check any pre-existing session mode $preexistingMode = Session::get('readingMode'); // Determine the reading mode if (isset($_GET['stage'])) { $stage = ucfirst(strtolower($_GET['stage'])); if (!in_array($stage, array(static::DRAFT, static::LIVE))) { $stage = static::LIVE; } $mode = 'Stage.' . $stage; } elseif (isset($_GET['archiveDate']) && strtotime($_GET['archiveDate'])) { $mode = 'Archive.' . $_GET['archiveDate']; } elseif ($preexistingMode) { $mode = $preexistingMode; } else { $mode = static::DEFAULT_MODE; } // Save reading mode Versioned::set_reading_mode($mode); // Try not to store the mode in the session if not needed if ($preexistingMode && $preexistingMode !== $mode || !$preexistingMode && $mode !== static::DEFAULT_MODE) { Session::set('readingMode', $mode); } if (!headers_sent() && !Director::is_cli()) { if (Versioned::get_stage() == 'Live') { // clear the cookie if it's set if (Cookie::get('bypassStaticCache')) { Cookie::force_expiry('bypassStaticCache', null, null, false, true); } } else { // set the cookie if it's cleared if (!Cookie::get('bypassStaticCache')) { Cookie::set('bypassStaticCache', '1', 0, null, null, false, true); } } } }