Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/3.0' into 3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Sean Harvey committed Aug 22, 2014
2 parents 6e0d9df + 1661213 commit 0e07f1a
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 36 deletions.
2 changes: 1 addition & 1 deletion dev/SapphireTestReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public function endTestSuite( PHPUnit_Framework_TestSuite $suite) {
$this->endCurrentTestSuite();
}
}

/**
* Risky test.
*
Expand Down
2 changes: 1 addition & 1 deletion dev/TestListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {

$this->class->tearDownOnce();
}

/**
* Risky test.
*
Expand Down
34 changes: 21 additions & 13 deletions forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,6 @@ class Form extends RequestHandler {
'forTemplate',
);

private static $casting = array(
'Message' => 'Text'
);

/**
* Create a new form, with the given fields an action buttons.
*
Expand Down Expand Up @@ -508,10 +504,10 @@ public function getRedirectToFormOnValidationError() {
* Add a plain text error message to a field on this form. It will be saved into the session
* and used the next time this form is displayed.
*/
public function addErrorMessage($fieldName, $message, $messageType) {
public function addErrorMessage($fieldName, $message, $messageType, $escapeHtml = true) {
Session::add_to_array("FormInfo.{$this->FormName()}.errors", array(
'fieldName' => $fieldName,
'message' => $message,
'message' => $escapeHtml ? Convert::raw2xml($message) : $message,
'messageType' => $messageType,
));
}
Expand Down Expand Up @@ -1035,9 +1031,12 @@ protected function getMessageFromSession() {
*
* @param message the text of the message
* @param type Should be set to good, bad, or warning.
* @param boolean $escapeHtml Automatically sanitize the message. Set to FALSE if the message contains HTML.
* In that case, you might want to use {@link Convert::raw2xml()} to escape any
* user supplied data in the message.
*/
public function setMessage($message, $type) {
$this->message = $message;
public function setMessage($message, $type, $escapeHtml = true) {
$this->message = ($escapeHtml) ? Convert::raw2xml($message) : $message;
$this->messageType = $type;
return $this;
}
Expand All @@ -1047,14 +1046,23 @@ public function setMessage($message, $type) {
*
* @param message the text of the message
* @param type Should be set to good, bad, or warning.
*/
public function sessionMessage($message, $type) {
Session::set("FormInfo.{$this->FormName()}.formError.message", $message);
* @param boolean $escapeHtml Automatically sanitize the message. Set to FALSE if the message contains HTML.
* In that case, you might want to use {@link Convert::raw2xml()} to escape any
* user supplied data in the message.
*/
public function sessionMessage($message, $type, $escapeHtml = true) {
Session::set(
"FormInfo.{$this->FormName()}.formError.message",
$escapeHtml ? Convert::raw2xml($message) : $message
);
Session::set("FormInfo.{$this->FormName()}.formError.type", $type);
}

public static function messageForForm( $formName, $message, $type ) {
Session::set("FormInfo.{$formName}.formError.message", $message);
public static function messageForForm( $formName, $message, $type, $escapeHtml = true) {
Session::set(
"FormInfo.{$formName}.formError.message",
$escapeHtml ? Convert::raw2xml($message) : $message
);
Session::set("FormInfo.{$formName}.formError.type", $type);
}

Expand Down
9 changes: 4 additions & 5 deletions forms/FormField.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,6 @@ class FormField extends RequestHandler {
*/
protected $attributes = array();

private static $casting = array(
'Message' => 'Text'
);

/**
* Takes a fieldname and converts camelcase to spaced
* words. Also resolves combined fieldnames with dot syntax
Expand Down Expand Up @@ -475,7 +471,10 @@ public function securityTokenEnabled() {

/**
* Sets the error message to be displayed on the form field
* Set by php validation of the form
* Set by php validation of the form.
*
* @param string $message Message to show to the user. Allows HTML content,
* which means you need to use Convert::raw2xml() for any user supplied data.
*/
public function setError($message, $messageType) {
$this->message = $message;
Expand Down
18 changes: 8 additions & 10 deletions forms/gridfield/GridFieldDetailForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ public function doSave($data, $form) {
$this->record->write();
$list->add($this->record, $extraData);
} catch(ValidationException $e) {
$form->sessionMessage($e->getResult()->message(), 'bad');
$form->sessionMessage($e->getResult()->message(), 'bad', false);
$responseNegotiator = new PjaxResponseNegotiator(array(
'CurrentForm' => function() use(&$form) {
return $form->forTemplate();
Expand All @@ -544,11 +544,9 @@ public function doSave($data, $form) {

// TODO Save this item into the given relationship

// TODO Allow HTML in form messages
// $link = '<a href="' . $this->Link('edit') . '">"'
// . htmlspecialchars($this->record->Title, ENT_QUOTES)
// . '"</a>';
$link = '"' . $this->record->Title . '"';
$link = '<a href="' . $this->Link('edit') . '">"'
. htmlspecialchars($this->record->Title, ENT_QUOTES)
. '"</a>';
$message = _t(
'GridFieldDetailForm.Saved',
'Saved {name} {link}',
Expand All @@ -558,7 +556,7 @@ public function doSave($data, $form) {
)
);

$form->sessionMessage($message, 'good');
$form->sessionMessage($message, 'good', false);

if($new_record) {
return $controller->redirect($this->Link());
Expand All @@ -585,7 +583,7 @@ public function doDelete($data, $form) {

$this->record->delete();
} catch(ValidationException $e) {
$form->sessionMessage($e->getResult()->message(), 'bad');
$form->sessionMessage($e->getResult()->message(), 'bad', false);
return $this->getToplevelController()->redirectBack();
}

Expand All @@ -598,9 +596,9 @@ public function doDelete($data, $form) {
$toplevelController = $this->getToplevelController();
if($toplevelController && $toplevelController instanceof LeftAndMain) {
$backForm = $toplevelController->getEditForm();
$backForm->sessionMessage($message, 'good');
$backForm->sessionMessage($message, 'good', false);
} else {
$form->sessionMessage($message, 'good');
$form->sessionMessage($message, 'good', false);
}

//when an item is deleted, redirect to the parent controller
Expand Down
5 changes: 4 additions & 1 deletion security/MemberLoginForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ public function __construct($controller, $name, $fields = null, $actions = null,
* Get message from session
*/
protected function getMessageFromSession() {
parent::getMessageFromSession();
if(($member = Member::currentUser()) && !Session::get('MemberLoginForm.force_message')) {
$this->message = _t(
'Member.LOGGEDINAS',
Expand All @@ -143,6 +142,10 @@ protected function getMessageFromSession() {
);
}
Session::set('MemberLoginForm.force_message', false);

parent::getMessageFromSession();

return $this->message;
}


Expand Down
46 changes: 46 additions & 0 deletions tests/forms/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,52 @@ public function testAttributesHTML() {
$this->assertNotContains('two="2"', $form->getAttributesHTML('one', 'two'));
$this->assertContains('three="3"', $form->getAttributesHTML('one', 'two'));
}

function testMessageEscapeHtml() {
$form = $this->getStubForm();
$form->Controller()->handleRequest(new SS_HTTPRequest('GET', '/'), DataModel::inst()); // stub out request
$form->sessionMessage('<em>Escaped HTML</em>', 'good', true);
$parser = new CSSContentParser($form->forTemplate());
$messageEls = $parser->getBySelector('.message');
$this->assertContains(
'&lt;em&gt;Escaped HTML&lt;/em&gt;',
$messageEls[0]->asXML()
);

$form = $this->getStubForm();
$form->Controller()->handleRequest(new SS_HTTPRequest('GET', '/'), DataModel::inst()); // stub out request
$form->sessionMessage('<em>Unescaped HTML</em>', 'good', false);
$parser = new CSSContentParser($form->forTemplate());
$messageEls = $parser->getBySelector('.message');
$this->assertContains(
'<em>Unescaped HTML</em>',
$messageEls[0]->asXML()
);
}

function testFieldMessageEscapeHtml() {
$form = $this->getStubForm();
$form->Controller()->handleRequest(new SS_HTTPRequest('GET', '/'), DataModel::inst()); // stub out request
$form->addErrorMessage('key1', '<em>Escaped HTML</em>', 'good', true);
$form->setupFormErrors();
$parser = new CSSContentParser($form->forTemplate());
$messageEls = $parser->getBySelector('#key1 .message');
$this->assertContains(
'&lt;em&gt;Escaped HTML&lt;/em&gt;',
$messageEls[0]->asXML()
);

$form = $this->getStubForm();
$form->Controller()->handleRequest(new SS_HTTPRequest('GET', '/'), DataModel::inst()); // stub out request
$form->addErrorMessage('key1', '<em>Unescaped HTML</em>', 'good', false);
$form->setupFormErrors();
$parser = new CSSContentParser($form->forTemplate());
$messageEls = $parser->getBySelector('#key1 .message');
$this->assertContains(
'<em>Unescaped HTML</em>',
$messageEls[0]->asXML()
);
}

protected function getStubForm() {
return new Form(
Expand Down
11 changes: 6 additions & 5 deletions tests/security/SecurityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public function testRepeatedLoginAttemptsLockingPeopleOut() {
$member->LockedOutUntil,
'User does not have a lockout time set if under threshold for failed attempts'
);
$this->assertContains($this->loginErrorMessage(), _t('Member.ERRORWRONGCRED'));
$this->assertContains($this->loginErrorMessage(), Convert::raw2xml(_t('Member.ERRORWRONGCRED')));
} else {
// Fuzzy matching for time to avoid side effects from slow running tests
$this->assertGreaterThan(
Expand Down Expand Up @@ -337,7 +337,7 @@ public function testRepeatedLoginAttemptsLockingPeopleOut() {
$member->ID,
'After lockout expires, the user can login again'
);

// Log the user out
$this->session()->inst_set('loggedInAs', null);

Expand All @@ -346,11 +346,12 @@ public function testRepeatedLoginAttemptsLockingPeopleOut() {
$this->doTestLoginForm('[email protected]' , 'incorrectpassword');
}
$this->assertNull($this->session()->inst_get('loggedInAs'));
$this->assertTrue(
false !== stripos($this->loginErrorMessage(), _t('Member.ERRORWRONGCRED')),
$this->assertContains(
$this->loginErrorMessage(),
Convert::raw2xml(_t('Member.ERRORWRONGCRED')),
'The user can retry with a wrong password after the lockout expires'
);

$this->doTestLoginForm('[email protected]' , '1nitialPassword');
$this->assertEquals(
$this->session()->inst_get('loggedInAs'),
Expand Down

0 comments on commit 0e07f1a

Please sign in to comment.