Skip to content

Commit

Permalink
API HTTPRequestBuilder::createFromEnvironment() now cleans up live gl…
Browse files Browse the repository at this point in the history
…obals

BUG Fix issue with SSViewer
Fix Security / View tests
  • Loading branch information
Damian Mooyman committed Jun 21, 2017
1 parent d88d4ed commit 5d235e6
Show file tree
Hide file tree
Showing 30 changed files with 228 additions and 147 deletions.
2 changes: 1 addition & 1 deletion src/Control/CLIRequestBuilder.php
Expand Up @@ -7,7 +7,7 @@
*/
class CLIRequestBuilder extends HTTPRequestBuilder
{
protected static function cleanEnvironment(array $variables)
public static function cleanEnvironment(array $variables)
{
// Create all blank vars
foreach (['_REQUEST', '_GET', '_POST', '_SESSION', '_SERVER', '_COOKIE', '_ENV', '_FILES'] as $key) {
Expand Down
3 changes: 3 additions & 0 deletions src/Control/Director.php
Expand Up @@ -315,6 +315,9 @@ public static function mockRequest(
$newVars['_SERVER']['REQUEST_URI'] = Director::baseURL() . $url;
$newVars['_REQUEST'] = array_merge($newVars['_GET'], $newVars['_POST']);

// Normalise vars
$newVars = HTTPRequestBuilder::cleanEnvironment($newVars);

// Create new request
$request = HTTPRequestBuilder::createFromVariables($newVars, $body);
if ($headers) {
Expand Down
10 changes: 6 additions & 4 deletions src/Control/HTTPRequestBuilder.php
Expand Up @@ -15,8 +15,12 @@ class HTTPRequestBuilder
*/
public static function createFromEnvironment()
{
// Clean and update live global variables
$variables = static::cleanEnvironment(Environment::getVariables());
Environment::setVariables($variables); // Currently necessary for SSViewer, etc to work

// Health-check prior to creating environment
return static::createFromVariables(Environment::getVariables(), @file_get_contents('php://input'));
return static::createFromVariables($variables, @file_get_contents('php://input'));
}

/**
Expand All @@ -28,8 +32,6 @@ public static function createFromEnvironment()
*/
public static function createFromVariables(array $variables, $input)
{
$variables = static::cleanEnvironment($variables);

// Strip `url` out of querystring
$url = $variables['_GET']['url'];
unset($variables['_GET']['url']);
Expand Down Expand Up @@ -92,7 +94,7 @@ protected static function extractRequestHeaders(array $server)
* @param array $variables
* @return array Cleaned variables
*/
protected static function cleanEnvironment(array $variables)
public static function cleanEnvironment(array $variables)
{
// IIS will sometimes generate this.
if (!empty($variables['_SERVER']['HTTP_X_ORIGINAL_URL'])) {
Expand Down
2 changes: 1 addition & 1 deletion src/Core/TempFolder.php
Expand Up @@ -34,7 +34,7 @@ public static function getTempFolder($base)
*
* @return string
*/
protected static function getTempFolderUsername()
public static function getTempFolderUsername()
{
$user = getenv('APACHE_RUN_USER');
if (!$user) {
Expand Down
4 changes: 2 additions & 2 deletions src/Dev/CSSContentParser.php
Expand Up @@ -69,7 +69,7 @@ public function __construct($content)
* See {@link getByXpath()} for a more direct selector syntax.
*
* @param String $selector
* @return SimpleXMLElement
* @return SimpleXMLElement[]
*/
public function getBySelector($selector)
{
Expand All @@ -81,7 +81,7 @@ public function getBySelector($selector)
* Allows querying the content through XPATH selectors.
*
* @param String $xpath SimpleXML compatible XPATH statement
* @return SimpleXMLElement|false
* @return SimpleXMLElement[]
*/
public function getByXpath($xpath)
{
Expand Down
6 changes: 3 additions & 3 deletions src/Dev/SapphireTest.php
Expand Up @@ -6,6 +6,7 @@
use LogicException;
use PHPUnit_Framework_TestCase;
use SilverStripe\CMS\Controllers\RootURLController;
use SilverStripe\Control\CLIRequestBuilder;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Cookie;
use SilverStripe\Control\Director;
Expand Down Expand Up @@ -889,9 +890,8 @@ public static function start()
static::set_is_running_test(true);

// Mock request
$session = new Session(isset($_SESSION) ? $_SESSION : array());
$request = new HTTPRequest('GET', '/');
$request->setSession($session);
$_SERVER['argv'] = ['vendor/bin/phpunit', '/'];
$request = CLIRequestBuilder::createFromEnvironment();

// Test application
$kernel = new TestKernel(BASE_PATH);
Expand Down
30 changes: 27 additions & 3 deletions src/Forms/Form.php
Expand Up @@ -2,9 +2,12 @@

namespace SilverStripe\Forms;

use BadMethodCallException;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HasRequestHandler;
use SilverStripe\Control\HTTP;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\NullHTTPRequest;
use SilverStripe\Control\RequestHandler;
use SilverStripe\Control\Session;
use SilverStripe\Core\ClassInfo;
Expand Down Expand Up @@ -341,16 +344,37 @@ public function clearFormState()
return $this;
}

/**
* Helper to get current request for this form
*
* @return HTTPRequest
*/
protected function getRequest()
{
// Check if current request handler has a request object
$controller = $this->getController();
if ($controller && !($controller->getRequest() instanceof NullHTTPRequest)) {
return $controller->getRequest();
}
// Fall back to current controller
if (Controller::has_curr() && !(Controller::curr()->getRequest() instanceof NullHTTPRequest)) {
return Controller::curr()->getRequest();
}
return null;
}

/**
* Get session for this form
*
* @return Session
*/
protected function getSession()
{
// Note: Session may not be available if this form doesn't have a request handler
$controller = $this->getController() ?: Controller::curr();
return $controller->getRequest()->getSession();
$request = $this->getRequest();
if ($request) {
return $request->getSession();
}
throw new BadMethodCallException("Session not available in the current context");
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Security/BasicAuth.php
Expand Up @@ -8,7 +8,7 @@
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Dev\Debug;
use SilverStripe\Security\MemberAuthenticator\MemberAuthenticator;

/**
Expand Down
18 changes: 13 additions & 5 deletions src/Security/DefaultAdminService.php
Expand Up @@ -18,9 +18,12 @@ class DefaultAdminService
use Injectable;

/**
* @var bool
* Can be set to explicitly true or false, or left null.
* If null, hasDefaultAdmin() will be inferred from environment.
*
* @var bool|null
*/
protected static $has_default_admin = false;
protected static $has_default_admin = null;

/**
* @var string
Expand Down Expand Up @@ -72,7 +75,7 @@ public static function getDefaultAdminUsername()
"No default admin configured. Please call hasDefaultAdmin() before getting default admin username"
);
}
return static::$default_username;
return static::$default_username ?: getenv('SS_DEFAULT_ADMIN_USERNAME');
}

/**
Expand All @@ -86,7 +89,7 @@ public static function getDefaultAdminPassword()
"No default admin configured. Please call hasDefaultAdmin() before getting default admin password"
);
}
return static::$default_password;
return static::$default_password ?: getenv('SS_DEFAULT_ADMIN_PASSWORD');
}

/**
Expand All @@ -96,11 +99,16 @@ public static function getDefaultAdminPassword()
*/
public static function hasDefaultAdmin()
{
// Check environment if not explicitly set
if (!isset(static::$has_default_admin)) {
return !empty(getenv('SS_DEFAULT_ADMIN_USERNAME'))
&& !empty(getenv('SS_DEFAULT_ADMIN_PASSWORD'));
}
return static::$has_default_admin;
}

/**
* Flush the default admin credentials
* Flush the default admin credentials.
*/
public static function clearDefaultAdmin()
{
Expand Down
21 changes: 10 additions & 11 deletions src/Security/MemberAuthenticator/MemberAuthenticator.php
Expand Up @@ -3,17 +3,16 @@
namespace SilverStripe\Security\MemberAuthenticator;

use InvalidArgumentException;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Session;
use SilverStripe\Core\Extensible;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\Extensible;
use SilverStripe\Dev\Debug;
use SilverStripe\ORM\ValidationResult;
use SilverStripe\Security\Authenticator;
use SilverStripe\Security\DefaultAdminService;
use SilverStripe\Security\LoginAttempt;
use SilverStripe\Security\Member;
use SilverStripe\Security\PasswordEncryptor;
use SilverStripe\Security\Security;
use SilverStripe\Security\DefaultAdminService;

/**
* Authenticator for the default "member" method
Expand Down Expand Up @@ -69,15 +68,15 @@ protected function authenticateMember($data, ValidationResult &$result = null, M
if ($result->isValid()) {
// Check if default admin credentials are correct
if (DefaultAdminService::isDefaultAdminCredentials($email, $data['Password'])) {
return $member;
} else {
$result->addError(_t(
'SilverStripe\\Security\\Member.ERRORWRONGCRED',
"The provided details don't seem to be correct. Please try again."
));
return $member;
} else {
$result->addError(_t(
'SilverStripe\\Security\\Member.ERRORWRONGCRED',
"The provided details don't seem to be correct. Please try again."
));
}
}
}
}

// Attempt to identify user by email
if (!$member && $email) {
Expand Down
9 changes: 5 additions & 4 deletions src/Security/MemberAuthenticator/MemberLoginForm.php
Expand Up @@ -4,7 +4,6 @@

use SilverStripe\Control\Director;
use SilverStripe\Control\RequestHandler;
use SilverStripe\Control\Session;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FormAction;
Expand Down Expand Up @@ -124,11 +123,11 @@ public function __construct(
*/
protected function getFormFields()
{
$request = $this->getController()->getRequest();
$request = $this->getRequest();
if ($request->getVar('BackURL')) {
$backURL = $request->getVar('BackURL');
} else {
$backURL = Session::get('BackURL');
$backURL = $request->getSession()->get('BackURL');
}

$label = Member::singleton()->fieldLabel(Member::config()->get('unique_identifier_field'));
Expand Down Expand Up @@ -191,11 +190,13 @@ protected function getFormActions()
return $actions;
}



public function restoreFormState()
{
parent::restoreFormState();

$session = Controller::curr()->getRequest()->getSession();
$session = $this->getSession();
$forceMessage = $session->get('MemberLoginForm.force_message');
if (($member = Security::getCurrentUser()) && !$forceMessage) {
$message = _t(
Expand Down
14 changes: 9 additions & 5 deletions src/Security/Security.php
Expand Up @@ -391,7 +391,7 @@ public static function permissionFailure($controller = null, $messageSet = null)
}

static::singleton()->setLoginMessage($message, ValidationResult::TYPE_WARNING);
$loginResponse = static::singleton()->login();
$loginResponse = static::singleton()->login($controller ? $controller->getRequest() : $controller);
if ($loginResponse instanceof HTTPResponse) {
return $loginResponse;
}
Expand Down Expand Up @@ -702,16 +702,20 @@ public static function clearLoginMessage()
*/
public function login($request = null, $service = Authenticator::LOGIN)
{
if ($request) {
$this->setRequest($request);
} elseif ($request) {
$request = $this->getRequest();
} else {
throw new HTTPResponse_Exception("No request available", 500);
}

// Check pre-login process
if ($response = $this->preLogin()) {
return $response;
}
$authName = null;

if (!$request) {
$request = $this->getRequest();
}

if ($request && $request->param('ID')) {
$authName = $request->param('ID');
}
Expand Down
9 changes: 6 additions & 3 deletions src/View/Requirements_Backend.php
Expand Up @@ -1325,9 +1325,12 @@ protected function getCombinedFileURL($combinedFile, $fileList, $type)
if ($minify && !$this->minifier) {
throw new Exception(
sprintf(
'Cannot minify files without a minification service defined.
Set %s::minifyCombinedFiles to false, or inject a %s service on
%s.properties.minifier',
<<<MESSAGE
Cannot minify files without a minification service defined.
Set %s::minifyCombinedFiles to false, or inject a %s service on
%s.properties.minifier
MESSAGE
,
__CLASS__,
Requirements_Minifier::class,
__CLASS__
Expand Down
9 changes: 7 additions & 2 deletions tests/php/Control/PjaxResponseNegotiatorTest.php
Expand Up @@ -2,9 +2,10 @@

namespace SilverStripe\Control\Tests;

use SilverStripe\Dev\SapphireTest;
use SilverStripe\Control\PjaxResponseNegotiator;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\PjaxResponseNegotiator;
use SilverStripe\Control\Session;
use SilverStripe\Dev\SapphireTest;

class PjaxResponseNegotiatorTest extends SapphireTest
{
Expand All @@ -19,6 +20,7 @@ public function testDefaultCallbacks()
)
);
$request = new HTTPRequest('GET', '/'); // not setting pjax header
$request->setSession(new Session([]));
$response = $negotiator->respond($request);
$this->assertEquals('default response', $response->getBody());
}
Expand All @@ -36,6 +38,7 @@ public function testSelectsFragmentByHeader()
)
);
$request = new HTTPRequest('GET', '/');
$request->setSession(new Session([]));
$request->addHeader('X-Pjax', 'myfragment');
$response = $negotiator->respond($request);
$this->assertEquals('{"myfragment":"myfragment response"}', $response->getBody());
Expand All @@ -57,6 +60,7 @@ public function testMultipleFragments()
)
);
$request = new HTTPRequest('GET', '/');
$request->setSession(new Session([]));
$request->addHeader('X-Pjax', 'myfragment,otherfragment');
$request->addHeader('Accept', 'text/json');
$response = $negotiator->respond($request);
Expand All @@ -81,6 +85,7 @@ public function testFragmentsOverride()
);

$request = new HTTPRequest('GET', '/');
$request->setSession(new Session([]));
$request->addHeader('X-Pjax', 'alpha');
$request->addHeader('Accept', 'text/json');

Expand Down

0 comments on commit 5d235e6

Please sign in to comment.