Merge remote-tracking branch 'origin/3.1.17' into 3.1

This commit is contained in:
Damian Mooyman 2016-02-24 16:54:18 +13:00
commit 06d5050321
19 changed files with 221 additions and 116 deletions

View File

@ -492,28 +492,28 @@ class Director implements TemplateGlobalProvider {
*/ */
public static function is_https() { public static function is_https() {
$return = false; $return = false;
// See https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
// See https://support.microsoft.com/?kbID=307347
$headerOverride = false;
if(TRUSTED_PROXY) {
$headers = (defined('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) ? array(SS_TRUSTED_PROXY_PROTOCOL_HEADER) : null;
if(!$headers) {
// Backwards compatible defaults
$headers = array('HTTP_X_FORWARDED_PROTO', 'HTTP_X_FORWARDED_PROTOCOL', 'HTTP_FRONT_END_HTTPS');
}
foreach($headers as $header) {
$headerCompareVal = ($header === 'HTTP_FRONT_END_HTTPS' ? 'on' : 'https');
if(!empty($_SERVER[$header]) && strtolower($_SERVER[$header]) == $headerCompareVal) {
$headerOverride = true;
break;
}
}
}
if ($protocol = Config::inst()->get('Director', 'alternate_protocol')) { if ($protocol = Config::inst()->get('Director', 'alternate_protocol')) {
$return = ($protocol == 'https'); $return = ($protocol == 'https');
} else if( } else if($headerOverride) {
TRUSTED_PROXY
&& isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
&& strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https'
) {
// Convention for (non-standard) proxy signaling a HTTPS forward,
// see https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
$return = true;
} else if(
TRUSTED_PROXY
&& isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])
&& strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https'
) {
// Less conventional proxy header
$return = true;
} else if(
isset($_SERVER['HTTP_FRONT_END_HTTPS'])
&& strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) == 'on'
) {
// Microsoft proxy convention: https://support.microsoft.com/?kbID=307347
$return = true; $return = true;
} else if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) { } else if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) {
$return = true; $return = true;

View File

@ -653,14 +653,27 @@ class SS_HTTPRequest implements ArrayAccess {
* @return string * @return string
*/ */
public function getIP() { public function getIP() {
if (TRUSTED_PROXY && !empty($_SERVER['HTTP_CLIENT_IP'])) { $headerOverrideIP = null;
//check ip from share internet if(TRUSTED_PROXY) {
return $_SERVER['HTTP_CLIENT_IP']; $headers = (defined('SS_TRUSTED_PROXY_IP_HEADER')) ? array(SS_TRUSTED_PROXY_IP_HEADER) : null;
} elseif (TRUSTED_PROXY && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { if(!$headers) {
//to check ip is pass from proxy // Backwards compatible defaults
return $_SERVER['HTTP_X_FORWARDED_FOR']; $headers = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR');
}
foreach($headers as $header) {
if(!empty($_SERVER[$header])) {
$headerOverrideIP = $_SERVER[$header];
break;
}
}
}
if ($headerOverrideIP) {
return $headerOverrideIP;
} elseif(isset($_SERVER['REMOTE_ADDR'])) { } elseif(isset($_SERVER['REMOTE_ADDR'])) {
return $_SERVER['REMOTE_ADDR']; return $_SERVER['REMOTE_ADDR'];
} else {
return null;
} }
} }

View File

@ -177,10 +177,13 @@ if(!isset($_SERVER['HTTP_HOST'])) {
/** /**
* Fix HTTP_HOST from reverse proxies * Fix HTTP_HOST from reverse proxies
*/ */
if (TRUSTED_PROXY && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { $trustedProxyHeader = (defined('SS_TRUSTED_PROXY_HOST_HEADER'))
? SS_TRUSTED_PROXY_HOST_HEADER
: 'HTTP_X_FORWARDED_HOST';
if (TRUSTED_PROXY && !empty($_SERVER[$trustedProxyHeader])) {
// Get the first host, in case there's multiple separated through commas // Get the first host, in case there's multiple separated through commas
$_SERVER['HTTP_HOST'] = strtok($_SERVER['HTTP_X_FORWARDED_HOST'], ','); $_SERVER['HTTP_HOST'] = strtok($_SERVER[SS_TRUSTED_PROXY_HOST_HEADER], ',');
} }
} }

View File

@ -160,26 +160,25 @@ class ParameterConfirmationToken {
// Are we http or https? Replicates Director::is_https() without its dependencies/ // Are we http or https? Replicates Director::is_https() without its dependencies/
$proto = 'http'; $proto = 'http';
if( // See https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
TRUSTED_PROXY // See https://support.microsoft.com/?kbID=307347
&& isset($_SERVER['HTTP_X_FORWARDED_PROTO']) $headerOverride = false;
&& strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' if(TRUSTED_PROXY) {
) { $headers = (defined('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) ? array(SS_TRUSTED_PROXY_PROTOCOL_HEADER) : null;
// Convention for (non-standard) proxy signaling a HTTPS forward, if(!$headers) {
// see https://en.wikipedia.org/wiki/List_of_HTTP_header_fields // Backwards compatible defaults
$proto = 'https'; $headers = array('HTTP_X_FORWARDED_PROTO', 'HTTP_X_FORWARDED_PROTOCOL', 'HTTP_FRONT_END_HTTPS');
} else if( }
TRUSTED_PROXY foreach($headers as $header) {
&& isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) $headerCompareVal = ($header === 'HTTP_FRONT_END_HTTPS' ? 'on' : 'https');
&& strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https' if(!empty($_SERVER[$header]) && strtolower($_SERVER[$header]) == $headerCompareVal) {
) { $headerOverride = true;
// Less conventional proxy header break;
$proto = 'https'; }
} else if( }
isset($_SERVER['HTTP_FRONT_END_HTTPS']) }
&& strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) == 'on'
) { if($headerOverride) {
// Microsoft proxy convention: https://support.microsoft.com/?kbID=307347
$proto = 'https'; $proto = 'https';
} else if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) { } else if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) {
$proto = 'https'; $proto = 'https';
@ -187,9 +186,6 @@ class ParameterConfirmationToken {
$proto = 'https'; $proto = 'https';
} }
if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) $proto = 'https';
if(isset($_SERVER['SSL'])) $proto = 'https';
$parts = array_filter(array( $parts = array_filter(array(
// What's our host // What's our host
$_SERVER['HTTP_HOST'], $_SERVER['HTTP_HOST'],

View File

@ -34,7 +34,8 @@ class DevelopmentAdmin extends Controller {
parent::init(); parent::init();
// Special case for dev/build: Defer permission checks to DatabaseAdmin->init() (see #4957) // Special case for dev/build: Defer permission checks to DatabaseAdmin->init() (see #4957)
$requestedDevBuild = (stripos($this->request->getURL(), 'dev/build') === 0); $requestedDevBuild = (stripos($this->getRequest()->getURL(), 'dev/build') === 0)
&& (stripos($this->getRequest()->getURL(), 'dev/build/defaults') === false);
// We allow access to this controller regardless of live-status or ADMIN permission only // We allow access to this controller regardless of live-status or ADMIN permission only
// if on CLI. Access to this controller is always allowed in "dev-mode", or of the user is ADMIN. // if on CLI. Access to this controller is always allowed in "dev-mode", or of the user is ADMIN.

View File

@ -502,7 +502,11 @@ server IPs using the SS_TRUSTED_PROXY_IPS define in your _ss_environment.php.
:::php :::php
define('SS_TRUSTED_PROXY_IPS', '127.0.0.1,192.168.0.1'); define('SS_TRUSTED_PROXY_IPS', '127.0.0.1,192.168.0.1');
define('SS_TRUSTED_PROXY_HOST_HEADER', 'HTTP_X_FORWARDED_HOST');
define('SS_TRUSTED_PROXY_IP_HEADER', 'HTTP_X_FORWARDED_FOR');
define('SS_TRUSTED_PROXY_PROTOCOL_HEADER', 'HTTP_X_FORWARDED_PROTOCOL');
At the same time, you'll also need to define which headers you trust from these proxy IPs. Since there are multiple ways through which proxies can pass through HTTP information on the original hostname, IP and protocol, these values need to be adjusted for your specific proxy. The header names match their equivalent `$_SERVER` values.
If there is no proxy server, 'none' can be used to distrust all clients. If there is no proxy server, 'none' can be used to distrust all clients.
If only trusted servers will make requests then you can use '*' to trust all clients. If only trusted servers will make requests then you can use '*' to trust all clients.
@ -525,7 +529,6 @@ In a future release this behaviour will be changed to be on by default, and this
variable will be no longer necessary, thus it will be necessary to always set variable will be no longer necessary, thus it will be necessary to always set
SS_TRUSTED_PROXY_IPS if using a proxy. SS_TRUSTED_PROXY_IPS if using a proxy.
## Related ## Related
* [http://silverstripe.org/security-releases/](http://silverstripe.org/security-releases/) * [http://silverstripe.org/security-releases/](http://silverstripe.org/security-releases/)

View File

@ -0,0 +1,19 @@
# 3.1.17
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### Security
* 2016-02-17 [37059eb](https://github.com/silverstripe/silverstripe-framework/commit/37059eb6b3546f304e9c031abca0f096ddb175c6) Hostname, IP and Protocol Spoofing through HTTP Headers (Ingo Schommer) - See [ss-2016-003](http://www.silverstripe.org/download/security-releases/ss-2016-003)
* 2016-02-17 [5d2fc0d](https://github.com/silverstripe/silverstripe-framework/commit/5d2fc0d7cac4ce686f7ae05c1a7b1ad8c01711a8) Block unauthenticated access to dev/build/defaults (Damian Mooyman) - See [ss-2015-028](http://www.silverstripe.org/download/security-releases/ss-2015-028)
* 2016-02-17 [013524a](https://github.com/silverstripe/silverstripe-framework/commit/013524af5069bb0cf909853f04418d9bef56d18c) Ensure Gridfield actions respect CSRF (Damian Mooyman) - See [ss-2016-002](http://www.silverstripe.org/download/security-releases/ss-2016-002)
### Bugfixes
* 2016-02-16 [644c807](https://github.com/silverstripe/silverstripe-cms/commit/644c8070311e82d35c39c6e1f0d37cc8aba53665) Use correct formaction for doRollback exemption #1378 (Andrew Aitken-Fincham)
* 2016-01-05 [00544ff](https://github.com/silverstripe/silverstripe-framework/commit/00544ff100048afdb7ccb1905304dddf8ab3205a) session_regenerate_id uses config system (Daniel Hensby)
* 2016-01-05 [4335d8e](https://github.com/silverstripe/silverstripe-framework/commit/4335d8ed221a2b402299b32e31f97fc2956ec161) Members with no ID inherit logged in user permission (Daniel Hensby)
* 2015-11-18 [e9b833f](https://github.com/silverstripe/silverstripe-framework/commit/e9b833f5f0f989af8d611f8cfe71f0b0e2cb0159) ConfirmedPassword field correctly reports mismatching passwords (Christopher Darling)
* 2015-11-05 [f577ecb](https://github.com/silverstripe/silverstripe-framework/commit/f577ecb81149d0d09dc846204f17b2153a244b5a) prevent use cache on browser back button (Igor Nadj)

View File

@ -0,0 +1,11 @@
# 3.1.17-rc2
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### Security
* 2016-02-17 [37059eb](https://github.com/silverstripe/silverstripe-framework/commit/37059eb6b3546f304e9c031abca0f096ddb175c6) Hostname, IP and Protocol Spoofing through HTTP Headers (Ingo Schommer) - See [ss-2016-003](http://www.silverstripe.org/download/security-releases/ss-2016-003)
* 2016-02-17 [5d2fc0d](https://github.com/silverstripe/silverstripe-framework/commit/5d2fc0d7cac4ce686f7ae05c1a7b1ad8c01711a8) Block unauthenticated access to dev/build/defaults (Damian Mooyman) - See [ss-2015-028](http://www.silverstripe.org/download/security-releases/ss-2015-028)
* 2016-02-17 [013524a](https://github.com/silverstripe/silverstripe-framework/commit/013524af5069bb0cf909853f04418d9bef56d18c) Ensure Gridfield actions respect CSRF (Damian Mooyman) - See [ss-2016-002](http://www.silverstripe.org/download/security-releases/ss-2016-002)

View File

@ -832,6 +832,18 @@ class GridField extends FormField {
*/ */
public function gridFieldAlterAction($data, $form, SS_HTTPRequest $request) { public function gridFieldAlterAction($data, $form, SS_HTTPRequest $request) {
$data = $request->requestVars(); $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(); $name = $this->getName();
$fieldData = null; $fieldData = null;

View File

@ -301,7 +301,7 @@ cs:
FROMWEB: 'Z webu' FROMWEB: 'Z webu'
FindInFolder: 'Hledat ve složce' FindInFolder: 'Hledat ve složce'
IMAGEALT: 'Alternativní text (alt)' IMAGEALT: 'Alternativní text (alt)'
IMAGEALTTEXT: 'Alternativní text (alt) - bude zobrazen, pokud obrázek nemúže být zobrazen' IMAGEALTTEXT: 'Alternativní text (alt) - bude ukázán, když obrázek nemúže být zobrazen'
IMAGEALTTEXTDESC: 'Zobrazeno na obrazovce, když obrázek nemůže být zobrazen' IMAGEALTTEXTDESC: 'Zobrazeno na obrazovce, když obrázek nemůže být zobrazen'
IMAGEDIMENSIONS: Rozměry IMAGEDIMENSIONS: Rozměry
IMAGEHEIGHTPX: Výška IMAGEHEIGHTPX: Výška
@ -336,13 +336,13 @@ cs:
LeftAndMain: LeftAndMain:
CANT_REORGANISE: 'Nemáte oprávnění měnit stránky nejvyšší úrovně. Vaše změna nebyla uložena.' CANT_REORGANISE: 'Nemáte oprávnění měnit stránky nejvyšší úrovně. Vaše změna nebyla uložena.'
DELETED: Smazáno. DELETED: Smazáno.
DropdownBatchActionsDefault: 'Vyberte akci...' DropdownBatchActionsDefault: Akce
HELP: Nápověda HELP: Nápověda
PAGETYPE: 'Typ stránky' PAGETYPE: 'Typ stránky'
PERMAGAIN: 'Byli jste odhlášeni z CMS. Pokud se chcete znovu přihlásit, zadejte níže své uživatelské jméno a heslo.' PERMAGAIN: 'Byli jste odhlášeni z CMS. Pokud se chcete znovu přihlásit, zadejte níže své uživatelské jméno a heslo.'
PERMALREADY: 'Omlouvám se, ale nemůžete vstoupit do této části CMS. Pokud se chcete přihlásit jako někdo jiný, udělejte tak níže.' PERMALREADY: 'Omlouvám se, ale nemůžete vstoupit do této části CMS. Pokud se chcete přihlásit jako někdo jiný, udělejte tak níže.'
PERMDEFAULT: 'Musíte být přihlášen/a k přístup do oblasti administrace, níže zadejte vaše přihlašovací údaje, prosím.' PERMDEFAULT: 'Musíte být přihlášen/a k přístup do oblasti administrace, níže zadejte vaše přihlašovací údaje, prosím.'
PLEASESAVE: 'Prosím uložte stránku: Tato stránka nemohla být aktualizována, protože ještě nebyla uložena.' PLEASESAVE: 'Prosím uložte stránku: Tato stránka nemohla být aktualizována, ještě nebyla uložena.'
PreviewButton: Náhled PreviewButton: Náhled
REORGANISATIONSUCCESSFUL: 'Strom webu reorganizován úspěšně.' REORGANISATIONSUCCESSFUL: 'Strom webu reorganizován úspěšně.'
SAVEDUP: Uloženo. SAVEDUP: Uloženo.

View File

@ -300,8 +300,6 @@ de:
FROMWEB: 'Aus dem Web' FROMWEB: 'Aus dem Web'
FindInFolder: 'In Ordner suchen' FindInFolder: 'In Ordner suchen'
IMAGEALT: 'Alternativtext (alt)' IMAGEALT: 'Alternativtext (alt)'
IMAGEALTTEXT: 'Alternativer Text (alt) - angezeigt, wenn das Bild nicht dargestellt werden kann'
IMAGEALTTEXTDESC: 'Wird von Screenreadern vorgelesen oder angezeigt, falls das Bild nicht dargestellt werden kann'
IMAGEDIMENSIONS: Dimensionen IMAGEDIMENSIONS: Dimensionen
IMAGEHEIGHTPX: Höhe (px) IMAGEHEIGHTPX: Höhe (px)
IMAGETITLE: 'Titeltext (Tooltip) - für zusätzliche Informationen über das Bild' IMAGETITLE: 'Titeltext (Tooltip) - für zusätzliche Informationen über das Bild'
@ -333,11 +331,9 @@ de:
CANT_REORGANISE: 'Sie besitzen nicht die benötigten Zugriffsrechte um Seiten der höchsten Ebene zu bearbeiten. Ihre Änderungen wurden nicht gespeichert.' CANT_REORGANISE: 'Sie besitzen nicht die benötigten Zugriffsrechte um Seiten der höchsten Ebene zu bearbeiten. Ihre Änderungen wurden nicht gespeichert.'
DELETED: Gelöscht. DELETED: Gelöscht.
HELP: Hilfe HELP: Hilfe
PAGETYPE: 'Seitentyp'
PERMAGAIN: 'Sie wurden aus dem System ausgeloggt. Falls Sie sich wieder einloggen möchten, geben Sie bitte Benutzernamen und Passwort im untenstehenden Formular an.' PERMAGAIN: 'Sie wurden aus dem System ausgeloggt. Falls Sie sich wieder einloggen möchten, geben Sie bitte Benutzernamen und Passwort im untenstehenden Formular an.'
PERMALREADY: 'Leider dürfen Sie diesen Teil des CMS nicht aufrufen. Wenn Sie sich als jemand anderes einloggen wollen, benutzen Sie bitte das nachstehende Formular.' PERMALREADY: 'Leider dürfen Sie diesen Teil des CMS nicht aufrufen. Wenn Sie sich als jemand anderes einloggen wollen, benutzen Sie bitte das nachstehende Formular.'
PERMDEFAULT: 'Sie müssen angemeldet sein, um auf diesen Bereich zugreifen zu können. Bitte geben Sie Ihre Zugangsdaten ein.' PERMDEFAULT: 'Sie müssen angemeldet sein, um auf diesen Bereich zugreifen zu können. Bitte geben Sie Ihre Zugangsdaten ein.'
PLEASESAVE: 'Diese Seite konnte nicht aktualisiert werden weil sie noch nicht gespeichert wurde - bitte speichern.'
PreviewButton: Vorschau PreviewButton: Vorschau
REORGANISATIONSUCCESSFUL: 'Der Seitenbaum wurde erfolgreich sortiert.' REORGANISATIONSUCCESSFUL: 'Der Seitenbaum wurde erfolgreich sortiert.'
SAVEDUP: Gespeichert. SAVEDUP: Gespeichert.

View File

@ -293,8 +293,6 @@ eo:
FROMWEB: 'El la TTT' FROMWEB: 'El la TTT'
FindInFolder: 'Serĉi en dosierujo' FindInFolder: 'Serĉi en dosierujo'
IMAGEALT: 'Alternativa teksto (alt)' IMAGEALT: 'Alternativa teksto (alt)'
IMAGEALTTEXT: 'Alternativa teksto (alt) - vidigi ĝin se ne eblas vidigi bildon'
IMAGEALTTEXTDESC: 'Vidigita al ekranlegiloj aŭ se ne eblas vidii bildon'
IMAGEDIMENSIONS: Dimensioj IMAGEDIMENSIONS: Dimensioj
IMAGEHEIGHTPX: Alto IMAGEHEIGHTPX: Alto
IMAGETITLE: 'Titola teksto (ŝpruchelpilo) - por plua informo pri la bildo' IMAGETITLE: 'Titola teksto (ŝpruchelpilo) - por plua informo pri la bildo'
@ -326,11 +324,9 @@ eo:
CANT_REORGANISE: 'Vi ne rajtas ŝanĝi supronivelajn paĝojn. Via ŝanĝo ne konserviĝis.' CANT_REORGANISE: 'Vi ne rajtas ŝanĝi supronivelajn paĝojn. Via ŝanĝo ne konserviĝis.'
DELETED: Forigita. DELETED: Forigita.
HELP: Helpo HELP: Helpo
PAGETYPE: 'Tipo de paĝo:'
PERMAGAIN: 'Vin adiaŭis la CMS. Se vi volas denove saluti, enigu salutnomon kaj pasvorton malsupre.' PERMAGAIN: 'Vin adiaŭis la CMS. Se vi volas denove saluti, enigu salutnomon kaj pasvorton malsupre.'
PERMALREADY: 'Bedaŭrinde vi ne povas aliri tiun parton de la CMS. Se vi volas ensaluti kiel aliulo, faru tion sube.' PERMALREADY: 'Bedaŭrinde vi ne povas aliri tiun parton de la CMS. Se vi volas ensaluti kiel aliulo, faru tion sube.'
PERMDEFAULT: 'Necesas ensaluti por aliri la administran zonon; bonvolu enigi viajn akreditaĵoj sube.' PERMDEFAULT: 'Necesas ensaluti por aliri la administran zonon; bonvolu enigi viajn akreditaĵoj sube.'
PLEASESAVE: 'Bonvolu konservi paĝon: Ne eblis ĝisdatigi ĉi tiun paĝon ĉar ĝi ankoraŭ ne estas konservita.'
PreviewButton: Antaŭvido PreviewButton: Antaŭvido
REORGANISATIONSUCCESSFUL: 'Sukcese reorganizis la retejan arbon.' REORGANISATIONSUCCESSFUL: 'Sukcese reorganizis la retejan arbon.'
SAVEDUP: Konservita. SAVEDUP: Konservita.

View File

@ -301,8 +301,6 @@ es:
FROMWEB: 'Desde la web' FROMWEB: 'Desde la web'
FindInFolder: 'Buscar en carpeta' FindInFolder: 'Buscar en carpeta'
IMAGEALT: 'Texto alternativo (alt)' IMAGEALT: 'Texto alternativo (alt)'
IMAGEALTTEXT: 'Texto alternativo (alt) - es mostrado si la imagen no puede ser visualizada'
IMAGEALTTEXTDESC: 'Mostrar a los lectores de pantalla o si la imagen no se puede visualizar'
IMAGEDIMENSIONS: Dimensiones IMAGEDIMENSIONS: Dimensiones
IMAGEHEIGHTPX: Alto IMAGEHEIGHTPX: Alto
IMAGETITLE: 'Texto del título (tooltip) - para obtener más información acerca de la imagen' IMAGETITLE: 'Texto del título (tooltip) - para obtener más información acerca de la imagen'
@ -336,13 +334,10 @@ es:
LeftAndMain: LeftAndMain:
CANT_REORGANISE: 'Usted no tiene permiso para modificar las páginas de nivel superior. Su modificación no se ha guardado.' CANT_REORGANISE: 'Usted no tiene permiso para modificar las páginas de nivel superior. Su modificación no se ha guardado.'
DELETED: Borrado DELETED: Borrado
DropdownBatchActionsDefault: 'Elegir una acción...'
HELP: Ayuda HELP: Ayuda
PAGETYPE: 'Tipo de página'
PERMAGAIN: 'Ha sido desconectado del CMS. Si quiere volver a entrar, introduzca su nombre de usuario y contraseña a continuación.' PERMAGAIN: 'Ha sido desconectado del CMS. Si quiere volver a entrar, introduzca su nombre de usuario y contraseña a continuación.'
PERMALREADY: 'Lamentablemente no puede acceder a esta parte del CMS. Si quiere entrar como alguien distinto, hágalo a continuación' PERMALREADY: 'Lamentablemente no puede acceder a esta parte del CMS. Si quiere entrar como alguien distinto, hágalo a continuación'
PERMDEFAULT: 'Debes estar conectado para acceder al área de administración; por favor ingresa tus datos a continuación' PERMDEFAULT: 'Debes estar conectado para acceder al área de administración; por favor ingresa tus datos a continuación'
PLEASESAVE: 'Por favor Guarde la Página: Esta página no se ha podido actualizar porque aún no ha sido salvada.'
PreviewButton: Vista previa PreviewButton: Vista previa
REORGANISATIONSUCCESSFUL: 'Reorganizado el árbol del sitio con éxito.' REORGANISATIONSUCCESSFUL: 'Reorganizado el árbol del sitio con éxito.'
SAVEDUP: Guardado SAVEDUP: Guardado

View File

@ -318,9 +318,7 @@ fa_IR:
TITLE: 'آی‌فریم آپلود عکس' TITLE: 'آی‌فریم آپلود عکس'
LeftAndMain: LeftAndMain:
DELETED: حذف شده DELETED: حذف شده
DropdownBatchActionsDefault: 'انتخاب یک عملیات...'
HELP: کمک HELP: کمک
PAGETYPE: 'نوع صفحه'
PERMAGAIN: 'شما از سیستم مدیریت محتوا خارج شده اید.اگر میخواهید دوباره وارد شوید نام کاربری و رمز عبور خود را در قسمت زیر وارد کنید' PERMAGAIN: 'شما از سیستم مدیریت محتوا خارج شده اید.اگر میخواهید دوباره وارد شوید نام کاربری و رمز عبور خود را در قسمت زیر وارد کنید'
PreviewButton: پیش‌نمایش PreviewButton: پیش‌نمایش
SAVEDUP: ذخیره شده SAVEDUP: ذخیره شده

View File

@ -299,8 +299,6 @@ fi:
FROMWEB: 'Webistä' FROMWEB: 'Webistä'
FindInFolder: 'Etsi kansiosta' FindInFolder: 'Etsi kansiosta'
IMAGEALT: 'Vaihtoehtoinen teksti (alt)' IMAGEALT: 'Vaihtoehtoinen teksti (alt)'
IMAGEALTTEXT: 'Vaihtoehtoinen teksti (alt) - näytetään jos kuvaa ei voida näyttää'
IMAGEALTTEXTDESC: 'Näytetään ruudunlukuohjelmille tai jos kuvaa ei voi näyttää'
IMAGEDIMENSIONS: Mitat IMAGEDIMENSIONS: Mitat
IMAGEHEIGHTPX: Korkeus IMAGEHEIGHTPX: Korkeus
IMAGETITLE: 'Otsikko (tooltip) - kuvan lisätietoja varten' IMAGETITLE: 'Otsikko (tooltip) - kuvan lisätietoja varten'
@ -333,11 +331,9 @@ fi:
CANT_REORGANISE: 'Sinulla ei ole oikeuksia mennä ylemmän tason sivuille. Muutoksiasi ei tallennettu.' CANT_REORGANISE: 'Sinulla ei ole oikeuksia mennä ylemmän tason sivuille. Muutoksiasi ei tallennettu.'
DELETED: Poistettu. DELETED: Poistettu.
HELP: Ohje HELP: Ohje
PAGETYPE: 'Sivutyyppi'
PERMAGAIN: 'Olet kirjautunut ulos CMS:stä. Jos haluat kirjautua uudelleen sisään, syötä käyttäjätunnuksesi ja salasanasi alla.' PERMAGAIN: 'Olet kirjautunut ulos CMS:stä. Jos haluat kirjautua uudelleen sisään, syötä käyttäjätunnuksesi ja salasanasi alla.'
PERMALREADY: 'Pahoittelut, mutta et pääse tähän osaan CMS:ää. Jos haluat kirjautua jonain muuna, voit tehdä sen alta.' PERMALREADY: 'Pahoittelut, mutta et pääse tähän osaan CMS:ää. Jos haluat kirjautua jonain muuna, voit tehdä sen alta.'
PERMDEFAULT: 'Sinun tulee olla kirjautuneena ylläpito-osioon; syötä tunnuksesi kenttiin.' PERMDEFAULT: 'Sinun tulee olla kirjautuneena ylläpito-osioon; syötä tunnuksesi kenttiin.'
PLEASESAVE: 'Tätä sivua ei voitu päivittää, koska sitä ei ole vielä tallennettu. Tallenna sivu.'
PreviewButton: Esikatselu PreviewButton: Esikatselu
REORGANISATIONSUCCESSFUL: 'Hakemistopuu uudelleenjärjestettiin onnistuneesti.' REORGANISATIONSUCCESSFUL: 'Hakemistopuu uudelleenjärjestettiin onnistuneesti.'
SAVEDUP: Tallennettu. SAVEDUP: Tallennettu.

View File

@ -336,7 +336,7 @@ lt:
LeftAndMain: LeftAndMain:
CANT_REORGANISE: 'Jūs neturite leidimo keisti aukščiausio lygio puslapių. Jūsų pakeitimai neišsaugoti.' CANT_REORGANISE: 'Jūs neturite leidimo keisti aukščiausio lygio puslapių. Jūsų pakeitimai neišsaugoti.'
DELETED: Ištrinta. DELETED: Ištrinta.
DropdownBatchActionsDefault: 'Pasirinkite veiksmą...' DropdownBatchActionsDefault: Veiksmai
HELP: Pagalba HELP: Pagalba
PAGETYPE: 'Puslapio tipas' PAGETYPE: 'Puslapio tipas'
PERMAGAIN: 'Jūs atsijungėte. Norėdami vėl prisijungti, įveskite savo duomenis į žemiau esančius laukelius.' PERMAGAIN: 'Jūs atsijungėte. Norėdami vėl prisijungti, įveskite savo duomenis į žemiau esančius laukelius.'

View File

@ -301,8 +301,8 @@ sk:
FROMWEB: 'Z webu' FROMWEB: 'Z webu'
FindInFolder: 'Vyhľadať v priečinku' FindInFolder: 'Vyhľadať v priečinku'
IMAGEALT: 'Atlernatívny text (alt)' IMAGEALT: 'Atlernatívny text (alt)'
IMAGEALTTEXT: 'Atlernatívny text (alt) - zobrazí sa, ak obrázok nemože byť zobrazený' IMAGEALTTEXT: 'Atlernatívny text (alt) - sa zobrazí, ak nemôže byť zobrazený obrázok'
IMAGEALTTEXTDESC: 'Zobrazí sa na čítačke obrazovky alebo ak obrázok nemôže byť zobrazený' IMAGEALTTEXTDESC: 'Zobrazí sa na obrazovke, keď obrázok nemôže byť zobrazený'
IMAGEDIMENSIONS: Rozmery IMAGEDIMENSIONS: Rozmery
IMAGEHEIGHTPX: Výška IMAGEHEIGHTPX: Výška
IMAGETITLE: 'Text titulky (tooltip) - pre doplňujúce informácie o obrázku' IMAGETITLE: 'Text titulky (tooltip) - pre doplňujúce informácie o obrázku'
@ -336,13 +336,13 @@ sk:
LeftAndMain: LeftAndMain:
CANT_REORGANISE: 'Nemáte oprávnenie meniť stránky najvyššej úrovne. Vaša zmena nebola uložená.' CANT_REORGANISE: 'Nemáte oprávnenie meniť stránky najvyššej úrovne. Vaša zmena nebola uložená.'
DELETED: Zmazané. DELETED: Zmazané.
DropdownBatchActionsDefault: 'Vybrať akciu...' DropdownBatchActionsDefault: Akcie
HELP: Pomoc HELP: Pomoc
PAGETYPE: 'Typ stránky' PAGETYPE: 'Typ stránky:'
PERMAGAIN: 'Boli ste odhlásený' PERMAGAIN: 'Boli ste odhlásený'
PERMALREADY: 'Je nám ľúto, ale k tejto časti CMS nemáte prístup . Ak sa chcete prihlásiť ako niekto iný, urobte tak nižšie.' PERMALREADY: 'Je nám ľúto, ale k tejto časti CMS nemáte prístup . Ak sa chcete prihlásiť ako niekto iný, urobte tak nižšie.'
PERMDEFAULT: 'Musíte byť prihlásený/á k prístupu do oblasti administrácie, zadajte vaše prihlasovacie údaje dole, prosím.' PERMDEFAULT: 'Musíte byť prihlásený/á k prístupu do oblasti administrácie, zadajte vaše prihlasovacie údaje dole, prosím.'
PLEASESAVE: 'Uložte stránku, prosím. Táto stránka nemôže byť aktualizovaná, pretože ešte nebola uložená.' PLEASESAVE: 'Prosím uložte stránku: Táto stránka nemôže byť aktualizovaná, ešte nebola uložená.'
PreviewButton: Náhľad PreviewButton: Náhľad
REORGANISATIONSUCCESSFUL: 'Strom webu bol reorganizovaný úspešne.' REORGANISATIONSUCCESSFUL: 'Strom webu bol reorganizovaný úspešne.'
SAVEDUP: Uložené. SAVEDUP: Uložené.

View File

@ -293,8 +293,6 @@ sv:
FROMWEB: 'Från webben' FROMWEB: 'Från webben'
FindInFolder: 'Hitta i mapp' FindInFolder: 'Hitta i mapp'
IMAGEALT: 'Alternativ text (alt)' IMAGEALT: 'Alternativ text (alt)'
IMAGEALTTEXT: 'Alternativ text (alt) - visas om bilden inte kan visas'
IMAGEALTTEXTDESC: 'Visas för skärmläsare eller om bilden inte kan visas'
IMAGEDIMENSIONS: Dimensioner IMAGEDIMENSIONS: Dimensioner
IMAGEHEIGHTPX: Höjd IMAGEHEIGHTPX: Höjd
IMAGETITLE: 'Titel text (tooltip) - för ytterligare information om bilden' IMAGETITLE: 'Titel text (tooltip) - för ytterligare information om bilden'
@ -326,11 +324,9 @@ sv:
CANT_REORGANISE: 'Du har inte tillstånd att ändra sidor på toppnivå. Dina ändringar har inte sparats.' CANT_REORGANISE: 'Du har inte tillstånd att ändra sidor på toppnivå. Dina ändringar har inte sparats.'
DELETED: Raderad DELETED: Raderad
HELP: Hjälp HELP: Hjälp
PAGETYPE: 'Sidtyp'
PERMAGAIN: 'Du har blivit utloggad. Om du vill logga in igen anger du dina uppgifter nedan.' PERMAGAIN: 'Du har blivit utloggad. Om du vill logga in igen anger du dina uppgifter nedan.'
PERMALREADY: 'Tyvärr så har du inte åtkomst till den delen av CMSet. Om du vill logga in med en annan användare kan du göra det nedan' PERMALREADY: 'Tyvärr så har du inte åtkomst till den delen av CMSet. Om du vill logga in med en annan användare kan du göra det nedan'
PERMDEFAULT: 'Du måste vara inloggad för att få åtkomst till administrativa delarna; var vänlig att logga in med dina användaruppgifter nedan.' PERMDEFAULT: 'Du måste vara inloggad för att få åtkomst till administrativa delarna; var vänlig att logga in med dina användaruppgifter nedan.'
PLEASESAVE: 'Var god spara sidan. Den kan inte uppdateras för att den har inte sparats ännu.'
PreviewButton: Förhandsgranska PreviewButton: Förhandsgranska
REORGANISATIONSUCCESSFUL: 'Omorganisationen av sidträdet luyckades.' REORGANISATIONSUCCESSFUL: 'Omorganisationen av sidträdet luyckades.'
SAVEDUP: Sparad. SAVEDUP: Sparad.

View File

@ -42,15 +42,54 @@ class GridFieldDeleteActionTest extends SapphireTest {
$this->assertEquals(3, count($deleteButtons), 'Delete buttons should show when logged in.'); $this->assertEquals(3, count($deleteButtons), 'Delete buttons should show when logged in.');
} }
public function testActionsRequireCSRF() {
$this->logInWithPermission('ADMIN');
$this->setExpectedException(
'SS_HTTPResponse_Exception',
_t("Form.CSRF_FAILED_MESSAGE",
"There seems to have been a technical problem. Please click the back button, ".
"refresh your browser, and try again."
),
400
);
$stateID = 'testGridStateActionField';
$request = new SS_HTTPRequest(
'POST',
'url',
array(),
array(
'action_gridFieldAlterAction?StateID='.$stateID,
'SecurityID' => null,
)
);
$this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request);
}
public function testDeleteActionWithoutCorrectPermission() { public function testDeleteActionWithoutCorrectPermission() {
if(Member::currentUser()) { Member::currentUser()->logOut(); } if(Member::currentUser()) { Member::currentUser()->logOut(); }
$this->setExpectedException('ValidationException'); $this->setExpectedException('ValidationException');
$stateID = 'testGridStateActionField'; $stateID = 'testGridStateActionField';
Session::set($stateID, array('grid'=>'', 'actionName'=>'deleterecord', Session::set(
'args'=>array('RecordID'=>$this->idFromFixture('GridFieldAction_Delete_Team', 'team1')))); $stateID,
$request = new SS_HTTPRequest('POST', 'url', array(), array(
array('action_gridFieldAlterAction?StateID='.$stateID=>true)); 'grid' => '',
'actionName' => 'deleterecord',
'args' => array(
'RecordID' => $this->idFromFixture('GridFieldAction_Delete_Team', 'team1')
)
)
);
$token = SecurityToken::inst();
$request = new SS_HTTPRequest(
'POST',
'url',
array(),
array(
'action_gridFieldAlterAction?StateID='.$stateID => true,
$token->getName() => $token->getValue(),
)
);
$this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request); $this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request);
$this->assertEquals(3, $this->list->count(), $this->assertEquals(3, $this->list->count(),
'User should\'t be able to delete records without correct permissions.'); 'User should\'t be able to delete records without correct permissions.');
@ -59,10 +98,26 @@ class GridFieldDeleteActionTest extends SapphireTest {
public function testDeleteActionWithAdminPermission() { public function testDeleteActionWithAdminPermission() {
$this->logInWithPermission('ADMIN'); $this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField'; $stateID = 'testGridStateActionField';
Session::set($stateID, array('grid'=>'', 'actionName'=>'deleterecord', Session::set(
'args'=>array('RecordID'=>$this->idFromFixture('GridFieldAction_Delete_Team', 'team1')))); $stateID,
$request = new SS_HTTPRequest('POST', 'url', array(), array(
array('action_gridFieldAlterAction?StateID='.$stateID=>true)); 'grid'=>'',
'actionName'=>'deleterecord',
'args' => array(
'RecordID' => $this->idFromFixture('GridFieldAction_Delete_Team', 'team1')
)
)
);
$token = SecurityToken::inst();
$request = new SS_HTTPRequest(
'POST',
'url',
array(),
array(
'action_gridFieldAlterAction?StateID='.$stateID=>true,
$token->getName() => $token->getValue(),
)
);
$this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request); $this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request);
$this->assertEquals(2, $this->list->count(), 'User should be able to delete records with ADMIN permission.'); $this->assertEquals(2, $this->list->count(), 'User should be able to delete records with ADMIN permission.');
} }
@ -76,11 +131,26 @@ class GridFieldDeleteActionTest extends SapphireTest {
$form = new Form(new Controller(), 'mockform', new FieldList(array($this->gridField)), new FieldList()); $form = new Form(new Controller(), 'mockform', new FieldList(array($this->gridField)), new FieldList());
$stateID = 'testGridStateActionField'; $stateID = 'testGridStateActionField';
Session::set($stateID, array('grid'=>'', 'actionName'=>'deleterecord', Session::set(
'args'=>array('RecordID'=>$this->idFromFixture('GridFieldAction_Delete_Team', 'team1')))); $stateID,
$request = new SS_HTTPRequest('POST', 'url', array(), array(
array('action_gridFieldAlterAction?StateID='.$stateID=>true)); 'grid'=>'',
'actionName'=>'deleterecord',
'args' => array(
'RecordID' => $this->idFromFixture('GridFieldAction_Delete_Team', 'team1')
)
)
);
$token = SecurityToken::inst();
$request = new SS_HTTPRequest(
'POST',
'url',
array(),
array(
'action_gridFieldAlterAction?StateID='.$stateID=>true,
$token->getName() => $token->getValue(),
)
);
$this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request); $this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request);
$this->assertEquals(2, $this->list->count(), 'User should be able to delete records with ADMIN permission.'); $this->assertEquals(2, $this->list->count(), 'User should be able to delete records with ADMIN permission.');