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]);
 }
Пример #4
0
 /**
  * @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();
 }
Пример #9
0
 /**
  * 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);
             }
         }
     }
 }