/** * Handles validation and saving new Member objects, as well as sending out validation emails. */ public function register($data, Form $form) { if ($member = $this->addMember($form)) { $this->addRegistration($form, $member); if (!$this->RequireApproval && $this->EmailType != 'Validation' && !$this->AllowAdding) { $member->logIn(); } if ($this->RegistrationRedirect) { if ($this->PostRegistrationTargetID) { $this->redirect($this->PostRegistrationTarget()->Link()); return; } if ($sessionTarget = Session::get('MemberProfile.REDIRECT')) { Session::clear('MemberProfile.REDIRECT'); if (Director::is_site_url($sessionTarget)) { $this->redirect($sessionTarget); return; } } } return $this->redirect($this->Link('afterregistration')); } else { return $this->redirectBack(); } }
public static function cleanBackUrl($back_url) { if (empty($back_url) || !empty($back_url) && !Director::is_site_url($back_url)) { $back_url = Director::baseURL(); } return $back_url; }
public static function handle_shortcode($arguments, $url, $parser, $shortcode) { $result = false; if (Director::is_site_url($url) && VideoEmbed::GetByURL($url)) { $result = VideoEmbed::GetByURL($url)->forTemplate(); } else { $result = parent::handle_shortcode($arguments, $url, $parser, $shortcode); } return $result; }
/** * Change the password * * @param array $data The user submitted data */ 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"); Director::redirectBack(); return; } } 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'); Director::redirect('loginpage'); return; } } // 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"); Director::redirectBack(); return; } else { if ($data['NewPassword1'] == $data['NewPassword2']) { $isValid = $member->changePassword($data['NewPassword1']); if ($isValid->valid()) { $this->clearMessage(); $this->sessionMessage(_t('Member.PASSWORDCHANGED', "Your password has been changed, and a copy emailed to you."), "good"); Session::clear('AutoLoginHash'); if (isset($_REQUEST['BackURL']) && $_REQUEST['BackURL'] && Director::is_site_url($_REQUEST['BackURL'])) { Director::redirect($_REQUEST['BackURL']); } else { // Redirect to default location - the login form saying "You are logged in as..." $redirectURL = HTTP::setGetVar('BackURL', Director::absoluteBaseURL(), Security::Link('login')); Director::redirect($redirectURL); } } else { $this->clearMessage(); $this->sessionMessage(sprintf(_t('Member.INVALIDNEWPASSWORD', "We couldn't accept that password: %s"), nl2br("\n" . $isValid->starredList())), "bad"); Director::redirectBack(); } } else { $this->clearMessage(); $this->sessionMessage(_t('Member.ERRORNEWPASSWORD', "You have entered your new password differently, try again"), "bad"); Director::redirectBack(); } } }
public function checkOwnAjaxRequest($request) { $referer = @$_SERVER['HTTP_REFERER']; if (empty($referer)) { return false; } //validate if (!Director::is_ajax()) { return false; } return Director::is_site_url($referer); }
/** * @param array $data * @param Form $form * * @return mixed */ public function doSubmit($data, $form) { $controller = Controller::curr(); $redirect = Director::baseURL() . $this->owner->URLSegment; if ((bool) Config::inst()->get('QuickFeedbackExtension', 'redirect_field') && isset($data['Redirect']) && Director::is_site_url($data['Redirect'])) { $redirect = Director::absoluteURL($data['Redirect'], true); } if (!$controller) { goto error; } $request = $controller->getRequest(); if (!$request) { goto error; } $limit = (int) Config::inst()->get('QuickFeedbackExtension', 'rate_limit'); $existing = Feedback::get()->filter('IP', $request->getIP())->sort('Created desc')->first(); if ($existing) { $created = $existing->dbObject('Created'); if (!$created) { goto error; } $seconds = abs(time() - strtotime($created->getValue())); $minutes = round($seconds / 60); if ($minutes <= $limit) { goto rate; } } $feedback = Feedback::create(); $feedback->Rating = $data['Rating']; $feedback->Comment = $data['Comment']; $feedback->IP = $request->getIP(); if (!empty($this->owner->ID)) { $feedback->PageID = $this->owner->ID; } if (!empty($this->owner->URLSegment)) { $feedback->URL = $this->owner->RelativeLink(); } if ((bool) Config::inst()->get('QuickFeedbackExtension', 'redirect_field') && isset($data['Redirect'])) { $feedback->URL = $data['Redirect']; } $feedback->write(); $form->sessionMessage(_t('QuickFeedback.ThanksMessage', 'Thanks for your comment!'), 'good'); return $this->owner->redirect($redirect . '?success=1'); error: $form->sessionMessage(_t('QuickFeedback.ErrorMessage', 'An error occurred!'), 'error'); return $this->owner->redirect($redirect . '?error=1'); rate: $form->sessionMessage(_t('QuickFeedback.RateMessage', 'Please wait a while before submitting!'), 'error'); return $this->owner->redirect($redirect . '?rate=1'); }
public function viewfile($request) { $result = false; if ($origUrl = $request->getVar('FileURL')) { if (Director::is_site_url($origUrl) && VideoEmbed::GetByURL($origUrl)) { $video = VideoEmbed::GetByURL($origUrl); $result = $this->GetResultForVideo($video); } } else { if ($fileId = $request->getVar('ID')) { $video = VideoEmbed::get()->filter(array("HTML5VideoID" => $fileId))->first(); $result = $this->GetResultForVideo($video); } } return $result ? $result : parent::viewfile($request); }
public function GetOembedData(SS_HTTPRequest $request) { $response = "{}"; $this->getResponse()->addHeader("Content-Type", "application/json; charset=utf-8"); $url = $request->postVar('url') ? $request->postVar('url') : $request->getVar("mediaurl"); if (Director::is_site_url($url) && VideoEmbed::GetByURL($url)) { $video = VideoEmbed::GetByURL($url); $response = $video->GetOembedJson(); } else { $oembed = Oembed::get_oembed_from_url($url); if ($oembed && $oembed->exists()) { $response = $oembed->toJson(); } } echo $response; }
protected function logInUserAndRedirect($data) { Session::clear('SessionForms.MemberLoginForm.Email'); Session::clear('SessionForms.MemberLoginForm.Remember'); if (Member::currentUser()->isPasswordExpired()) { if (isset($_REQUEST['BackURL']) && ($backURL = $_REQUEST['BackURL'])) { Session::set('BackURL', $backURL); } $cp = new ChangePasswordForm($this->controller, 'ChangePasswordForm'); $cp->sessionMessage(_t('Member.PASSWORDEXPIRED', 'Your password has expired. Please choose a new one.'), 'good'); return $this->controller->redirect('Security/changepassword'); } // Absolute redirection URLs may cause spoofing if (!empty($_REQUEST['BackURL'])) { $url = $_REQUEST['BackURL']; if (Director::is_site_url($url)) { $url = Director::absoluteURL($url); } else { // Spoofing attack, redirect to homepage instead of spoofing url $url = Director::absoluteBaseURL(); } return $this->controller->redirect($url); } // If a default login dest has been set, redirect to that. if ($url = Security::config()->default_login_dest) { $url = Controller::join_links(Director::absoluteBaseURL(), $url); return $this->controller->redirect($url); } // Redirect the user to the page where they came from $member = Member::currentUser(); if ($member) { $firstname = Convert::raw2xml($member->FirstName); if (!empty($data['Remember'])) { Session::set('SessionForms.MemberLoginForm.Remember', '1'); $member->logIn(true); } else { $member->logIn(); } Session::set('Security.Message.message', _t('Member.WELCOMEBACK', "Welcome Back, {firstname}", array('firstname' => $firstname))); Session::set("Security.Message.type", "good"); } // Do checks of pagetypes to see where we were and where to go then for the rest redirect to baseurl // $url = "/resources/"; $url = "/resources/"; $url = Controller::join_links(Director::absoluteBaseURL(), $url); return $this->controller->redirect($url); }
public function callback() { $redirectUri = 'http' . (isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] ? 's' : '' : '') . '://' . $_SERVER['HTTP_HOST'] . '/GoogleAuthenticatorController/callback'; $client = new Google_Client(); $client->setClientId(GOOGLE_AUTHENTICATOR_CLIENT_ID); $client->setClientSecret(GOOGLE_AUTHENTICATOR_CLIENT_SECRET); $client->setRedirectUri($redirectUri); $client->addScope("email"); if (isset($_GET['code'])) { $client->authenticate($_GET['code']); $_SESSION['google_accesstoken'] = $client->getAccessToken(); header('Location: ' . filter_var($redirectUri, FILTER_SANITIZE_URL)); } if (isset($_SESSION['google_accesstoken']) && $_SESSION['google_accesstoken']) { $client->setAccessToken($_SESSION['google_accesstoken']); } $form = new GoogleAuthenticatorLoginForm($this, 'LoginForm'); if ($client->getAccessToken() && !$client->isAccessTokenExpired()) { $_SESSION['google_accesstoken'] = $client->getAccessToken(); $token_data = $client->verifyIdToken()->getAttributes(); $email = $token_data['payload']['email']; $member = Member::get()->filter(array('Email' => $email))->first(); if (isset($_SESSION['BackURL']) && $_SESSION['BackURL'] && Director::is_site_url($_SESSION['BackURL'])) { $backURL = $_SESSION['BackURL']; } if ($member) { $member->logIn(); if ($backURL) { return $this->redirect($backURL); } if (Security::config()->default_login_dest) { return $this->redirect(Director::absoluteBaseURL() . Security::config()->default_login_dest); } return Controller::curr()->redirectBack(); } else { $form->sessionMessage("The Google account {$email} is not authorised to access the system.", 'bad'); } } else { $form->sessionMessage("There is an error authenticating with Google. Please try again.", 'bad'); } $loginLink = Director::absoluteURL('/Security/login'); if ($backURL) { $loginLink .= '?BackURL=' . urlencode($backURL); } $loginLink .= '#GoogleAuthenticatorLoginForm_LoginForm_tab'; return $this->redirect($loginLink); }
/** * Overidden, added call to redirectByGroup(). * * Login in the user and figure out where to redirect the browser. * * The $data has this format * array( * 'AuthenticationMethod' => 'MemberAuthenticator', * 'Email' => '*****@*****.**', * 'Password' => '1nitialPassword', * 'BackURL' => 'test/link', * [Optional: 'Remember' => 1 ] * ) * * * @param array $data * @return void */ protected function logInUserAndRedirect($data) { Session::clear('SessionForms.MemberLoginForm.Email'); Session::clear('SessionForms.MemberLoginForm.Remember'); if (Member::currentUser()->isPasswordExpired()) { if (isset($_REQUEST['BackURL']) && ($backURL = $_REQUEST['BackURL'])) { Session::set('BackURL', $backURL); } $cp = new ChangePasswordForm($this->controller, 'ChangePasswordForm'); $cp->sessionMessage('Your password has expired. Please choose a new one.', 'good'); return $this->controller->redirect('Security/changepassword'); } // Absolute redirection URLs may cause spoofing if (isset($_REQUEST['BackURL']) && $_REQUEST['BackURL'] && Director::is_site_url($_REQUEST['BackURL'])) { return $this->controller->redirect($_REQUEST['BackURL']); } // Spoofing attack, redirect to homepage instead of spoofing url if (isset($_REQUEST['BackURL']) && $_REQUEST['BackURL'] && !Director::is_site_url($_REQUEST['BackURL'])) { return $this->controller->redirect(Director::absoluteBaseURL()); } // If a default login dest has been set, redirect to that. if (Security::default_login_dest()) { return $this->controller->redirect(Director::absoluteBaseURL() . Security::default_login_dest()); } // redirect by group if (singleton('Group')->hasExtension('GroupLoginDataExtension')) { $this->redirectByGroup(); } // Redirect the user to the page where he came from $member = Member::currentUser(); if ($member) { $firstname = Convert::raw2xml($member->FirstName); if (!empty($data['Remember'])) { Session::set('SessionForms.MemberLoginForm.Remember', '1'); $member->logIn(true); } else { $member->logIn(); } Session::set('Security.Message.message', _t('Member.WELCOMEBACK', "Welcome Back, {firstname}", array('firstname' => $firstname))); Session::set("Security.Message.type", "good"); } Controller::curr()->redirectBack(); }
/** * Handles requests to view a vidyard video in the cms * @param {SS_HTTPRequest} $request HTTP Request object * @return {string} Rendered view on success null on error * @throws SS_HTTPResponse_Exception */ public function viewvidyard(SS_HTTPRequest $request) { $file = null; $url = null; if ($fileUrl = $request->getVar('VidyardURL')) { // If this isn't an absolute URL, or is, but is to this site, try and get the File object // that is associated with it if (Director::is_absolute_url($fileUrl) && !Director::is_site_url($fileUrl) && Vidyard::validateVidyardURL($fileUrl)) { list($file, $url) = $this->getVideoByURL($fileUrl); } else { throw new SS_HTTPResponse_Exception('"VidyardURL" is not a valid Vidyard Video', 400); } } else { throw new SS_HTTPResponse_Exception('Need "VidyardURL" parameter to identify the file', 400); } $fileWrapper = new VidyardInsertMedia_Embed($url, $file); $fields = $this->getFieldsForVidyard($url, $fileWrapper); return $fileWrapper->customise(array('Fields' => $fields))->renderWith('HtmlEditorField_viewfile'); }
/** * @return SS_HTTPResponse */ protected function getRedirect() { // Absolute redirection URLs may cause spoofing if (Session::get('BackURL') && Director::is_site_url(Session::get('BackURL'))) { return $this->redirect(Session::get('BackURL')); } // Spoofing attack, redirect to homepage instead of spoofing url if (Session::get('BackURL') && !Director::is_site_url(Session::get('BackURL'))) { return $this->redirect(Director::absoluteBaseURL()); } // If a default login dest has been set, redirect to that. if (Security::config()->default_login_dest) { return $this->redirect(Director::absoluteBaseURL() . Security::config()->default_login_dest); } // fallback to redirect back to home page return $this->redirect(Director::absoluteBaseURL()); }
/** * Redirect back. Uses either the HTTP_REFERER or a manually set request-variable called * _REDIRECT_BACK_URL. * This variable is needed in scenarios where not HTTP-Referer is sent ( * e.g when calling a page by location.href in IE). * If none of the two variables is available, it will redirect to the base * URL (see {@link Director::baseURL()}). * @uses redirect() */ function redirectBack() { $url = null; // In edge-cases, this will be called outside of a handleRequest() context; in that case, // redirect to the homepage - don't break into the global state at this stage because we'll // be calling from a test context or something else where the global state is inappropraite if ($this->request) { if ($this->request->requestVar('_REDIRECT_BACK_URL')) { $url = $this->request->requestVar('_REDIRECT_BACK_URL'); } else { if ($this->request->getHeader('Referer')) { $url = $this->request->getHeader('Referer'); } } } if (!$url) { $url = Director::baseURL(); } // absolute redirection URLs not located on this site may cause phishing if (Director::is_site_url($url)) { return $this->redirect($url); } else { return false; } }
/** * Redirect back. Uses either the HTTP_REFERER or a manually set request-variable called * _REDIRECT_BACK_URL. * This variable is needed in scenarios where not HTTP-Referer is sent ( * e.g when calling a page by location.href in IE). * If none of the two variables is available, it will redirect to the base * URL (see {@link Director::baseURL()}). * @uses redirect() */ function redirectBack() { if ($this->request->requestVar('_REDIRECT_BACK_URL')) { $url = $this->request->requestVar('_REDIRECT_BACK_URL'); } else { if ($this->request->getHeader('Referer')) { $url = $this->request->getHeader('Referer'); } else { $url = Director::baseURL(); } } // absolute redirection URLs not located on this site may cause phishing if (Director::is_site_url($url)) { return $this->redirect($url); } else { return false; } }
/** * Given a successful login, tell the parent frame to close the dialog * * @return SS_HTTPResponse */ 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)); 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')); }
/** * @return string A BackURL as specified originally when accessing /Security/login, for use after authentication */ public function getBackURL() { if (!empty($_REQUEST['BackURL'])) { $url = $_REQUEST['BackURL']; } elseif (Session::get('BackURL')) { $url = Session::get('BackURL'); Session::clear('BackURL'); // Ensure we don't redirect back to the same error twice } if (isset($url) && Director::is_site_url($url)) { $url = Director::absoluteURL($url); } else { // Spoofing attack or no back URL set, redirect to homepage instead of spoofing url $url = Director::absoluteBaseURL(); } return $url; }
/** * Mostly tested by {@link testIsRelativeUrl()}, * just adding the host name matching aspect here. */ public function testIsSiteUrl() { $this->assertFalse(Director::is_site_url("http://test.com")); $this->assertTrue(Director::is_site_url(Director::absoluteBaseURL())); $this->assertFalse(Director::is_site_url("http://test.com?url=" . Director::absoluteBaseURL())); $this->assertFalse(Director::is_site_url("http://test.com?url=" . urlencode(Director::absoluteBaseURL()))); $this->assertFalse(Director::is_site_url("//test.com?url=" . Director::absoluteBaseURL())); }
/** * View of a single file, either on the filesystem or on the web. */ public function viewfile($request) { // TODO Would be cleaner to consistently pass URL for both local and remote files, // but GridField doesn't allow for this kind of metadata customization at the moment. if ($url = $request->getVar('FileURL')) { if (Director::is_absolute_url($url) && !Director::is_site_url($url)) { $url = $url; $file = new File(array('Title' => basename($url), 'Filename' => $url)); } else { $url = Director::makeRelative($request->getVar('FileURL')); $url = preg_replace('/_resampled\\/[^-]+-/', '', $url); $file = File::get()->filter('Filename', $url)->first(); if (!$file) { $file = new File(array('Title' => basename($url), 'Filename' => $url)); } } } elseif ($id = $request->getVar('ID')) { $file = DataObject::get_by_id('File', $id); $url = $file->RelativeLink(); } else { throw new LogicException('Need either "ID" or "FileURL" parameter to identify the file'); } // Instanciate file wrapper and get fields based on its type // Check if appCategory is an image and exists on the local system, otherwise use oEmbed to refference a // remote image if ($file && $file->appCategory() == 'image' && Director::is_site_url($url)) { $fileWrapper = new HtmlEditorField_Image($url, $file); } elseif (!Director::is_site_url($url)) { $fileWrapper = new HtmlEditorField_Embed($url, $file); } else { $fileWrapper = new HtmlEditorField_File($url, $file); } $fields = $this->getFieldsForFile($url, $fileWrapper); $this->extend('updateFieldsForFile', $fields, $url, $fileWrapper); return $fileWrapper->customise(array('Fields' => $fields))->renderWith($this->templateViewFile); }
/** * Handle a form submission. GET and POST requests behave identically. * Populates the form with {@link loadDataFrom()}, calls {@link validate()}, * and only triggers the requested form action/method * if the form is valid. */ function httpSubmission($request) { $vars = $request->requestVars(); if (isset($funcName)) { Form::set_current_action($funcName); } // Populate the form $this->loadDataFrom($vars, true); // Protection against CSRF attacks if ($this->securityTokenEnabled()) { $securityID = Session::get('SecurityID'); if (!$securityID || !isset($vars['SecurityID']) || $securityID != $vars['SecurityID']) { $this->httpError(400, "SecurityID doesn't match, possible CSRF attack."); } } // Determine the action button clicked $funcName = null; foreach ($vars as $paramName => $paramVal) { if (substr($paramName, 0, 7) == 'action_') { // Break off querystring arguments included in the action if (strpos($paramName, '?') !== false) { list($paramName, $paramVars) = explode('?', $paramName, 2); $newRequestParams = array(); parse_str($paramVars, $newRequestParams); $vars = array_merge((array) $vars, (array) $newRequestParams); } // Cleanup action_, _x and _y from image fields $funcName = preg_replace(array('/^action_/', '/_x$|_y$/'), '', $paramName); break; } } // If the action wasnt' set, choose the default on the form. if (!isset($funcName) && ($defaultAction = $this->defaultAction())) { $funcName = $defaultAction->actionName(); } if (isset($funcName)) { $this->setButtonClicked($funcName); } // Validate the form if (!$this->validate()) { if (Director::is_ajax()) { // Special case for legacy Validator.js implementation (assumes eval'ed javascript collected through FormResponse) if ($this->validator->getJavascriptValidationHandler() == 'prototype') { return FormResponse::respond(); } else { $acceptType = $request->getHeader('Accept'); if (strpos($acceptType, 'application/json') !== FALSE) { // Send validation errors back as JSON with a flag at the start $response = new SS_HTTPResponse(Convert::array2json($this->validator->getErrors())); $response->addHeader('Content-Type', 'application/json'); } else { $this->setupFormErrors(); // Send the newly rendered form tag as HTML $response = new SS_HTTPResponse($this->forTemplate()); $response->addHeader('Content-Type', 'text/html'); } return $response; } } else { if ($this->getRedirectToFormOnValidationError()) { if ($pageURL = $request->getHeader('Referer')) { if (Director::is_site_url($pageURL)) { // Remove existing pragmas $pageURL = preg_replace('/(#.*)/', '', $pageURL); return Director::redirect($pageURL . '#' . $this->FormName()); } } } return Director::redirectBack(); } } // First, try a handler method on the controller if ($this->controller->hasMethod($funcName)) { return $this->controller->{$funcName}($vars, $this, $request); // Otherwise, try a handler method on the form object } else { if ($this->hasMethod($funcName)) { return $this->{$funcName}($vars, $this, $request); } } }
/** * Handles performing a callback to the Salesforce auth server with the * provided authorisation code. * * @param string $code * @param string $state * @return SS_HTTPResponse * @throws SalesforceAuthException On authentication failure. */ public function callback($code, $state) { $callback = new RestfulService(self::CALLBACK_URL, -1); $callback = $callback->request('', 'POST', array('code' => $code, 'grant_type' => 'authorization_code', 'client_id' => $this->getClientID(), 'client_secret' => $this->getClientSecret(), 'redirect_uri' => $this->getRedirectURL())); $callback = json_decode($callback->getBody()); if (!$callback || !$callback->id) { throw new SalesforceAuthException('An invalid authorisation response was returned'); } $id = new RestfulService($callback->id, -1); $id->setQueryString(array('oauth_token' => $callback->access_token)); $id = json_decode($id->request()->getBody()); if (!$id || !$id->email) { throw new SalesforceAuthException('An invalid identity response was returned'); } /** @var Member $member */ $member = Member::get()->filter('Email', $id->email)->first(); if (!$member) { throw new SalesforceAuthException(sprintf('No member was found for the Salesforce email "%s"', $id->email)); } $state = json_decode($state); $redirect = isset($state->redirect) ? $state->redirect : null; $member->logIn(!empty($state->remember)); $member->extend('onSalesforceIdentify', $id); $response = new SS_HTTPResponse(); if ($redirect && Director::is_site_url($redirect)) { return $response->redirect($redirect); } if ($redirect = Config::inst()->get('Security', 'default_login_dest')) { return $response->redirect($redirect); } return $response->redirect(Director::absoluteBaseURL()); }
public function Absolute() { $relative = $this->getURL(); return Director::is_site_url($relative) && Director::is_relative_url($relative) ? Controller::join_links(Director::protocolAndHost(), $relative) : $relative; }
/** * Gets the url to return to after build * * @return string|null */ protected function getReturnURL() { $url = $this->request->getVar('returnURL'); // Check that this url is a site url if (empty($url) || !Director::is_site_url($url)) { return null; } // Convert to absolute URL return Director::absoluteURL($url, true); }
public function testIsSiteUrl() { $siteUrl = Director::absoluteBaseURL(); $siteUrlNoProtocol = preg_replace('/https?:\\/\\//', '', $siteUrl); $this->assertTrue(Director::is_site_url($siteUrl)); $this->assertTrue(Director::is_site_url("{$siteUrl}/testpage")); $this->assertTrue(Director::is_site_url(" {$siteUrl}/testpage ")); $this->assertTrue(Director::is_site_url("{$siteUrlNoProtocol}/testpage")); $this->assertFalse(Director::is_site_url('http://test.com/testpage')); //$this->assertFalse(Director::is_site_url('test.com/testpage')); $this->assertTrue(Director::is_site_url('/relative')); $this->assertTrue(Director::is_site_url('relative')); $this->assertFalse(Director::is_site_url("http://test.com/?url={$siteUrl}")); }
/** * Returns the appropriate response up the controller chain * if {@link validate()} fails (which is checked prior to executing any form actions). * By default, returns different views for ajax/non-ajax request, and * handles 'appliction/json' requests with a JSON object containing the error messages. * Behaviour can be influenced by setting {@link $redirectToFormOnValidationError}. * * @return SS_HTTPResponse|string */ protected function getValidationErrorResponse() { $request = $this->getRequest(); if ($request->isAjax()) { // Special case for legacy Validator.js implementation // (assumes eval'ed javascript collected through FormResponse) $acceptType = $request->getHeader('Accept'); if (strpos($acceptType, 'application/json') !== FALSE) { // Send validation errors back as JSON with a flag at the start $response = new SS_HTTPResponse(Convert::array2json($this->validator->getErrors())); $response->addHeader('Content-Type', 'application/json'); } else { $this->setupFormErrors(); // Send the newly rendered form tag as HTML $response = new SS_HTTPResponse($this->forTemplate()); $response->addHeader('Content-Type', 'text/html'); } return $response; } else { if ($this->getRedirectToFormOnValidationError()) { if ($pageURL = $request->getHeader('Referer')) { if (Director::is_site_url($pageURL)) { // Remove existing pragmas $pageURL = preg_replace('/(#.*)/', '', $pageURL); return $this->controller->redirect($pageURL . '#' . $this->FormName()); } } } return $this->controller->redirectBack(); } }
/** * Change the password * * @param array $data The user submitted data * @return SS_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()) { $member->logIn(); // TODO Add confirmation message to login redirect Session::clear('AutoLoginHash'); // Clear locked out status $member->LockedOutUntil = null; $member->FailedLoginCount = null; $member->write(); 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" . $isValid->starredList()))), "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 { $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')); } } }
/** * Login form handler method * * This method is called when the user clicks on "Log in" * * @param array $data Submitted data */ public function createorupdateaccount($data, $form) { $passwordOK = true; if (!$passwordOK) { Session::set('Security.Message.message', _t('Member.PASSWORDINVALID', "Your password is not valid.")); $loginLink = Director::absoluteURL(Security::Link("login")); if ($backURL) { $loginLink .= '?BackURL=' . urlencode($backURL); } Director::redirect($loginLink . '#' . $this->FormName() . '_tab'); } if ($this->createOrUpdateUser($data, $form)) { Session::clear('SessionForms.MemberLoginForm.EmailSignup'); Session::clear('SessionForms.MemberLoginForm.FirstNameSignup'); Session::clear('SessionForms.MemberLoginForm.SurnameSignup'); Session::clear('SessionForms.MemberLoginForm.RememberSignup'); if (!isset($_REQUEST['BackURL'])) { if (Session::get("BackURL")) { $_REQUEST['BackURL'] = Session::get("BackURL"); } } Session::clear("BackURL"); if (isset($_REQUEST['BackURL']) && $_REQUEST['BackURL'] && Director::is_site_url($_REQUEST['BackURL'])) { Director::redirect($_REQUEST['BackURL']); } elseif (Security::default_login_dest()) { Director::redirect(Director::absoluteBaseURL() . Security::default_login_dest()); } else { $member = Member::currentUser(); if ($member) { $firstname = Convert::raw2xml($member->FirstName); if (!empty($data['RememberSignup'])) { Session::set('SessionForms.MemberLoginForm.RememberSignup', '1'); $member->logIn(true); } else { $member->logIn(); } Session::set('Security.Message.message', sprintf(_t('Member.THANKYOUFORCREATINGACCOUNT', "Thank you for creating an account, %s"), $firstname)); Session::set("Security.Message.type", "good"); } Director::redirectBack(); } } else { Session::set('Security.Message.message', _t('Member.MEMBERALREADYEXISTS', "A member with this email already exists.")); Session::set("Security.Message.type", "error"); Session::set('SessionForms.MemberLoginFormWithSignup.EmailSignupSignup', $data['EmailSignup']); Session::set('SessionForms.MemberLoginFormWithSignup.FirstNameSignup', $data['FirstNameSignup']); Session::set('SessionForms.MemberLoginFormWithSignup.SurnameSignup', $data['SurnameSignup']); Session::set('SessionForms.MemberLoginFormWithSignup.RememberSignup', isset($data['RememberSignup'])); if (isset($_REQUEST['BackURL'])) { $backURL = $_REQUEST['BackURL']; } else { $backURL = null; } if ($backURL) { Session::set('BackURL', $backURL); } if ($badLoginURL = Session::get("BadLoginURL")) { Director::redirect($badLoginURL); } else { // Show the right tab on failed login $loginLink = Director::absoluteURL(Security::Link("login")); if ($backURL) { $loginLink .= '?BackURL=' . urlencode($backURL); } Director::redirect($loginLink . '#' . $this->FormName() . '_tab'); } } }
/** * Handle a form submission. GET and POST requests behave identically. * Populates the form with {@link loadDataFrom()}, calls {@link validate()}, * and only triggers the requested form action/method * if the form is valid. */ public function httpSubmission($request) { $vars = $request->requestVars(); if(isset($funcName)) { Form::set_current_action($funcName); } // Populate the form $this->loadDataFrom($vars, true); // Protection against CSRF attacks $token = $this->getSecurityToken(); if(!$token->checkRequest($request)) { $this->httpError(400, "Sorry, your session has timed out."); } // Determine the action button clicked $funcName = null; foreach($vars as $paramName => $paramVal) { if(substr($paramName,0,7) == 'action_') { // Break off querystring arguments included in the action if(strpos($paramName,'?') !== false) { list($paramName, $paramVars) = explode('?', $paramName, 2); $newRequestParams = array(); parse_str($paramVars, $newRequestParams); $vars = array_merge((array)$vars, (array)$newRequestParams); } // Cleanup action_, _x and _y from image fields $funcName = preg_replace(array('/^action_/','/_x$|_y$/'),'',$paramName); break; } } // If the action wasnt' set, choose the default on the form. if(!isset($funcName) && $defaultAction = $this->defaultAction()){ $funcName = $defaultAction->actionName(); } if(isset($funcName)) { $this->setButtonClicked($funcName); } // Permission checks (first on controller, then falling back to form) if( // Ensure that the action is actually a button or method on the form, // and not just a method on the controller. $this->controller->hasMethod($funcName) && !$this->controller->checkAccessAction($funcName) // If a button exists, allow it on the controller && !$this->Actions()->fieldByName('action_' . $funcName) ) { return $this->httpError( 403, sprintf('Action "%s" not allowed on controller (Class: %s)', $funcName, get_class($this->controller)) ); } elseif( $this->hasMethod($funcName) && !$this->checkAccessAction($funcName) // No checks for button existence or $allowed_actions is performed - // all form methods are callable (e.g. the legacy "callfieldmethod()") ) { return $this->httpError( 403, sprintf('Action "%s" not allowed on form (Name: "%s")', $funcName, $this->Name()) ); } // TODO : Once we switch to a stricter policy regarding allowed_actions (meaning actions must be set explicitly in allowed_actions in order to run) // Uncomment the following for checking security against running actions on form fields /* else { // Try to find a field that has the action, and allows it $fieldsHaveMethod = false; foreach ($this->Fields() as $field){ if ($field->hasMethod($funcName) && $field->checkAccessAction($funcName)) { $fieldsHaveMethod = true; } } if (!$fieldsHaveMethod) { return $this->httpError( 403, sprintf('Action "%s" not allowed on any fields of form (Name: "%s")', $funcName, $this->Name()) ); } }*/ // Validate the form if(!$this->validate()) { if(Director::is_ajax()) { // Special case for legacy Validator.js implementation (assumes eval'ed javascript collected through FormResponse) $acceptType = $request->getHeader('Accept'); if(strpos($acceptType, 'application/json') !== FALSE) { // Send validation errors back as JSON with a flag at the start $response = new SS_HTTPResponse(Convert::array2json($this->validator->getErrors())); $response->addHeader('Content-Type', 'application/json'); } else { $this->setupFormErrors(); // Send the newly rendered form tag as HTML $response = new SS_HTTPResponse($this->forTemplate()); $response->addHeader('Content-Type', 'text/html'); } return $response; } else { if($this->getRedirectToFormOnValidationError()) { if($pageURL = $request->getHeader('Referer')) { if(Director::is_site_url($pageURL)) { // Remove existing pragmas $pageURL = preg_replace('/(#.*)/', '', $pageURL); return $this->controller->redirect($pageURL . '#' . $this->FormName()); } } } return $this->controller->redirectBack(); } } // First, try a handler method on the controller (has been checked for allowed_actions above already) if($this->controller->hasMethod($funcName)) { return $this->controller->$funcName($vars, $this, $request); // Otherwise, try a handler method on the form object. } elseif($this->hasMethod($funcName)) { return $this->$funcName($vars, $this, $request); } elseif($field = $this->checkFieldsForAction($this->Fields(), $funcName)) { return $field->$funcName($vars, $this, $request); } return $this->httpError(404); }
/** * Login form handler method * * This method is called when the user clicks on "Log in" * * @param array $data Submitted data */ public function dologin($data) { if ($this->performLogin($data)) { Session::clear('SessionForms.MemberLoginForm.Email'); Session::clear('SessionForms.MemberLoginForm.Remember'); if (Member::currentUser()->isPasswordExpired()) { if (isset($_REQUEST['BackURL']) && ($backURL = $_REQUEST['BackURL'])) { Session::set('BackURL', $backURL); } $cp = new ChangePasswordForm($this->controller, 'ChangePasswordForm'); $cp->sessionMessage('Your password has expired. Please choose a new one.', 'good'); Director::redirect('Security/changepassword'); } elseif (isset($_REQUEST['BackURL']) && $_REQUEST['BackURL'] && Director::is_site_url($_REQUEST['BackURL'])) { Director::redirect($_REQUEST['BackURL']); } elseif (Security::default_login_dest()) { Director::redirect(Director::absoluteBaseURL() . Security::default_login_dest()); } else { $member = Member::currentUser(); if ($member) { $firstname = Convert::raw2xml($member->FirstName); if (!empty($data['Remember'])) { Session::set('SessionForms.MemberLoginForm.Remember', '1'); $member->logIn(true); } else { $member->logIn(); } Session::set('Security.Message.message', sprintf(_t('Member.WELCOMEBACK', "Welcome Back, %s"), $firstname)); Session::set("Security.Message.type", "good"); } Director::redirectBack(); } } else { Session::set('SessionForms.MemberLoginForm.Email', $data['Email']); Session::set('SessionForms.MemberLoginForm.Remember', isset($data['Remember'])); if (isset($_REQUEST['BackURL'])) { $backURL = $_REQUEST['BackURL']; } else { $backURL = null; } if ($backURL) { Session::set('BackURL', $backURL); } if ($badLoginURL = Session::get("BadLoginURL")) { Director::redirect($badLoginURL); } else { // Show the right tab on failed login $loginLink = Director::absoluteURL(Security::Link("login")); if ($backURL) { $loginLink .= '?BackURL=' . urlencode($backURL); } Director::redirect($loginLink . '#' . $this->FormName() . '_tab'); } } }
/** * Redirect back. Uses either the HTTP_REFERER or a manually set request-variable called "BackURL". * This variable is needed in scenarios where not HTTP-Referer is sent ( * e.g when calling a page by location.href in IE). * If none of the two variables is available, it will redirect to the base * URL (see {@link Director::baseURL()}). * @uses redirect() */ public function redirectBack() { // Don't cache the redirect back ever HTTP::set_cache_age(0); $url = null; // In edge-cases, this will be called outside of a handleRequest() context; in that case, // redirect to the homepage - don't break into the global state at this stage because we'll // be calling from a test context or something else where the global state is inappropraite if ($this->request) { if ($this->request->requestVar('BackURL')) { $url = $this->request->requestVar('BackURL'); } else { if ($this->request->isAjax() && $this->request->getHeader('X-Backurl')) { $url = $this->request->getHeader('X-Backurl'); } else { if ($this->request->getHeader('Referer')) { $url = $this->request->getHeader('Referer'); } } } } if (!$url) { $url = Director::baseURL(); } // absolute redirection URLs not located on this site may cause phishing if (Director::is_site_url($url)) { $url = Director::absoluteURL($url, true); return $this->redirect($url); } else { return false; } }