API Apply Framework\Security namespace

This commit is contained in:
Damian Mooyman 2016-06-23 11:37:22 +12:00
parent 20efb0e8e1
commit af22a83166
155 changed files with 1704 additions and 1049 deletions

View File

@ -115,8 +115,49 @@ mappings:
VersionedGridFieldDetailForm: SilverStripe\ORM\Versioning\VersionedGridFieldDetailForm VersionedGridFieldDetailForm: SilverStripe\ORM\Versioning\VersionedGridFieldDetailForm
VersionedGridFieldItemRequest: SilverStripe\ORM\Versioning\VersionedGridFieldItemRequest VersionedGridFieldItemRequest: SilverStripe\ORM\Versioning\VersionedGridFieldItemRequest
Hierarchy: SilverStripe\ORM\Hierarchy\Hierarchy Hierarchy: SilverStripe\ORM\Hierarchy\Hierarchy
Authenticator: SilverStripe\Security\Authenticator
BasicAuth: SilverStripe\Security\BasicAuth
ChangePasswordForm: SilverStripe\Security\ChangePasswordForm
CMSMemberLoginForm: SilverStripe\Security\CMSMemberLoginForm
CMSSecurity: SilverStripe\Security\CMSSecurity
Group: SilverStripe\Security\Group
GroupCsvBulkLoader: SilverStripe\Security\GroupCsvBulkLoader
LoginAttempt: SilverStripe\Security\LoginAttempt
LoginForm: SilverStripe\Security\LoginForm
Member: SilverStripe\Security\Member
Member_GroupSet: SilverStripe\Security\Member_GroupSet
Member_Validator: SilverStripe\Security\Member_Validator
MemberAuthenticator: SilverStripe\Security\MemberAuthenticator
MemberCsvBulkLoader: SilverStripe\Security\MemberCsvBulkLoader
MemberLoginForm: SilverStripe\Security\MemberLoginForm
MemberPassword: SilverStripe\Security\MemberPassword
PasswordEncryptor: SilverStripe\Security\PasswordEncryptor
PasswordEncryptor_Blowfish: SilverStripe\Security\PasswordEncryptor_Blowfish
PasswordEncryptor_PHPHash: SilverStripe\Security\PasswordEncryptor_PHPHash
PasswordEncryptor_LegacyPHPHash: SilverStripe\Security\PasswordEncryptor_LegacyPHPHash
PasswordEncryptor_MySQLPassword: SilverStripe\Security\PasswordEncryptor_MySQLPassword
PasswordEncryptor_MySQLOldPassword: SilverStripe\Security\PasswordEncryptor_MySQLOldPassword
PasswordEncryptor_None: SilverStripe\Security\PasswordEncryptor_None
PasswordEncryptor_NotFoundException: SilverStripe\Security\PasswordEncryptor_NotFoundException
PasswordEncryptor_EncryptionFailed: SilverStripe\Security\PasswordEncryptor_EncryptionFailed
PasswordValidator: SilverStripe\Security\PasswordValidator
Permission: SilverStripe\Security\Permission
Permission_Group: SilverStripe\Security\Permission_Group
PermissionCheckboxSetField: SilverStripe\Security\PermissionCheckboxSetField
PermissionCheckboxSetField_Readonly: SilverStripe\Security\PermissionCheckboxSetField_Readonly
PermissionFailureException: SilverStripe\Security\PermissionFailureException
PermissionProvider: SilverStripe\Security\PermissionProvider
PermissionRole: SilverStripe\Security\PermissionRole
PermissionRoleCode: SilverStripe\Security\PermissionRoleCode
RandomGenerator: SilverStripe\Security\RandomGenerator
RememberLoginHash: SilverStripe\Security\RememberLoginHash
Security: SilverStripe\Security\Security
SecurityToken: SilverStripe\Security\SecurityToken
NullSecurityToken: SilverStripe\Security\NullSecurityToken
skipConfigs: skipConfigs:
- db - db
- casting - casting
- table_name - table_name
- fixed_fields - fixed_fields
- menu_title
- allowed_actions

View File

@ -5,6 +5,7 @@ namespace SilverStripe\ORM\Connect;
use Config; use Config;
use Exception; use Exception;
use PaginatedList; use PaginatedList;
use SilverStripe\Framework\Core\Configurable;
use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataList;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;

View File

@ -16,8 +16,10 @@ class MySQLSchemaManager extends DBSchemaManager {
/** /**
* Identifier for this schema, used for configuring schema-specific table * Identifier for this schema, used for configuring schema-specific table
* creation options * creation options
*
* @skipUpgrade
*/ */
const ID = 'SilverStripe\ORM\Connect\MySQLDatabase'; const ID = 'MySQLDatabase';
public function createTable($table, $fields = null, $indexes = null, $options = null, $advancedOptions = null) { public function createTable($table, $fields = null, $indexes = null, $options = null, $advancedOptions = null) {
$fieldSchemas = $indexSchemas = ""; $fieldSchemas = $indexSchemas = "";

View File

@ -9,7 +9,9 @@ use Config;
use LogicException; use LogicException;
use Cookie; use Cookie;
use Injector; use Injector;
use SilverStripe\ORM\Connect\DBConnector;
use SilverStripe\ORM\Connect\DBSchemaManager; use SilverStripe\ORM\Connect\DBSchemaManager;
use SilverStripe\ORM\Connect\SS_Query;
use SilverStripe\ORM\Queries\SQLExpression; use SilverStripe\ORM\Queries\SQLExpression;
use SilverStripe\ORM\Connect\SS_Database; use SilverStripe\ORM\Connect\SS_Database;
@ -53,8 +55,8 @@ class DB {
* Pass an object that's a subclass of SS_Database. This object will be used when {@link DB::query()} * Pass an object that's a subclass of SS_Database. This object will be used when {@link DB::query()}
* is called. * is called.
* *
* @param $connection The connecton object to set as the connection. * @param SS_Database $connection The connecton object to set as the connection.
* @param $name The name to give to this connection. If you omit this argument, the connection * @param string $name The name to give to this connection. If you omit this argument, the connection
* will be the default one used by the ORM. However, you can store other named connections to * will be the default one used by the ORM. However, you can store other named connections to
* be accessed through DB::get_conn($name). This is useful when you have an application that * be accessed through DB::get_conn($name). This is useful when you have an application that
* needs to connect to more than one database. * needs to connect to more than one database.
@ -147,6 +149,7 @@ class DB {
* *
* Note that the database will be set on the next request. * Note that the database will be set on the next request.
* Set it to null to revert to the main database. * Set it to null to revert to the main database.
* @param string $name
*/ */
public static function set_alternative_database_name($name = null) { public static function set_alternative_database_name($name = null) {
// Skip if CLI // Skip if CLI
@ -161,7 +164,7 @@ class DB {
)); ));
} }
$key = Config::inst()->get('Security', 'token'); $key = Config::inst()->get('SilverStripe\\Security\\Security', 'token');
if(!$key) { if(!$key) {
throw new LogicException('"Security.token" not found, run "sake dev/generatesecuretoken"'); throw new LogicException('"Security.token" not found, run "sake dev/generatesecuretoken"');
} }
@ -193,7 +196,7 @@ class DB {
$iv = Cookie::get("alternativeDatabaseNameIv"); $iv = Cookie::get("alternativeDatabaseNameIv");
if($name) { if($name) {
$key = Config::inst()->get('Security', 'token'); $key = Config::inst()->get('SilverStripe\\Security\\Security', 'token');
if(!$key) { if(!$key) {
throw new LogicException('"Security.token" not found, run "sake dev/generatesecuretoken"'); throw new LogicException('"Security.token" not found, run "sake dev/generatesecuretoken"');
} }
@ -231,10 +234,9 @@ class DB {
* Given the database configuration, this method will create the correct * Given the database configuration, this method will create the correct
* subclass of {@link SS_Database}. * subclass of {@link SS_Database}.
* *
* @param array $database A map of options. The 'type' is the name of the subclass of SS_Database to use. For the * @param array $databaseConfig A map of options. The 'type' is the name of the
* rest of the options, see the specific class. * subclass of SS_Database to use. For the rest of the options, see the specific class.
* @param string $name identifier for the connection * @param string $label identifier for the connection
*
* @return SS_Database * @return SS_Database
*/ */
public static function connect($databaseConfig, $label = 'default') { public static function connect($databaseConfig, $label = 'default') {
@ -296,7 +298,7 @@ class DB {
* *
* @param array|integer $input An array of items needing placeholders, or a * @param array|integer $input An array of items needing placeholders, or a
* number to specify the number of placeholders * number to specify the number of placeholders
* @param string The string to join each placeholder together with * @param string $join The string to join each placeholder together with
* @return string|null Either a list of placeholders, or null * @return string|null Either a list of placeholders, or null
*/ */
public static function placeholders($input, $join = ', ') { public static function placeholders($input, $join = ', ') {
@ -374,6 +376,8 @@ class DB {
/** /**
* Get the autogenerated ID from the previous INSERT query. * Get the autogenerated ID from the previous INSERT query.
*
* @param string $table
* @return int * @return int
*/ */
public static function get_generated_id($table) { public static function get_generated_id($table) {
@ -427,13 +431,14 @@ class DB {
/** /**
* Create a new table. * Create a new table.
* @param string $tableName The name of the table * @param string $table The name of the table
* @param array$fields A map of field names to field types * @param array$fields A map of field names to field types
* @param array $indexes A map of indexes * @param array $indexes A map of indexes
* @param array $options An map of additional options. The available keys are as follows: * @param array $options An map of additional options. The available keys are as follows:
* - 'MSSQLDatabase'/'MySQLDatabase'/'PostgreSQLDatabase' - database-specific options such as "engine" * - 'MSSQLDatabase'/'MySQLDatabase'/'PostgreSQLDatabase' - database-specific options such as "engine"
* for MySQL. * for MySQL.
* - 'temporary' - If true, then a temporary table will be created * - 'temporary' - If true, then a temporary table will be created
* @param array $advancedOptions
* @return string The table name generated. This may be different from the table name, for example with * @return string The table name generated. This may be different from the table name, for example with
* temporary tables. * temporary tables.
*/ */
@ -577,7 +582,7 @@ class DB {
/** /**
* Checks a table's integrity and repairs it if necessary. * Checks a table's integrity and repairs it if necessary.
* *
* @param string $tableName The name of the table. * @param string $table The name of the table.
* @return boolean Return true if the table has integrity after the method is complete. * @return boolean Return true if the table has integrity after the method is complete.
*/ */
public static function check_and_repair_table($table) { public static function check_and_repair_table($table) {

View File

@ -19,8 +19,8 @@ use SearchContext;
use FieldList; use FieldList;
use FormField; use FormField;
use FormScaffolder; use FormScaffolder;
use Member;
use Permission;
use Object; use Object;
use SearchFilter; use SearchFilter;
use SilverStripe\ORM\Queries\SQLInsert; use SilverStripe\ORM\Queries\SQLInsert;
@ -30,6 +30,9 @@ use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\FieldType\DBComposite; use SilverStripe\ORM\FieldType\DBComposite;
use SilverStripe\ORM\FieldType\DBClassName; use SilverStripe\ORM\FieldType\DBClassName;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
/** /**
* A single database record & abstract class for the data-access-model. * A single database record & abstract class for the data-access-model.
@ -907,10 +910,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
* Caution: Does not delete the merged object. * Caution: Does not delete the merged object.
* Caution: Does now overwrite Created date on the original object. * Caution: Does now overwrite Created date on the original object.
* *
* @param $obj DataObject * @param DataObject $rightObj
* @param $priority String left|right Determines who wins in case of a conflict (optional) * @param string $priority left|right Determines who wins in case of a conflict (optional)
* @param $includeRelations Boolean Merge any existing relations (optional) * @param bool $includeRelations Merge any existing relations (optional)
* @param $overwriteWithEmpty Boolean Overwrite existing left values with empty right values. * @param bool $overwriteWithEmpty Overwrite existing left values with empty right values.
* Only applicable with $priority='right'. (optional) * Only applicable with $priority='right'. (optional)
* @return Boolean * @return Boolean
*/ */

View File

@ -5,12 +5,15 @@ namespace SilverStripe\ORM;
use Controller; use Controller;
use SapphireTest; use SapphireTest;
use Director; use Director;
use Security;
use Permission;
use SS_ClassLoader; use SS_ClassLoader;
use ClassInfo; use ClassInfo;
use TestOnly; use TestOnly;
use Deprecation; use Deprecation;
use SilverStripe\Security\Security;
use SilverStripe\Security\Permission;
// Include the DB class // Include the DB class
require_once("DB.php"); require_once("DB.php");
@ -183,6 +186,7 @@ class DatabaseAdmin extends Controller {
* *
* @param boolean $quiet Don't show messages * @param boolean $quiet Don't show messages
* @param boolean $populate Populate the database, as well as setting up its schema * @param boolean $populate Populate the database, as well as setting up its schema
* @param bool $testMode
*/ */
public function doBuild($quiet = false, $populate = true, $testMode = false) { public function doBuild($quiet = false, $populate = true, $testMode = false) {
if($quiet) { if($quiet) {

View File

@ -2,13 +2,15 @@
namespace SilverStripe\ORM\FieldType; namespace SilverStripe\ORM\FieldType;
use Member;
use Zend_Date; use Zend_Date;
use DateTime; use DateTime;
use DateField; use DateField;
use Convert; use Convert;
use Exception; use Exception;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\Security\Member;
/** /**
* Represents a date field. * Represents a date field.

View File

@ -4,12 +4,13 @@ namespace SilverStripe\ORM\FieldType;
use Convert; use Convert;
use Exception; use Exception;
use Member;
use DatetimeField; use DatetimeField;
use Zend_Date; use Zend_Date;
use TemplateGlobalProvider; use TemplateGlobalProvider;
use DateTime; use DateTime;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\Security\Member;
/** /**
* Represents a date-time field. * Represents a date-time field.
@ -60,11 +61,11 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider {
if(is_numeric($value)) { if(is_numeric($value)) {
$this->value = date('Y-m-d H:i:s', $value); $this->value = date('Y-m-d H:i:s', $value);
} elseif(is_string($value)) { } elseif(is_string($value)) {
try { try{
$date = new DateTime($value); $date = new DateTime($value);
$this->value = $date->format('Y-m-d H:i:s'); $this->value = $date->format('Y-m-d H:i:s');
return; return;
} catch(Exception $e) { }catch(Exception $e){
$this->value = null; $this->value = null;
return; return;
} }

View File

@ -768,14 +768,15 @@ class Hierarchy extends DataExtension {
* @return DataObject * @return DataObject
*/ */
public function getParent($filter = null) { public function getParent($filter = null) {
if($p = $this->owner->__get("ParentID")) { $parentID = $this->owner->ParentID;
$tableClasses = ClassInfo::dataClassesFor($this->owner->class); if(empty($parentID)) {
$baseClass = array_shift($tableClasses); return null;
return DataObject::get_one($this->owner->class, array(
array("\"$baseClass\".\"ID\"" => $p),
$filter
));
} }
$idSQL = $this->owner->getSchema()->sqlColumnForField($this->owner, 'ID');
return DataObject::get_one($this->owner->class, array(
array($idSQL => $parentID),
$filter
));
} }
/** /**

View File

@ -4,6 +4,7 @@ namespace SilverStripe\ORM\Queries;
use Exception; use Exception;
use Convert; use Convert;
use SilverStripe\ORM\Connect\SS_Query;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
/** /**

View File

@ -2,9 +2,11 @@
namespace SilverStripe\ORM\Versioning; namespace SilverStripe\ORM\Versioning;
use Member;
use Permission;
use Exception;
use FieldList; use FieldList;
use SilverStripe\ORM\HasManyList;
use TextField; use TextField;
use ReadonlyField; use ReadonlyField;
use i18n; use i18n;
@ -13,6 +15,9 @@ use LogicException;
use SilverStripe\ORM\ValidationException; use SilverStripe\ORM\ValidationException;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
/** /**
* The ChangeSet model tracks several VersionedAndStaged objects for later publication as a single * The ChangeSet model tracks several VersionedAndStaged objects for later publication as a single
@ -57,7 +62,7 @@ class ChangeSet extends DataObject {
); );
private static $has_one = array( private static $has_one = array(
'Owner' => 'Member', 'Owner' => 'SilverStripe\\Security\\Member',
); );
private static $casting = array( private static $casting = array(

View File

@ -4,12 +4,18 @@ namespace SilverStripe\ORM\Versioning;
use Exception; use Exception;
use BadMethodCallException; use BadMethodCallException;
use Member;
use Permission;
use CMSPreviewable; use CMSPreviewable;
use Controller; use Controller;
use SilverStripe\Filesystem\Thumbnail; use SilverStripe\Filesystem\Thumbnail;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ManyManyList;
use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
/** /**
* A single line in a changeset * A single line in a changeset

View File

@ -2,16 +2,17 @@
namespace SilverStripe\ORM\Versioning; namespace SilverStripe\ORM\Versioning;
use SS_HTTPRequest;
use TemplateGlobalProvider; use TemplateGlobalProvider;
use Session; use Session;
use Deprecation; use Deprecation;
use InvalidArgumentException; use InvalidArgumentException;
use Config; use Config;
use LogicException; use LogicException;
use Member;
use ClassInfo; use ClassInfo;
use Object; use Object;
use Permission;
use Director; use Director;
use Cookie; use Cookie;
use FieldList; use FieldList;
@ -25,6 +26,9 @@ use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\SS_List; use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\ORM\Queries\SQLUpdate; use SilverStripe\ORM\Queries\SQLUpdate;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
/** /**
* The Versioned extension allows your DataObjects to have several versions, * The Versioned extension allows your DataObjects to have several versions,
@ -235,8 +239,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
* Amend freshly created DataQuery objects with versioned-specific * Amend freshly created DataQuery objects with versioned-specific
* information. * information.
* *
* @param SQLSelect * @param SQLSelect $query
* @param DataQuery * @param DataQuery $dataQuery
*/ */
public function augmentDataQueryCreation(SQLSelect &$query, DataQuery &$dataQuery) { public function augmentDataQueryCreation(SQLSelect &$query, DataQuery &$dataQuery) {
$parts = explode('.', Versioned::get_reading_mode()); $parts = explode('.', Versioned::get_reading_mode());
@ -2397,7 +2401,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
} }
/** /**
* @param FieldList * @param FieldList $fields
*/ */
public function updateCMSFields(FieldList $fields) { public function updateCMSFields(FieldList $fields) {
// remove the version field from the CMS as this should be left // remove the version field from the CMS as this should be left

View File

@ -1,4 +1,11 @@
<?php <?php
namespace SilverStripe\Security;
use Object;
use Form;
use Controller;
/** /**
* Abstract base class for an authentication method * Abstract base class for an authentication method
* *
@ -16,7 +23,7 @@ abstract class Authenticator extends Object {
* *
* @var array * @var array
*/ */
private static $authenticators = array('MemberAuthenticator'); private static $authenticators = array('SilverStripe\\Security\\MemberAuthenticator');
/** /**
* Used to influence the order of authenticators on the login-screen * Used to influence the order of authenticators on the login-screen
@ -24,7 +31,7 @@ abstract class Authenticator extends Object {
* *
* @var string * @var string
*/ */
private static $default_authenticator = 'MemberAuthenticator'; private static $default_authenticator = 'SilverStripe\\Security\\MemberAuthenticator';
/** /**
@ -43,7 +50,7 @@ abstract class Authenticator extends Object {
/** /**
* Method that creates the login form for this authentication method * Method that creates the login form for this authentication method
* *
* @param Controller The parent controller, necessary to create the * @param Controller $controller The parent controller, necessary to create the
* appropriate form action tag * appropriate form action tag
* @return Form Returns the login form to use with this authentication * @return Form Returns the login form to use with this authentication
* method * method
@ -99,7 +106,7 @@ abstract class Authenticator extends Object {
if(class_exists($authenticator) == false) if(class_exists($authenticator) == false)
return false; return false;
if(is_subclass_of($authenticator, 'Authenticator') == false) if(is_subclass_of($authenticator, 'SilverStripe\\Security\\Authenticator') == false)
return false; return false;
if(in_array($authenticator, self::$authenticators) == false) { if(in_array($authenticator, self::$authenticators) == false) {

View File

@ -1,4 +1,13 @@
<?php <?php
namespace SilverStripe\Security;
use SapphireTest;
use Director;
use SS_HTTPResponse;
use SS_HTTPResponse_Exception;
use Config;
/** /**
* Provides an interface to HTTP basic authentication. * Provides an interface to HTTP basic authentication.
* *
@ -125,14 +134,15 @@ class BasicAuth {
* define('SS_USE_BASIC_AUTH', true); * define('SS_USE_BASIC_AUTH', true);
* *
* @param boolean $protect Set this to false to disable protection. * @param boolean $protect Set this to false to disable protection.
* @param String $code {@link Permission} code that is required from the user. * @param string $code {@link Permission} code that is required from the user.
* Defaults to "ADMIN". Set to NULL to just require a valid login, regardless * Defaults to "ADMIN". Set to NULL to just require a valid login, regardless
* of the permission codes a user has. * of the permission codes a user has.
* @param string $message
*/ */
public static function protect_entire_site($protect = true, $code = 'ADMIN', $message = null) { public static function protect_entire_site($protect = true, $code = 'ADMIN', $message = null) {
Config::inst()->update('BasicAuth', 'entire_site_protected', $protect); Config::inst()->update('SilverStripe\\Security\\BasicAuth', 'entire_site_protected', $protect);
Config::inst()->update('BasicAuth', 'entire_site_protected_code', $code); Config::inst()->update('SilverStripe\\Security\\BasicAuth', 'entire_site_protected_code', $code);
Config::inst()->update('BasicAuth', 'entire_site_protected_message', $message); Config::inst()->update('SilverStripe\\Security\\BasicAuth', 'entire_site_protected_message', $message);
} }
/** /**
@ -143,7 +153,7 @@ class BasicAuth {
* please use {@link protect_entire_site()}. * please use {@link protect_entire_site()}.
*/ */
public static function protect_site_if_necessary() { public static function protect_site_if_necessary() {
$config = Config::inst()->forClass('BasicAuth'); $config = Config::inst()->forClass('SilverStripe\\Security\\BasicAuth');
if($config->entire_site_protected) { if($config->entire_site_protected) {
self::requireLogin($config->entire_site_protected_message, $config->entire_site_protected_code, false); self::requireLogin($config->entire_site_protected_message, $config->entire_site_protected_code, false);
} }

View File

@ -1,5 +1,19 @@
<?php <?php
namespace SilverStripe\Security;
use Controller;
use FieldList;
use HiddenField;
use PasswordField;
use LiteralField;
use CheckboxField;
use FormAction;
use Session;
use Convert;
use SS_HTTPResponse;
/** /**
* Provides the in-cms session re-authentication form for the "member" authenticator * Provides the in-cms session re-authentication form for the "member" authenticator
* *
@ -8,7 +22,7 @@
*/ */
class CMSMemberLoginForm extends LoginForm { class CMSMemberLoginForm extends LoginForm {
protected $authenticator_class = 'MemberAuthenticator'; protected $authenticator_class = 'SilverStripe\\Security\\MemberAuthenticator';
/** /**
* Get link to use for external security actions * Get link to use for external security actions
@ -68,7 +82,7 @@ class CMSMemberLoginForm extends LoginForm {
/** /**
* Try to authenticate the user * Try to authenticate the user
* *
* @param array Submitted data * @param array $data Submitted data
* @return Member Returns the member object on successful authentication * @return Member Returns the member object on successful authentication
* or NULL on failure. * or NULL on failure.
*/ */
@ -89,6 +103,7 @@ class CMSMemberLoginForm extends LoginForm {
* This method is called when the user clicks on "Log in" * This method is called when the user clicks on "Log in"
* *
* @param array $data Submitted data * @param array $data Submitted data
* @return \SS_HTTPResponse
*/ */
public function dologin($data) { public function dologin($data) {
if($this->performLogin($data)) { if($this->performLogin($data)) {
@ -110,7 +125,7 @@ class CMSMemberLoginForm extends LoginForm {
*/ */
protected function redirectToChangePassword() { protected function redirectToChangePassword() {
// Since this form is loaded via an iframe, this redirect must be performed via javascript // Since this form is loaded via an iframe, this redirect must be performed via javascript
$changePasswordForm = new ChangePasswordForm($this->controller, 'ChangePasswordForm'); $changePasswordForm = new ChangePasswordForm($this->controller, 'SilverStripe\\Security\\ChangePasswordForm');
$changePasswordForm->sessionMessage( $changePasswordForm->sessionMessage(
_t('Member.PASSWORDEXPIRED', 'Your password has expired. Please choose a new one.'), _t('Member.PASSWORDEXPIRED', 'Your password has expired. Please choose a new one.'),
'good' 'good'

View File

@ -1,5 +1,16 @@
<?php <?php
namespace SilverStripe\Security;
use Requirements;
use Controller;
use Director;
use Convert;
use Session;
use AdminRootController;
use SS_HTTPResponse;
/** /**
* Provides a security interface functionality within the cms * Provides a security interface functionality within the cms
* @package framework * @package framework
@ -12,7 +23,7 @@ class CMSSecurity extends Security {
); );
private static $allowed_actions = array( private static $allowed_actions = array(
'LoginForm', 'SilverStripe\\Security\\LoginForm',
'success' 'success'
); );
@ -43,6 +54,7 @@ class CMSSecurity extends Security {
} }
public function Link($action = null) { public function Link($action = null) {
/** @skipUpgrade */
return Controller::join_links(Director::baseURL(), "CMSSecurity", $action); return Controller::join_links(Director::baseURL(), "CMSSecurity", $action);
} }
@ -173,7 +185,7 @@ PHP
} }
public function getTemplatesFor($action) { public function getTemplatesFor($action) {
return array("CMSSecurity_{$action}", "CMSSecurity") return array("CMSSecurity_{$action}", "SilverStripe\\Security\\CMSSecurity")
+ parent::getTemplatesFor($action); + parent::getTemplatesFor($action);
} }

View File

@ -1,4 +1,17 @@
<?php <?php
namespace SilverStripe\Security;
use Form;
use Session;
use FieldList;
use PasswordField;
use FormAction;
use HiddenField;
use Director;
use HTTP;
use Convert;
/** /**
* Standard Change Password Form * Standard Change Password Form
* @package framework * @package framework

View File

@ -1,8 +1,33 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\HasManyList;
use SilverStripe\ORM\ManyManyList;
use SilverStripe\ORM\UnsavedRelationList; use SilverStripe\ORM\UnsavedRelationList;
use Requirements;
use FieldList;
use TabSet;
use Tab;
use TextField;
use DropdownField;
use TextareaField;
use Config;
use GridFieldConfig_RelationEditor;
use GridFieldButtonRow;
use GridFieldExportButton;
use GridFieldPrintButton;
use GridField;
use HTMLEditorConfig;
use LiteralField;
use ListboxField;
use HiddenField;
use InvalidArgumentException;
use Convert;
/** /**
* A security group. * A security group.
* *
@ -35,23 +60,25 @@ class Group extends DataObject {
); );
private static $has_one = array( private static $has_one = array(
"Parent" => "Group", "Parent" => "SilverStripe\\Security\\Group",
); );
private static $has_many = array( private static $has_many = array(
"Permissions" => "Permission", "Permissions" => "SilverStripe\\Security\\Permission",
"Groups" => "Group" "Groups" => "SilverStripe\\Security\\Group"
); );
private static $many_many = array( private static $many_many = array(
"Members" => "Member", "Members" => "SilverStripe\\Security\\Member",
"Roles" => "PermissionRole", "Roles" => "SilverStripe\\Security\\PermissionRole",
); );
private static $extensions = array( private static $extensions = array(
"SilverStripe\\ORM\\Hierarchy\\Hierarchy", "SilverStripe\\ORM\\Hierarchy\\Hierarchy",
); );
private static $table_name = "Group";
public function populateDefaults() { public function populateDefaults() {
parent::populateDefaults(); parent::populateDefaults();
@ -61,7 +88,7 @@ class Group extends DataObject {
public function getAllChildren() { public function getAllChildren() {
$doSet = new ArrayList(); $doSet = new ArrayList();
$children = DataObject::get('Group')->filter("ParentID", $this->ID); $children = Group::get()->filter("ParentID", $this->ID);
foreach($children as $child) { foreach($children as $child) {
$doSet->push($child); $doSet->push($child);
$doSet->merge($child->getAllChildren()); $doSet->merge($child->getAllChildren());
@ -94,7 +121,7 @@ class Group extends DataObject {
$permissionsField = new PermissionCheckboxSetField( $permissionsField = new PermissionCheckboxSetField(
'Permissions', 'Permissions',
false, false,
'Permission', 'SilverStripe\\Security\\Permission',
'GroupID', 'GroupID',
$this $this
) )
@ -163,7 +190,7 @@ class Group extends DataObject {
// Only show the "Roles" tab if permissions are granted to edit them, // Only show the "Roles" tab if permissions are granted to edit them,
// and at least one role exists // and at least one role exists
if(Permission::check('APPLY_ROLES') && DataObject::get('PermissionRole')) { if(Permission::check('APPLY_ROLES') && DataObject::get('SilverStripe\\Security\\PermissionRole')) {
$fields->findOrMakeTab('Root.Roles', _t('SecurityAdmin.ROLES', 'Roles')); $fields->findOrMakeTab('Root.Roles', _t('SecurityAdmin.ROLES', 'Roles'));
$fields->addFieldToTab('Root.Roles', $fields->addFieldToTab('Root.Roles',
new LiteralField( new LiteralField(
@ -223,9 +250,8 @@ class Group extends DataObject {
} }
/** /**
* * @param bool $includerelations Indicate if the labels returned include relation fields
* @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields * @return array
*
*/ */
public function fieldLabels($includerelations = true) { public function fieldLabels($includerelations = true) {
$labels = parent::fieldLabels($includerelations); $labels = parent::fieldLabels($includerelations);
@ -358,7 +384,7 @@ class Group extends DataObject {
$inheritedCodes = Permission::get() $inheritedCodes = Permission::get()
->filter('GroupID', $this->Parent()->collateAncestorIDs()) ->filter('GroupID', $this->Parent()->collateAncestorIDs())
->column('Code'); ->column('Code');
$privilegedCodes = Config::inst()->get('Permission', 'privileged_permissions'); $privilegedCodes = Config::inst()->get('SilverStripe\\Security\\Permission', 'privileged_permissions');
if(array_intersect($inheritedCodes, $privilegedCodes)) { if(array_intersect($inheritedCodes, $privilegedCodes)) {
$result->error(sprintf( $result->error(sprintf(
_t( _t(
@ -406,7 +432,7 @@ class Group extends DataObject {
* @return boolean * @return boolean
*/ */
public function canEdit($member = null) { public function canEdit($member = null) {
if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); if(!$member || !(is_a($member, 'SilverStripe\\Security\\Member')) || is_numeric($member)) $member = Member::currentUser();
// extended access checks // extended access checks
$results = $this->extend('canEdit', $member); $results = $this->extend('canEdit', $member);
@ -436,7 +462,7 @@ class Group extends DataObject {
* @return boolean * @return boolean
*/ */
public function canView($member = null) { public function canView($member = null) {
if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); if(!$member || !(is_a($member, 'SilverStripe\\Security\\Member')) || is_numeric($member)) $member = Member::currentUser();
// extended access checks // extended access checks
$results = $this->extend('canView', $member); $results = $this->extend('canView', $member);
@ -449,7 +475,7 @@ class Group extends DataObject {
} }
public function canDelete($member = null) { public function canDelete($member = null) {
if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); if(!$member || !(is_a($member, 'SilverStripe\\Security\\Member')) || is_numeric($member)) $member = Member::currentUser();
// extended access checks // extended access checks
$results = $this->extend('canDelete', $member); $results = $this->extend('canDelete', $member);
@ -487,7 +513,7 @@ class Group extends DataObject {
parent::requireDefaultRecords(); parent::requireDefaultRecords();
// Add default author group if no other group exists // Add default author group if no other group exists
$allGroups = DataObject::get('Group'); $allGroups = DataObject::get('SilverStripe\\Security\\Group');
if(!$allGroups->count()) { if(!$allGroups->count()) {
$authorGroup = new Group(); $authorGroup = new Group();
$authorGroup->Code = 'content-authors'; $authorGroup->Code = 'content-authors';

View File

@ -1,6 +1,11 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use CsvBulkLoader;
/** /**
* @todo Migrate Permission->Arg and Permission->Type values * @todo Migrate Permission->Arg and Permission->Type values
* *
@ -14,7 +19,7 @@ class GroupCsvBulkLoader extends CsvBulkLoader {
); );
public function __construct($objectClass = null) { public function __construct($objectClass = null) {
if(!$objectClass) $objectClass = 'Group'; if(!$objectClass) $objectClass = 'SilverStripe\\Security\\Group';
parent::__construct($objectClass); parent::__construct($objectClass);
} }
@ -30,7 +35,7 @@ class GroupCsvBulkLoader extends CsvBulkLoader {
// are imported to avoid missing "early" references to parents // are imported to avoid missing "early" references to parents
// which are imported later on in the CSV file. // which are imported later on in the CSV file.
if(isset($record['ParentCode']) && $record['ParentCode']) { if(isset($record['ParentCode']) && $record['ParentCode']) {
$parentGroup = DataObject::get_one('Group', array( $parentGroup = DataObject::get_one('SilverStripe\\Security\\Group', array(
'"Group"."Code"' => $record['ParentCode'] '"Group"."Code"' => $record['ParentCode']
)); ));
if($parentGroup) { if($parentGroup) {
@ -43,7 +48,7 @@ class GroupCsvBulkLoader extends CsvBulkLoader {
// existing permissions arent cleared. // existing permissions arent cleared.
if(isset($record['PermissionCodes']) && $record['PermissionCodes']) { if(isset($record['PermissionCodes']) && $record['PermissionCodes']) {
foreach(explode(',', $record['PermissionCodes']) as $code) { foreach(explode(',', $record['PermissionCodes']) as $code) {
$p = DataObject::get_one('Permission', array( $p = DataObject::get_one('SilverStripe\\Security\\Permission', array(
'"Permission"."Code"' => $code, '"Permission"."Code"' => $code,
'"Permission"."GroupID"' => $group->ID '"Permission"."GroupID"' => $group->ID
)); ));

View File

@ -1,6 +1,11 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
/** /**
* Record all login attempts through the {@link LoginForm} object. * Record all login attempts through the {@link LoginForm} object.
* This behaviour is disabled by default. * This behaviour is disabled by default.
@ -31,19 +36,14 @@ class LoginAttempt extends DataObject {
); );
private static $has_one = array( private static $has_one = array(
'Member' => 'Member', // only linked if the member actually exists 'Member' => 'SilverStripe\\Security\\Member', // only linked if the member actually exists
); );
private static $has_many = array(); private static $table_name = "LoginAttempt";
private static $many_many = array();
private static $belongs_many_many = array();
/** /**
* * @param bool $includerelations Indicate if the labels returned include relation fields
* @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields * @return array
*
*/ */
public function fieldLabels($includerelations = true) { public function fieldLabels($includerelations = true) {
$labels = parent::fieldLabels($includerelations); $labels = parent::fieldLabels($includerelations);

View File

@ -1,4 +1,10 @@
<?php <?php
namespace SilverStripe\Security;
use Form;
use Injector;
/** /**
* Abstract base class for a login form * Abstract base class for a login form
* *
@ -27,7 +33,7 @@ abstract class LoginForm extends Form {
* @return Authenticator Returns the authenticator instance for this login form. * @return Authenticator Returns the authenticator instance for this login form.
*/ */
public function getAuthenticator() { public function getAuthenticator() {
if(!class_exists($this->authenticator_class) || !is_subclass_of($this->authenticator_class, 'Authenticator')) { if(!class_exists($this->authenticator_class) || !is_subclass_of($this->authenticator_class, 'SilverStripe\\Security\\Authenticator')) {
user_error("The form uses an invalid authenticator class! '{$this->authenticator_class}'" user_error("The form uses an invalid authenticator class! '{$this->authenticator_class}'"
. " is not a subclass of 'Authenticator'", E_USER_ERROR); . " is not a subclass of 'Authenticator'", E_USER_ERROR);
return; return;

View File

@ -1,6 +1,8 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\SS_Map;
use SilverStripe\ORM\ValidationResult; use SilverStripe\ORM\ValidationResult;
use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
@ -10,7 +12,30 @@ use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\ORM\ManyManyList; use SilverStripe\ORM\ManyManyList;
use SilverStripe\MSSQL\MSSQLDatabase;
use TemplateGlobalProvider;
use Deprecation;
use i18n;
use Director;
use Session;
use Cookie;
use Config;
use SapphireTest;
use DateTime;
use DropdownField;
use ConfirmedPasswordField;
use Injector;
use TestMailer;
use Email;
use FieldList;
use ListboxField;
use Zend_Locale_Format;
use Zend_Locale;
use Zend_Date;
use MemberDatetimeOptionsetField;
use HTMLEditorConfig;
use RequiredFields;
use GridFieldDetailForm_ItemRequest;
/** /**
* The member class which represents the users of the system * The member class which represents the users of the system
@ -63,19 +88,15 @@ class Member extends DataObject implements TemplateGlobalProvider {
); );
private static $belongs_many_many = array( private static $belongs_many_many = array(
'Groups' => 'Group', 'Groups' => 'SilverStripe\\Security\\Group',
); );
private static $has_one = array();
private static $has_many = array( private static $has_many = array(
'LoggedPasswords' => 'MemberPassword', 'LoggedPasswords' => 'SilverStripe\\Security\\MemberPassword',
'RememberLoginHashes' => 'RememberLoginHash' 'RememberLoginHashes' => 'SilverStripe\\Security\\RememberLoginHash'
); );
private static $many_many = array(); private static $table_name = "Member";
private static $many_many_extraFields = array();
private static $default_sort = '"Surname", "FirstName"'; private static $default_sort = '"Surname", "FirstName"';
@ -133,7 +154,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
/** /**
* @config * @config
* @var Array See {@link set_title_columns()} * @var array See {@link set_title_columns()}
*/ */
private static $title_format = null; private static $title_format = null;
@ -148,8 +169,10 @@ class Member extends DataObject implements TemplateGlobalProvider {
private static $unique_identifier_field = 'Email'; private static $unique_identifier_field = 'Email';
/** /**
* Object for validating user's password
*
* @config * @config
* {@link PasswordValidator} object for validating user's password * @var PasswordValidator
*/ */
private static $password_validator = null; private static $password_validator = null;
@ -243,8 +266,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
if(!Security::has_default_admin()) return null; if(!Security::has_default_admin()) return null;
// Find or create ADMIN group // Find or create ADMIN group
singleton('Group')->requireDefaultRecords(); Group::singleton()->requireDefaultRecords();
$adminGroup = Permission::get_groups_by_permission('ADMIN')->First(); $adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
// Find member // Find member
$admin = Member::get() $admin = Member::get()
@ -423,6 +446,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
/** /**
* Set a {@link PasswordValidator} object to use to validate member's passwords. * Set a {@link PasswordValidator} object to use to validate member's passwords.
*
* @param PasswordValidator $pv
*/ */
public static function set_password_validator($pv) { public static function set_password_validator($pv) {
self::$password_validator = $pv; self::$password_validator = $pv;
@ -430,6 +455,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
/** /**
* Returns the current {@link PasswordValidator} * Returns the current {@link PasswordValidator}
*
* @return PasswordValidator
*/ */
public static function password_validator() { public static function password_validator() {
return self::$password_validator; return self::$password_validator;
@ -482,8 +509,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
} }
if($remember) { if($remember) {
$rememberLoginHash = RememberLoginHash::generate($this); $rememberLoginHash = RememberLoginHash::generate($this);
$tokenExpiryDays = Config::inst()->get('RememberLoginHash', 'token_expiry_days'); $tokenExpiryDays = Config::inst()->get('SilverStripe\\Security\\RememberLoginHash', 'token_expiry_days');
$deviceExpiryDays = Config::inst()->get('RememberLoginHash', 'device_expiry_days'); $deviceExpiryDays = Config::inst()->get('SilverStripe\\Security\\RememberLoginHash', 'device_expiry_days');
Cookie::set('alc_enc', $this->ID . ':' . $rememberLoginHash->getToken(), Cookie::set('alc_enc', $this->ID . ':' . $rememberLoginHash->getToken(),
$tokenExpiryDays, null, null, null, true); $tokenExpiryDays, null, null, null, true);
Cookie::set('alc_device', $rememberLoginHash->DeviceID, $deviceExpiryDays, null, null, null, true); Cookie::set('alc_device', $rememberLoginHash->DeviceID, $deviceExpiryDays, null, null, null, true);
@ -497,10 +524,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
// Clear the incorrect log-in count // Clear the incorrect log-in count
$this->registerSuccessfulLogin(); $this->registerSuccessfulLogin();
// Don't set column if its not built yet (the login might be precursor to a /dev/build...) $this->LockedOutUntil = null;
if(array_key_exists('LockedOutUntil', DB::field_list('Member'))) {
$this->LockedOutUntil = null;
}
$this->regenerateTempID(); $this->regenerateTempID();
@ -534,7 +558,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
*/ */
public static function logged_in_session_exists() { public static function logged_in_session_exists() {
if($id = Member::currentUserID()) { if($id = Member::currentUserID()) {
if($member = DataObject::get_by_id('Member', $id)) { if($member = DataObject::get_by_id('SilverStripe\\Security\\Member', $id)) {
if($member->exists()) return true; if($member->exists()) return true;
} }
} }
@ -570,7 +594,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
$deviceID = Cookie::get('alc_device'); $deviceID = Cookie::get('alc_device');
$member = Member::get()->byId($uid); $member = Member::get()->byID($uid);
$rememberLoginHash = null; $rememberLoginHash = null;
@ -606,7 +630,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
if ($rememberLoginHash) { if ($rememberLoginHash) {
$rememberLoginHash->renew(); $rememberLoginHash->renew();
$tokenExpiryDays = Config::inst()->get('RememberLoginHash', 'token_expiry_days'); $tokenExpiryDays = Config::inst()->get('SilverStripe\\Security\\RememberLoginHash', 'token_expiry_days');
Cookie::set('alc_enc', $member->ID . ':' . $rememberLoginHash->getToken(), Cookie::set('alc_enc', $member->ID . ':' . $rememberLoginHash->getToken(),
$tokenExpiryDays, null, null, false, true); $tokenExpiryDays, null, null, false, true);
} }
@ -652,6 +676,10 @@ class Member extends DataObject implements TemplateGlobalProvider {
/** /**
* Utility for generating secure password hashes for this member. * Utility for generating secure password hashes for this member.
*
* @param string $string
* @return string
* @throws PasswordEncryptor_NotFoundException
*/ */
public function encryptWithUserSettings($string) { public function encryptWithUserSettings($string) {
if (!$string) return null; if (!$string) return null;
@ -683,7 +711,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
$generator = new RandomGenerator(); $generator = new RandomGenerator();
$token = $generator->randomToken(); $token = $generator->randomToken();
$hash = $this->encryptWithUserSettings($token); $hash = $this->encryptWithUserSettings($token);
} while(DataObject::get_one('Member', array( } while(DataObject::get_one('SilverStripe\\Security\\Member', array(
'"Member"."AutoLoginHash"' => $hash '"Member"."AutoLoginHash"' => $hash
))); )));
@ -720,7 +748,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
public static function member_from_autologinhash($hash, $login = false) { public static function member_from_autologinhash($hash, $login = false) {
$nowExpression = DB::get_conn()->now(); $nowExpression = DB::get_conn()->now();
$member = DataObject::get_one('Member', array( $member = DataObject::get_one('SilverStripe\\Security\\Member', array(
"\"Member\".\"AutoLoginHash\"" => $hash, "\"Member\".\"AutoLoginHash\"" => $hash,
"\"Member\".\"AutoLoginExpired\" > $nowExpression" // NOW() can't be parameterised "\"Member\".\"AutoLoginExpired\" > $nowExpression" // NOW() can't be parameterised
)); ));
@ -815,7 +843,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
* @return Member_Validator * @return Member_Validator
*/ */
public function getValidator() { public function getValidator() {
$validator = Injector::inst()->create('Member_Validator'); $validator = Injector::inst()->create('SilverStripe\\Security\\Member_Validator');
$validator->setForMember($this); $validator->setForMember($this);
$this->extend('updateValidator', $validator); $this->extend('updateValidator', $validator);
@ -826,13 +854,13 @@ class Member extends DataObject implements TemplateGlobalProvider {
/** /**
* Returns the current logged in user * Returns the current logged in user
* *
* @return Member|null * @return Member
*/ */
public static function currentUser() { public static function currentUser() {
$id = Member::currentUserID(); $id = Member::currentUserID();
if($id) { if($id) {
return Member::get()->byId($id); return Member::get()->byID($id);
} }
} }
@ -860,7 +888,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
* @return string Returns a random password. * @return string Returns a random password.
*/ */
public static function create_new_password() { public static function create_new_password() {
$words = Config::inst()->get('Security', 'word_list'); $words = Config::inst()->get('SilverStripe\\Security\\Security', 'word_list');
if($words && file_exists($words)) { if($words && file_exists($words)) {
$words = file($words); $words = file($words);
@ -897,7 +925,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
if($this->ID) { if($this->ID) {
$filter[] = array('"Member"."ID" <> ?' => $this->ID); $filter[] = array('"Member"."ID" <> ?' => $this->ID);
} }
$existingRecord = DataObject::get_one('Member', $filter); $existingRecord = DataObject::get_one('SilverStripe\\Security\\Member', $filter);
if($existingRecord) { if($existingRecord) {
throw new ValidationException(ValidationResult::create(false, _t( throw new ValidationException(ValidationResult::create(false, _t(
@ -1001,8 +1029,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
* Filter out admin groups to avoid privilege escalation, * Filter out admin groups to avoid privilege escalation,
* If any admin groups are requested, deny the whole save operation. * If any admin groups are requested, deny the whole save operation.
* *
* @param Array $ids Database IDs of Group records * @param array $ids Database IDs of Group records
* @return boolean True if the change can be accepted * @return bool True if the change can be accepted
*/ */
public function onChangeGroups($ids) { public function onChangeGroups($ids) {
// unless the current user is an admin already OR the logged in user is an admin // unless the current user is an admin already OR the logged in user is an admin
@ -1042,9 +1070,9 @@ class Member extends DataObject implements TemplateGlobalProvider {
*/ */
public function inGroup($group, $strict = false) { public function inGroup($group, $strict = false) {
if(is_numeric($group)) { if(is_numeric($group)) {
$groupCheckObj = DataObject::get_by_id('Group', $group); $groupCheckObj = DataObject::get_by_id('SilverStripe\\Security\\Group', $group);
} elseif(is_string($group)) { } elseif(is_string($group)) {
$groupCheckObj = DataObject::get_one('Group', array( $groupCheckObj = DataObject::get_one('SilverStripe\\Security\\Group', array(
'"Group"."Code"' => $group '"Group"."Code"' => $group
)); ));
} elseif($group instanceof Group) { } elseif($group instanceof Group) {
@ -1068,10 +1096,10 @@ class Member extends DataObject implements TemplateGlobalProvider {
* group code does not return a valid group object. * group code does not return a valid group object.
* *
* @param string $groupcode * @param string $groupcode
* @param string Title of the group * @param string $title Title of the group
*/ */
public function addToGroupByCode($groupcode, $title = "") { public function addToGroupByCode($groupcode, $title = "") {
$group = DataObject::get_one('Group', array( $group = DataObject::get_one('SilverStripe\\Security\\Group', array(
'"Group"."Code"' => $groupcode '"Group"."Code"' => $groupcode
)); ));
@ -1103,7 +1131,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
} }
/** /**
* @param Array $columns Column names on the Member record to show in {@link getTitle()}. * @param array $columns Column names on the Member record to show in {@link getTitle()}.
* @param String $sep Separator * @param String $sep Separator
*/ */
public static function set_title_columns($columns, $sep = ' ') { public static function set_title_columns($columns, $sep = ' ') {
@ -1151,24 +1179,28 @@ class Member extends DataObject implements TemplateGlobalProvider {
* Return a SQL CONCAT() fragment suitable for a SELECT statement. * Return a SQL CONCAT() fragment suitable for a SELECT statement.
* Useful for custom queries which assume a certain member title format. * Useful for custom queries which assume a certain member title format.
* *
* @param String $tableName
* @return String SQL * @return String SQL
*/ */
public static function get_title_sql($tableName = 'Member') { public static function get_title_sql() {
// This should be abstracted to SSDatabase concatOperator or similar. // This should be abstracted to SSDatabase concatOperator or similar.
$op = (DB::get_conn() instanceof MSSQLDatabase) ? " + " : " || "; $op = (DB::get_conn() instanceof MSSQLDatabase) ? " + " : " || ";
$format = self::config()->title_format; // Get title_format with fallback to default
if ($format) { $format = static::config()->title_format;
$columnsWithTablename = array(); if (!$format) {
foreach($format['columns'] as $column) { $format = [
$columnsWithTablename[] = "\"$tableName\".\"$column\""; 'columns' => ['Surname', 'FirstName'],
} 'sep' => ' ',
];
return "(".join(" $op '".$format['sep']."' $op ", $columnsWithTablename).")";
} else {
return "(\"$tableName\".\"Surname\" $op ' ' $op \"$tableName\".\"FirstName\")";
} }
$columnsWithTablename = array();
foreach($format['columns'] as $column) {
$columnsWithTablename[] = static::getSchema()->sqlColumnForField(__CLASS__, $column);
}
$sepSQL = \Convert::raw2sql($format['sep'], true);
return "(".join(" $op $sepSQL $op ", $columnsWithTablename).")";
} }
@ -1249,7 +1281,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
* @return Member_Groupset * @return Member_Groupset
*/ */
public function Groups() { public function Groups() {
$groups = Member_GroupSet::create('Group', 'Group_Members', 'GroupID', 'MemberID'); $groups = Member_GroupSet::create('SilverStripe\\Security\\Group', 'Group_Members', 'GroupID', 'MemberID');
$groups = $groups->forForeignID($this->ID); $groups = $groups->forForeignID($this->ID);
$this->extend('updateGroups', $groups); $this->extend('updateGroups', $groups);
@ -1326,7 +1358,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
} }
$permsClause = DB::placeholders($perms); $permsClause = DB::placeholders($perms);
$groups = DataObject::get('Group') /** @skipUpgrade */
$groups = DataObject::get('SilverStripe\\Security\\Group')
->innerJoin("Permission", '"Permission"."GroupID" = "Group"."ID"') ->innerJoin("Permission", '"Permission"."GroupID" = "Group"."ID"')
->where(array( ->where(array(
"\"Permission\".\"Code\" IN ($permsClause)" => $perms "\"Permission\".\"Code\" IN ($permsClause)" => $perms
@ -1343,6 +1376,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
$groupIDList = $groups; $groupIDList = $groups;
} }
/** @skipUpgrade */
$members = Member::get() $members = Member::get()
->innerJoin("Group_Members", '"Group_Members"."MemberID" = "Member"."ID"') ->innerJoin("Group_Members", '"Group_Members"."MemberID" = "Member"."ID"')
->innerJoin("Group", '"Group"."ID" = "Group_Members"."GroupID"'); ->innerJoin("Group", '"Group"."ID" = "Group_Members"."GroupID"');
@ -1429,7 +1463,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
} }
asort($groupsMap); asort($groupsMap);
$fields->addFieldToTab('Root.Main', $fields->addFieldToTab('Root.Main',
ListboxField::create('DirectGroups', singleton('Group')->i18n_plural_name()) ListboxField::create('DirectGroups', singleton('SilverStripe\\Security\\Group')->i18n_plural_name())
->setSource($groupsMap) ->setSource($groupsMap)
->setAttribute( ->setAttribute(
'data-placeholder', 'data-placeholder',
@ -1445,12 +1479,12 @@ class Member extends DataObject implements TemplateGlobalProvider {
$permissionsField = new PermissionCheckboxSetField_Readonly( $permissionsField = new PermissionCheckboxSetField_Readonly(
'Permissions', 'Permissions',
false, false,
'Permission', 'SilverStripe\\Security\\Permission',
'GroupID', 'GroupID',
// we don't want parent relationships, they're automatically resolved in the field // we don't want parent relationships, they're automatically resolved in the field
$self->getManyManyComponents('Groups') $self->getManyManyComponents('Groups')
); );
$fields->findOrMakeTab('Root.Permissions', singleton('Permission')->i18n_plural_name()); $fields->findOrMakeTab('Root.Permissions', singleton('SilverStripe\\Security\\Permission')->i18n_plural_name());
$fields->addFieldToTab('Root.Permissions', $permissionsField); $fields->addFieldToTab('Root.Permissions', $permissionsField);
} }
} }
@ -1499,9 +1533,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
} }
/** /**
* * @param bool $includerelations Indicate if the labels returned include relation fields
* @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields * @return array
*
*/ */
public function fieldLabels($includerelations = true) { public function fieldLabels($includerelations = true) {
$labels = parent::fieldLabels($includerelations); $labels = parent::fieldLabels($includerelations);
@ -1522,11 +1555,14 @@ class Member extends DataObject implements TemplateGlobalProvider {
return $labels; return $labels;
} }
/** /**
* Users can view their own record. * Users can view their own record.
* Otherwise they'll need ADMIN or CMS_ACCESS_SecurityAdmin permissions. * Otherwise they'll need ADMIN or CMS_ACCESS_SecurityAdmin permissions.
* This is likely to be customized for social sites etc. with a looser permission model. * This is likely to be customized for social sites etc. with a looser permission model.
*/ *
* @param Member $member
* @return bool
*/
public function canView($member = null) { public function canView($member = null) {
//get member //get member
if(!($member instanceof Member)) { if(!($member instanceof Member)) {
@ -1549,10 +1585,14 @@ class Member extends DataObject implements TemplateGlobalProvider {
//standard check //standard check
return Permission::checkMember($member, 'CMS_ACCESS_SecurityAdmin'); return Permission::checkMember($member, 'CMS_ACCESS_SecurityAdmin');
} }
/**
* Users can edit their own record. /**
* Otherwise they'll need ADMIN or CMS_ACCESS_SecurityAdmin permissions * Users can edit their own record.
*/ * Otherwise they'll need ADMIN or CMS_ACCESS_SecurityAdmin permissions
*
* @param Member $member
* @return bool
*/
public function canEdit($member = null) { public function canEdit($member = null) {
//get member //get member
if(!($member instanceof Member)) { if(!($member instanceof Member)) {
@ -1583,6 +1623,9 @@ class Member extends DataObject implements TemplateGlobalProvider {
/** /**
* Users can edit their own record. * Users can edit their own record.
* Otherwise they'll need ADMIN or CMS_ACCESS_SecurityAdmin permissions * Otherwise they'll need ADMIN or CMS_ACCESS_SecurityAdmin permissions
*
* @param Member $member
* @return bool
*/ */
public function canDelete($member = null) { public function canDelete($member = null) {
if(!($member instanceof Member)) { if(!($member instanceof Member)) {
@ -1641,7 +1684,8 @@ class Member extends DataObject implements TemplateGlobalProvider {
* Change password. This will cause rehashing according to * Change password. This will cause rehashing according to
* the `PasswordEncryption` property. * the `PasswordEncryption` property.
* *
* @param String $password Cleartext password * @param string $password Cleartext password
* @return ValidationResult
*/ */
public function changePassword($password) { public function changePassword($password) {
$this->Password = $password; $this->Password = $password;
@ -1755,7 +1799,7 @@ class Member_GroupSet extends ManyManyList {
$allGroupIDs = array(); $allGroupIDs = array();
while($groupIDs) { while($groupIDs) {
$allGroupIDs = array_merge($allGroupIDs, $groupIDs); $allGroupIDs = array_merge($allGroupIDs, $groupIDs);
$groupIDs = DataObject::get("Group")->byIDs($groupIDs)->column("ParentID"); $groupIDs = DataObject::get("SilverStripe\\Security\\Group")->byIDs($groupIDs)->column("ParentID");
$groupIDs = array_filter($groupIDs); $groupIDs = array_filter($groupIDs);
} }
@ -1811,7 +1855,7 @@ class Member_GroupSet extends ManyManyList {
protected function getMember() { protected function getMember() {
$id = $this->getForeignID(); $id = $this->getForeignID();
if($id) { if($id) {
return DataObject::get_by_id('Member', $id); return DataObject::get_by_id('SilverStripe\\Security\\Member', $id);
} }
} }
} }

View File

@ -1,6 +1,14 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\ValidationResult; use SilverStripe\ORM\ValidationResult;
use InvalidArgumentException;
use Controller;
use Form;
use Session;
/** /**
* Authenticator for the default "member" method * Authenticator for the default "member" method
* *
@ -123,7 +131,7 @@ class MemberAuthenticator extends Authenticator {
} else { } else {
// Audit logging hook // Audit logging hook
singleton('Member')->extend('authenticationFailedUnknownUser', $data); Member::singleton()->extend('authenticationFailedUnknownUser', $data);
} }
} }
@ -170,16 +178,18 @@ class MemberAuthenticator extends Authenticator {
/** /**
* Method that creates the login form for this authentication method * Method that creates the login form for this authentication method
* *
* @param Controller The parent controller, necessary to create the * @param Controller $controller The parent controller, necessary to create the
* appropriate form action tag * appropriate form action tag
* @return Form Returns the login form to use with this authentication * @return Form Returns the login form to use with this authentication
* method * method
*/ */
public static function get_login_form(Controller $controller) { public static function get_login_form(Controller $controller) {
/** @skipUpgrade */
return MemberLoginForm::create($controller, "LoginForm"); return MemberLoginForm::create($controller, "LoginForm");
} }
public static function get_cms_login_form(\Controller $controller) { public static function get_cms_login_form(\Controller $controller) {
/** @skipUpgrade */
return CMSMemberLoginForm::create($controller, "LoginForm"); return CMSMemberLoginForm::create($controller, "LoginForm");
} }

View File

@ -1,6 +1,12 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use CsvBulkLoader;
use Convert;
/** /**
* Imports member records, and checks/updates duplicates based on their * Imports member records, and checks/updates duplicates based on their
* 'Email' property. * 'Email' property.
@ -17,7 +23,7 @@ class MemberCsvBulkLoader extends CsvBulkLoader {
protected $groups = array(); protected $groups = array();
public function __construct($objectClass = null) { public function __construct($objectClass = null) {
if(!$objectClass) $objectClass = 'Member'; if(!$objectClass) $objectClass = 'SilverStripe\\Security\\Member';
parent::__construct($objectClass); parent::__construct($objectClass);
} }
@ -64,14 +70,14 @@ class MemberCsvBulkLoader extends CsvBulkLoader {
} }
/** /**
* @param Array $groups * @param array $groups
*/ */
public function setGroups($groups) { public function setGroups($groups) {
$this->groups = $groups; $this->groups = $groups;
} }
/** /**
* @return Array * @return array
*/ */
public function getGroups() { public function getGroups() {
return $this->groups; return $this->groups;

View File

@ -1,4 +1,24 @@
<?php <?php
namespace SilverStripe\Security;
use Director;
use Requirements;
use Session;
use FieldList;
use HiddenField;
use FormAction;
use SS_HTTPResponse;
use TextField;
use PasswordField;
use CheckboxField;
use Config;
use LiteralField;
use RequiredFields;
use Controller;
use Convert;
use Email;
/** /**
* Log-in form for the "member" authentication method. * Log-in form for the "member" authentication method.
* *
@ -20,7 +40,7 @@ class MemberLoginForm extends LoginForm {
*/ */
public $loggedInAsField = 'FirstName'; public $loggedInAsField = 'FirstName';
protected $authenticator_class = 'MemberAuthenticator'; protected $authenticator_class = 'SilverStripe\\Security\\MemberAuthenticator';
/** /**
* Since the logout and dologin actions may be conditionally removed, it's necessary to ensure these * Since the logout and dologin actions may be conditionally removed, it's necessary to ensure these
@ -38,7 +58,7 @@ class MemberLoginForm extends LoginForm {
* create the appropriate form action tag. * create the appropriate form action tag.
* @param string $name The method on the controller that will return this * @param string $name The method on the controller that will return this
* form object. * form object.
* @param FieldList|FormField $fields All of the fields in the form - a * @param FieldList $fields All of the fields in the form - a
* {@link FieldList} of {@link FormField} * {@link FieldList} of {@link FormField}
* objects. * objects.
* @param FieldList|FormAction $actions All of the action buttons in the * @param FieldList|FormAction $actions All of the action buttons in the
@ -47,7 +67,6 @@ class MemberLoginForm extends LoginForm {
* @param bool $checkCurrentUser If set to TRUE, it will be checked if a * @param bool $checkCurrentUser If set to TRUE, it will be checked if a
* the user is currently logged in, and if * the user is currently logged in, and if
* so, only a logout button will be rendered * so, only a logout button will be rendered
* @param string $authenticatorClassName Name of the authenticator class that this form uses.
*/ */
public function __construct($controller, $name, $fields = null, $actions = null, public function __construct($controller, $name, $fields = null, $actions = null,
$checkCurrentUser = true) { $checkCurrentUser = true) {
@ -75,7 +94,7 @@ class MemberLoginForm extends LoginForm {
); );
} else { } else {
if(!$fields) { if(!$fields) {
$label=singleton('Member')->fieldLabel(Member::config()->unique_identifier_field); $label=singleton('SilverStripe\\Security\\Member')->fieldLabel(Member::config()->unique_identifier_field);
$fields = FieldList::create( $fields = FieldList::create(
HiddenField::create("AuthenticationMethod", null, $this->authenticator_class, $this), HiddenField::create("AuthenticationMethod", null, $this->authenticator_class, $this),
// Regardless of what the unique identifer field is (usually 'Email'), it will be held in the // Regardless of what the unique identifer field is (usually 'Email'), it will be held in the
@ -99,7 +118,7 @@ class MemberLoginForm extends LoginForm {
'title', 'title',
sprintf( sprintf(
_t('Member.REMEMBERME', "Remember me next time? (for %d days on this device)"), _t('Member.REMEMBERME', "Remember me next time? (for %d days on this device)"),
Config::inst()->get('RememberLoginHash', 'token_expiry_days') Config::inst()->get('SilverStripe\\Security\\RememberLoginHash', 'token_expiry_days')
) )
) )
); );
@ -212,7 +231,7 @@ JS;
if(isset($_REQUEST['BackURL']) && $backURL = $_REQUEST['BackURL']) { if(isset($_REQUEST['BackURL']) && $backURL = $_REQUEST['BackURL']) {
Session::set('BackURL', $backURL); Session::set('BackURL', $backURL);
} }
$cp = ChangePasswordForm::create($this->controller, 'ChangePasswordForm'); $cp = ChangePasswordForm::create($this->controller, 'SilverStripe\\Security\\ChangePasswordForm');
$cp->sessionMessage( $cp->sessionMessage(
_t('Member.PASSWORDEXPIRED', 'Your password has expired. Please choose a new one.'), _t('Member.PASSWORDEXPIRED', 'Your password has expired. Please choose a new one.'),
'good' 'good'
@ -275,7 +294,7 @@ JS;
/** /**
* Try to authenticate the user * Try to authenticate the user
* *
* @param array Submitted data * @param array $data Submitted data
* @return Member Returns the member object on successful authentication * @return Member Returns the member object on successful authentication
* or NULL on failure. * or NULL on failure.
*/ */
@ -300,6 +319,7 @@ JS;
* in the form detailing why the action was denied. * in the form detailing why the action was denied.
* *
* @param array $data Submitted data * @param array $data Submitted data
* @return SS_HTTPResponse
*/ */
public function forgotPassword($data) { public function forgotPassword($data) {
// Ensure password is given // Ensure password is given

View File

@ -1,6 +1,11 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
/** /**
* Keep track of users' previous passwords, so that we can check that new passwords aren't changed back to old ones. * Keep track of users' previous passwords, so that we can check that new passwords aren't changed back to old ones.
* @package framework * @package framework
@ -22,18 +27,16 @@ class MemberPassword extends DataObject {
); );
private static $has_one = array( private static $has_one = array(
'Member' => 'Member' 'Member' => 'SilverStripe\\Security\\Member'
); );
private static $has_many = array(); private static $table_name = "MemberPassword";
private static $many_many = array();
private static $belongs_many_many = array();
/** /**
* Log a password change from the given member. * Log a password change from the given member.
* Call MemberPassword::log($this) from within Member whenever the password is changed. * Call MemberPassword::log($this) from within Member whenever the password is changed.
*
* @param Member $member
*/ */
public static function log($member) { public static function log($member) {
$record = new MemberPassword(); $record = new MemberPassword();

View File

@ -1,6 +1,13 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use Config;
use ReflectionClass;
use Exception;
/** /**
* Allows pluggable password encryption. * Allows pluggable password encryption.
* By default, this might be PHP's integrated sha1() * By default, this might be PHP's integrated sha1()
@ -22,10 +29,10 @@ abstract class PasswordEncryptor {
private static $encryptors = array(); private static $encryptors = array();
/** /**
* @return Array Map of encryptor code to the used class. * @return array Map of encryptor code to the used class.
*/ */
public static function get_encryptors() { public static function get_encryptors() {
return Config::inst()->get('PasswordEncryptor', 'encryptors'); return Config::inst()->get('SilverStripe\\Security\\PasswordEncryptor', 'encryptors');
} }
/** /**
@ -73,9 +80,9 @@ abstract class PasswordEncryptor {
* *
* @uses RandomGenerator * @uses RandomGenerator
* *
* @param String $password Cleartext password * @param string $password Cleartext password
* @param Member $member (Optional) * @param Member $member (Optional)
* @return String Maximum of 50 characters * @return string Maximum of 50 characters
*/ */
public function salt($password, $member = null) { public function salt($password, $member = null) {
$generator = new RandomGenerator(); $generator = new RandomGenerator();
@ -87,6 +94,12 @@ abstract class PasswordEncryptor {
* but is necessary for retain compatibility with password hashed * but is necessary for retain compatibility with password hashed
* with flawed algorithms - see {@link PasswordEncryptor_LegacyPHPHash} and * with flawed algorithms - see {@link PasswordEncryptor_LegacyPHPHash} and
* {@link PasswordEncryptor_Blowfish} * {@link PasswordEncryptor_Blowfish}
*
* @param string $hash
* @param string $password
* @param string $salt
* @param Member $member
* @return bool
*/ */
public function check($hash, $password, $salt = null, $member = null) { public function check($hash, $password, $salt = null, $member = null) {
return $hash === $this->encrypt($password, $salt, $member); return $hash === $this->encrypt($password, $salt, $member);
@ -129,8 +142,7 @@ class PasswordEncryptor_Blowfish extends PasswordEncryptor {
/** /**
* Gets the cost that is set for the blowfish algorithm * Gets the cost that is set for the blowfish algorithm
* *
* @param int $cost * @return int
* @return null
*/ */
public static function get_cost() { public static function get_cost() {
return self::$cost; return self::$cost;
@ -242,6 +254,10 @@ class PasswordEncryptor_Blowfish extends PasswordEncryptor {
/** /**
* self::$cost param is forced to be two digits with leading zeroes for ints 4-9 * self::$cost param is forced to be two digits with leading zeroes for ints 4-9
*
* @param string $password
* @param Member $member
* @return string
*/ */
public function salt($password, $member = null) { public function salt($password, $member = null) {
$generator = new RandomGenerator(); $generator = new RandomGenerator();
@ -274,7 +290,8 @@ class PasswordEncryptor_PHPHash extends PasswordEncryptor {
protected $algorithm = 'sha1'; protected $algorithm = 'sha1';
/** /**
* @param String $algorithm A PHP built-in hashing algorithm as defined by hash_algos() * @param string $algorithm A PHP built-in hashing algorithm as defined by hash_algos()
* @throws Exception
*/ */
public function __construct($algorithm) { public function __construct($algorithm) {
if(!in_array($algorithm, hash_algos())) { if(!in_array($algorithm, hash_algos())) {

View File

@ -1,6 +1,11 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\ValidationResult; use SilverStripe\ORM\ValidationResult;
use Object;
/** /**
* This class represents a validator for member passwords. * This class represents a validator for member passwords.

View File

@ -1,8 +1,16 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\SS_List;
use TemplateGlobalProvider;
use ClassInfo;
use TestOnly;
/** /**
* Represents a permission assigned to a group. * Represents a permission assigned to a group.
* @package framework * @package framework
@ -25,20 +33,20 @@ class Permission extends DataObject implements TemplateGlobalProvider {
"Arg" => "Int", "Arg" => "Int",
"Type" => "Int(1)" "Type" => "Int(1)"
); );
private static $has_one = array( private static $has_one = array(
"Group" => "Group" "Group" => "SilverStripe\\Security\\Group"
); );
private static $indexes = array( private static $indexes = array(
"Code" => true "Code" => true
); );
private static $defaults = array( private static $defaults = array(
"Type" => 1 "Type" => 1
); );
private static $has_many = array();
private static $many_many = array(); private static $table_name = "Permission";
private static $belongs_many_many = array();
/** /**
* This is the value to use for the "Type" field if a permission should be * This is the value to use for the "Type" field if a permission should be
@ -63,7 +71,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
* Method to globally disable "strict" checking, which means a permission * Method to globally disable "strict" checking, which means a permission
* will be granted if the key does not exist at all. * will be granted if the key does not exist at all.
* *
* @var bool * @var array
*/ */
private static $declared_permissions = null; private static $declared_permissions = null;
@ -172,10 +180,14 @@ class Permission extends DataObject implements TemplateGlobalProvider {
} }
// Turn the code into an array as we may need to add other permsissions to the set we check // Turn the code into an array as we may need to add other permsissions to the set we check
if(!is_array($code)) $code = array($code); if(!is_array($code)) {
$code = array($code);
}
// Check if admin should be treated as holding all permissions
$adminImpliesAll = (bool)static::config()->admin_implies_all;
if($arg == 'any') { if($arg == 'any') {
$adminImpliesAll = (bool)Config::inst()->get('Permission', 'admin_implies_all');
// Cache the permissions in memory // Cache the permissions in memory
if(!isset(self::$cache_permissions[$memberID])) { if(!isset(self::$cache_permissions[$memberID])) {
self::$cache_permissions[$memberID] = self::permissions_for_member($memberID); self::$cache_permissions[$memberID] = self::permissions_for_member($memberID);
@ -208,8 +220,8 @@ class Permission extends DataObject implements TemplateGlobalProvider {
// Code filters // Code filters
$codeParams = is_array($code) ? $code : array($code); $codeParams = is_array($code) ? $code : array($code);
$codeClause = DB::placeholders($codeParams); $codeClause = DB::placeholders($codeParams);
$adminParams = (self::$admin_implies_all) ? array('ADMIN') : array(); $adminParams = $adminImpliesAll ? array('ADMIN') : array();
$adminClause = (self::$admin_implies_all) ? ", ?" : ''; $adminClause = $adminImpliesAll ? ", ?" : '';
// The following code should only be used if you're not using the "any" arg. This is kind // The following code should only be used if you're not using the "any" arg. This is kind
// of obselete functionality and could possibly be deprecated. // of obselete functionality and could possibly be deprecated.
@ -235,7 +247,6 @@ class Permission extends DataObject implements TemplateGlobalProvider {
user_error("Permission::checkMember: bad arg '$arg'", E_USER_ERROR); user_error("Permission::checkMember: bad arg '$arg'", E_USER_ERROR);
} }
} }
$adminFilter = (Config::inst()->get('Permission', 'admin_implies_all')) ? ",'ADMIN'" : '';
// Raw SQL for efficiency // Raw SQL for efficiency
$permission = DB::prepared_query( $permission = DB::prepared_query(
@ -259,7 +270,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
if($permission) return $permission; if($permission) return $permission;
// Strict checking disabled? // Strict checking disabled?
if(!Config::inst()->get('Permission', 'strict_checking') || !$strict) { if(!static::config()->strict_checking || !$strict) {
$hasPermission = DB::prepared_query( $hasPermission = DB::prepared_query(
"SELECT COUNT(*) "SELECT COUNT(*)
FROM \"Permission\" FROM \"Permission\"
@ -270,7 +281,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
array_merge($codeParams, array(self::GRANT_PERMISSION)) array_merge($codeParams, array(self::GRANT_PERMISSION))
)->value(); )->value();
if(!$hasPermission) return; if(!$hasPermission) return false;
} }
return false; return false;
@ -279,6 +290,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
/** /**
* Get all the 'any' permission codes available to the given member. * Get all the 'any' permission codes available to the given member.
* *
* @param int $memberID
* @return array * @return array
*/ */
public static function permissions_for_member($memberID) { public static function permissions_for_member($memberID) {
@ -332,7 +344,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
if($member && isset($_SESSION['Permission_groupList'][$member->ID])) if($member && isset($_SESSION['Permission_groupList'][$member->ID]))
return $_SESSION['Permission_groupList'][$member->ID]; return $_SESSION['Permission_groupList'][$member->ID];
} else { } else {
$member = DataObject::get_by_id("Member", $memberID); $member = DataObject::get_by_id("SilverStripe\\Security\\Member", $memberID);
} }
if($member) { if($member) {
@ -364,7 +376,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
* *
* @param int $groupID The ID of the group * @param int $groupID The ID of the group
* @param string $code The permission code * @param string $code The permission code
* @param string Optional: The permission argument (e.g. a page ID). * @param string $arg Optional: The permission argument (e.g. a page ID).
* @returns Permission Returns the new permission object. * @returns Permission Returns the new permission object.
*/ */
public static function grant($groupID, $code, $arg = "any") { public static function grant($groupID, $code, $arg = "any") {
@ -379,6 +391,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
break; break;
case "all": case "all":
$perm->Arg = -1; $perm->Arg = -1;
break;
default: default:
if(is_numeric($arg)) { if(is_numeric($arg)) {
$perm->Arg = $arg; $perm->Arg = $arg;
@ -398,7 +411,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
* *
* @param int $groupID The ID of the group * @param int $groupID The ID of the group
* @param string $code The permission code * @param string $code The permission code
* @param string Optional: The permission argument (e.g. a page ID). * @param string $arg Optional: The permission argument (e.g. a page ID).
* @returns Permission Returns the new permission object. * @returns Permission Returns the new permission object.
*/ */
public static function deny($groupID, $code, $arg = "any") { public static function deny($groupID, $code, $arg = "any") {
@ -413,6 +426,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
break; break;
case "all": case "all":
$perm->Arg = -1; $perm->Arg = -1;
break;
default: default:
if(is_numeric($arg)) { if(is_numeric($arg)) {
$perm->Arg = $arg; $perm->Arg = $arg;
@ -448,6 +462,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
if(empty($groupIDs)) return new ArrayList(); if(empty($groupIDs)) return new ArrayList();
$groupClause = DB::placeholders($groupIDs); $groupClause = DB::placeholders($groupIDs);
/** @skipUpgrade */
$members = Member::get() $members = Member::get()
->where(array("\"Group\".\"ID\" IN ($groupClause)" => $groupIDs)) ->where(array("\"Group\".\"ID\" IN ($groupClause)" => $groupIDs))
->leftJoin("Group_Members", '"Member"."ID" = "Group_Members"."MemberID"') ->leftJoin("Group_Members", '"Member"."ID" = "Group_Members"."MemberID"')
@ -458,7 +473,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
/** /**
* Return all of the groups that have one of the given permission codes * Return all of the groups that have one of the given permission codes
* @param $codes array|string Either a single permission code, or an array of permission codes * @param array|string $codes Either a single permission code, or an array of permission codes
* @return SS_List The matching group objects * @return SS_List The matching group objects
*/ */
public static function get_groups_by_permission($codes) { public static function get_groups_by_permission($codes) {
@ -466,7 +481,8 @@ class Permission extends DataObject implements TemplateGlobalProvider {
$codeClause = DB::placeholders($codeParams); $codeClause = DB::placeholders($codeParams);
// Via Roles are groups that have the permission via a role // Via Roles are groups that have the permission via a role
return DataObject::get('Group') /** @skipUpgrade */
return Group::get()
->where(array( ->where(array(
"\"PermissionRoleCode\".\"Code\" IN ($codeClause) OR \"Permission\".\"Code\" IN ($codeClause)" "\"PermissionRoleCode\".\"Code\" IN ($codeClause) OR \"Permission\".\"Code\" IN ($codeClause)"
=> array_merge($codeParams, $codeParams) => array_merge($codeParams, $codeParams)
@ -491,7 +507,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
* suitable for using in an interface. * suitable for using in an interface.
*/ */
public static function get_codes($grouped = true) { public static function get_codes($grouped = true) {
$classes = ClassInfo::implementorsOf('PermissionProvider'); $classes = ClassInfo::implementorsOf('SilverStripe\\Security\\PermissionProvider');
$allCodes = array(); $allCodes = array();
$adminCategory = _t('Permission.AdminGroup', 'Administrator'); $adminCategory = _t('Permission.AdminGroup', 'Administrator');
@ -571,6 +587,9 @@ class Permission extends DataObject implements TemplateGlobalProvider {
/** /**
* Sort permissions based on their sort value, or name * Sort permissions based on their sort value, or name
* *
* @param array $a
* @param array $b
* @return int
*/ */
public static function sort_permissions($a, $b) { public static function sort_permissions($a, $b) {
if ($a['sort'] == $b['sort']) { if ($a['sort'] == $b['sort']) {
@ -582,48 +601,6 @@ class Permission extends DataObject implements TemplateGlobalProvider {
} }
} }
/**
* add a permission represented by the $code to the {@link slef::$hidden_permissions} list
*
* @deprecated 4.0 Use "Permission.hidden_permissions" config setting instead
* @param $code string - the permissions code
* @return void
*/
public static function add_to_hidden_permissions($code){
if(is_string($codes)) $codes = array($codes);
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
Config::inst()->update('Permission', 'hidden_permissions', $codes);
}
/**
* remove a permission represented by the $code from the {@link slef::$hidden_permissions} list
*
* @deprecated 4.0 Use "Permission.hidden_permissions" config setting instead
* @param $code string - the permissions code
* @return void
*/
public static function remove_from_hidden_permissions($code){
if(is_string($codes)) $codes = array($codes);
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
Config::inst()->remove('Permission', 'hidden_permissions', $codes);
}
/**
* Declare an array of permissions for the system.
*
* Permissions can be grouped by nesting arrays. Scalar values are always
* treated as permissions.
*
* @deprecated 4.0 Use "Permission.declared_permissions" config setting instead
* @param array $permArray A (possibly nested) array of permissions to
* declare for the system.
*/
public static function declare_permissions($permArray) {
Deprecation::notice('4.0', 'Use "Permission.declared_permissions" config setting instead');
self::config()->declared_permissions = $permArray;
}
/** /**
* Get a linear list of the permissions in the system. * Get a linear list of the permissions in the system.
* *
@ -638,8 +615,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
self::$declared_permissions_list = array(); self::$declared_permissions_list = array();
self::traverse_declared_permissions(self::$declared_permissions, self::traverse_declared_permissions(self::$declared_permissions, self::$declared_permissions_list);
self::$declared_permissions_list);
return self::$declared_permissions_list; return self::$declared_permissions_list;
} }
@ -647,8 +623,8 @@ class Permission extends DataObject implements TemplateGlobalProvider {
/** /**
* Look up the human-readable title for the permission as defined by <code>Permission::declare_permissions</code> * Look up the human-readable title for the permission as defined by <code>Permission::declare_permissions</code>
* *
* @param $perm Permission code * @param string $perm Permission code
* @return Label for the given permission, or the permission itself if the label doesn't exist * @return string Label for the given permission, or the permission itself if the label doesn't exist
*/ */
public static function get_label_for_permission($perm) { public static function get_label_for_permission($perm) {
$list = self::get_declared_permissions_list(); $list = self::get_declared_permissions_list();
@ -660,8 +636,8 @@ class Permission extends DataObject implements TemplateGlobalProvider {
* Recursively traverse the nested list of declared permissions and create * Recursively traverse the nested list of declared permissions and create
* a linear list. * a linear list.
* *
* @param aeeay $declared Nested structure of permissions. * @param array $declared Nested structure of permissions.
* @param $list List of permissions in the structure. The result will be * @param array $list List of permissions in the structure. The result will be
* written to this array. * written to this array.
*/ */
protected static function traverse_declared_permissions($declared, &$list) { protected static function traverse_declared_permissions($declared, &$list) {

View File

@ -1,10 +1,19 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\ORM\SS_List; use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\DataObjectInterface;
use FormField;
use InvalidArgumentException;
use Requirements;
use Config;
/** /**
@ -21,7 +30,7 @@ use SilverStripe\ORM\DataObjectInterface;
class PermissionCheckboxSetField extends FormField { class PermissionCheckboxSetField extends FormField {
/** /**
* @var Array Filter certain permission codes from the output. * @var array Filter certain permission codes from the output.
* Useful to simplify the interface * Useful to simplify the interface
*/ */
protected $hiddenPermissions = array(); protected $hiddenPermissions = array();
@ -66,14 +75,14 @@ class PermissionCheckboxSetField extends FormField {
} }
/** /**
* @param Array $codes * @param array $codes
*/ */
public function setHiddenPermissions($codes) { public function setHiddenPermissions($codes) {
$this->hiddenPermissions = $codes; $this->hiddenPermissions = $codes;
} }
/** /**
* @return Array * @return array
*/ */
public function getHiddenPermissions() { public function getHiddenPermissions() {
return $this->hiddenPermissions; return $this->hiddenPermissions;
@ -81,7 +90,7 @@ class PermissionCheckboxSetField extends FormField {
/** /**
* @param array $properties * @param array $properties
* @return HTMLText * @return DBHTMLText
*/ */
public function Field($properties = array()) { public function Field($properties = array()) {
Requirements::css(FRAMEWORK_DIR . '/client/dist/styles/CheckboxSetField.css'); Requirements::css(FRAMEWORK_DIR . '/client/dist/styles/CheckboxSetField.css');
@ -96,7 +105,7 @@ class PermissionCheckboxSetField extends FormField {
$record = $this->form->getRecord(); $record = $this->form->getRecord();
if( if(
$record $record
&& (is_a($record, 'Group') || is_a($record, 'PermissionRole')) && ($record instanceof Group || $record instanceof PermissionRole)
&& !$records->find('ID', $record->ID) && !$records->find('ID', $record->ID)
) { ) {
$records->push($record); $records->push($record);
@ -117,7 +126,7 @@ class PermissionCheckboxSetField extends FormField {
// Special case for Group records (not PermissionRole): // Special case for Group records (not PermissionRole):
// Determine inherited assignments // Determine inherited assignments
if(is_a($record, 'Group')) { if(is_a($record, 'SilverStripe\\Security\\Group')) {
// Get all permissions from roles // Get all permissions from roles
if ($record->Roles()->Count()) { if ($record->Roles()->Count()) {
foreach($record->Roles() as $role) { foreach($record->Roles() as $role) {
@ -172,7 +181,7 @@ class PermissionCheckboxSetField extends FormField {
$odd = 0; $odd = 0;
$options = ''; $options = '';
$globalHidden = (array)Config::inst()->get('Permission', 'hidden_permissions'); $globalHidden = (array)Config::inst()->get('SilverStripe\\Security\\Permission', 'hidden_permissions');
if($this->source) { if($this->source) {
$privilegedPermissions = Permission::config()->privileged_permissions; $privilegedPermissions = Permission::config()->privileged_permissions;
@ -188,7 +197,7 @@ class PermissionCheckboxSetField extends FormField {
$odd = ($odd + 1) % 2; $odd = ($odd + 1) % 2;
$extraClass = $odd ? 'odd' : 'even'; $extraClass = $odd ? 'odd' : 'even';
$extraClass .= ' val' . str_replace(' ', '', $code); $extraClass .= ' val' . str_replace(' ', '', $code);
$itemID = $this->id() . '_' . preg_replace('/[^a-zA-Z0-9]+/', '', $code); $itemID = $this->ID() . '_' . preg_replace('/[^a-zA-Z0-9]+/', '', $code);
$checked = $disabled = $inheritMessage = ''; $checked = $disabled = $inheritMessage = '';
$checked = (isset($uninheritedCodes[$code]) || isset($inheritedCodes[$code])) $checked = (isset($uninheritedCodes[$code]) || isset($inheritedCodes[$code]))
? ' checked="checked"' ? ' checked="checked"'
@ -240,7 +249,7 @@ class PermissionCheckboxSetField extends FormField {
} }
if($this->readonly) { if($this->readonly) {
return DBField::create_field('HTMLText', return DBField::create_field('HTMLText',
"<ul id=\"{$this->id()}\" class=\"optionset checkboxsetfield{$this->extraClass()}\">\n" . "<ul id=\"{$this->ID()}\" class=\"optionset checkboxsetfield{$this->extraClass()}\">\n" .
"<li class=\"help\">" . "<li class=\"help\">" .
_t( _t(
'Permissions.UserPermissionsIntro', 'Permissions.UserPermissionsIntro',
@ -253,7 +262,7 @@ class PermissionCheckboxSetField extends FormField {
); );
} else { } else {
return DBField::create_field('HTMLText', return DBField::create_field('HTMLText',
"<ul id=\"{$this->id()}\" class=\"optionset checkboxsetfield{$this->extraClass()}\">\n" . "<ul id=\"{$this->ID()}\" class=\"optionset checkboxsetfield{$this->extraClass()}\">\n" .
$options . $options .
"</ul>\n" "</ul>\n"
); );
@ -263,7 +272,7 @@ class PermissionCheckboxSetField extends FormField {
/** /**
* Update the permission set associated with $record DataObject * Update the permission set associated with $record DataObject
* *
* @param DataObject $record * @param DataObjectInterface $record
*/ */
public function saveInto(DataObjectInterface $record) { public function saveInto(DataObjectInterface $record) {
$fieldname = $this->name; $fieldname = $this->name;

View File

@ -1,4 +1,9 @@
<?php <?php
namespace SilverStripe\Security;
use Exception;
/** /**
* Throw this exception to register that a user doesn't have permission to do the given action * Throw this exception to register that a user doesn't have permission to do the given action
* and potentially redirect them to the log-in page. The exception message may be presented to the * and potentially redirect them to the log-in page. The exception message may be presented to the

View File

@ -1,4 +1,9 @@
<?php <?php
namespace SilverStripe\Security;
/** /**
* Used to let classes provide new permission codes. * Used to let classes provide new permission codes.
* Every implementor of PermissionProvider is accessed and providePermissions() called to get the full list of * Every implementor of PermissionProvider is accessed and providePermissions() called to get the full list of

View File

@ -1,6 +1,12 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\HasManyList;
use SilverStripe\ORM\ManyManyList;
/** /**
* A PermissionRole represents a collection of permission codes that can be applied to groups. * A PermissionRole represents a collection of permission codes that can be applied to groups.
* *
@ -28,13 +34,15 @@ class PermissionRole extends DataObject {
); );
private static $has_many = array( private static $has_many = array(
"Codes" => "PermissionRoleCode", "Codes" => "SilverStripe\\Security\\PermissionRoleCode",
); );
private static $belongs_many_many = array( private static $belongs_many_many = array(
"Groups" => "Group", "Groups" => "SilverStripe\\Security\\Group",
); );
private static $table_name = "PermissionRole";
private static $default_sort = '"Title"'; private static $default_sort = '"Title"';
private static $singular_name = 'Role'; private static $singular_name = 'Role';
@ -51,13 +59,13 @@ class PermissionRole extends DataObject {
'Root.Main', 'Root.Main',
$permissionField = new PermissionCheckboxSetField( $permissionField = new PermissionCheckboxSetField(
'Codes', 'Codes',
singleton('Permission')->i18n_plural_name(), Permission::singleton()->i18n_plural_name(),
'PermissionRoleCode', 'SilverStripe\\Security\\PermissionRoleCode',
'RoleID' 'RoleID'
) )
); );
$permissionField->setHiddenPermissions( $permissionField->setHiddenPermissions(
Config::inst()->get('Permission', 'hidden_permissions') Permission::config()->hidden_permissions
); );
return $fields; return $fields;

View File

@ -1,6 +1,9 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
/** /**
* A PermissionRoleCode represents a single permission code assigned to a {@link PermissionRole}. * A PermissionRoleCode represents a single permission code assigned to a {@link PermissionRole}.
* *
@ -19,14 +22,16 @@ class PermissionRoleCode extends DataObject {
); );
private static $has_one = array( private static $has_one = array(
"Role" => "PermissionRole", "Role" => "SilverStripe\\Security\\PermissionRole",
); );
private static $table_name = "PermissionRoleCode";
public function validate() { public function validate() {
$result = parent::validate(); $result = parent::validate();
// Check that new code doesn't increase privileges, unless an admin is editing. // Check that new code doesn't increase privileges, unless an admin is editing.
$privilegedCodes = Config::inst()->get('Permission', 'privileged_permissions'); $privilegedCodes = Permission::config()->privileged_permissions;
if( if(
$this->Code $this->Code
&& in_array($this->Code, $privilegedCodes) && in_array($this->Code, $privilegedCodes)

View File

@ -1,4 +1,9 @@
<?php <?php
namespace SilverStripe\Security;
use Exception;
/** /**
* Generates entropy values based on strongest available methods * Generates entropy values based on strongest available methods
* (mcrypt_create_iv(), openssl_random_pseudo_bytes(), /dev/urandom, COM.CAPICOM.Utilities.1, mt_rand()). * (mcrypt_create_iv(), openssl_random_pseudo_bytes(), /dev/urandom, COM.CAPICOM.Utilities.1, mt_rand()).
@ -46,7 +51,7 @@ class RandomGenerator {
// try to read from the windows RNG // try to read from the windows RNG
if($isWin && class_exists('COM')) { if($isWin && class_exists('COM')) {
try { try {
$comObj = new COM('CAPICOM.Utilities.1'); $comObj = new \COM('CAPICOM.Utilities.1');
if(is_callable(array($comObj,'GetRandom'))) { if(is_callable(array($comObj,'GetRandom'))) {
return base64_decode($comObj->GetRandom(64, 0)); return base64_decode($comObj->GetRandom(64, 0));

View File

@ -1,7 +1,13 @@
<?php <?php
namespace SilverStripe\Security;
use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use DateTime;
use DateInterval;
/** /**
* Persists a token associated with a device for users who opted for the "Remember Me" * Persists a token associated with a device for users who opted for the "Remember Me"
* feature when logging in. * feature when logging in.
@ -26,7 +32,7 @@ class RememberLoginHash extends DataObject {
); );
private static $has_one = array ( private static $has_one = array (
'Member' => 'Member', 'Member' => 'SilverStripe\\Security\\Member',
); );
private static $indexes = array( private static $indexes = array(
@ -34,6 +40,8 @@ class RememberLoginHash extends DataObject {
'Hash' => true 'Hash' => true
); );
private static $table_name = "RememberLoginHash";
/** /**
* Determines if logging out on one device also clears existing login tokens * Determines if logging out on one device also clears existing login tokens
* on all other devices owned by the member. * on all other devices owned by the member.
@ -95,7 +103,7 @@ class RememberLoginHash extends DataObject {
/** /**
* Creates a new random token and hashes it using the * Creates a new random token and hashes it using the
* member information * member information
* @param Member The logged in user * @param Member $member The logged in user
* @return string The hash to be stored in the database * @return string The hash to be stored in the database
*/ */
public function getNewHash(Member $member){ public function getNewHash(Member $member){
@ -109,25 +117,27 @@ class RememberLoginHash extends DataObject {
* The device is assigned a globally unique device ID * The device is assigned a globally unique device ID
* The returned login hash stores the hashed token in the * The returned login hash stores the hashed token in the
* database, for this device and this member * database, for this device and this member
* @param Member The logged in user * @param Member $member The logged in user
* @return RememberLoginHash The generated login hash * @return RememberLoginHash The generated login hash
*/ */
public static function generate(Member $member) { public static function generate(Member $member) {
if(!$member->exists()) { return; } if(!$member->exists()) {
if (Config::inst()->get('RememberLoginHash', 'force_single_token') == true) { return null;
$rememberLoginHash = RememberLoginHash::get()->filter('MemberID', $member->ID)->removeAll(); }
if (static::config()->force_single_token) {
RememberLoginHash::get()->filter('MemberID', $member->ID)->removeAll();
} }
$rememberLoginHash = RememberLoginHash::create(); $rememberLoginHash = RememberLoginHash::create();
do { do {
$deviceID = $rememberLoginHash->getNewDeviceID(); $deviceID = $rememberLoginHash->getNewDeviceID();
} while (RememberLoginHash::get()->filter('DeviceID', $deviceID)->Count()); } while (RememberLoginHash::get()->filter('DeviceID', $deviceID)->count());
$rememberLoginHash->DeviceID = $deviceID; $rememberLoginHash->DeviceID = $deviceID;
$rememberLoginHash->Hash = $rememberLoginHash->getNewHash($member); $rememberLoginHash->Hash = $rememberLoginHash->getNewHash($member);
$rememberLoginHash->MemberID = $member->ID; $rememberLoginHash->MemberID = $member->ID;
$now = DBDatetime::now(); $now = DBDatetime::now();
$expiryDate = new DateTime($now->Rfc2822()); $expiryDate = new DateTime($now->Rfc2822());
$tokenExpiryDays = Config::inst()->get('RememberLoginHash', 'token_expiry_days'); $tokenExpiryDays = static::config()->token_expiry_days;
$expiryDate->add(new DateInterval('P'.$tokenExpiryDays.'D')); $expiryDate->add(new DateInterval('P'.$tokenExpiryDays.'D'));
$rememberLoginHash->ExpiryDate = $expiryDate->format('Y-m-d H:i:s'); $rememberLoginHash->ExpiryDate = $expiryDate->format('Y-m-d H:i:s');
$rememberLoginHash->extend('onAfterGenerateToken'); $rememberLoginHash->extend('onAfterGenerateToken');
@ -137,7 +147,7 @@ class RememberLoginHash extends DataObject {
/** /**
* Generates a new hash for this member but keeps the device ID intact * Generates a new hash for this member but keeps the device ID intact
* @param Member the logged in user *
* @return RememberLoginHash * @return RememberLoginHash
*/ */
public function renew() { public function renew() {
@ -152,11 +162,14 @@ class RememberLoginHash extends DataObject {
* Deletes existing tokens for this member * Deletes existing tokens for this member
* if logout_across_devices is true, all tokens are deleted, otherwise * if logout_across_devices is true, all tokens are deleted, otherwise
* only the token for the provided device ID will be removed * only the token for the provided device ID will be removed
*
* @param Member $member
* @param string $alcDevice
*/ */
public static function clear(Member $member, $alcDevice = null) { public static function clear(Member $member, $alcDevice = null) {
if(!$member->exists()) { return; } if(!$member->exists()) { return; }
$filter = array('MemberID'=>$member->ID); $filter = array('MemberID'=>$member->ID);
if ((Config::inst()->get('RememberLoginHash', 'logout_across_devices') == false) && $alcDevice) { if (!static::config()->logout_across_devices && $alcDevice) {
$filter['DeviceID'] = $alcDevice; $filter['DeviceID'] = $alcDevice;
} }
RememberLoginHash::get() RememberLoginHash::get()

View File

@ -1,8 +1,30 @@
<?php <?php
namespace SilverStripe\Security;
use Form;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use Controller;
use SS_HTTPRequest;
use TemplateGlobalProvider;
use Deprecation;
use Director;
use SS_HTTPResponse;
use Session;
use Config;
use Exception;
use Page;
use Page_Controller;
use ArrayData;
use FieldList;
use EmailField;
use FormAction;
use Convert;
use Object;
use ClassInfo;
/** /**
* Implements a basic security model * Implements a basic security model
* @package framework * @package framework
@ -303,7 +325,7 @@ class Security extends Controller implements TemplateGlobalProvider {
$controller->extend('permissionDenied', $member); $controller->extend('permissionDenied', $member);
return $controller->redirect( return $controller->redirect(
Config::inst()->get('Security', 'login_url') Config::inst()->get('SilverStripe\\Security\\Security', 'login_url')
. "?BackURL=" . urlencode($_SERVER['REQUEST_URI']) . "?BackURL=" . urlencode($_SERVER['REQUEST_URI'])
); );
} }
@ -341,6 +363,7 @@ class Security extends Controller implements TemplateGlobalProvider {
* Get the login form to process according to the submitted data * Get the login form to process according to the submitted data
* *
* @return Form * @return Form
* @throws Exception
*/ */
public function LoginForm() { public function LoginForm() {
$authenticator = $this->getAuthenticator(); $authenticator = $this->getAuthenticator();
@ -375,6 +398,7 @@ class Security extends Controller implements TemplateGlobalProvider {
* @return string Returns the link to the given action * @return string Returns the link to the given action
*/ */
public function Link($action = null) { public function Link($action = null) {
/** @skipUpgrade */
return Controller::join_links(Director::baseURL(), "Security", $action); return Controller::join_links(Director::baseURL(), "Security", $action);
} }
@ -448,6 +472,7 @@ class Security extends Controller implements TemplateGlobalProvider {
// Use sitetree pages to render the security page // Use sitetree pages to render the security page
$tmpPage = new Page(); $tmpPage = new Page();
$tmpPage->Title = $title; $tmpPage->Title = $title;
/** @skipUpgrade */
$tmpPage->URLSegment = "Security"; $tmpPage->URLSegment = "Security";
// Disable ID-based caching of the log-in page by making it a random number // Disable ID-based caching of the log-in page by making it a random number
$tmpPage->ID = -1 * rand(1,10000000); $tmpPage->ID = -1 * rand(1,10000000);
@ -465,6 +490,7 @@ class Security extends Controller implements TemplateGlobalProvider {
* @return array Template list * @return array Template list
*/ */
public function getTemplatesFor($action) { public function getTemplatesFor($action) {
/** @skipUpgrade */
return array("Security_{$action}", 'Security', $this->stat('template_main'), 'BlankPage'); return array("Security_{$action}", 'Security', $this->stat('template_main'), 'BlankPage');
} }
@ -558,7 +584,7 @@ class Security extends Controller implements TemplateGlobalProvider {
public function basicauthlogin() { public function basicauthlogin() {
$member = BasicAuth::requireLogin("SilverStripe login", 'ADMIN'); $member = BasicAuth::requireLogin("SilverStripe login", 'ADMIN');
$member->LogIn(); $member->logIn();
} }
/** /**
@ -652,7 +678,8 @@ class Security extends Controller implements TemplateGlobalProvider {
* - t: plaintext token * - t: plaintext token
* *
* @param Member $member Member object associated with this link. * @param Member $member Member object associated with this link.
* @param string $autoLoginHash The auto login token. * @param string $autologinToken The auto login token.
* @return string
*/ */
public static function getPasswordResetLink($member, $autologinToken) { public static function getPasswordResetLink($member, $autologinToken) {
$autologinToken = urldecode($autologinToken); $autologinToken = urldecode($autologinToken);
@ -682,7 +709,7 @@ class Security extends Controller implements TemplateGlobalProvider {
// Extract the member from the URL. // Extract the member from the URL.
$member = null; $member = null;
if (isset($_REQUEST['m'])) { if (isset($_REQUEST['m'])) {
$member = Member::get()->filter('ID', (int)$_REQUEST['m'])->First(); $member = Member::get()->filter('ID', (int)$_REQUEST['m'])->first();
} }
// Check whether we are merely changin password, or resetting. // Check whether we are merely changin password, or resetting.
@ -743,17 +770,23 @@ class Security extends Controller implements TemplateGlobalProvider {
/** /**
* Factory method for the lost password form * Factory method for the lost password form
* *
* @return Form Returns the lost password form * @return ChangePasswordForm Returns the lost password form
*/ */
public function ChangePasswordForm() { public function ChangePasswordForm() {
return Object::create('ChangePasswordForm', $this, 'ChangePasswordForm'); /** @skipUpgrade */
$formName = 'ChangePasswordForm';
return \Injector::inst()->createWithArgs(
'SilverStripe\\Security\\ChangePasswordForm',
[ $this, $formName]
);
} }
/** /**
* Gets the template for an include used for security. * Gets the template for an include used for security.
* For use in any subclass. * For use in any subclass.
* *
* @return string|array Returns the template(s) for rendering * @param string $name
* @return array Returns the template(s) for rendering
*/ */
public function getIncludeTemplate($name) { public function getIncludeTemplate($name) {
return array('Security_' . $name); return array('Security_' . $name);
@ -776,17 +809,17 @@ class Security extends Controller implements TemplateGlobalProvider {
// coupling to subsites module // coupling to subsites module
$origSubsite = null; $origSubsite = null;
if(is_callable('Subsite::changeSubsite')) { if(is_callable('Subsite::changeSubsite')) {
$origSubsite = Subsite::currentSubsiteID(); $origSubsite = \Subsite::currentSubsiteID();
Subsite::changeSubsite(0); \Subsite::changeSubsite(0);
} }
$member = null; $member = null;
// find a group with ADMIN permission // find a group with ADMIN permission
$adminGroup = Permission::get_groups_by_permission('ADMIN')->First(); $adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
if(is_callable('Subsite::changeSubsite')) { if(is_callable('Subsite::changeSubsite')) {
Subsite::changeSubsite($origSubsite); \Subsite::changeSubsite($origSubsite);
} }
if ($adminGroup) { if ($adminGroup) {
@ -794,13 +827,13 @@ class Security extends Controller implements TemplateGlobalProvider {
} }
if(!$adminGroup) { if(!$adminGroup) {
singleton('Group')->requireDefaultRecords(); Group::singleton()->requireDefaultRecords();
$adminGroup = Permission::get_groups_by_permission('ADMIN')->First(); $adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
} }
if(!$member) { if(!$member) {
singleton('Member')->requireDefaultRecords(); Member::singleton()->requireDefaultRecords();
$member = Permission::get_members_by_permission('ADMIN')->First(); $member = Permission::get_members_by_permission('ADMIN')->first();
} }
if(!$member) { if(!$member) {
@ -841,6 +874,7 @@ class Security extends Controller implements TemplateGlobalProvider {
* *
* @param string $username The user name * @param string $username The user name
* @param string $password The password (in cleartext) * @param string $password The password (in cleartext)
* @return bool
*/ */
public static function setDefaultAdmin($username, $password) { public static function setDefaultAdmin($username, $password) {
// don't overwrite if already set // don't overwrite if already set
@ -1004,9 +1038,9 @@ class Security extends Controller implements TemplateGlobalProvider {
return self::$database_is_ready; return self::$database_is_ready;
} }
$requiredClasses = ClassInfo::dataClassesFor('Member'); $requiredClasses = ClassInfo::dataClassesFor('SilverStripe\\Security\\Member');
$requiredClasses[] = 'Group'; $requiredClasses[] = 'SilverStripe\\Security\\Group';
$requiredClasses[] = 'Permission'; $requiredClasses[] = 'SilverStripe\\Security\\Permission';
foreach($requiredClasses as $class) { foreach($requiredClasses as $class) {
// Skip test classes, as not all test classes are scaffolded at once // Skip test classes, as not all test classes are scaffolded at once

View File

@ -1,4 +1,15 @@
<?php <?php
namespace SilverStripe\Security;
use FieldList;
use Object;
use SS_HTTPRequest;
use TemplateGlobalProvider;
use Session;
use HiddenField;
use Controller;
/** /**
* @package framework * @package framework
* @subpackage security * @subpackage security
@ -110,7 +121,8 @@ class SecurityToken extends Object implements TemplateGlobalProvider {
} }
/** /**
* @return String * @param string $name
* @return string
*/ */
public function setName($name) { public function setName($name) {
$val = $this->getValue(); $val = $this->getValue();

View File

@ -1,17 +1,17 @@
--- ---
name: coreencryptors name: coreencryptors
--- ---
PasswordEncryptor: 'SilverStripe\Security\PasswordEncryptor':
encryptors: encryptors:
none: none:
PasswordEncryptor_None: 'SilverStripe\Security\PasswordEncryptor_None':
md5: md5:
PasswordEncryptor_LegacyPHPHash: md5 'SilverStripe\Security\PasswordEncryptor_LegacyPHPHash': md5
sha1: sha1:
PasswordEncryptor_LegacyPHPHash: sha1 'SilverStripe\Security\PasswordEncryptor_LegacyPHPHash': sha1
md5_v2.4: md5_v2.4:
PasswordEncryptor_PHPHash: md5 'SilverStripe\Security\PasswordEncryptor_PHPHash': md5
sha1_v2.4: sha1_v2.4:
PasswordEncryptor_PHPHash: sha1 'SilverStripe\Security\PasswordEncryptor_PHPHash': sha1
blowfish: blowfish:
PasswordEncryptor_Blowfish: 'SilverStripe\Security\PasswordEncryptor_Blowfish':

View File

@ -14,8 +14,8 @@ After:
--- ---
Director: Director:
rules: rules:
'Security//$Action/$ID/$OtherID': 'Security' 'Security//$Action/$ID/$OtherID': 'SilverStripe\Security\Security'
'CMSSecurity//$Action/$ID/$OtherID': 'CMSSecurity' 'CMSSecurity//$Action/$ID/$OtherID': 'SilverStripe\Security\CMSSecurity'
'dev': 'DevelopmentAdmin' 'dev': 'DevelopmentAdmin'
'interactive': 'SapphireREPL' 'interactive': 'SapphireREPL'
'InstallerTest//$Action/$ID/$OtherID': 'InstallerTest' 'InstallerTest//$Action/$ID/$OtherID': 'InstallerTest'

View File

@ -2,8 +2,11 @@
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\SecurityToken;
/** /**
* Special request handler for admin/batchaction * Special request handler for admin/batchaction
@ -28,6 +31,9 @@ class CMSBatchActionHandler extends RequestHandler {
'handleConfirmation', 'handleConfirmation',
); );
/**
* @var Controller
*/
protected $parentController; protected $parentController;
/** /**
@ -43,7 +49,7 @@ class CMSBatchActionHandler extends RequestHandler {
protected $recordClass = 'SiteTree'; protected $recordClass = 'SiteTree';
/** /**
* @param string $parentController * @param Controller $parentController
* @param string $urlSegment * @param string $urlSegment
* @param string $recordClass * @param string $recordClass
*/ */
@ -61,9 +67,10 @@ class CMSBatchActionHandler extends RequestHandler {
* Register a new batch action. Each batch action needs to be represented by a subclass * Register a new batch action. Each batch action needs to be represented by a subclass
* of {@link CMSBatchAction}. * of {@link CMSBatchAction}.
* *
* @param $urlSegment The URL Segment of the batch action - the URL used to process this * @param string $urlSegment The URL Segment of the batch action - the URL used to process this
* action will be admin/batchactions/(urlSegment) * action will be admin/batchactions/(urlSegment)
* @param $batchActionClass The name of the CMSBatchAction subclass to register * @param string $batchActionClass The name of the CMSBatchAction subclass to register
* @param string $recordClass
*/ */
public static function register($urlSegment, $batchActionClass, $recordClass = 'SiteTree') { public static function register($urlSegment, $batchActionClass, $recordClass = 'SiteTree') {
if(is_subclass_of($batchActionClass, 'CMSBatchAction')) { if(is_subclass_of($batchActionClass, 'CMSBatchAction')) {

View File

@ -1,4 +1,6 @@
<?php <?php
use SilverStripe\Security\Member;
/** /**
* The object manages the main CMS menu. See {@link LeftAndMain::init()} for * The object manages the main CMS menu. See {@link LeftAndMain::init()} for
* example usage. * example usage.
@ -53,7 +55,6 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider {
* Add a LeftAndMain controller to the CMS menu. * Add a LeftAndMain controller to the CMS menu.
* *
* @param string $controllerClass The class name of the controller * @param string $controllerClass The class name of the controller
* @return The result of the operation
* @todo A director rule is added when a controller link is added, but it won't be removed * @todo A director rule is added when a controller link is added, but it won't be removed
* when the item is removed. Functionality needed in {@link Director}. * when the item is removed. Functionality needed in {@link Director}.
*/ */
@ -65,6 +66,9 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider {
/** /**
* Return a CMSMenuItem to add the given controller to the CMSMenu * Return a CMSMenuItem to add the given controller to the CMSMenu
*
* @param string $controllerClass
* @return CMSMenuItem
*/ */
protected static function menuitem_for_controller($controllerClass) { protected static function menuitem_for_controller($controllerClass) {
$urlBase = Config::inst()->get($controllerClass, 'url_base', Config::FIRST_SET); $urlBase = Config::inst()->get($controllerClass, 'url_base', Config::FIRST_SET);
@ -107,15 +111,15 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider {
* uses {@link CMSMenu::$menu_items} * uses {@link CMSMenu::$menu_items}
* *
* @param string $code Unique identifier for this menu item (e.g. used by {@link replace_menu_item()} and * @param string $code Unique identifier for this menu item (e.g. used by {@link replace_menu_item()} and
* {@link remove_menu_item}. Also used as a CSS-class for icon customization. * {@link remove_menu_item}. Also used as a CSS-class for icon customization.
* @param string $menuTitle Localized title showing in the menu bar * @param string $menuTitle Localized title showing in the menu bar
* @param string $url A relative URL that will be linked in the menu bar. * @param string $url A relative URL that will be linked in the menu bar.
* @param string $controllerClass The controller class for this menu, used to check permisssions. * @param string $controllerClass The controller class for this menu, used to check permisssions.
* If blank, it's assumed that this is public, and always shown to users who * If blank, it's assumed that this is public, and always shown to users who
* have the rights to access some other part of the admin area. * have the rights to access some other part of the admin area.
* @param int $priority
* @param array $attributes an array of attributes to include on the link. * @param array $attributes an array of attributes to include on the link.
* * @return bool Success
* @return boolean Success
*/ */
public static function add_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1, public static function add_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1,
$attributes = null) { $attributes = null) {
@ -237,16 +241,16 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider {
* Replace a navigation item to the main administration menu showing in the top bar. * Replace a navigation item to the main administration menu showing in the top bar.
* *
* @param string $code Unique identifier for this menu item (e.g. used by {@link replace_menu_item()} and * @param string $code Unique identifier for this menu item (e.g. used by {@link replace_menu_item()} and
* {@link remove_menu_item}. Also used as a CSS-class for icon customization. * {@link remove_menu_item}. Also used as a CSS-class for icon customization.
* @param string $menuTitle Localized title showing in the menu bar * @param string $menuTitle Localized title showing in the menu bar
* @param string $url A relative URL that will be linked in the menu bar. * @param string $url A relative URL that will be linked in the menu bar.
* Make sure to add a matching route via {@link Director::$rules} to this url. * Make sure to add a matching route via {@link Director::$rules} to this url.
* @param string $controllerClass The controller class for this menu, used to check permisssions. * @param string $controllerClass The controller class for this menu, used to check permisssions.
* If blank, it's assumed that this is public, and always shown to users who * If blank, it's assumed that this is public, and always shown to users who
* have the rights to access some other part of the admin area. * have the rights to access some other part of the admin area.
* @param int $priority
* @param array $attributes an array of attributes to include on the link. * @param array $attributes an array of attributes to include on the link.
* * @return bool Success
* @return boolean Success
*/ */
public static function replace_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1, public static function replace_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1,
$attributes = null) { $attributes = null) {
@ -265,6 +269,9 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider {
/** /**
* Add a previously built menu item object to the menu * Add a previously built menu item object to the menu
*
* @param string $code
* @param CMSMenuItem $cmsMenuItem
*/ */
protected static function add_menu_item_obj($code, $cmsMenuItem) { protected static function add_menu_item_obj($code, $cmsMenuItem) {
self::$menu_item_changes[] = array( self::$menu_item_changes[] = array(

View File

@ -1,7 +1,9 @@
<?php <?php
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
/** /**
* @package framework * @package framework
@ -15,7 +17,7 @@ class CMSProfileController extends LeftAndMain {
private static $required_permission_codes = false; private static $required_permission_codes = false;
private static $tree_class = 'Member'; private static $tree_class = 'SilverStripe\\Security\\Member';
public function getEditForm($id = null, $fields = null) { public function getEditForm($id = null, $fields = null) {
$this->setCurrentPageID(Member::currentUserID()); $this->setCurrentPageID(Member::currentUserID());
@ -40,7 +42,7 @@ class CMSProfileController extends LeftAndMain {
if($member = Member::currentUser()) { if($member = Member::currentUser()) {
$form->setValidator($member->getValidator()); $form->setValidator($member->getValidator());
} else { } else {
$form->setValidator(Injector::inst()->get('Member')->getValidator()); $form->setValidator(Member::singleton()->getValidator());
} }
if($form->Fields()->hasTabset()) { if($form->Fields()->hasTabset()) {
@ -70,7 +72,7 @@ class CMSProfileController extends LeftAndMain {
} }
public function save($data, $form) { public function save($data, $form) {
$member = DataObject::get_by_id("Member", $data['ID']); $member = Member::get()->byID($data['ID']);
if(!$member) return $this->httpError(404); if(!$member) return $this->httpError(404);
$origLocale = $member->Locale; $origLocale = $member->Locale;
@ -93,6 +95,9 @@ class CMSProfileController extends LeftAndMain {
* Only show first element, as the profile form is limited to editing * Only show first element, as the profile form is limited to editing
* the current member it doesn't make much sense to show the member name * the current member it doesn't make much sense to show the member name
* in the breadcrumbs. * in the breadcrumbs.
*
* @param bool $unlinked
* @return ArrayList
*/ */
public function Breadcrumbs($unlinked = false) { public function Breadcrumbs($unlinked = false) {
$items = parent::Breadcrumbs($unlinked); $items = parent::Breadcrumbs($unlinked);

View File

@ -1,8 +1,12 @@
<?php <?php
use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\Versioning\ChangeSet; use SilverStripe\ORM\Versioning\ChangeSet;
use SilverStripe\ORM\Versioning\ChangeSetItem; use SilverStripe\ORM\Versioning\ChangeSetItem;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\SecurityToken;
use SilverStripe\Security\PermissionProvider;
/** /**
* Campaign section of the CMS * Campaign section of the CMS

View File

@ -1,5 +1,8 @@
<?php <?php
use SilverStripe\Security\Group;
use SilverStripe\Security\GroupCsvBulkLoader;
/** /**
* Imports {@link Group} records by CSV upload, as defined in * Imports {@link Group} records by CSV upload, as defined in
* {@link GroupCsvBulkLoader}. * {@link GroupCsvBulkLoader}.

View File

@ -7,6 +7,8 @@
use SilverStripe\Forms\Schema\FormSchema; use SilverStripe\Forms\Schema\FormSchema;
use SilverStripe\ORM\Hierarchy\Hierarchy;
use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\DataModel; use SilverStripe\ORM\DataModel;
use SilverStripe\ORM\ValidationException; use SilverStripe\ORM\ValidationException;
@ -15,6 +17,12 @@ use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\Security\SecurityToken;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
use SilverStripe\Security\PermissionProvider;
/** /**
@ -660,6 +668,7 @@ class LeftAndMain extends Controller implements PermissionProvider {
* You should implement a Link() function in your subclass of LeftAndMain, * You should implement a Link() function in your subclass of LeftAndMain,
* to point to the URL of that particular controller. * to point to the URL of that particular controller.
* *
* @param string $action
* @return string * @return string
*/ */
public function Link($action = null) { public function Link($action = null) {
@ -733,6 +742,11 @@ class LeftAndMain extends Controller implements PermissionProvider {
return ''; return '';
} }
/**
* @param SS_HTTPRequest $request
* @return SS_HTTPResponse
* @throws SS_HTTPResponse_Exception
*/
public function show($request) { public function show($request) {
// TODO Necessary for TableListField URLs to work properly // TODO Necessary for TableListField URLs to work properly
if($request->param('ID')) $this->setCurrentPageID($request->param('ID')); if($request->param('ID')) $this->setCurrentPageID($request->param('ID'));
@ -775,7 +789,7 @@ class LeftAndMain extends Controller implements PermissionProvider {
* Returns the main menu of the CMS. This is also used by init() * Returns the main menu of the CMS. This is also used by init()
* to work out which sections the user has access to. * to work out which sections the user has access to.
* *
* @param Boolean * @param bool $cached
* @return SS_List * @return SS_List
*/ */
public function MainMenu($cached = true) { public function MainMenu($cached = true) {
@ -874,6 +888,7 @@ class LeftAndMain extends Controller implements PermissionProvider {
* Return a list of appropriate templates for this class, with the given suffix using * Return a list of appropriate templates for this class, with the given suffix using
* {@link SSViewer::get_templates_by_class()} * {@link SSViewer::get_templates_by_class()}
* *
* @param string $suffix
* @return array * @return array
*/ */
public function getTemplatesWithSuffix($suffix) { public function getTemplatesWithSuffix($suffix) {
@ -898,6 +913,7 @@ class LeftAndMain extends Controller implements PermissionProvider {
} }
/** /**
* @param bool $unlinked
* @return ArrayList * @return ArrayList
*/ */
public function Breadcrumbs($unlinked = false) { public function Breadcrumbs($unlinked = false) {
@ -965,12 +981,15 @@ class LeftAndMain extends Controller implements PermissionProvider {
/** /**
* Get a site tree HTML listing which displays the nodes under the given criteria. * Get a site tree HTML listing which displays the nodes under the given criteria.
* *
* @param $className The class of the root object * @param string $className The class of the root object
* @param $rootID The ID of the root object. If this is null then a complete tree will be * @param string $rootID The ID of the root object. If this is null then a complete tree will be
* shown * shown
* @param $childrenMethod The method to call to get the children of the tree. For example, * @param string $childrenMethod The method to call to get the children of the tree. For example,
* Children, AllChildrenIncludingDeleted, or AllHistoricalChildren * Children, AllChildrenIncludingDeleted, or AllHistoricalChildren
* @return String Nested unordered list with links to each page * @param string $numChildrenMethod
* @param callable $filterFunction
* @param int $nodeCountThreshold
* @return string Nested unordered list with links to each page
*/ */
public function getSiteTreeFor($className, $rootID = null, $childrenMethod = null, $numChildrenMethod = null, public function getSiteTreeFor($className, $rootID = null, $childrenMethod = null, $numChildrenMethod = null,
$filterFunction = null, $nodeCountThreshold = 30) { $filterFunction = null, $nodeCountThreshold = 30) {
@ -1100,6 +1119,9 @@ class LeftAndMain extends Controller implements PermissionProvider {
/** /**
* Get a subtree underneath the request param 'ID'. * Get a subtree underneath the request param 'ID'.
* If ID = 0, then get the whole tree. * If ID = 0, then get the whole tree.
*
* @param SS_HTTPRequest $request
* @return string
*/ */
public function getsubtree($request) { public function getsubtree($request) {
$html = $this->getSiteTreeFor( $html = $this->getSiteTreeFor(
@ -1124,7 +1146,8 @@ class LeftAndMain extends Controller implements PermissionProvider {
* all children with the node. Useful to refresh views after * all children with the node. Useful to refresh views after
* state modifications, e.g. saving a form. * state modifications, e.g. saving a form.
* *
* @return String JSON * @param SS_HTTPRequest $request
* @return string JSON
*/ */
public function updatetreenodes($request) { public function updatetreenodes($request) {
$data = array(); $data = array();
@ -1264,7 +1287,9 @@ class LeftAndMain extends Controller implements PermissionProvider {
* - 'SiblingIDs': Array of all sibling nodes to the moved node (incl. the node itself). * - 'SiblingIDs': Array of all sibling nodes to the moved node (incl. the node itself).
* In case of a 'ParentID' change, relates to the new siblings under the new parent. * In case of a 'ParentID' change, relates to the new siblings under the new parent.
* *
* @param SS_HTTPRequest $request
* @return SS_HTTPResponse JSON string with a * @return SS_HTTPResponse JSON string with a
* @throws SS_HTTPResponse_Exception
*/ */
public function savetreenode($request) { public function savetreenode($request) {
if (!SecurityToken::inst()->checkRequest($request)) { if (!SecurityToken::inst()->checkRequest($request)) {

View File

@ -1,5 +1,7 @@
<?php <?php
use SilverStripe\Security\MemberCsvBulkLoader;
/** /**
* Imports {@link Member} records by CSV upload, as defined in * Imports {@link Member} records by CSV upload, as defined in
* {@link MemberCsvBulkLoader}. * {@link MemberCsvBulkLoader}.

View File

@ -1,6 +1,9 @@
<?php <?php
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Member;
/** /**
* Generates a three-pane UI for editing model classes, with an * Generates a three-pane UI for editing model classes, with an
* automatically generated search panel, tabular results and edit forms. * automatically generated search panel, tabular results and edit forms.
@ -248,6 +251,8 @@ abstract class ModelAdmin extends LeftAndMain {
/** /**
* Sanitise a model class' name for inclusion in a link * Sanitise a model class' name for inclusion in a link
*
* @param string $class
* @return string * @return string
*/ */
protected function sanitiseClassName($class) { protected function sanitiseClassName($class) {
@ -256,6 +261,8 @@ abstract class ModelAdmin extends LeftAndMain {
/** /**
* Unsanitise a model class' name from a URL param * Unsanitise a model class' name from a URL param
*
* @param string $class
* @return string * @return string
*/ */
protected function unsanitiseClassName($class) { protected function unsanitiseClassName($class) {
@ -444,6 +451,7 @@ abstract class ModelAdmin extends LeftAndMain {
} }
/** /**
* @param bool $unlinked
* @return ArrayList * @return ArrayList
*/ */
public function Breadcrumbs($unlinked = false) { public function Breadcrumbs($unlinked = false) {

View File

@ -1,5 +1,12 @@
<?php <?php
use SilverStripe\Security\Security;
use SilverStripe\Security\Member;
use SilverStripe\Security\Group;
use SilverStripe\Security\Permission;
use SilverStripe\Security\PermissionRole;
use SilverStripe\Security\PermissionProvider;
/** /**
* Security section of the CMS * Security section of the CMS
* *
@ -14,9 +21,9 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
private static $menu_title = 'Security'; private static $menu_title = 'Security';
private static $tree_class = 'Group'; private static $tree_class = 'SilverStripe\\Security\\Group';
private static $subitem_class = 'Member'; private static $subitem_class = 'SilverStripe\\Security\\Member';
private static $allowed_actions = array( private static $allowed_actions = array(
'EditForm', 'EditForm',
@ -36,6 +43,9 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
/** /**
* Shortcut action for setting the correct active tab. * Shortcut action for setting the correct active tab.
*
* @param SS_HTTPRequest $request
* @return SS_HTTPResponse
*/ */
public function users($request) { public function users($request) {
return $this->index($request); return $this->index($request);
@ -43,6 +53,9 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
/** /**
* Shortcut action for setting the correct active tab. * Shortcut action for setting the correct active tab.
*
* @param SS_HTTPRequest $request
* @return SS_HTTPResponse
*/ */
public function groups($request) { public function groups($request) {
return $this->index($request); return $this->index($request);
@ -50,6 +63,9 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
/** /**
* Shortcut action for setting the correct active tab. * Shortcut action for setting the correct active tab.
*
* @param SS_HTTPRequest $request
* @return SS_HTTPResponse
*/ */
public function roles($request) { public function roles($request) {
return $this->index($request); return $this->index($request);
@ -79,7 +95,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
if($record && method_exists($record, 'getValidator')) { if($record && method_exists($record, 'getValidator')) {
$validator = $record->getValidator(); $validator = $record->getValidator();
} else { } else {
$validator = Injector::inst()->get('Member')->getValidator(); $validator = Member::singleton()->getValidator();
} }
$memberListConfig $memberListConfig
@ -94,7 +110,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
); );
$columns = $groupList->getConfig()->getComponentByType('GridFieldDataColumns'); $columns = $groupList->getConfig()->getComponentByType('GridFieldDataColumns');
$columns->setDisplayFields(array( $columns->setDisplayFields(array(
'Breadcrumbs' => singleton('Group')->fieldLabel('Title') 'Breadcrumbs' => singleton('SilverStripe\\Security\\Group')->fieldLabel('Title')
)); ));
$columns->setFieldFormatting(array( $columns->setFieldFormatting(array(
'Breadcrumbs' => function($val, $item) { 'Breadcrumbs' => function($val, $item) {
@ -117,7 +133,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
) )
) )
), ),
$groupsTab = new Tab('Groups', singleton('Group')->i18n_plural_name(), $groupsTab = new Tab('Groups', singleton('SilverStripe\\Security\\Group')->i18n_plural_name(),
$groupList $groupList
) )
), ),
@ -276,7 +292,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
$firstCrumb = $crumbs->shift(); $firstCrumb = $crumbs->shift();
if($params['FieldName'] == 'Groups') { if($params['FieldName'] == 'Groups') {
$crumbs->unshift(new ArrayData(array( $crumbs->unshift(new ArrayData(array(
'Title' => singleton('Group')->i18n_plural_name(), 'Title' => singleton('SilverStripe\\Security\\Group')->i18n_plural_name(),
'Link' => $this->Link('groups') 'Link' => $this->Link('groups')
))); )));
} elseif($params['FieldName'] == 'Users') { } elseif($params['FieldName'] == 'Users') {
@ -335,7 +351,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
public static function add_hidden_permission($codes){ public static function add_hidden_permission($codes){
if(is_string($codes)) $codes = array($codes); if(is_string($codes)) $codes = array($codes);
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead'); Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
Config::inst()->update('Permission', 'hidden_permissions', $codes); Config::inst()->update('SilverStripe\\Security\\Permission', 'hidden_permissions', $codes);
} }
/** /**
@ -345,7 +361,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
public static function remove_hidden_permission($codes){ public static function remove_hidden_permission($codes){
if(is_string($codes)) $codes = array($codes); if(is_string($codes)) $codes = array($codes);
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead'); Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
Config::inst()->remove('Permission', 'hidden_permissions', $codes); Config::inst()->remove('SilverStripe\\Security\\Permission', 'hidden_permissions', $codes);
} }
/** /**
@ -354,7 +370,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
*/ */
public static function get_hidden_permissions(){ public static function get_hidden_permissions(){
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead'); Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
Config::inst()->get('Permission', 'hidden_permissions', Config::FIRST_SET); Config::inst()->get('SilverStripe\\Security\\Permission', 'hidden_permissions', Config::FIRST_SET);
} }
/** /**
@ -364,6 +380,6 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
*/ */
public static function clear_hidden_permissions(){ public static function clear_hidden_permissions(){
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead'); Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
Config::inst()->remove('Permission', 'hidden_permissions', Config::anything()); Config::inst()->remove('SilverStripe\\Security\\Permission', 'hidden_permissions', Config::anything());
} }
} }

View File

@ -64,7 +64,7 @@ class LeftAndMainTest extends FunctionalTest {
public function testExtraCssAndJavascript() { public function testExtraCssAndJavascript() {
$admin = $this->objFromFixture('Member', 'admin'); $admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$this->session()->inst_set('loggedInAs', $admin->ID); $this->session()->inst_set('loggedInAs', $admin->ID);
$response = $this->get('LeftAndMainTest_Controller'); $response = $this->get('LeftAndMainTest_Controller');
@ -146,7 +146,7 @@ class LeftAndMainTest extends FunctionalTest {
* Check that all subclasses of leftandmain can be accessed * Check that all subclasses of leftandmain can be accessed
*/ */
public function testLeftAndMainSubclasses() { public function testLeftAndMainSubclasses() {
$adminuser = $this->objFromFixture('Member','admin'); $adminuser = $this->objFromFixture('SilverStripe\\Security\\Member','admin');
$this->session()->inst_set('loggedInAs', $adminuser->ID); $this->session()->inst_set('loggedInAs', $adminuser->ID);
$this->resetMenu(); $this->resetMenu();
@ -172,9 +172,9 @@ class LeftAndMainTest extends FunctionalTest {
} }
public function testCanView() { public function testCanView() {
$adminuser = $this->objFromFixture('Member', 'admin'); $adminuser = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$securityonlyuser = $this->objFromFixture('Member', 'securityonlyuser'); $securityonlyuser = $this->objFromFixture('SilverStripe\\Security\\Member', 'securityonlyuser');
$allcmssectionsuser = $this->objFromFixture('Member', 'allcmssectionsuser'); $allcmssectionsuser = $this->objFromFixture('SilverStripe\\Security\\Member', 'allcmssectionsuser');
$allValsFn = create_function('$obj', 'return $obj->getValue();'); $allValsFn = create_function('$obj', 'return $obj->getValue();');
// anonymous user // anonymous user

View File

@ -1,129 +1,129 @@
LeftAndMainTest_Object: LeftAndMainTest_Object:
page1: page1:
Title: Page 1 Title: Page 1
Sort: 1 Sort: 1
page2: page2:
Title: Page 2 Title: Page 2
Sort: 2 Sort: 2
page3: page3:
Title: Page 3 Title: Page 3
Sort: 3 Sort: 3
page31: page31:
Title: Page 3.1 Title: Page 3.1
Parent: =>LeftAndMainTest_Object.page3 Parent: =>LeftAndMainTest_Object.page3
Sort: 1 Sort: 1
page32: page32:
Title: Page 3.2 Title: Page 3.2
Parent: =>LeftAndMainTest_Object.page3 Parent: =>LeftAndMainTest_Object.page3
Sort: 2 Sort: 2
page4: page4:
Title: Page 4 Title: Page 4
Sort: 4 Sort: 4
page5: page5:
Title: Page 5 Title: Page 5
Sort: 5 Sort: 5
page6: page6:
Title: Page 6 Title: Page 6
Sort: 6 Sort: 6
page7: page7:
Title: Page 7 Title: Page 7
Sort: 7 Sort: 7
page8: page8:
Title: Page 8 Title: Page 8
Sort: 8 Sort: 8
page9: page9:
Title: Page 9 Title: Page 9
Sort: 9 Sort: 9
page10: page10:
Title: Page 10 Title: Page 10
Sort: 10 Sort: 10
page11: page11:
Title: Page 11 Title: Page 11
Sort: 11 Sort: 11
page12: page12:
Title: Page 12 Title: Page 12
Sort: 12 Sort: 12
page13: page13:
Title: Page 13 Title: Page 13
Sort: 13 Sort: 13
page14: page14:
Title: Page 14 Title: Page 14
Sort: 14 Sort: 14
page15: page15:
Title: Page 15 Title: Page 15
Sort: 15 Sort: 15
page16: page16:
Title: Page 16 Title: Page 16
Sort: 16 Sort: 16
page17: page17:
Title: Page 17 Title: Page 17
Sort: 17 Sort: 17
page18: page18:
Title: Page 18 Title: Page 18
Sort: 18 Sort: 18
page19: page19:
Title: Page 19 Title: Page 19
Sort: 19 Sort: 19
page20: page20:
Title: Page 20 Title: Page 20
Sort: 20 Sort: 20
page21: page21:
Title: Page 21 Title: Page 21
Sort: 21 Sort: 21
page22: page22:
Title: Page 22 Title: Page 22
Sort: 22 Sort: 22
page23: page23:
Title: Page 23 Title: Page 23
Sort: 23 Sort: 23
page24: page24:
Title: Page 24 Title: Page 24
Sort: 24 Sort: 24
page25: page25:
Title: Page 25 Title: Page 25
Sort: 25 Sort: 25
page26: page26:
Title: Page 26 Title: Page 26
Sort: 26 Sort: 26
home: home:
Title: Home Title: Home
URLSegment: home URLSegment: home
Sort: 0 Sort: 0
Group: SilverStripe\Security\Group:
admin: admin:
Title: Administrators Title: Administrators
empty: empty:
Title: Empty Group Title: Empty Group
securityonly: securityonly:
Title: securityonly Title: securityonly
allcmssections: allcmssections:
Title: allcmssections Title: allcmssections
rooteditusers: rooteditusers:
Title: rooteditusers Title: rooteditusers
Member: SilverStripe\Security\Member:
admin: admin:
Email: admin@example.com Email: admin@example.com
Password: ZXXlkwecxz2390232233 Password: ZXXlkwecxz2390232233
Groups: =>Group.admin Groups: =>SilverStripe\Security\Group.admin
securityonlyuser: securityonlyuser:
Email: securityonlyuser@test.com Email: securityonlyuser@test.com
Groups: =>Group.securityonly Groups: =>SilverStripe\Security\Group.securityonly
allcmssectionsuser: allcmssectionsuser:
Email: allcmssectionsuser@test.com Email: allcmssectionsuser@test.com
Groups: =>Group.allcmssections Groups: =>SilverStripe\Security\Group.allcmssections
rootedituser: rootedituser:
Email: rootedituser@test.com Email: rootedituser@test.com
Groups: =>Group.rooteditusers Groups: =>SilverStripe\Security\Group.rooteditusers
Permission: SilverStripe\Security\Permission:
admin: admin:
Code: ADMIN Code: ADMIN
GroupID: =>Group.admin GroupID: =>SilverStripe\Security\Group.admin
securityonly: securityonly:
Code: CMS_ACCESS_SecurityAdmin Code: CMS_ACCESS_SecurityAdmin
GroupID: =>Group.securityonly GroupID: =>SilverStripe\Security\Group.securityonly
allcmssections: allcmssections:
Code: CMS_ACCESS_LeftAndMain Code: CMS_ACCESS_LeftAndMain
GroupID: =>Group.allcmssections GroupID: =>SilverStripe\Security\Group.allcmssections
allcmssections2: allcmssections2:
Code: CMS_ACCESS_LeftAndMain Code: CMS_ACCESS_LeftAndMain
GroupID: =>Group.rooteditusers GroupID: =>SilverStripe\Security\Group.rooteditusers

View File

@ -1,6 +1,8 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Permission;
class ModelAdminTest extends FunctionalTest { class ModelAdminTest extends FunctionalTest {
protected static $fixture_file = 'ModelAdminTest.yml'; protected static $fixture_file = 'ModelAdminTest.yml';

View File

@ -1,19 +1,19 @@
ModelAdminTest_Contact: ModelAdminTest_Contact:
sam: sam:
Name: Sam Name: Sam
Phone: 021 123 456 Phone: 021 123 456
ingo: ingo:
Name: ingo Name: ingo
Phone: 04 987 6543 Phone: 04 987 6543
Member: SilverStripe\Security\Member:
admin: admin:
FirstName: admin FirstName: admin
Group: SilverStripe\Security\Group:
admin: admin:
Title: Admin Title: Admin
Members: =>Member.admin Members: =>SilverStripe\Security\Member.admin
Permission: SilverStripe\Security\Permission:
admin: admin:
Code: ADMIN Code: ADMIN
Group: =>Group.admin Group: =>SilverStripe\Security\Group.admin

View File

@ -46,11 +46,11 @@ class SecurityAdminTest extends FunctionalTest {
// } // }
public function testPermissionFieldRespectsHiddenPermissions() { public function testPermissionFieldRespectsHiddenPermissions() {
$this->session()->inst_set('loggedInAs', $this->idFromFixture('Member', 'admin')); $this->session()->inst_set('loggedInAs', $this->idFromFixture('SilverStripe\\Security\\Member', 'admin'));
$group = $this->objFromFixture('Group', 'admin'); $group = $this->objFromFixture('SilverStripe\\Security\\Group', 'admin');
Config::inst()->update('Permission', 'hidden_permissions', array('CMS_ACCESS_ReportAdmin')); Config::inst()->update('SilverStripe\\Security\\Permission', 'hidden_permissions', array('CMS_ACCESS_ReportAdmin'));
$response = $this->get(sprintf('admin/security/EditForm/field/Groups/item/%d/edit', $group->ID)); $response = $this->get(sprintf('admin/security/EditForm/field/Groups/item/%d/edit', $group->ID));
$this->assertContains( $this->assertContains(

View File

@ -1,4 +1,7 @@
<?php <?php
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/** /**
* Base class invoked from CLI rather than the webserver (Cron jobs, handling email bounces). * Base class invoked from CLI rather than the webserver (Cron jobs, handling email bounces).
* You can call subclasses of CliController directly, which will trigger a * You can call subclasses of CliController directly, which will trigger a

View File

@ -52,6 +52,8 @@
use Monolog\Logger; use Monolog\Logger;
use Monolog\Handler\StreamHandler; use Monolog\Handler\StreamHandler;
use SilverStripe\Security\Security;
/* /*
* _ss_environment.php handler * _ss_environment.php handler
@ -139,7 +141,7 @@ if(defined('SS_DEFAULT_ADMIN_USERNAME')) {
Security::setDefaultAdmin(SS_DEFAULT_ADMIN_USERNAME, SS_DEFAULT_ADMIN_PASSWORD); Security::setDefaultAdmin(SS_DEFAULT_ADMIN_USERNAME, SS_DEFAULT_ADMIN_PASSWORD);
} }
if(defined('SS_USE_BASIC_AUTH') && SS_USE_BASIC_AUTH) { if(defined('SS_USE_BASIC_AUTH') && SS_USE_BASIC_AUTH) {
Config::inst()->update('BasicAuth', 'entire_site_protected', SS_USE_BASIC_AUTH); Config::inst()->update('SilverStripe\\Security\\BasicAuth', 'entire_site_protected', SS_USE_BASIC_AUTH);
} }
if(defined('SS_ERROR_LOG')) { if(defined('SS_ERROR_LOG')) {

View File

@ -1,6 +1,10 @@
<?php <?php
use SilverStripe\ORM\DataModel; use SilverStripe\ORM\DataModel;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\Security\BasicAuth;
use SilverStripe\Security\Member;
/** /**
* Controllers are the cornerstone of all site functionality in SilverStripe. The {@link Director} * Controllers are the cornerstone of all site functionality in SilverStripe. The {@link Director}
@ -221,7 +225,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
* Prepare the response (we can receive an assortment of response types (strings/objects/HTTPResponses) and * Prepare the response (we can receive an assortment of response types (strings/objects/HTTPResponses) and
* changes the controller response object appropriately * changes the controller response object appropriately
* *
* @param $response * @param SS_HTTPResponse|Object $response
*/ */
protected function prepareResponse($response) { protected function prepareResponse($response) {
if ($response instanceof SS_HTTPResponse) { if ($response instanceof SS_HTTPResponse) {
@ -263,7 +267,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
* @param SS_HTTPRequest $request * @param SS_HTTPRequest $request
* @param string $action * @param string $action
* *
* @return HTMLText|SS_HTTPResponse * @return DBHTMLText|SS_HTTPResponse
*/ */
protected function handleAction($request, $action) { protected function handleAction($request, $action) {
foreach($request->latestParams() as $k => $v) { foreach($request->latestParams() as $k => $v) {
@ -302,6 +306,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
/** /**
* @param array $urlParams * @param array $urlParams
* @return $this
*/ */
public function setURLParams($urlParams) { public function setURLParams($urlParams) {
$this->urlParams = $urlParams; $this->urlParams = $urlParams;
@ -373,8 +378,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
* controller object with the template returned by {@link getViewer()}. * controller object with the template returned by {@link getViewer()}.
* *
* @param string $action * @param string $action
* * @return DBHTMLText
* @return HTMLText
*/ */
public function defaultAction($action) { public function defaultAction($action) {
return $this->getViewer($action)->process($this); return $this->getViewer($action)->process($this);

View File

@ -1,6 +1,10 @@
<?php <?php
use SilverStripe\ORM\DataModel; use SilverStripe\ORM\DataModel;
use SilverStripe\Security\Security;
use SilverStripe\Security\PermissionFailureException;
use SilverStripe\Security\Permission;
/** /**
* This class is the base class of any SilverStripe object that can be used to handle HTTP requests. * This class is the base class of any SilverStripe object that can be used to handle HTTP requests.
@ -123,6 +127,8 @@ class RequestHandler extends ViewableData {
/** /**
* Set the DataModel for this request. * Set the DataModel for this request.
*
* @param DataModel $model
*/ */
public function setDataModel($model) { public function setDataModel($model) {
$this->model = $model; $this->model = $model;
@ -144,9 +150,8 @@ class RequestHandler extends ViewableData {
* action will return an array of data with which to * action will return an array of data with which to
* customise the controller. * customise the controller.
* *
* @param $request The {@link SS_HTTPRequest} object that is reponsible for distributing URL parsing * @param SS_HTTPRequest $request The object that is reponsible for distributing URL parsing
* @uses SS_HTTPRequest * @param DataModel $model
* @uses SS_HTTPRequest->match()
* @return SS_HTTPResponse|RequestHandler|string|array * @return SS_HTTPResponse|RequestHandler|string|array
*/ */
public function handleRequest(SS_HTTPRequest $request, DataModel $model) { public function handleRequest(SS_HTTPRequest $request, DataModel $model) {
@ -240,6 +245,10 @@ class RequestHandler extends ViewableData {
return $this; return $this;
} }
/**
* @param SS_HTTPRequest $request
* @return array
*/
protected function findAction($request) { protected function findAction($request) {
$handlerClass = ($this->class) ? $this->class : get_class($this); $handlerClass = ($this->class) ? $this->class : get_class($this);
@ -386,6 +395,9 @@ class RequestHandler extends ViewableData {
/** /**
* Return the class that defines the given action, so that we know where to check allowed_actions. * Return the class that defines the given action, so that we know where to check allowed_actions.
*
* @param string $actionOrigCasing
* @return string
*/ */
protected function definingClassForAction($actionOrigCasing) { protected function definingClassForAction($actionOrigCasing) {
$action = strtolower($actionOrigCasing); $action = strtolower($actionOrigCasing);
@ -403,6 +415,10 @@ class RequestHandler extends ViewableData {
/** /**
* Check that the given action is allowed to be called from a URL. * Check that the given action is allowed to be called from a URL.
* It will interrogate {@link self::$allowed_actions} to determine this. * It will interrogate {@link self::$allowed_actions} to determine this.
*
* @param string $action
* @return bool
* @throws Exception
*/ */
public function checkAccessAction($action) { public function checkAccessAction($action) {
$actionOrigCasing = $action; $actionOrigCasing = $action;

View File

@ -2,6 +2,8 @@
use SilverStripe\ORM\DataModel; use SilverStripe\ORM\DataModel;
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\Security\Security;
/** /**
* Initialises the versioned stage when a request is made. * Initialises the versioned stage when a request is made.

View File

@ -1,5 +1,7 @@
<?php <?php
use SilverStripe\Security\RandomGenerator;
/** /**
* Class ParameterConfirmationToken * Class ParameterConfirmationToken
* *

View File

@ -20,24 +20,24 @@ class SS_Backtrace {
array('mysqli', 'mysqli'), array('mysqli', 'mysqli'),
array('mysqli', 'select_db'), array('mysqli', 'select_db'),
array('SilverStripe\\ORM\\DB', 'connect'), array('SilverStripe\\ORM\\DB', 'connect'),
array('Security', 'check_default_admin'), array('SilverStripe\\Security\\Security', 'check_default_admin'),
array('Security', 'encrypt_password'), array('SilverStripe\\Security\\Security', 'encrypt_password'),
array('Security', 'setDefaultAdmin'), array('SilverStripe\\Security\\Security', 'setDefaultAdmin'),
array('SilverStripe\\ORM\\DB', 'createDatabase'), array('SilverStripe\\ORM\\DB', 'createDatabase'),
array('Member', 'checkPassword'), array('SilverStripe\\Security\\Member', 'checkPassword'),
array('Member', 'changePassword'), array('SilverStripe\\Security\\Member', 'changePassword'),
array('MemberPassword', 'checkPassword'), array('SilverStripe\\Security\\MemberPassword', 'checkPassword'),
array('PasswordValidator', 'validate'), array('SilverStripe\\Security\\PasswordValidator', 'validate'),
array('PasswordEncryptor_PHPHash', 'encrypt'), array('SilverStripe\\Security\\PasswordEncryptor_PHPHash', 'encrypt'),
array('PasswordEncryptor_PHPHash', 'salt'), array('SilverStripe\\Security\\PasswordEncryptor_PHPHash', 'salt'),
array('PasswordEncryptor_LegacyPHPHash', 'encrypt'), array('SilverStripe\\Security\\PasswordEncryptor_LegacyPHPHash', 'encrypt'),
array('PasswordEncryptor_LegacyPHPHash', 'salt'), array('SilverStripe\\Security\\PasswordEncryptor_LegacyPHPHash', 'salt'),
array('PasswordEncryptor_MySQLPassword', 'encrypt'), array('SilverStripe\\Security\\PasswordEncryptor_MySQLPassword', 'encrypt'),
array('PasswordEncryptor_MySQLPassword', 'salt'), array('SilverStripe\\Security\\PasswordEncryptor_MySQLPassword', 'salt'),
array('PasswordEncryptor_MySQLOldPassword', 'encrypt'), array('SilverStripe\\Security\\PasswordEncryptor_MySQLOldPassword', 'encrypt'),
array('PasswordEncryptor_MySQLOldPassword', 'salt'), array('SilverStripe\\Security\\PasswordEncryptor_MySQLOldPassword', 'salt'),
array('PasswordEncryptor_Blowfish', 'encrypt'), array('SilverStripe\\Security\\PasswordEncryptor_Blowfish', 'encrypt'),
array('PasswordEncryptor_Blowfish', 'salt'), array('SilverStripe\\Security\\PasswordEncryptor_Blowfish', 'salt'),
); );
/** /**
@ -113,9 +113,10 @@ class SS_Backtrace {
/** /**
* Render or return a backtrace from the given scope. * Render or return a backtrace from the given scope.
* *
* @param unknown_type $returnVal * @param mixed $returnVal
* @param unknown_type $ignoreAjax * @param bool $ignoreAjax
* @return unknown * @param array $ignoredFunctions
* @return mixed
*/ */
public static function backtrace($returnVal = false, $ignoreAjax = false, $ignoredFunctions = null) { public static function backtrace($returnVal = false, $ignoreAjax = false, $ignoredFunctions = null) {
$plainText = Director::is_cli() || (Director::is_ajax() && !$ignoreAjax); $plainText = Director::is_cli() || (Director::is_ajax() && !$ignoreAjax);
@ -132,9 +133,9 @@ class SS_Backtrace {
* shown * shown
* *
* @param Object $item * @param Object $item
* @param boolean $showArg * @param bool $showArgs
* @param Int $argCharLimit * @param int $argCharLimit
* @return String * @return string
*/ */
public static function full_func_name($item, $showArgs = false, $argCharLimit = 10000) { public static function full_func_name($item, $showArgs = false, $argCharLimit = 10000) {
$funcName = ''; $funcName = '';
@ -164,7 +165,7 @@ class SS_Backtrace {
* *
* @param array $bt The trace array, as returned by debug_backtrace() or Exception::getTrace() * @param array $bt The trace array, as returned by debug_backtrace() or Exception::getTrace()
* @param boolean $plainText Set to false for HTML output, or true for plain-text output * @param boolean $plainText Set to false for HTML output, or true for plain-text output
* @param array List of functions that should be ignored. If not set, a default is provided * @param array $ignoredFunctions List of functions that should be ignored. If not set, a default is provided
* @return string The rendered backtrace * @return string The rendered backtrace
*/ */
public static function get_rendered_backtrace($bt, $plainText = false, $ignoredFunctions = null) { public static function get_rendered_backtrace($bt, $plainText = false, $ignoredFunctions = null) {

View File

@ -1,6 +1,9 @@
<?php <?php
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/** /**
* Supports debugging and core error handling. * Supports debugging and core error handling.
@ -30,6 +33,9 @@ class Debug {
/** /**
* Show the contents of val in a debug-friendly way. * Show the contents of val in a debug-friendly way.
* Debug::show() is intended to be equivalent to dprintr() * Debug::show() is intended to be equivalent to dprintr()
*
* @param mixed $val
* @param bool $showHeader
*/ */
public static function show($val, $showHeader = true) { public static function show($val, $showHeader = true) {
if(!Director::isLive()) { if(!Director::isLive()) {
@ -195,9 +201,9 @@ class Debug {
// This basically does the same as // This basically does the same as
// Security::permissionFailure(null, "You need to login with developer access to make use of debugging tools.") // Security::permissionFailure(null, "You need to login with developer access to make use of debugging tools.")
// We have to do this because of how early this method is called in execution. // We have to do this because of how early this method is called in execution.
$_SESSION['Security']['Message']['message'] $_SESSION['SilverStripe\\Security\\Security']['Message']['message']
= "You need to login with developer access to make use of debugging tools."; = "You need to login with developer access to make use of debugging tools.";
$_SESSION['Security']['Message']['type'] = 'warning'; $_SESSION['SilverStripe\\Security\\Security']['Message']['type'] = 'warning';
$_SESSION['BackURL'] = $_SERVER['REQUEST_URI']; $_SESSION['BackURL'] = $_SERVER['REQUEST_URI'];
header($_SERVER['SERVER_PROTOCOL'] . " 302 Found"); header($_SERVER['SERVER_PROTOCOL'] . " 302 Found");
header("Location: " . Director::baseURL() . Security::login_url()); header("Location: " . Director::baseURL() . Security::login_url());

View File

@ -218,10 +218,10 @@ class DebugView extends Object
* *
* @param string $title The main title * @param string $title The main title
* @param string $subtitle The subtitle * @param string $subtitle The subtitle
* @param string|false $description The description to show * @param string|bool $description The description to show
* @return string * @return string
*/ */
public function renderInfo($title, $subtitle, $description=false) { public function renderInfo($title, $subtitle, $description = false) {
$output = '<div class="info">'; $output = '<div class="info">';
$output .= "<h1>" . Convert::raw2xml($title) . "</h1>"; $output .= "<h1>" . Convert::raw2xml($title) . "</h1>";
if($subtitle) $output .= "<h3>" . Convert::raw2xml($subtitle) . "</h3>"; if($subtitle) $output .= "<h3>" . Convert::raw2xml($subtitle) . "</h3>";
@ -274,7 +274,7 @@ class DebugView extends Object
* Render a fragment of the a source file * Render a fragment of the a source file
* *
* @param array $lines An array of file lines; the keys should be the original line numbers * @param array $lines An array of file lines; the keys should be the original line numbers
* @param int errLine The line of the error * @param int $errline The line of the error
* @return string * @return string
*/ */
public function renderSourceFragment($lines, $errline) { public function renderSourceFragment($lines, $errline) {

View File

@ -2,6 +2,10 @@
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\DatabaseAdmin; use SilverStripe\ORM\DatabaseAdmin;
use SilverStripe\Security\Permission;
use SilverStripe\Security\RandomGenerator;
use SilverStripe\Security\Security;
/** /**
* Base class for development tools. * Base class for development tools.
@ -202,7 +206,7 @@ class DevelopmentAdmin extends Controller {
* Returns the token and suggests PHP configuration to set it. * Returns the token and suggests PHP configuration to set it.
*/ */
public function generatesecuretoken() { public function generatesecuretoken() {
$generator = Injector::inst()->create('RandomGenerator'); $generator = Injector::inst()->create('SilverStripe\\Security\\RandomGenerator');
$token = $generator->randomToken('sha1'); $token = $generator->randomToken('sha1');
$body = <<<TXT $body = <<<TXT
Generated new token. Please add the following code to your YAML configuration: Generated new token. Please add the following code to your YAML configuration:

View File

@ -1,5 +1,9 @@
<?php <?php
use SilverStripe\Security\BasicAuth;
use SilverStripe\Security\Member;
use SilverStripe\Security\SecurityToken;
/** /**
* SilverStripe-specific testing object designed to support functional testing of your web app. It simulates get/post * SilverStripe-specific testing object designed to support functional testing of your web app. It simulates get/post
* requests, form submission, and can validate resulting HTML, looking up content by CSS selector. * requests, form submission, and can validate resulting HTML, looking up content by CSS selector.
@ -362,12 +366,13 @@ class FunctionalTest extends SapphireTest {
/** /**
* Log in as the given member * Log in as the given member
* @param $member The ID, fixture codename, or Member object of the member that you want to log in *
* @param Member|int|string $member The ID, fixture codename, or Member object of the member that you want to log in
*/ */
public function logInAs($member) { public function logInAs($member) {
if(is_object($member)) $memberID = $member->ID; if(is_object($member)) $memberID = $member->ID;
elseif(is_numeric($member)) $memberID = $member; elseif(is_numeric($member)) $memberID = $member;
else $memberID = $this->idFromFixture('Member', $member); else $memberID = $this->idFromFixture('SilverStripe\\Security\\Member', $member);
$this->session()->inst_set('loggedInAs', $memberID); $this->session()->inst_set('loggedInAs', $memberID);
} }
@ -377,7 +382,7 @@ class FunctionalTest extends SapphireTest {
* This is helpful if you're not testing publication functionality and don't want "stage management" cluttering * This is helpful if you're not testing publication functionality and don't want "stage management" cluttering
* your test. * your test.
* *
* @param bool toggle the use of the draft site * @param bool $enabled toggle the use of the draft site
*/ */
public function useDraftSite($enabled = true) { public function useDraftSite($enabled = true) {
if($enabled) { if($enabled) {

View File

@ -1,4 +1,7 @@
<?php <?php
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/** /**
* Returns information about the current site instance. * Returns information about the current site instance.
* @package framework * @package framework

View File

@ -9,6 +9,11 @@ use SilverStripe\ORM\DataModel;
use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
use SilverStripe\Security\Group;
use SilverStripe\Security\Permission;
/** /**
@ -1015,7 +1020,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$group->Permissions()->add($permission); $group->Permissions()->add($permission);
} }
$member = DataObject::get_one('Member', array( $member = DataObject::get_one('SilverStripe\\Security\\Member', array(
'"Member"."Email"' => "$permCode@example.org" '"Member"."Email"' => "$permCode@example.org"
)); ));
if (!$member) { if (!$member) {

View File

@ -1,4 +1,7 @@
<?php <?php
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/** /**
* @package framework * @package framework
* @subpackage dev * @subpackage dev
@ -59,6 +62,9 @@ class TaskRunner extends Controller {
} }
} }
/**
* @param SS_HTTPRequest $request
*/
public function runTask($request) { public function runTask($request) {
$name = $request->param('TaskName'); $name = $request->param('TaskName');
$tasks = $this->getTasks(); $tasks = $this->getTasks();

View File

@ -31,6 +31,7 @@
* `File` is now versioned, and should be published before they can be used on the frontend. * `File` is now versioned, and should be published before they can be used on the frontend.
See section on [Migrating File DataObject from 3.x to 4.0](#migrating-file-dataobject-from-3x-to-40) See section on [Migrating File DataObject from 3.x to 4.0](#migrating-file-dataobject-from-3x-to-40)
below for upgrade notes. below for upgrade notes.
* Removed `RegenerateCachedImagesTask`
* Removed `dev/tests/` controller in favour of standard `vendor/bin/phpunit` command * Removed `dev/tests/` controller in favour of standard `vendor/bin/phpunit` command
* Updated PHPUnit from 3.7 to 4.8 ([upgrade notes](https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-4.0.0#backwards-compatibility-issues)). * Updated PHPUnit from 3.7 to 4.8 ([upgrade notes](https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-4.0.0#backwards-compatibility-issues)).
Please remove any PHPUnit related `require_once()` calls (e.g. in `FeatureContext` Please remove any PHPUnit related `require_once()` calls (e.g. in `FeatureContext`

View File

@ -4,13 +4,15 @@ namespace SilverStripe\Filesystem;
use Injector; use Injector;
use Member;
use SilverStripe\Filesystem\Storage\AssetStore; use SilverStripe\Filesystem\Storage\AssetStore;
use SilverStripe\Filesystem\Storage\DBFile; use SilverStripe\Filesystem\Storage\DBFile;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\DataExtension; use SilverStripe\ORM\DataExtension;
use SilverStripe\Security\Member;
/** /**

View File

@ -9,6 +9,9 @@ use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\ValidationResult; use SilverStripe\ORM\ValidationResult;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
/** /**
@ -100,7 +103,7 @@ class File extends DataObject implements ShortcodeHandler, AssetContainer, Thumb
private static $has_one = array( private static $has_one = array(
"Parent" => "File", "Parent" => "File",
"Owner" => "Member" "Owner" => "SilverStripe\\Security\\Member"
); );
private static $defaults = array( private static $defaults = array(
@ -186,7 +189,7 @@ class File extends DataObject implements ShortcodeHandler, AssetContainer, Thumb
/** /**
* @config * @config
* @var If this is true, then restrictions set in {@link $allowed_max_file_size} and * @var bool If this is true, then restrictions set in {@link $allowed_max_file_size} and
* {@link $allowed_extensions} will be applied to users with admin privileges as * {@link $allowed_extensions} will be applied to users with admin privileges as
* well. * well.
*/ */

View File

@ -1,6 +1,9 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/** /**
* A collection of static methods for manipulating the filesystem. * A collection of static methods for manipulating the filesystem.
* *
@ -105,9 +108,10 @@ class Filesystem extends Object {
/** /**
* Return the most recent modification time of anything in the folder. * Return the most recent modification time of anything in the folder.
* *
* @param $folder The folder, relative to the site root * @param string $folder The folder, relative to the site root
* @param $extensionList An option array of file extensions to limit the search to * @param array $extensionList An option array of file extensions to limit the search to
* @return String Same as filemtime() format. * @param bool $recursiveCall Not used
* @return string Same as filemtime() format.
*/ */
public static function folderModTime($folder, $extensionList = null, $recursiveCall = false) { public static function folderModTime($folder, $extensionList = null, $recursiveCall = false) {
//$cacheID = $folder . ',' . implode(',', $extensionList); //$cacheID = $folder . ',' . implode(',', $extensionList);

View File

@ -4,6 +4,8 @@ use SilverStripe\Filesystem\Storage\AssetContainer;
use SilverStripe\Filesystem\Storage\AssetNameGenerator; use SilverStripe\Filesystem\Storage\AssetNameGenerator;
use SilverStripe\Filesystem\Storage\AssetStore; use SilverStripe\Filesystem\Storage\AssetStore;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
/** /**
@ -148,8 +150,8 @@ class Upload extends Controller {
/** /**
* Save an file passed from a form post into the AssetStore directly * Save an file passed from a form post into the AssetStore directly
* *
* @param $tmpFile array Indexed array that PHP generated for every file it uploads. * @param array $tmpFile Indexed array that PHP generated for every file it uploads.
* @param $folderPath string Folder path relative to /assets * @param string|bool $folderPath Folder path relative to /assets
* @return array|false Either the tuple array, or false if the file could not be saved * @return array|false Either the tuple array, or false if the file could not be saved
*/ */
public function load($tmpFile, $folderPath = false) { public function load($tmpFile, $folderPath = false) {
@ -174,7 +176,9 @@ class Upload extends Controller {
* *
* @param array $tmpFile * @param array $tmpFile
* @param AssetContainer $file * @param AssetContainer $file
* @param string|bool $folderPath
* @return bool True if the file was successfully saved into this record * @return bool True if the file was successfully saved into this record
* @throws Exception
*/ */
public function loadIntoFile($tmpFile, $file = null, $folderPath = false) { public function loadIntoFile($tmpFile, $file = null, $folderPath = false) {
$this->file = $file; $this->file = $file;

View File

@ -10,12 +10,14 @@ use Injector;
use AssetField; use AssetField;
use File; use File;
use Director; use Director;
use Permission;
use SilverStripe\ORM\ValidationResult; use SilverStripe\ORM\ValidationResult;
use SilverStripe\ORM\ValidationException; use SilverStripe\ORM\ValidationException;
use SilverStripe\ORM\FieldType\DBComposite; use SilverStripe\ORM\FieldType\DBComposite;
use SilverStripe\Security\Permission;
/** /**

View File

@ -6,6 +6,8 @@ use SilverStripe\Filesystem\Storage\DBFile;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ValidationException; use SilverStripe\ORM\ValidationException;
use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\Security\Permission;
/** /**
@ -149,7 +151,6 @@ class AssetField extends FileField {
* *
* @param string $name The internal field name, passed to forms. * @param string $name The internal field name, passed to forms.
* @param string $title The field label. * @param string $title The field label.
* @param Form $form Reference to the container form
*/ */
public function __construct($name, $title = null) { public function __construct($name, $title = null) {
$this->addExtraClass('ss-upload'); // class, used by js $this->addExtraClass('ss-upload'); // class, used by js
@ -237,7 +238,9 @@ class AssetField extends FileField {
/** /**
* Force a record to be used as "Parent" for uploaded Files (eg a Page with a has_one to File) * Force a record to be used as "Parent" for uploaded Files (eg a Page with a has_one to File)
*
* @param DataObject $record * @param DataObject $record
* @return $this
*/ */
public function setRecord($record) { public function setRecord($record) {
$this->record = $record; $this->record = $record;
@ -444,7 +447,7 @@ class AssetField extends FileField {
* Defaults to 'ss-uploadfield-uploadtemplate' * Defaults to 'ss-uploadfield-uploadtemplate'
* *
* @see javascript/UploadField_uploadtemplate.js * @see javascript/UploadField_uploadtemplate.js
* @var string * @return string
*/ */
public function getUploadTemplateName() { public function getUploadTemplateName() {
return $this->getConfig('uploadTemplateName'); return $this->getConfig('uploadTemplateName');
@ -465,7 +468,7 @@ class AssetField extends FileField {
* Defaults to 'ss-downloadfield-downloadtemplate' * Defaults to 'ss-downloadfield-downloadtemplate'
* *
* @see javascript/DownloadField_downloadtemplate.js * @see javascript/DownloadField_downloadtemplate.js
* @var string * @return string
*/ */
public function getDownloadTemplateName() { public function getDownloadTemplateName() {
return $this->getConfig('downloadTemplateName'); return $this->getConfig('downloadTemplateName');
@ -753,7 +756,7 @@ class AssetField extends FileField {
* Gets the foreign class that needs to be created, or 'File' as default if there * Gets the foreign class that needs to be created, or 'File' as default if there
* is no relationship, or it cannot be determined. * is no relationship, or it cannot be determined.
* *
* @param $default Default value to return if no value could be calculated * @param string $default Default value to return if no value could be calculated
* @return string Foreign class name. * @return string Foreign class name.
*/ */
public function getRelationAutosetClass($default = 'File') { public function getRelationAutosetClass($default = 'File') {

View File

@ -2,6 +2,9 @@
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\Security\Member;
/** /**
* Two masked input fields, checks for matching passwords. * Two masked input fields, checks for matching passwords.
@ -141,7 +144,7 @@ class ConfirmedPasswordField extends FormField {
/** /**
* @param array $properties * @param array $properties
* *
* @return HTMLText * @return DBHTMLText
*/ */
public function Field($properties = array()) { public function Field($properties = array()) {
Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js'); Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js');

View File

@ -1,5 +1,7 @@
<?php <?php
use SilverStripe\Security\Member;
/** /**
* A simple extension to dropdown field, pre-configured to list countries. * A simple extension to dropdown field, pre-configured to list countries.
* It will default to the country of the current visitor. * It will default to the country of the current visitor.

View File

@ -1,6 +1,8 @@
<?php <?php
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\FieldType\DBHTMLText;
/** /**
* Dropdown field, created from a <select> tag. * Dropdown field, created from a <select> tag.
* *
@ -112,7 +114,7 @@ class DropdownField extends SingleSelectField {
/** /**
* @param array $properties * @param array $properties
* @return HTMLText * @return DBHTMLText
*/ */
public function Field($properties = array()) { public function Field($properties = array()) {
$options = array(); $options = array();

View File

@ -89,6 +89,7 @@ class FieldGroup extends CompositeField {
$compositeTitle .= $subfield->getName(); $compositeTitle .= $subfield->getName();
if($subfield->getName()) $count++; if($subfield->getName()) $count++;
} }
/** @skipUpgrade */
if($count == 1) $compositeTitle .= 'Group'; if($count == 1) $compositeTitle .= 'Group';
return preg_replace("/[^a-zA-Z0-9]+/", "", $compositeTitle); return preg_replace("/[^a-zA-Z0-9]+/", "", $compositeTitle);
} }

View File

@ -1,7 +1,13 @@
<?php <?php
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\ORM\SS_List;
use SilverStripe\Security\SecurityToken;
use SilverStripe\Security\NullSecurityToken;
/** /**
* Base class for all forms. * Base class for all forms.
* The form class is an extensible base for all forms on a SilverStripe application. It can be used * The form class is an extensible base for all forms on a SilverStripe application. It can be used
@ -700,6 +706,7 @@ class Form extends RequestHandler {
* Set actions that are exempt from validation * Set actions that are exempt from validation
* *
* @param array * @param array
* @return $this
*/ */
public function setValidationExemptActions($actions) { public function setValidationExemptActions($actions) {
$this->validationExemptActions = $actions; $this->validationExemptActions = $actions;
@ -855,7 +862,8 @@ class Form extends RequestHandler {
} }
/** /**
* @return string $name * @param string $name
* @return string
*/ */
public function getAttribute($name) { public function getAttribute($name) {
if(isset($this->attributes[$name])) return $this->attributes[$name]; if(isset($this->attributes[$name])) return $this->attributes[$name];
@ -887,7 +895,7 @@ class Form extends RequestHandler {
/** /**
* Return the attributes of the form tag - used by the templates. * Return the attributes of the form tag - used by the templates.
* *
* @param array Custom attributes to process. Falls back to {@link getAttributes()}. * @param array $attrs Custom attributes to process. Falls back to {@link getAttributes()}.
* If at least one argument is passed as a string, all arguments act as excludes by name. * If at least one argument is passed as a string, all arguments act as excludes by name.
* *
* @return string HTML attributes, ready for insertion into an HTML tag * @return string HTML attributes, ready for insertion into an HTML tag
@ -966,7 +974,7 @@ class Form extends RequestHandler {
* Set the target of this form to any value - useful for opening the form * Set the target of this form to any value - useful for opening the form
* contents in a new window or refreshing another frame. * contents in a new window or refreshing another frame.
* *
* @param target $target The value of the target * @param string $target The value of the target
* @return $this * @return $this
*/ */
public function setTarget($target) { public function setTarget($target) {
@ -1611,7 +1619,7 @@ class Form extends RequestHandler {
* This is returned when you access a form as $FormObject rather * This is returned when you access a form as $FormObject rather
* than <% with FormObject %> * than <% with FormObject %>
* *
* @return HTML * @return DBHTMLText
*/ */
public function forTemplate() { public function forTemplate() {
$return = $this->renderWith(array_merge( $return = $this->renderWith(array_merge(
@ -1631,7 +1639,7 @@ class Form extends RequestHandler {
* It triggers slightly different behaviour, such as disabling the rewriting * It triggers slightly different behaviour, such as disabling the rewriting
* of # links. * of # links.
* *
* @return HTML * @return DBHTMLText
*/ */
public function forAjaxTemplate() { public function forAjaxTemplate() {
$view = new SSViewer(array( $view = new SSViewer(array(
@ -1654,7 +1662,7 @@ class Form extends RequestHandler {
* and _form_enctype. These are the attributes of the form. These fields * and _form_enctype. These are the attributes of the form. These fields
* can be used to send the form to Ajax. * can be used to send the form to Ajax.
* *
* @return HTML * @return DBHTMLText
*/ */
public function formHtmlContent() { public function formHtmlContent() {
$this->IncludeFormTag = false; $this->IncludeFormTag = false;
@ -1674,7 +1682,7 @@ class Form extends RequestHandler {
* Render this form using the given template, and return the result as a string * Render this form using the given template, and return the result as a string
* You can pass either an SSViewer or a template name * You can pass either an SSViewer or a template name
* @param string|array $template * @param string|array $template
* @return HTMLText * @return DBHTMLText
*/ */
public function renderWithoutActionButton($template) { public function renderWithoutActionButton($template) {
$custom = $this->customise(array( $custom = $this->customise(array(
@ -1724,7 +1732,7 @@ class Form extends RequestHandler {
public function defaultAction() { public function defaultAction() {
if($this->hasDefaultAction && $this->actions) { if($this->hasDefaultAction && $this->actions) {
return $this->actions->First(); return $this->actions->First();
} }
} }
/** /**
@ -1796,7 +1804,7 @@ class Form extends RequestHandler {
public static function single_field_required() { public static function single_field_required() {
if(self::current_action() == 'callfieldmethod') { if(self::current_action() == 'callfieldmethod') {
return $_REQUEST['fieldName']; return $_REQUEST['fieldName'];
} }
} }
/** /**

View File

@ -1201,7 +1201,8 @@ class FormField extends RequestHandler {
* @return string * @return string
*/ */
public function Type() { public function Type() {
return strtolower(preg_replace('/Field$/', '', $this->class)); $type = new ReflectionClass($this);
return strtolower(preg_replace('/Field$/', '', $type->getShortName()));
} }
/** /**

View File

@ -41,9 +41,9 @@ class FormTemplateHelper {
return Convert::raw2htmlid($id); return Convert::raw2htmlid($id);
} }
return Convert::raw2htmlid( $reflection = new ReflectionClass($form);
get_class($form) . '_' . str_replace(array('.', '/'), '', $form->getName()) $shortName = str_replace(array('.', '/'), '', $form->getName());
); return Convert::raw2htmlid($reflection->getShortName() . '_' . $shortName);
} }
/** /**

View File

@ -1,6 +1,8 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBHTMLText;
/** /**
* Dropdown-like field that allows you to select an item from a hierarchical * Dropdown-like field that allows you to select an item from a hierarchical
* AJAX-expandable tree. * AJAX-expandable tree.
@ -95,7 +97,7 @@ class TreeDropdownField extends FormField {
* @param bool $showSearch enable the ability to search the tree by * @param bool $showSearch enable the ability to search the tree by
* entering the text in the input field. * entering the text in the input field.
*/ */
public function __construct($name, $title = null, $sourceObject = 'Group', $keyField = 'ID', public function __construct($name, $title = null, $sourceObject = 'SilverStripe\\Security\\Group', $keyField = 'ID',
$labelField = 'TreeTitle', $showSearch = true $labelField = 'TreeTitle', $showSearch = true
) { ) {
@ -120,6 +122,7 @@ class TreeDropdownField extends FormField {
* displays the whole tree. * displays the whole tree.
* *
* @param int $ID * @param int $ID
* @return $this
*/ */
public function setTreeBaseID($ID) { public function setTreeBaseID($ID) {
$this->baseID = (int) $ID; $this->baseID = (int) $ID;
@ -131,6 +134,7 @@ class TreeDropdownField extends FormField {
* displaying to the user. * displaying to the user.
* *
* @param callback $callback * @param callback $callback
* @return $this
*/ */
public function setFilterFunction($callback) { public function setFilterFunction($callback) {
if(!is_callable($callback, true)) { if(!is_callable($callback, true)) {
@ -145,6 +149,7 @@ class TreeDropdownField extends FormField {
* Set a callback used to disable checkboxes for some items in the tree * Set a callback used to disable checkboxes for some items in the tree
* *
* @param callback $callback * @param callback $callback
* @return $this
*/ */
public function setDisableFunction($callback) { public function setDisableFunction($callback) {
if(!is_callable($callback, true)) { if(!is_callable($callback, true)) {
@ -160,6 +165,7 @@ class TreeDropdownField extends FormField {
* applying the filter. * applying the filter.
* *
* @param callback $callback * @param callback $callback
* @return $this
*/ */
public function setSearchFunction($callback) { public function setSearchFunction($callback) {
if(!is_callable($callback, true)) { if(!is_callable($callback, true)) {
@ -175,7 +181,8 @@ class TreeDropdownField extends FormField {
} }
/** /**
* @param Boolean * @param bool $bool
* @return $this
*/ */
public function setShowSearch($bool) { public function setShowSearch($bool) {
$this->showSearch = $bool; $this->showSearch = $bool;
@ -183,12 +190,13 @@ class TreeDropdownField extends FormField {
} }
/** /**
* @param $method The parameter to ChildrenMethod to use when calling Hierarchy->getChildrenAsUL in * @param string $method The parameter to ChildrenMethod to use when calling Hierarchy->getChildrenAsUL in
* {@link Hierarchy}. The method specified determines the structure of the returned list. Use "ChildFolders" * {@link Hierarchy}. The method specified determines the structure of the returned list. Use "ChildFolders"
* in place of the default to get a drop-down listing with only folders, i.e. not including the child elements in * in place of the default to get a drop-down listing with only folders, i.e. not including the child elements in
* the currently selected folder. setNumChildrenMethod() should be used as well for proper functioning. * the currently selected folder. setNumChildrenMethod() should be used as well for proper functioning.
* *
* See {@link Hierarchy} for a complete list of possible methods. * See {@link Hierarchy} for a complete list of possible methods.
* @return $this
*/ */
public function setChildrenMethod($method) { public function setChildrenMethod($method) {
$this->childrenMethod = $method; $this->childrenMethod = $method;
@ -196,9 +204,10 @@ class TreeDropdownField extends FormField {
} }
/** /**
* @param $method The parameter to numChildrenMethod to use when calling Hierarchy->getChildrenAsUL in * @param string $method The parameter to numChildrenMethod to use when calling Hierarchy->getChildrenAsUL in
* {@link Hierarchy}. Should be used in conjunction with setChildrenMethod(). * {@link Hierarchy}. Should be used in conjunction with setChildrenMethod().
* *
* @return $this
*/ */
public function setNumChildrenMethod($method) { public function setNumChildrenMethod($method) {
$this->numChildrenMethod = $method; $this->numChildrenMethod = $method;
@ -206,7 +215,8 @@ class TreeDropdownField extends FormField {
} }
/** /**
* @return HTMLText * @param array $properties
* @return DBHTMLText
*/ */
public function Field($properties = array()) { public function Field($properties = array()) {
Requirements::add_i18n_javascript(FRAMEWORK_DIR . '/client/lang'); Requirements::add_i18n_javascript(FRAMEWORK_DIR . '/client/lang');
@ -263,6 +273,7 @@ class TreeDropdownField extends FormField {
* *
* @param SS_HTTPRequest $request * @param SS_HTTPRequest $request
* @return string * @return string
* @throws Exception
*/ */
public function tree(SS_HTTPRequest $request) { public function tree(SS_HTTPRequest $request) {
// Array sourceObject is an explicit list of values - construct a "flat tree" // Array sourceObject is an explicit list of values - construct a "flat tree"
@ -387,8 +398,8 @@ class TreeDropdownField extends FormField {
* Marking public function for the tree, which combines different filters sensibly. * Marking public function for the tree, which combines different filters sensibly.
* If a filter function has been set, that will be called. And if search text is set, * If a filter function has been set, that will be called. And if search text is set,
* filter on that too. Return true if all applicable conditions are true, false otherwise. * filter on that too. Return true if all applicable conditions are true, false otherwise.
* @param $node * @param object $node
* @return unknown_type * @return mixed
*/ */
public function filterMarking($node) { public function filterMarking($node) {
if ($this->filterCallback && !call_user_func($this->filterCallback, $node)) return false; if ($this->filterCallback && !call_user_func($this->filterCallback, $node)) return false;
@ -409,7 +420,8 @@ class TreeDropdownField extends FormField {
} }
/** /**
* @param String $field * @param string $field
* @return $this
*/ */
public function setLabelField($field) { public function setLabelField($field) {
$this->labelField = $field; $this->labelField = $field;
@ -424,7 +436,8 @@ class TreeDropdownField extends FormField {
} }
/** /**
* @param String $field * @param string $field
* @return $this
*/ */
public function setKeyField($field) { public function setKeyField($field) {
$this->keyField = $field; $this->keyField = $field;
@ -439,7 +452,8 @@ class TreeDropdownField extends FormField {
} }
/** /**
* @param String $field * @param string $class
* @return $this
*/ */
public function setSourceObject($class) { public function setSourceObject($class) {
$this->sourceObject = $class; $this->sourceObject = $class;

View File

@ -3,6 +3,8 @@
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\FieldType\DBHTMLText;
/** /**
* This formfield represents many-many joins using a tree selector shown in a dropdown styled element * This formfield represents many-many joins using a tree selector shown in a dropdown styled element
* which can be added to any form usually in the CMS. * which can be added to any form usually in the CMS.
@ -48,7 +50,7 @@ use SilverStripe\ORM\DataObjectInterface;
* @subpackage fields-relational * @subpackage fields-relational
*/ */
class TreeMultiselectField extends TreeDropdownField { class TreeMultiselectField extends TreeDropdownField {
public function __construct($name, $title=null, $sourceObject="Group", $keyField="ID", $labelField="Title") { public function __construct($name, $title=null, $sourceObject="SilverStripe\\Security\\Group", $keyField="ID", $labelField="Title") {
parent::__construct($name, $title, $sourceObject, $keyField, $labelField); parent::__construct($name, $title, $sourceObject, $keyField, $labelField);
$this->removeExtraClass('single'); $this->removeExtraClass('single');
$this->addExtraClass('multiple'); $this->addExtraClass('multiple');
@ -88,9 +90,13 @@ class TreeMultiselectField extends TreeDropdownField {
return $record->$fieldName(); return $record->$fieldName();
} }
} }
/** /**
* We overwrite the field attribute to add our hidden fields, as this * We overwrite the field attribute to add our hidden fields, as this
* formfield can contain multiple values. * formfield can contain multiple values.
*
* @param array $properties
* @return DBHTMLText
*/ */
public function Field($properties = array()) { public function Field($properties = array()) {
Requirements::add_i18n_javascript(FRAMEWORK_DIR . '/client/lang'); Requirements::add_i18n_javascript(FRAMEWORK_DIR . '/client/lang');
@ -146,6 +152,8 @@ class TreeMultiselectField extends TreeDropdownField {
* Save the results into the form * Save the results into the form
* Calls function $record->onChange($items) before saving to the assummed * Calls function $record->onChange($items) before saving to the assummed
* Component set. * Component set.
*
* @param DataObjectInterface $record
*/ */
public function saveInto(DataObjectInterface $record) { public function saveInto(DataObjectInterface $record) {
// Detect whether this field has actually been updated // Detect whether this field has actually been updated

View File

@ -9,6 +9,8 @@ use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\RelationList; use SilverStripe\ORM\RelationList;
use SilverStripe\ORM\UnsavedRelationList; use SilverStripe\ORM\UnsavedRelationList;
use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataList;
use SilverStripe\Security\Permission;
/** /**
@ -220,7 +222,6 @@ class UploadField extends FileField {
* @param string $title The field label. * @param string $title The field label.
* @param SS_List $items If no items are defined, the field will try to auto-detect an existing relation on * @param SS_List $items If no items are defined, the field will try to auto-detect an existing relation on
* @link $record}, with the same name as the field name. * @link $record}, with the same name as the field name.
* @param Form $form Reference to the container form
*/ */
public function __construct($name, $title = null, SS_List $items = null) { public function __construct($name, $title = null, SS_List $items = null) {
@ -248,7 +249,8 @@ class UploadField extends FileField {
/** /**
* Set name of template used for Buttons on each file (replace, edit, remove, delete) (without path or extension) * Set name of template used for Buttons on each file (replace, edit, remove, delete) (without path or extension)
* *
* @param string * @param string $template
* @return $this
*/ */
public function setTemplateFileButtons($template) { public function setTemplateFileButtons($template) {
$this->templateFileButtons = $template; $this->templateFileButtons = $template;
@ -265,7 +267,8 @@ class UploadField extends FileField {
/** /**
* Set name of template used for the edit (inline & popup) of a file file (without path or extension) * Set name of template used for the edit (inline & popup) of a file file (without path or extension)
* *
* @param string * @param string $template
* @return $this
*/ */
public function setTemplateFileEdit($template) { public function setTemplateFileEdit($template) {
$this->templateFileEdit = $template; $this->templateFileEdit = $template;
@ -328,7 +331,8 @@ class UploadField extends FileField {
} }
/** /**
* @param String * @param string $name
* @return $this
*/ */
public function setDisplayFolderName($name) { public function setDisplayFolderName($name) {
$this->displayFolderName = $name; $this->displayFolderName = $name;
@ -344,7 +348,9 @@ class UploadField extends FileField {
/** /**
* Force a record to be used as "Parent" for uploaded Files (eg a Page with a has_one to File) * Force a record to be used as "Parent" for uploaded Files (eg a Page with a has_one to File)
*
* @param DataObject $record * @param DataObject $record
* @return $this
*/ */
public function setRecord($record) { public function setRecord($record) {
$this->record = $record; $this->record = $record;
@ -389,6 +395,7 @@ class UploadField extends FileField {
* @param array|DataObject|SS_List $record Full source record, either as a DataObject, * @param array|DataObject|SS_List $record Full source record, either as a DataObject,
* SS_List of items, or an array of submitted form data * SS_List of items, or an array of submitted form data
* @return $this Self reference * @return $this Self reference
* @throws ValidationException
*/ */
public function setValue($value, $record = null) { public function setValue($value, $record = null) {
@ -727,7 +734,7 @@ class UploadField extends FileField {
* Defaults to 'ss-uploadfield-uploadtemplate' * Defaults to 'ss-uploadfield-uploadtemplate'
* *
* @see javascript/UploadField_uploadtemplate.js * @see javascript/UploadField_uploadtemplate.js
* @var string * @return string
*/ */
public function getUploadTemplateName() { public function getUploadTemplateName() {
return $this->getConfig('uploadTemplateName'); return $this->getConfig('uploadTemplateName');
@ -748,7 +755,7 @@ class UploadField extends FileField {
* Defaults to 'ss-downloadfield-downloadtemplate' * Defaults to 'ss-downloadfield-downloadtemplate'
* *
* @see javascript/DownloadField_downloadtemplate.js * @see javascript/DownloadField_downloadtemplate.js
* @var string * @return string
*/ */
public function getDownloadTemplateName() { public function getDownloadTemplateName() {
return $this->getConfig('downloadTemplateName'); return $this->getConfig('downloadTemplateName');
@ -1295,6 +1302,7 @@ class UploadField extends FileField {
* Determines if a specified file exists * Determines if a specified file exists
* *
* @param SS_HTTPRequest $request * @param SS_HTTPRequest $request
* @return SS_HTTPResponse
*/ */
public function fileexists(SS_HTTPRequest $request) { public function fileexists(SS_HTTPRequest $request) {
// Assert that requested filename doesn't attempt to escape the directory // Assert that requested filename doesn't attempt to escape the directory
@ -1327,7 +1335,7 @@ class UploadField extends FileField {
* Gets the foreign class that needs to be created, or 'File' as default if there * Gets the foreign class that needs to be created, or 'File' as default if there
* is no relationship, or it cannot be determined. * is no relationship, or it cannot be determined.
* *
* @param $default Default value to return if no value could be calculated * @param string $default Default value to return if no value could be calculated
* @return string Foreign class name. * @return string Foreign class name.
*/ */
public function getRelationAutosetClass($default = 'File') { public function getRelationAutosetClass($default = 'File') {
@ -1605,7 +1613,7 @@ class UploadField_SelectHandler extends RequestHandler {
} }
/** /**
* @param $folderID The ID of the folder to display. * @param int $folderID The ID of the folder to display.
* @return FormField * @return FormField
*/ */
protected function getListField($folderID) { protected function getListField($folderID) {

View File

@ -3,6 +3,9 @@
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\Security\Member;
/** /**
@ -81,10 +84,11 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr
/** /**
* Handle the print action. * Handle the print action.
* *
* @param GridField * @param GridField $gridField
* @param string * @param string $actionName
* @param array * @param array $arguments
* @param array * @param array $data
* @return DBHTMLText
*/ */
public function handleAction(GridField $gridField, $actionName, $arguments, $data) { public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if($actionName == 'print') { if($actionName == 'print') {
@ -106,7 +110,11 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr
/** /**
* Handle the print, for both the action button and the URL * Handle the print, for both the action button and the URL
*/ *
* @param GridField $gridField
* @param SS_HTTPRequest $request
* @return DBHTMLText
*/
public function handlePrint($gridField, $request = null) { public function handlePrint($gridField, $request = null) {
set_time_limit(60); set_time_limit(60);
Requirements::clear(); Requirements::clear();
@ -172,8 +180,9 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr
/** /**
* Export core. * Export core.
* *
* @param GridField * @param GridField $gridField
*/ * @return ArrayData
*/
public function generatePrintData(GridField $gridField) { public function generatePrintData(GridField $gridField) {
$printColumns = $this->getPrintColumnsForGridField($gridField); $printColumns = $this->getPrintColumnsForGridField($gridField);
@ -234,7 +243,8 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr
} }
/** /**
* @param array * @param array $cols
* @return $this
*/ */
public function setPrintColumns($cols) { public function setPrintColumns($cols) {
$this->printColumns = $cols; $this->printColumns = $cols;
@ -250,7 +260,8 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr
} }
/** /**
* @param boolean * @param bool $bool
* @return $this
*/ */
public function setPrintHasHeader($bool) { public function setPrintHasHeader($bool) {
$this->printHasHeader = $bool; $this->printHasHeader = $bool;

View File

@ -2,6 +2,9 @@
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\DataModel; use SilverStripe\ORM\DataModel;
use SilverStripe\Security\Security;
use SilverStripe\Security\Permission;
/************************************************************************************ /************************************************************************************
************************************************************************************ ************************************************************************************
@ -162,7 +165,7 @@ $chain
} }
// Fail and redirect the user to the login page // Fail and redirect the user to the login page
$loginPage = Director::absoluteURL(Config::inst()->get('Security', 'login_url')); $loginPage = Director::absoluteURL(Security::config()->login_url);
$loginPage .= "?BackURL=" . urlencode($_SERVER['REQUEST_URI']); $loginPage .= "?BackURL=" . urlencode($_SERVER['REQUEST_URI']);
header('location: '.$loginPage, true, 302); header('location: '.$loginPage, true, 302);
die; die;

View File

@ -1,4 +1,7 @@
<?php <?php
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/** /**
* Cleans up leftover databases from aborted test executions (starting with ss_tmpdb) * Cleans up leftover databases from aborted test executions (starting with ss_tmpdb)
* Task is restricted to users with administrator rights or running through CLI. * Task is restricted to users with administrator rights or running through CLI.

View File

@ -1,6 +1,10 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/** /**
* Encrypt all passwords * Encrypt all passwords
* *
@ -37,7 +41,7 @@ class EncryptAllPasswordsTask extends BuildTask {
} }
// Are there members with a clear text password? // Are there members with a clear text password?
$members = DataObject::get("Member")->where(array( $members = Member::get()->where(array(
'"Member"."PasswordEncryption"' => 'none', '"Member"."PasswordEncryption"' => 'none',
'"Member"."Password" IS NOT NULL' '"Member"."Password" IS NOT NULL'
)); ));

View File

@ -1,46 +0,0 @@
<?php
use SilverStripe\ORM\DataObject;
/**
* Regenerate all cached images that have been created as the result of a manipulation method being called on a
* {@link Image} object
*
* @package framework
* @subpackage filesystem
*/
class RegenerateCachedImagesTask extends BuildTask {
protected $title = 'Regenerate Cached Images Task';
protected $description = 'Regenerate all cached images created as the result of an image manipulation';
/**
* Check that the user has appropriate permissions to execute this task
*/
public function init() {
if(!Director::is_cli() && !Director::isDev() && !Permission::check('ADMIN')) {
return Security::permissionFailure();
}
parent::init();
}
/**
* Actually regenerate all the images
*/
public function run($request) {
$processedImages = 0;
$regeneratedImages = 0;
if($images = DataObject::get('Image')) foreach($images as $image) {
if($generated = $image->regenerateFormattedImages()) {
$regeneratedImages += $generated;
}
$processedImages++;
}
echo "Regenerated $regeneratedImages cached images from $processedImages Image objects stored in the Database.";
}
}

View File

@ -1,4 +1,7 @@
<?php <?php
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/** /**
* @package framework * @package framework
* @subpackage tasks * @subpackage tasks

View File

@ -1,14 +0,0 @@
Group:
admins:
Title: Administrators
Permission:
admin:
Code: ADMIN
Group: =>Group.admins
Member:
admin:
Email: admin
Password: password
Groups: =>Group.admins

View File

@ -42,11 +42,11 @@ class FeatureContext extends SilverStripeContext {
// Use blueprints to set user name from identifier // Use blueprints to set user name from identifier
$factory = $fixtureContext->getFixtureFactory(); $factory = $fixtureContext->getFixtureFactory();
$blueprint = \Injector::inst()->create('FixtureBlueprint', 'Member'); $blueprint = \Injector::inst()->create('FixtureBlueprint', 'SilverStripe\\Security\\Member');
$blueprint->addCallback('beforeCreate', function($identifier, &$data, &$fixtures) { $blueprint->addCallback('beforeCreate', function($identifier, &$data, &$fixtures) {
if(!isset($data['FirstName'])) $data['FirstName'] = $identifier; if(!isset($data['FirstName'])) $data['FirstName'] = $identifier;
}); });
$factory->define('Member', $blueprint); $factory->define('SilverStripe\\Security\\Member', $blueprint);
} }
public function setMinkParameters(array $parameters) { public function setMinkParameters(array $parameters) {

View File

@ -13,8 +13,8 @@ class CMSProfileControllerTest extends FunctionalTest {
public $autoFollowRedirection = false; public $autoFollowRedirection = false;
public function testMemberCantEditAnother() { public function testMemberCantEditAnother() {
$member = $this->objFromFixture('Member', 'user1'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'user1');
$anotherMember = $this->objFromFixture('Member', 'user2'); $anotherMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'user2');
$this->session()->inst_set('loggedInAs', $member->ID); $this->session()->inst_set('loggedInAs', $member->ID);
$response = $this->post('admin/myprofile/EditForm', array( $response = $this->post('admin/myprofile/EditForm', array(
@ -28,13 +28,13 @@ class CMSProfileControllerTest extends FunctionalTest {
'Password[_ConfirmPassword]' => 'password', 'Password[_ConfirmPassword]' => 'password',
)); ));
$anotherMember = $this->objFromFixture('Member', 'user2'); $anotherMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'user2');
$this->assertNotEquals($anotherMember->FirstName, 'JoeEdited', 'FirstName field stays the same'); $this->assertNotEquals($anotherMember->FirstName, 'JoeEdited', 'FirstName field stays the same');
} }
public function testMemberEditsOwnProfile() { public function testMemberEditsOwnProfile() {
$member = $this->objFromFixture('Member', 'user3'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'user3');
$this->session()->inst_set('loggedInAs', $member->ID); $this->session()->inst_set('loggedInAs', $member->ID);
$response = $this->post('admin/myprofile/EditForm', array( $response = $this->post('admin/myprofile/EditForm', array(
@ -48,16 +48,16 @@ class CMSProfileControllerTest extends FunctionalTest {
'Password[_ConfirmPassword]' => 'password', 'Password[_ConfirmPassword]' => 'password',
)); ));
$member = $this->objFromFixture('Member', 'user3'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'user3');
$this->assertEquals('JoeEdited', $member->FirstName, 'FirstName field was changed'); $this->assertEquals('JoeEdited', $member->FirstName, 'FirstName field was changed');
} }
public function testExtendedPermissionsStopEditingOwnProfile() { public function testExtendedPermissionsStopEditingOwnProfile() {
$existingExtensions = Config::inst()->get('Member', 'extensions'); $existingExtensions = Config::inst()->get('SilverStripe\\Security\\Member', 'extensions');
Config::inst()->update('Member', 'extensions', array('CMSProfileControllerTestExtension')); Config::inst()->update('SilverStripe\\Security\\Member', 'extensions', array('CMSProfileControllerTestExtension'));
$member = $this->objFromFixture('Member', 'user1'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'user1');
$this->session()->inst_set('loggedInAs', $member->ID); $this->session()->inst_set('loggedInAs', $member->ID);
$response = $this->post('admin/myprofile/EditForm', array( $response = $this->post('admin/myprofile/EditForm', array(
@ -71,13 +71,13 @@ class CMSProfileControllerTest extends FunctionalTest {
'Password[_ConfirmPassword]' => 'password', 'Password[_ConfirmPassword]' => 'password',
)); ));
$member = $this->objFromFixture('Member', 'user1'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'user1');
$this->assertNotEquals($member->FirstName, 'JoeEdited', $this->assertNotEquals($member->FirstName, 'JoeEdited',
'FirstName field was NOT changed because we modified canEdit'); 'FirstName field was NOT changed because we modified canEdit');
Config::inst()->remove('Member', 'extensions'); Config::inst()->remove('SilverStripe\\Security\\Member', 'extensions');
Config::inst()->update('Member', 'extensions', $existingExtensions); Config::inst()->update('SilverStripe\\Security\\Member', 'extensions', $existingExtensions);
} }
} }

View File

@ -1,4 +1,4 @@
Permission: 'SilverStripe\Security\Permission':
admin: admin:
Code: ADMIN Code: ADMIN
cmsmain: cmsmain:
@ -8,31 +8,31 @@ Permission:
test: test:
Code: CMS_ACCESS_TestController Code: CMS_ACCESS_TestController
Group: 'SilverStripe\Security\Group':
admins: admins:
Title: Administrators Title: Administrators
Permissions: =>Permission.admin Permissions: '=>SilverStripe\Security\Permission.admin'
cmsusers: cmsusers:
Title: CMS Users Title: CMS Users
Permissions: =>Permission.cmsmain, =>Permission.leftandmain Permissions: '=>SilverStripe\Security\Permission.cmsmain, =>SilverStripe\Security\Permission.leftandmain'
test: test:
Title: Test group Title: Test group
Permissions: =>Permission.test Permissions: '=>SilverStripe\Security\Permission.test'
Member: 'SilverStripe\Security\Member':
admin: admin:
FirstName: Admin FirstName: Admin
Email: admin@user.com Email: admin@user.com
Groups: =>Group.admins Groups: '=>SilverStripe\Security\Group.admins'
user1: user1:
FirstName: Joe FirstName: Joe
Email: user1@user.com Email: user1@user.com
Groups: =>Group.cmsusers Groups: '=>SilverStripe\Security\Group.cmsusers'
user2: user2:
FirstName: Steve FirstName: Steve
Email: user2@user.com Email: user2@user.com
Groups: =>Group.cmsusers Groups: '=>SilverStripe\Security\Group.cmsusers'
user3: user3:
FirstName: Files FirstName: Files
Email: user3@example.com Email: user3@example.com
Groups: =>Group.test Groups: '=>SilverStripe\Security\Group.test'

View File

@ -57,7 +57,7 @@ class ControllerTest extends FunctionalTest {
} }
public function testAllowedActions() { public function testAllowedActions() {
$adminUser = $this->objFromFixture('Member', 'admin'); $adminUser = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$response = $this->get("ControllerTest_UnsecuredController/"); $response = $this->get("ControllerTest_UnsecuredController/");
$this->assertEquals(200, $response->getStatusCode(), $this->assertEquals(200, $response->getStatusCode(),

View File

@ -1,11 +1,11 @@
Permission: 'SilverStripe\Security\Permission':
admin: admin:
Code: ADMIN Code: ADMIN
Group: 'SilverStripe\Security\Group':
admins: admins:
Code: admins Code: admins
Permissions: =>Permission.admin Permissions: '=>SilverStripe\Security\Permission.admin'
Member: 'SilverStripe\Security\Member':
admin: admin:
Email: admin@test.com Email: admin@test.com
Groups: =>Group.admins Groups: '=>SilverStripe\Security\Group.admins'

View File

@ -394,7 +394,7 @@ class DirectorTest extends SapphireTest {
} }
public function testForceSSLOnSubPagesPattern() { public function testForceSSLOnSubPagesPattern() {
$_SERVER['REQUEST_URI'] = Director::baseURL() . Config::inst()->get('Security', 'login_url'); $_SERVER['REQUEST_URI'] = Director::baseURL() . Config::inst()->get('SilverStripe\\Security\\Security', 'login_url');
$output = Director::forceSSL(array('/^Security/')); $output = Director::forceSSL(array('/^Security/'));
$this->assertEquals($output, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); $this->assertEquals($output, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
} }

View File

@ -1,5 +1,7 @@
<?php <?php
use SilverStripe\Security\SecurityToken;
/** /**
* Tests for RequestHandler and SS_HTTPRequest. * Tests for RequestHandler and SS_HTTPRequest.
* We've set up a simple URL handling model based on * We've set up a simple URL handling model based on

View File

@ -8,6 +8,10 @@
class NamespacedClassManifestTest extends SapphireTest { class NamespacedClassManifestTest extends SapphireTest {
protected $base; protected $base;
/**
* @var SS_ClassManifest
*/
protected $manifest; protected $manifest;
public function setUp() { public function setUp() {
@ -28,13 +32,14 @@ class NamespacedClassManifestTest extends SapphireTest {
$tokens = token_get_all($file); $tokens = token_get_all($file);
$parsedTokens = SS_ClassManifest::get_imported_namespace_parser()->findAll($tokens); $parsedTokens = SS_ClassManifest::get_imported_namespace_parser()->findAll($tokens);
/** @skipUpgrade */
$expectedItems = array( $expectedItems = array(
array('ModelAdmin'), array('ModelAdmin'),
array('Controller', ' ', 'as', ' ', 'Cont'), array('Controller', ' ', 'as', ' ', 'Cont'),
array( array(
'SS_HTTPRequest', ' ', 'as', ' ', 'Request', ',', 'SS_HTTPRequest', ' ', 'as', ' ', 'Request', ',',
'SS_HTTPResponse', ' ', 'AS', ' ', 'Response', ',', 'SS_HTTPResponse', ' ', 'as', ' ', 'Response', ',',
'PermissionProvider', ' ', 'AS', ' ', 'P', 'SilverStripe', '\\', 'Security', '\\', 'PermissionProvider', ' ', 'as', ' ', 'P',
), ),
array('silverstripe', '\\', 'test', '\\', 'ClassA'), array('silverstripe', '\\', 'test', '\\', 'ClassA'),
array('\\', 'Object'), array('\\', 'Object'),
@ -59,7 +64,7 @@ class NamespacedClassManifestTest extends SapphireTest {
'Cont' => 'Controller', 'Cont' => 'Controller',
'Request' => 'SS_HTTPRequest', 'Request' => 'SS_HTTPRequest',
'Response' => 'SS_HTTPResponse', 'Response' => 'SS_HTTPResponse',
'P' => 'PermissionProvider', 'P' => 'SilverStripe\\Security\\PermissionProvider',
'silverstripe\test\ClassA', 'silverstripe\test\ClassA',
'\Object', '\Object',
); );
@ -71,7 +76,7 @@ class NamespacedClassManifestTest extends SapphireTest {
} }
public function testClassInfoIsCorrect() { public function testClassInfoIsCorrect() {
$this->assertContains('SilverStripe\Framework\Tests\ClassI', ClassInfo::implementorsOf('PermissionProvider')); $this->assertContains('SilverStripe\Framework\Tests\ClassI', ClassInfo::implementorsOf('SilverStripe\\Security\\PermissionProvider'));
//because we're using a nested manifest we have to "coalesce" the descendants again to correctly populate the //because we're using a nested manifest we have to "coalesce" the descendants again to correctly populate the
// descendants of the core classes we want to test against - this is a limitation of the test manifest not // descendants of the core classes we want to test against - this is a limitation of the test manifest not
@ -83,20 +88,26 @@ class NamespacedClassManifestTest extends SapphireTest {
$this->assertContains('SilverStripe\Framework\Tests\ClassI', ClassInfo::subclassesFor('ModelAdmin')); $this->assertContains('SilverStripe\Framework\Tests\ClassI', ClassInfo::subclassesFor('ModelAdmin'));
} }
/**
* @skipUpgrade
*/
public function testFindClassOrInterfaceFromCandidateImports() { public function testFindClassOrInterfaceFromCandidateImports() {
$method = new ReflectionMethod($this->manifest, 'findClassOrInterfaceFromCandidateImports'); $method = new ReflectionMethod($this->manifest, 'findClassOrInterfaceFromCandidateImports');
$method->setAccessible(true); $method->setAccessible(true);
$this->assertTrue(ClassInfo::exists('silverstripe\test\ClassA')); $this->assertTrue(ClassInfo::exists('silverstripe\test\ClassA'));
$this->assertEquals('PermissionProvider', $method->invokeArgs($this->manifest, array( $this->assertEquals(
'\PermissionProvider', 'PermissionProvider',
'Test\Namespace', $method->invokeArgs($this->manifest, [
array( '\PermissionProvider',
'TestOnly', 'Test\Namespace',
'Controller', array(
), 'TestOnly',
))); 'Controller',
),
])
);
$this->assertEquals('PermissionProvider', $method->invokeArgs($this->manifest, array( $this->assertEquals('PermissionProvider', $method->invokeArgs($this->manifest, array(
'PermissionProvider', 'PermissionProvider',
@ -236,7 +247,7 @@ class NamespacedClassManifestTest extends SapphireTest {
'silverstripe\test\interfacea' => array('silverstripe\test\ClassE'), 'silverstripe\test\interfacea' => array('silverstripe\test\ClassE'),
'interfacea' => array('silverstripe\test\ClassF'), 'interfacea' => array('silverstripe\test\ClassF'),
'silverstripe\test\subtest\interfacea' => array('silverstripe\test\ClassG'), 'silverstripe\test\subtest\interfacea' => array('silverstripe\test\ClassG'),
'permissionprovider' => array('SilverStripe\Framework\Tests\ClassI'), 'silverstripe\security\permissionprovider' => array('SilverStripe\Framework\Tests\ClassI'),
); );
$this->assertEquals($expect, $this->manifest->getImplementors()); $this->assertEquals($expect, $this->manifest->getImplementors());
} }

View File

@ -4,9 +4,10 @@ namespace SilverStripe\Framework\Tests;
//whitespace here is important for tests, please don't change it //whitespace here is important for tests, please don't change it
use ModelAdmin; use ModelAdmin;
use Controller as Cont ; use Controller as Cont ;
use SS_HTTPRequest as Request,SS_HTTPResponse AS Response, PermissionProvider AS P; use SS_HTTPRequest as Request, SS_HTTPResponse as Response, SilverStripe\Security\PermissionProvider as P;
use silverstripe\test\ClassA; use silverstripe\test\ClassA;
use \Object; use \Object;
class ClassI extends ModelAdmin implements P { class ClassI extends ModelAdmin implements P {
} }

View File

@ -2,6 +2,8 @@
use SilverStripe\Filesystem\Storage\AssetStore; use SilverStripe\Filesystem\Storage\AssetStore;
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
/** /**

View File

@ -5,6 +5,8 @@ use SilverStripe\Filesystem\Storage\AssetStore;
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ValidationException; use SilverStripe\ORM\ValidationException;
use SilverStripe\Security\Member;
/** /**
@ -509,23 +511,23 @@ class FileTest extends SapphireTest {
$this->assertFalse($file->canEdit(), "Anonymous users can't edit files"); $this->assertFalse($file->canEdit(), "Anonymous users can't edit files");
// Test permissionless user // Test permissionless user
$this->objFromFixture('Member', 'frontend')->logIn(); $this->objFromFixture('SilverStripe\\Security\\Member', 'frontend')->logIn();
$this->assertFalse($file->canEdit(), "Permissionless users can't edit files"); $this->assertFalse($file->canEdit(), "Permissionless users can't edit files");
// Test global CMS section users // Test global CMS section users
$this->objFromFixture('Member', 'cms')->logIn(); $this->objFromFixture('SilverStripe\\Security\\Member', 'cms')->logIn();
$this->assertTrue($file->canEdit(), "Users with all CMS section access can edit files"); $this->assertTrue($file->canEdit(), "Users with all CMS section access can edit files");
// Test cms access users without file access // Test cms access users without file access
$this->objFromFixture('Member', 'security')->logIn(); $this->objFromFixture('SilverStripe\\Security\\Member', 'security')->logIn();
$this->assertFalse($file->canEdit(), "Security CMS users can't edit files"); $this->assertFalse($file->canEdit(), "Security CMS users can't edit files");
// Test asset-admin user // Test asset-admin user
$this->objFromFixture('Member', 'assetadmin')->logIn(); $this->objFromFixture('SilverStripe\\Security\\Member', 'assetadmin')->logIn();
$this->assertTrue($file->canEdit(), "Asset admin users can edit files"); $this->assertTrue($file->canEdit(), "Asset admin users can edit files");
// Test admin // Test admin
$this->objFromFixture('Member', 'admin')->logIn(); $this->objFromFixture('SilverStripe\\Security\\Member', 'admin')->logIn();
$this->assertTrue($file->canEdit(), "Admins can edit files"); $this->assertTrue($file->canEdit(), "Admins can edit files");
} }

View File

@ -45,7 +45,7 @@ Image:
FileFilename: FileTest.png FileFilename: FileTest.png
FileHash: 55b443b60176235ef09801153cca4e6da7494a0c FileHash: 55b443b60176235ef09801153cca4e6da7494a0c
Name: FileTest.png Name: FileTest.png
Permission: 'SilverStripe\Security\Permission':
admin: admin:
Code: ADMIN Code: ADMIN
cmsmain: cmsmain:
@ -54,31 +54,31 @@ Permission:
Code: CMS_ACCESS_AssetAdmin Code: CMS_ACCESS_AssetAdmin
securityadmin: securityadmin:
Code: CMS_ACCESS_SecurityAdmin Code: CMS_ACCESS_SecurityAdmin
Group: 'SilverStripe\Security\Group':
admins: admins:
Title: Administrators Title: Administrators
Permissions: =>Permission.admin Permissions: '=>SilverStripe\Security\Permission.admin'
cmsusers: cmsusers:
Title: 'CMS Users' Title: 'CMS Users'
Permissions: =>Permission.cmsmain Permissions: '=>SilverStripe\Security\Permission.cmsmain'
securityusers: securityusers:
Title: 'Security Users' Title: 'Security Users'
Permissions: =>Permission.securityadmin Permissions: '=>SilverStripe\Security\Permission.securityadmin'
assetusers: assetusers:
Title: 'Asset Users' Title: 'Asset Users'
Permissions: =>Permission.assetadmin Permissions: '=>SilverStripe\Security\Permission.assetadmin'
Member: 'SilverStripe\Security\Member':
frontend: frontend:
Email: frontend@example.com Email: frontend@example.com
cms: cms:
Email: cms@silverstripe.com Email: cms@silverstripe.com
Groups: =>Group.cmsusers Groups: '=>SilverStripe\Security\Group.cmsusers'
admin: admin:
Email: admin@silverstripe.com Email: admin@silverstripe.com
Groups: =>Group.admins Groups: '=>SilverStripe\Security\Group.admins'
assetadmin: assetadmin:
Email: assetadmin@silverstripe.com Email: assetadmin@silverstripe.com
Groups: =>Group.assetusers Groups: '=>SilverStripe\Security\Group.assetusers'
security: security:
Email: security@silverstripe.com Email: security@silverstripe.com
Groups: =>Group.securityusers Groups: '=>SilverStripe\Security\Group.securityusers'

View File

@ -1,4 +1,6 @@
<?php <?php
use SilverStripe\Security\Member;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests

View File

@ -2,6 +2,8 @@
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataExtension; use SilverStripe\ORM\DataExtension;
use SilverStripe\Security\Member;
/** /**
* Tests for DataObject FormField scaffolding * Tests for DataObject FormField scaffolding

View File

@ -2,6 +2,9 @@
use SilverStripe\ORM\DataModel; use SilverStripe\ORM\DataModel;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\SecurityToken;
use SilverStripe\Security\RandomGenerator;
/** /**
* @package framework * @package framework
@ -387,12 +390,12 @@ class FormTest extends FunctionalTest {
SecurityToken::enable(); SecurityToken::enable();
$form1 = $this->getStubForm(); $form1 = $this->getStubForm();
$this->assertInstanceOf('SecurityToken', $form1->getSecurityToken()); $this->assertInstanceOf('SilverStripe\\Security\\SecurityToken', $form1->getSecurityToken());
SecurityToken::disable(); SecurityToken::disable();
$form2 = $this->getStubForm(); $form2 = $this->getStubForm();
$this->assertInstanceOf('NullSecurityToken', $form2->getSecurityToken()); $this->assertInstanceOf('SilverStripe\\Security\\NullSecurityToken', $form2->getSecurityToken());
SecurityToken::enable(); SecurityToken::enable();
} }

View File

@ -3,6 +3,8 @@
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\SS_List; use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
class GridFieldTest extends SapphireTest { class GridFieldTest extends SapphireTest {
/** /**
@ -75,7 +77,7 @@ class GridFieldTest extends SapphireTest {
*/ */
public function testGridFieldModelClass() { public function testGridFieldModelClass() {
$obj = new GridField('testfield', 'testfield', Member::get()); $obj = new GridField('testfield', 'testfield', Member::get());
$this->assertEquals('Member', $obj->getModelClass(), 'Should return Member'); $this->assertEquals('SilverStripe\\Security\\Member', $obj->getModelClass(), 'Should return Member');
$obj->setModelClass('SilverStripe\\ORM\\DataModel'); $obj->setModelClass('SilverStripe\\ORM\\DataModel');
$this->assertEquals('SilverStripe\\ORM\\DataModel', $obj->getModelClass(), 'Should return Member'); $this->assertEquals('SilverStripe\\ORM\\DataModel', $obj->getModelClass(), 'Should return Member');
} }

View File

@ -66,11 +66,11 @@ class LookupFieldTest extends SapphireTest {
} }
public function testArrayValueWithSqlMapSource() { public function testArrayValueWithSqlMapSource() {
$member1 = $this->objFromFixture('Member', 'member1'); $member1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member1');
$member2 = $this->objFromFixture('Member', 'member2'); $member2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member2');
$member3 = $this->objFromFixture('Member', 'member3'); $member3 = $this->objFromFixture('SilverStripe\\Security\\Member', 'member3');
$source = DataObject::get('Member'); $source = DataObject::get('SilverStripe\\Security\\Member');
$f = new LookupField('test', 'test', $source->map('ID', 'FirstName')); $f = new LookupField('test', 'test', $source->map('ID', 'FirstName'));
$f->setValue(array($member1->ID, $member2->ID)); $f->setValue(array($member1->ID, $member2->ID));

View File

@ -1,4 +1,4 @@
Member: 'SilverStripe\Security\Member':
member1: member1:
FirstName: member1 FirstName: member1
member2: member2:

View File

@ -45,7 +45,7 @@ class MemberDatetimeOptionsetFieldTest extends SapphireTest {
public function testDateFormatDefaultCheckedInFormField() { public function testDateFormatDefaultCheckedInFormField() {
Config::inst()->update('i18n', 'date_format', 'yyyy-MM-dd'); Config::inst()->update('i18n', 'date_format', 'yyyy-MM-dd');
$field = $this->createDateFormatFieldForMember($this->objFromFixture('Member', 'noformatmember')); $field = $this->createDateFormatFieldForMember($this->objFromFixture('SilverStripe\\Security\\Member', 'noformatmember'));
$field->setForm(new Form(new MemberDatetimeOptionsetFieldTest_Controller(), 'Form', new FieldList(), $field->setForm(new Form(new MemberDatetimeOptionsetFieldTest_Controller(), 'Form', new FieldList(),
new FieldList())); // fake form new FieldList())); // fake form
$parser = new CSSContentParser($field->Field()); $parser = new CSSContentParser($field->Field());
@ -55,7 +55,7 @@ class MemberDatetimeOptionsetFieldTest extends SapphireTest {
public function testTimeFormatDefaultCheckedInFormField() { public function testTimeFormatDefaultCheckedInFormField() {
Config::inst()->update('i18n', 'time_format', 'h:mm:ss a'); Config::inst()->update('i18n', 'time_format', 'h:mm:ss a');
$field = $this->createTimeFormatFieldForMember($this->objFromFixture('Member', 'noformatmember')); $field = $this->createTimeFormatFieldForMember($this->objFromFixture('SilverStripe\\Security\\Member', 'noformatmember'));
$field->setForm(new Form(new MemberDatetimeOptionsetFieldTest_Controller(), 'Form', new FieldList(), $field->setForm(new Form(new MemberDatetimeOptionsetFieldTest_Controller(), 'Form', new FieldList(),
new FieldList())); // fake form new FieldList())); // fake form
$parser = new CSSContentParser($field->Field()); $parser = new CSSContentParser($field->Field());
@ -64,7 +64,7 @@ class MemberDatetimeOptionsetFieldTest extends SapphireTest {
} }
public function testDateFormatChosenIsCheckedInFormField() { public function testDateFormatChosenIsCheckedInFormField() {
$member = $this->objFromFixture('Member', 'noformatmember'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'noformatmember');
$member->setField('DateFormat', 'MM/dd/yyyy'); $member->setField('DateFormat', 'MM/dd/yyyy');
$field = $this->createDateFormatFieldForMember($member); $field = $this->createDateFormatFieldForMember($member);
$field->setForm(new Form(new MemberDatetimeOptionsetFieldTest_Controller(), 'Form', new FieldList(), $field->setForm(new Form(new MemberDatetimeOptionsetFieldTest_Controller(), 'Form', new FieldList(),
@ -75,7 +75,7 @@ class MemberDatetimeOptionsetFieldTest extends SapphireTest {
} }
public function testDateFormatCustomFormatAppearsInCustomInputInField() { public function testDateFormatCustomFormatAppearsInCustomInputInField() {
$member = $this->objFromFixture('Member', 'noformatmember'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'noformatmember');
$member->setField('DateFormat', 'dd MM yy'); $member->setField('DateFormat', 'dd MM yy');
$field = $this->createDateFormatFieldForMember($member); $field = $this->createDateFormatFieldForMember($member);
$field->setForm(new Form(new MemberDatetimeOptionsetFieldTest_Controller(), 'Form', new FieldList(), $field->setForm(new Form(new MemberDatetimeOptionsetFieldTest_Controller(), 'Form', new FieldList(),

View File

@ -1,4 +1,4 @@
Member: 'SilverStripe\Security\Member':
noformatmember: noformatmember:
Email: noformat@test.com Email: noformat@test.com
delocalemember: delocalemember:

View File

@ -1,4 +1,6 @@
<?php <?php
use SilverStripe\Security\Member;
class GridFieldDataColumnsTest extends SapphireTest { class GridFieldDataColumnsTest extends SapphireTest {
/** /**
@ -6,7 +8,7 @@ class GridFieldDataColumnsTest extends SapphireTest {
*/ */
public function testGridFieldGetDefaultDisplayFields() { public function testGridFieldGetDefaultDisplayFields() {
$obj = new GridField('testfield', 'testfield', Member::get()); $obj = new GridField('testfield', 'testfield', Member::get());
$expected = singleton('Member')->summaryFields(); $expected = singleton('SilverStripe\\Security\\Member')->summaryFields();
$columns = $obj->getConfig()->getComponentByType('GridFieldDataColumns'); $columns = $obj->getConfig()->getComponentByType('GridFieldDataColumns');
$this->assertEquals($expected, $columns->getDisplayFields($obj)); $this->assertEquals($expected, $columns->getDisplayFields($obj));
} }

View File

@ -2,6 +2,9 @@
use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\SecurityToken;
class GridFieldDeleteActionTest extends SapphireTest { class GridFieldDeleteActionTest extends SapphireTest {

View File

@ -2,6 +2,8 @@
use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
class GridFieldEditButtonTest extends SapphireTest { class GridFieldEditButtonTest extends SapphireTest {

View File

@ -590,15 +590,15 @@ class i18nTest_DataObject extends DataObject implements TestOnly {
); );
private static $has_one = array( private static $has_one = array(
'HasOneRelation' => 'Member' 'HasOneRelation' => 'SilverStripe\\Security\\Member'
); );
private static $has_many = array( private static $has_many = array(
'HasManyRelation' => 'Member' 'HasManyRelation' => 'SilverStripe\\Security\\Member'
); );
private static $many_many = array( private static $many_many = array(
'ManyManyRelation' => 'Member' 'ManyManyRelation' => 'SilverStripe\\Security\\Member'
); );
/** /**

View File

@ -12,7 +12,7 @@ class i18nTextCollectorTestMyObject extends DataObject implements TestOnly {
); );
private static $has_many = array( private static $has_many = array(
'Relation' => 'Group' 'Relation' => 'SilverStripe\\Security\\Group'
); );
private static $singular_name = "My Object"; private static $singular_name = "My Object";

View File

@ -9,7 +9,7 @@ class i18nTextCollectorTestMySubObject extends i18nTextCollectorTestMyObject imp
); );
private static $has_many = array( private static $has_many = array(
'SubRelation' => 'Group' 'SubRelation' => 'SilverStripe\\Security\\Group'
); );
private static $singular_name = "My Sub Object"; private static $singular_name = "My Sub Object";

View File

@ -4,6 +4,8 @@ use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\Versioning\ChangeSet; use SilverStripe\ORM\Versioning\ChangeSet;
use SilverStripe\ORM\Versioning\ChangeSetItem; use SilverStripe\ORM\Versioning\ChangeSetItem;
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\Security\Permission;
/** /**
* Provides a set of targettable permissions for tested models * Provides a set of targettable permissions for tested models

View File

@ -1,6 +1,8 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests

View File

@ -253,7 +253,7 @@ class DBDateTest extends SapphireTest {
public function testFormatFromSettings() { public function testFormatFromSettings() {
$memberID = $this->logInWithPermission(); $memberID = $this->logInWithPermission();
$member = DataObject::get_by_id('Member', $memberID); $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $memberID);
$member->DateFormat = 'dd/MM/YYYY'; $member->DateFormat = 'dd/MM/YYYY';
$member->write(); $member->write();

View File

@ -120,8 +120,8 @@ class DataExtensionTest extends SapphireTest {
// in SiteTree->can*() methods to test one single feature reliably with them // in SiteTree->can*() methods to test one single feature reliably with them
$obj = $this->objFromFixture('DataExtensionTest_MyObject', 'object1'); $obj = $this->objFromFixture('DataExtensionTest_MyObject', 'object1');
$websiteuser = $this->objFromFixture('Member', 'websiteuser'); $websiteuser = $this->objFromFixture('SilverStripe\\Security\\Member', 'websiteuser');
$admin = $this->objFromFixture('Member', 'admin'); $admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$this->assertFalse( $this->assertFalse(
$obj->canOne($websiteuser), $obj->canOne($websiteuser),

View File

@ -1,24 +1,24 @@
DataExtensionTest_RelatedObject: DataExtensionTest_RelatedObject:
obj1: obj1:
FieldOne: Obj1 FieldOne: Obj1
obj2: obj2:
FieldOne: Obj2 FieldOne: Obj2
Permission: 'SilverStripe\Security\Permission':
adminpermission: adminpermission:
Code: ADMIN Code: ADMIN
Group: 'SilverStripe\Security\Group':
admingroup: admingroup:
Permissions: =>Permission.adminpermission Permissions: '=>SilverStripe\Security\Permission.adminpermission'
Member: 'SilverStripe\Security\Member':
admin: admin:
Email: admin@test.com Email: admin@test.com
Groups: =>Group.admingroup Groups: '=>SilverStripe\Security\Group.admingroup'
websiteuser: websiteuser:
Email: websiteuser@test.com Email: websiteuser@test.com
DataExtensionTest_Member: DataExtensionTest_Member:
member1: member1:
Name: Sam Name: Sam
Website: http://www.example.org Website: http://www.example.org
DataExtensionTest_MyObject: DataExtensionTest_MyObject:
object1: object1:
Title: Object 1 Title: Object 1

View File

@ -7,6 +7,8 @@ use SilverStripe\ORM\DB;
use SilverStripe\ORM\Connect\MySQLDatabase; use SilverStripe\ORM\Connect\MySQLDatabase;
use SilverStripe\ORM\DataExtension; use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\ValidationResult; use SilverStripe\ORM\ValidationResult;
use SilverStripe\Security\Member;
/** /**

View File

@ -43,12 +43,12 @@ class DataQueryTest extends SapphireTest {
* Test the leftJoin() and innerJoin method of the DataQuery object * Test the leftJoin() and innerJoin method of the DataQuery object
*/ */
public function testJoins() { public function testJoins() {
$dq = new DataQuery('Member'); $dq = new DataQuery('SilverStripe\\Security\\Member');
$dq->innerJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\""); $dq->innerJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\"");
$this->assertSQLContains("INNER JOIN \"Group_Members\" ON \"Group_Members\".\"MemberID\" = \"Member\".\"ID\"", $this->assertSQLContains("INNER JOIN \"Group_Members\" ON \"Group_Members\".\"MemberID\" = \"Member\".\"ID\"",
$dq->sql($parameters)); $dq->sql($parameters));
$dq = new DataQuery('Member'); $dq = new DataQuery('SilverStripe\\Security\\Member');
$dq->leftJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\""); $dq->leftJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\"");
$this->assertSQLContains("LEFT JOIN \"Group_Members\" ON \"Group_Members\".\"MemberID\" = \"Member\".\"ID\"", $this->assertSQLContains("LEFT JOIN \"Group_Members\" ON \"Group_Members\".\"MemberID\" = \"Member\".\"ID\"",
$dq->sql($parameters)); $dq->sql($parameters));

View File

@ -4,6 +4,8 @@ use SilverStripe\ORM\DB;
use SilverStripe\ORM\Connect\MySQLDatabase; use SilverStripe\ORM\Connect\MySQLDatabase;
use SilverStripe\ORM\Connect\MySQLSchemaManager; use SilverStripe\ORM\Connect\MySQLSchemaManager;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\MSSQL\MSSQLDatabase;
/** /**
* @package framework * @package framework
* @subpackage Testing * @subpackage Testing

View File

@ -202,7 +202,7 @@ class DBDatetimeTest extends SapphireTest {
public function testFormatFromSettings() { public function testFormatFromSettings() {
$memberID = $this->logInWithPermission(); $memberID = $this->logInWithPermission();
$member = DataObject::get_by_id('Member', $memberID); $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $memberID);
$member->DateFormat = 'dd/MM/YYYY'; $member->DateFormat = 'dd/MM/YYYY';
$member->TimeFormat = 'hh:mm:ss'; $member->TimeFormat = 'hh:mm:ss';
$member->write(); $member->write();

View File

@ -4,6 +4,9 @@ use SilverStripe\ORM\DB;
use SilverStripe\ORM\Connect\MySQLDatabase; use SilverStripe\ORM\Connect\MySQLDatabase;
use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\SQLite\SQLite3Database;
use SilverStripe\PostgreSQL\PostgreSQLDatabase;
/** /**
* @package framework * @package framework

View File

@ -1,4 +1,8 @@
<?php <?php
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
use SilverStripe\Security\BasicAuth;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests

View File

@ -1,11 +1,11 @@
Group: 'SilverStripe\Security\Group':
mygroup: mygroup:
Code: mygroup Code: mygroup
Member: SilverStripe\Security\Member:
user-in-mygroup: user-in-mygroup:
Email: user-in-mygroup@test.com Email: user-in-mygroup@test.com
Password: test Password: test
Groups: =>Group.mygroup Groups: '=>SilverStripe\Security\Group.mygroup'
user-without-groups: user-without-groups:
Email: user-without-groups@test.com Email: user-without-groups@test.com
Password: test Password: test
@ -13,7 +13,7 @@ Member:
Email: failedlogin@test.com Email: failedlogin@test.com
Password: Password Password: Password
FailedLoginCount: 0 FailedLoginCount: 0
Permission: 'SilverStripe\Security\Permission':
mycode: mycode:
Code: MYCODE Code: MYCODE
Group: =>Group.mygroup Group: '=>SilverStripe\Security\Group.mygroup'

View File

@ -1,4 +1,7 @@
<?php <?php
use SilverStripe\Security\GroupCsvBulkLoader;
use SilverStripe\Security\Group;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests

View File

@ -1,7 +1,7 @@
Permission: 'SilverStripe\Security\Permission':
permission1: permission1:
Code: CODE1 Code: CODE1
Group: 'SilverStripe\Security\Group':
existinggroup: existinggroup:
Code: existinggroup Code: existinggroup
Permissions: =>Permission.permission1 Permissions: '=>SilverStripe\Security\Permission.permission1'

View File

@ -1,6 +1,9 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
@ -30,9 +33,9 @@ class GroupTest extends FunctionalTest {
public function testMemberGroupRelationForm() { public function testMemberGroupRelationForm() {
Session::set('loggedInAs', $this->idFromFixture('GroupTest_Member', 'admin')); Session::set('loggedInAs', $this->idFromFixture('GroupTest_Member', 'admin'));
$adminGroup = $this->objFromFixture('Group', 'admingroup'); $adminGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'admingroup');
$parentGroup = $this->objFromFixture('Group', 'parentgroup'); $parentGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'parentgroup');
$childGroup = $this->objFromFixture('Group', 'childgroup'); $childGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'childgroup');
// Test single group relation through checkboxsetfield // Test single group relation through checkboxsetfield
$form = new GroupTest_MemberForm($this, 'Form'); $form = new GroupTest_MemberForm($this, 'Form');
@ -86,8 +89,8 @@ class GroupTest extends FunctionalTest {
} }
public function testCollateAncestorIDs() { public function testCollateAncestorIDs() {
$parentGroup = $this->objFromFixture('Group', 'parentgroup'); $parentGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'parentgroup');
$childGroup = $this->objFromFixture('Group', 'childgroup'); $childGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'childgroup');
$orphanGroup = new Group(); $orphanGroup = new Group();
$orphanGroup->ParentID = 99999; $orphanGroup->ParentID = 99999;
$orphanGroup->write(); $orphanGroup->write();
@ -110,26 +113,26 @@ class GroupTest extends FunctionalTest {
} }
public function testDelete() { public function testDelete() {
$group = $this->objFromFixture('Group', 'parentgroup'); $group = $this->objFromFixture('SilverStripe\\Security\\Group', 'parentgroup');
$groupID = $group->ID; $groupID = $group->ID;
$childGroupID = $this->idFromFixture('Group', 'childgroup'); $childGroupID = $this->idFromFixture('SilverStripe\\Security\\Group', 'childgroup');
$group->delete(); $group->delete();
$this->assertEquals(0, DataObject::get('Group', "\"ID\" = {$groupID}")->Count(), $this->assertEquals(0, DataObject::get('SilverStripe\\Security\\Group', "\"ID\" = {$groupID}")->Count(),
'Group is removed'); 'Group is removed');
$this->assertEquals(0, DataObject::get('Permission', "\"GroupID\" = {$groupID}")->Count(), $this->assertEquals(0, DataObject::get('SilverStripe\\Security\\Permission', "\"GroupID\" = {$groupID}")->Count(),
'Permissions removed along with the group'); 'Permissions removed along with the group');
$this->assertEquals(0, DataObject::get('Group', "\"ParentID\" = {$groupID}")->Count(), $this->assertEquals(0, DataObject::get('SilverStripe\\Security\\Group', "\"ParentID\" = {$groupID}")->Count(),
'Child groups are removed'); 'Child groups are removed');
$this->assertEquals(0, DataObject::get('Group', "\"ParentID\" = {$childGroupID}")->Count(), $this->assertEquals(0, DataObject::get('SilverStripe\\Security\\Group', "\"ParentID\" = {$childGroupID}")->Count(),
'Grandchild groups are removed'); 'Grandchild groups are removed');
} }
public function testValidatesPrivilegeLevelOfParent() { public function testValidatesPrivilegeLevelOfParent() {
$nonAdminUser = $this->objFromFixture('GroupTest_Member', 'childgroupuser'); $nonAdminUser = $this->objFromFixture('GroupTest_Member', 'childgroupuser');
$adminUser = $this->objFromFixture('GroupTest_Member', 'admin'); $adminUser = $this->objFromFixture('GroupTest_Member', 'admin');
$nonAdminGroup = $this->objFromFixture('Group', 'childgroup'); $nonAdminGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'childgroup');
$adminGroup = $this->objFromFixture('Group', 'admingroup'); $adminGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'admingroup');
$nonAdminValidateMethod = new ReflectionMethod($nonAdminGroup, 'validate'); $nonAdminValidateMethod = new ReflectionMethod($nonAdminGroup, 'validate');
$nonAdminValidateMethod->setAccessible(true); $nonAdminValidateMethod->setAccessible(true);
@ -154,7 +157,7 @@ class GroupTest extends FunctionalTest {
$newlyAdminGroup = $nonAdminGroup; $newlyAdminGroup = $nonAdminGroup;
$this->logInWithPermission('ADMIN'); $this->logInWithPermission('ADMIN');
$inheritedAdminGroup = $this->objFromFixture('Group', 'group1'); $inheritedAdminGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'group1');
$inheritedAdminMethod = new ReflectionMethod($inheritedAdminGroup, 'validate'); $inheritedAdminMethod = new ReflectionMethod($inheritedAdminGroup, 'validate');
$inheritedAdminMethod->setAccessible(true); $inheritedAdminMethod->setAccessible(true);
$inheritedAdminGroup->ParentID = $adminGroup->ID; $inheritedAdminGroup->ParentID = $adminGroup->ID;
@ -173,7 +176,7 @@ class GroupTest extends FunctionalTest {
class GroupTest_Member extends Member implements TestOnly { class GroupTest_Member extends Member implements TestOnly {
public function getCMSFields() { public function getCMSFields() {
$groups = DataObject::get('Group'); $groups = DataObject::get('SilverStripe\\Security\\Group');
$groupsMap = ($groups) ? $groups->map() : false; $groupsMap = ($groups) ? $groups->map() : false;
$fields = new FieldList( $fields = new FieldList(
new HiddenField('ID', 'ID'), new HiddenField('ID', 'ID'),

View File

@ -1,32 +1,32 @@
Group: 'SilverStripe\Security\Group':
admingroup: admingroup:
Code: admingroup Code: admingroup
parentgroup: parentgroup:
Code: parentgroup Code: parentgroup
childgroup: childgroup:
Code: childgroup Code: childgroup
Parent: =>Group.parentgroup Parent: '=>SilverStripe\Security\Group.parentgroup'
grandchildgroup: grandchildgroup:
Code: grandchildgroup Code: grandchildgroup
Parent: =>Group.childgroup Parent: '=>SilverStripe\Security\Group.childgroup'
group1: group1:
Title: Group 1 Title: Group 1
group2: group2:
Title: Group 2 Title: Group 2
GroupTest_Member: GroupTest_Member:
admin: admin:
FirstName: Admin FirstName: Admin
Groups: =>Group.admingroup Groups: '=>SilverStripe\Security\Group.admingroup'
parentgroupuser: parentgroupuser:
FirstName: Parent Group User FirstName: Parent Group User
Groups: =>Group.parentgroup Groups: '=>SilverStripe\Security\Group.parentgroup'
childgroupuser: childgroupuser:
FirstName: Child Group User FirstName: Child Group User
Groups: =>Group.childgroup Groups: '=>SilverStripe\Security\Group.childgroup'
allgroupuser: allgroupuser:
FirstName: All Group User FirstName: All Group User
Groups: =>Group.admingroup,=>Group.parentgroup,=>Group.childgroup Groups: '=>SilverStripe\Security\Group.admingroup,=>SilverStripe\Security\Group.parentgroup,=>SilverStripe\Security\Group.childgroup'
Permission: 'SilverStripe\Security\Permission':
admincode: admincode:
Code: ADMIN Code: ADMIN
Group: =>Group.admingroup Group: '=>SilverStripe\Security\Group.admingroup'

View File

@ -2,6 +2,12 @@
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\Security\Security;
use SilverStripe\Security\Member;
use SilverStripe\Security\MemberAuthenticator;
use SilverStripe\Security\MemberLoginForm;
use SilverStripe\Security\CMSMemberLoginForm;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
@ -43,15 +49,18 @@ class MemberAuthenticatorTest extends SapphireTest {
); );
MemberAuthenticator::authenticate($data); MemberAuthenticator::authenticate($data);
$member = DataObject::get_by_id('Member', $member->ID); $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member->ID);
$this->assertEquals($member->PasswordEncryption, "sha1_v2.4"); $this->assertEquals($member->PasswordEncryption, "sha1_v2.4");
$result = $member->checkPassword('mypassword'); $result = $member->checkPassword('mypassword');
$this->assertTrue($result->valid()); $this->assertTrue($result->valid());
} }
public function testNoLegacyPasswordHashMigrationOnIncompatibleAlgorithm() { public function testNoLegacyPasswordHashMigrationOnIncompatibleAlgorithm() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('crc32'=>array('PasswordEncryptor_PHPHash'=>'crc32'))); 'SilverStripe\\Security\\PasswordEncryptor',
'encryptors',
array('crc32' => array('SilverStripe\\Security\\PasswordEncryptor_PHPHash' => 'crc32'))
);
$field=Member::config()->unique_identifier_field; $field=Member::config()->unique_identifier_field;
$member = new Member(); $member = new Member();
@ -66,7 +75,7 @@ class MemberAuthenticatorTest extends SapphireTest {
); );
MemberAuthenticator::authenticate($data); MemberAuthenticator::authenticate($data);
$member = DataObject::get_by_id('Member', $member->ID); $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $member->ID);
$this->assertEquals($member->PasswordEncryption, "crc32"); $this->assertEquals($member->PasswordEncryption, "crc32");
$result = $member->checkPassword('mypassword'); $result = $member->checkPassword('mypassword');
$this->assertTrue($result->valid()); $this->assertTrue($result->valid());
@ -77,7 +86,7 @@ class MemberAuthenticatorTest extends SapphireTest {
$origField = Member::config()->unique_identifier_field; $origField = Member::config()->unique_identifier_field;
Member::config()->unique_identifier_field = 'Username'; Member::config()->unique_identifier_field = 'Username';
$label=singleton('Member')->fieldLabel(Member::config()->unique_identifier_field); $label=singleton('SilverStripe\\Security\\Member')->fieldLabel(Member::config()->unique_identifier_field);
$this->assertEquals($label, 'Username'); $this->assertEquals($label, 'Username');
@ -170,8 +179,8 @@ class MemberAuthenticatorTest extends SapphireTest {
public function testDefaultAdminLockOut() public function testDefaultAdminLockOut()
{ {
Config::inst()->update('Member', 'lock_out_after_incorrect_logins', 1); Config::inst()->update('SilverStripe\\Security\\Member', 'lock_out_after_incorrect_logins', 1);
Config::inst()->update('Member', 'lock_out_delay_mins', 10); Config::inst()->update('SilverStripe\\Security\\Member', 'lock_out_delay_mins', 10);
DBDatetime::set_mock_now('2016-04-18 00:00:00'); DBDatetime::set_mock_now('2016-04-18 00:00:00');
$controller = new Security(); $controller = new Security();
$form = new Form($controller, 'Form', new FieldList(), new FieldList()); $form = new Form($controller, 'Form', new FieldList(), new FieldList());

View File

@ -1,6 +1,10 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\MemberCsvBulkLoader;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
@ -35,7 +39,7 @@ class MemberCsvBulkLoaderTest extends SapphireTest {
} }
public function testAddToPredefinedGroups() { public function testAddToPredefinedGroups() {
$existinggroup = $this->objFromFixture('Group', 'existinggroup'); $existinggroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'existinggroup');
$loader = new MemberCsvBulkLoader(); $loader = new MemberCsvBulkLoader();
$loader->setGroups(array($existinggroup)); $loader->setGroups(array($existinggroup));
@ -51,12 +55,12 @@ class MemberCsvBulkLoaderTest extends SapphireTest {
} }
public function testAddToCsvColumnGroupsByCode() { public function testAddToCsvColumnGroupsByCode() {
$existinggroup = $this->objFromFixture('Group', 'existinggroup'); $existinggroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'existinggroup');
$loader = new MemberCsvBulkLoader(); $loader = new MemberCsvBulkLoader();
$results = $loader->load($this->getCurrentRelativePath() . '/MemberCsvBulkLoaderTest_withGroups.csv'); $results = $loader->load($this->getCurrentRelativePath() . '/MemberCsvBulkLoaderTest_withGroups.csv');
$newgroup = DataObject::get_one('Group', array( $newgroup = DataObject::get_one('SilverStripe\\Security\\Group', array(
'"Group"."Code"' => 'newgroup' '"Group"."Code"' => 'newgroup'
)); ));
$this->assertEquals($newgroup->Title, 'newgroup'); $this->assertEquals($newgroup->Title, 'newgroup');
@ -78,7 +82,7 @@ class MemberCsvBulkLoaderTest extends SapphireTest {
$member = $results->Created()->First(); $member = $results->Created()->First();
$memberID = $member->ID; $memberID = $member->ID;
DataObject::flush_and_destroy_cache(); DataObject::flush_and_destroy_cache();
$member = DataObject::get_by_id('Member', $memberID); $member = DataObject::get_by_id('SilverStripe\\Security\\Member', $memberID);
// TODO Direct getter doesn't work, wtf! // TODO Direct getter doesn't work, wtf!
$this->assertEquals(Security::config()->password_encryption_algorithm, $member->getField('PasswordEncryption')); $this->assertEquals(Security::config()->password_encryption_algorithm, $member->getField('PasswordEncryption'));

View File

@ -1,7 +1,7 @@
Group: 'SilverStripe\Security\Group':
existinggroup: existinggroup:
Code: existinggroup Code: existinggroup
Member: 'SilverStripe\Security\Member':
existingauthor: existingauthor:
Email: existingauthor@test.com Email: existingauthor@test.com
FirstName: Existing Author FirstName: Existing Author

View File

@ -4,6 +4,16 @@ use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\DataExtension; use SilverStripe\ORM\DataExtension;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
use SilverStripe\Security\MemberPassword;
use SilverStripe\Security\Group;
use SilverStripe\Security\Permission;
use SilverStripe\Security\PasswordEncryptor_Blowfish;
use SilverStripe\Security\RememberLoginHash;
use SilverStripe\Security\Member_Validator;
use SilverStripe\Security\PasswordValidator;
/** /**
* @package framework * @package framework
@ -16,7 +26,7 @@ class MemberTest extends FunctionalTest {
protected $local = null; protected $local = null;
protected $illegalExtensions = array( protected $illegalExtensions = array(
'Member' => array( 'SilverStripe\\Security\\Member' => array(
// TODO Coupling with modules, this should be resolved by automatically // TODO Coupling with modules, this should be resolved by automatically
// removing all applied extensions before a unit test // removing all applied extensions before a unit test
'ForumRole', 'ForumRole',
@ -140,7 +150,7 @@ class MemberTest extends FunctionalTest {
} }
public function testSetPassword() { public function testSetPassword() {
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$member->Password = "test1"; $member->Password = "test1";
$member->write(); $member->write();
$result = $member->checkPassword('test1'); $result = $member->checkPassword('test1');
@ -151,7 +161,7 @@ class MemberTest extends FunctionalTest {
* Test that password changes are logged properly * Test that password changes are logged properly
*/ */
public function testPasswordChangeLogging() { public function testPasswordChangeLogging() {
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$this->assertNotNull($member); $this->assertNotNull($member);
$member->Password = "test1"; $member->Password = "test1";
$member->write(); $member->write();
@ -162,7 +172,7 @@ class MemberTest extends FunctionalTest {
$member->Password = "test3"; $member->Password = "test3";
$member->write(); $member->write();
$passwords = DataObject::get("MemberPassword", "\"MemberID\" = $member->ID", "\"Created\" DESC, \"ID\" DESC") $passwords = DataObject::get("SilverStripe\\Security\\MemberPassword", "\"MemberID\" = $member->ID", "\"Created\" DESC, \"ID\" DESC")
->getIterator(); ->getIterator();
$this->assertNotNull($passwords); $this->assertNotNull($passwords);
$passwords->rewind(); $passwords->rewind();
@ -191,11 +201,11 @@ class MemberTest extends FunctionalTest {
* Test that changed passwords will send an email * Test that changed passwords will send an email
*/ */
public function testChangedPasswordEmaling() { public function testChangedPasswordEmaling() {
Config::inst()->update('Member', 'notify_password_change', true); Config::inst()->update('SilverStripe\\Security\\Member', 'notify_password_change', true);
$this->clearEmails(); $this->clearEmails();
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$this->assertNotNull($member); $this->assertNotNull($member);
$valid = $member->changePassword('32asDF##$$%%'); $valid = $member->changePassword('32asDF##$$%%');
$this->assertTrue($valid->valid()); $this->assertTrue($valid->valid());
@ -212,7 +222,7 @@ class MemberTest extends FunctionalTest {
$this->clearEmails(); $this->clearEmails();
$this->autoFollowRedirection = false; $this->autoFollowRedirection = false;
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$this->assertNotNull($member); $this->assertNotNull($member);
// Initiate a password-reset // Initiate a password-reset
@ -236,7 +246,7 @@ class MemberTest extends FunctionalTest {
* - at least 7 characters long * - at least 7 characters long
*/ */
public function testValidatePassword() { public function testValidatePassword() {
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$this->assertNotNull($member); $this->assertNotNull($member);
Member::set_password_validator(new MemberTest_PasswordValidator()); Member::set_password_validator(new MemberTest_PasswordValidator());
@ -320,7 +330,7 @@ class MemberTest extends FunctionalTest {
public function testPasswordExpirySetting() { public function testPasswordExpirySetting() {
Member::config()->password_expiry_days = 90; Member::config()->password_expiry_days = 90;
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$this->assertNotNull($member); $this->assertNotNull($member);
$valid = $member->changePassword("Xx?1234234"); $valid = $member->changePassword("Xx?1234234");
$this->assertTrue($valid->valid()); $this->assertTrue($valid->valid());
@ -336,15 +346,15 @@ class MemberTest extends FunctionalTest {
} }
public function testIsPasswordExpired() { public function testIsPasswordExpired() {
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$this->assertNotNull($member); $this->assertNotNull($member);
$this->assertFalse($member->isPasswordExpired()); $this->assertFalse($member->isPasswordExpired());
$member = $this->objFromFixture('Member', 'noexpiry'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'noexpiry');
$member->PasswordExpiry = null; $member->PasswordExpiry = null;
$this->assertFalse($member->isPasswordExpired()); $this->assertFalse($member->isPasswordExpired());
$member = $this->objFromFixture('Member', 'expiredpassword'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'expiredpassword');
$this->assertTrue($member->isPasswordExpired()); $this->assertTrue($member->isPasswordExpired());
// Check the boundary conditions // Check the boundary conditions
@ -361,21 +371,21 @@ class MemberTest extends FunctionalTest {
public function testMemberWithNoDateFormatFallsbackToGlobalLocaleDefaultFormat() { public function testMemberWithNoDateFormatFallsbackToGlobalLocaleDefaultFormat() {
Config::inst()->update('i18n', 'date_format', 'yyyy-MM-dd'); Config::inst()->update('i18n', 'date_format', 'yyyy-MM-dd');
Config::inst()->update('i18n', 'time_format', 'H:mm'); Config::inst()->update('i18n', 'time_format', 'H:mm');
$member = $this->objFromFixture('Member', 'noformatmember'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'noformatmember');
$this->assertEquals('yyyy-MM-dd', $member->DateFormat); $this->assertEquals('yyyy-MM-dd', $member->DateFormat);
$this->assertEquals('H:mm', $member->TimeFormat); $this->assertEquals('H:mm', $member->TimeFormat);
} }
public function testInGroups() { public function testInGroups() {
$staffmember = $this->objFromFixture('Member', 'staffmember'); $staffmember = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember');
$managementmember = $this->objFromFixture('Member', 'managementmember'); $managementmember = $this->objFromFixture('SilverStripe\\Security\\Member', 'managementmember');
$accountingmember = $this->objFromFixture('Member', 'accountingmember'); $accountingmember = $this->objFromFixture('SilverStripe\\Security\\Member', 'accountingmember');
$ceomember = $this->objFromFixture('Member', 'ceomember'); $ceomember = $this->objFromFixture('SilverStripe\\Security\\Member', 'ceomember');
$staffgroup = $this->objFromFixture('Group', 'staffgroup'); $staffgroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'staffgroup');
$managementgroup = $this->objFromFixture('Group', 'managementgroup'); $managementgroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'managementgroup');
$accountinggroup = $this->objFromFixture('Group', 'accountinggroup'); $accountinggroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'accountinggroup');
$ceogroup = $this->objFromFixture('Group', 'ceogroup'); $ceogroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'ceogroup');
$this->assertTrue( $this->assertTrue(
$staffmember->inGroups(array($staffgroup, $managementgroup)), $staffmember->inGroups(array($staffgroup, $managementgroup)),
@ -392,8 +402,8 @@ class MemberTest extends FunctionalTest {
} }
public function testAddToGroupByCode() { public function testAddToGroupByCode() {
$grouplessMember = $this->objFromFixture('Member', 'grouplessmember'); $grouplessMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'grouplessmember');
$memberlessGroup = $this->objFromFixture('Group','memberlessgroup'); $memberlessGroup = $this->objFromFixture('SilverStripe\\Security\\Group','memberlessgroup');
$this->assertFalse($grouplessMember->Groups()->exists()); $this->assertFalse($grouplessMember->Groups()->exists());
$this->assertFalse($memberlessGroup->Members()->exists()); $this->assertFalse($memberlessGroup->Members()->exists());
@ -406,7 +416,7 @@ class MemberTest extends FunctionalTest {
$grouplessMember->addToGroupByCode('somegroupthatwouldneverexist', 'New Group'); $grouplessMember->addToGroupByCode('somegroupthatwouldneverexist', 'New Group');
$this->assertEquals($grouplessMember->Groups()->Count(), 2); $this->assertEquals($grouplessMember->Groups()->Count(), 2);
$group = DataObject::get_one('Group', array( $group = DataObject::get_one('SilverStripe\\Security\\Group', array(
'"Group"."Code"' => 'somegroupthatwouldneverexist' '"Group"."Code"' => 'somegroupthatwouldneverexist'
)); ));
$this->assertNotNull($group); $this->assertNotNull($group);
@ -416,8 +426,8 @@ class MemberTest extends FunctionalTest {
} }
public function testRemoveFromGroupByCode() { public function testRemoveFromGroupByCode() {
$grouplessMember = $this->objFromFixture('Member', 'grouplessmember'); $grouplessMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'grouplessmember');
$memberlessGroup = $this->objFromFixture('Group','memberlessgroup'); $memberlessGroup = $this->objFromFixture('SilverStripe\\Security\\Group','memberlessgroup');
$this->assertFalse($grouplessMember->Groups()->exists()); $this->assertFalse($grouplessMember->Groups()->exists());
$this->assertFalse($memberlessGroup->Members()->exists()); $this->assertFalse($memberlessGroup->Members()->exists());
@ -430,7 +440,7 @@ class MemberTest extends FunctionalTest {
$grouplessMember->addToGroupByCode('somegroupthatwouldneverexist', 'New Group'); $grouplessMember->addToGroupByCode('somegroupthatwouldneverexist', 'New Group');
$this->assertEquals($grouplessMember->Groups()->Count(), 2); $this->assertEquals($grouplessMember->Groups()->Count(), 2);
$group = DataObject::get_one('Group', "\"Code\" = 'somegroupthatwouldneverexist'"); $group = DataObject::get_one('SilverStripe\\Security\\Group', "\"Code\" = 'somegroupthatwouldneverexist'");
$this->assertNotNull($group); $this->assertNotNull($group);
$this->assertEquals($group->Code, 'somegroupthatwouldneverexist'); $this->assertEquals($group->Code, 'somegroupthatwouldneverexist');
$this->assertEquals($group->Title, 'New Group'); $this->assertEquals($group->Title, 'New Group');
@ -444,15 +454,15 @@ class MemberTest extends FunctionalTest {
} }
public function testInGroup() { public function testInGroup() {
$staffmember = $this->objFromFixture('Member', 'staffmember'); $staffmember = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember');
$managementmember = $this->objFromFixture('Member', 'managementmember'); $managementmember = $this->objFromFixture('SilverStripe\\Security\\Member', 'managementmember');
$accountingmember = $this->objFromFixture('Member', 'accountingmember'); $accountingmember = $this->objFromFixture('SilverStripe\\Security\\Member', 'accountingmember');
$ceomember = $this->objFromFixture('Member', 'ceomember'); $ceomember = $this->objFromFixture('SilverStripe\\Security\\Member', 'ceomember');
$staffgroup = $this->objFromFixture('Group', 'staffgroup'); $staffgroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'staffgroup');
$managementgroup = $this->objFromFixture('Group', 'managementgroup'); $managementgroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'managementgroup');
$accountinggroup = $this->objFromFixture('Group', 'accountinggroup'); $accountinggroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'accountinggroup');
$ceogroup = $this->objFromFixture('Group', 'ceogroup'); $ceogroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'ceogroup');
$this->assertTrue( $this->assertTrue(
$staffmember->inGroup($staffgroup), $staffmember->inGroup($staffgroup),
@ -501,9 +511,9 @@ class MemberTest extends FunctionalTest {
* edit and delete their own record too. * edit and delete their own record too.
*/ */
public function testCanManipulateOwnRecord() { public function testCanManipulateOwnRecord() {
$extensions = $this->removeExtensions(Object::get_extensions('Member')); $extensions = $this->removeExtensions(Object::get_extensions('SilverStripe\\Security\\Member'));
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$member2 = $this->objFromFixture('Member', 'staffmember'); $member2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember');
$this->session()->inst_set('loggedInAs', null); $this->session()->inst_set('loggedInAs', null);
@ -529,9 +539,9 @@ class MemberTest extends FunctionalTest {
} }
public function testAuthorisedMembersCanManipulateOthersRecords() { public function testAuthorisedMembersCanManipulateOthersRecords() {
$extensions = $this->removeExtensions(Object::get_extensions('Member')); $extensions = $this->removeExtensions(Object::get_extensions('SilverStripe\\Security\\Member'));
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$member2 = $this->objFromFixture('Member', 'staffmember'); $member2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember');
/* Group members with SecurityAdmin permissions can manipulate other records */ /* Group members with SecurityAdmin permissions can manipulate other records */
$this->session()->inst_set('loggedInAs', $member->ID); $this->session()->inst_set('loggedInAs', $member->ID);
@ -544,8 +554,8 @@ class MemberTest extends FunctionalTest {
} }
public function testExtendedCan() { public function testExtendedCan() {
$extensions = $this->removeExtensions(Object::get_extensions('Member')); $extensions = $this->removeExtensions(Object::get_extensions('SilverStripe\\Security\\Member'));
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
/* Normal behaviour is that you can't view a member unless canView() on an extension returns true */ /* Normal behaviour is that you can't view a member unless canView() on an extension returns true */
$this->assertFalse($member->canView()); $this->assertFalse($member->canView());
@ -554,7 +564,7 @@ class MemberTest extends FunctionalTest {
/* Apply a extension that allows viewing in any case (most likely the case for member profiles) */ /* Apply a extension that allows viewing in any case (most likely the case for member profiles) */
Member::add_extension('MemberTest_ViewingAllowedExtension'); Member::add_extension('MemberTest_ViewingAllowedExtension');
$member2 = $this->objFromFixture('Member', 'staffmember'); $member2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember');
$this->assertTrue($member2->canView()); $this->assertTrue($member2->canView());
$this->assertFalse($member2->canDelete()); $this->assertFalse($member2->canDelete());
@ -563,7 +573,7 @@ class MemberTest extends FunctionalTest {
/* Apply a extension that denies viewing of the Member */ /* Apply a extension that denies viewing of the Member */
Member::remove_extension('MemberTest_ViewingAllowedExtension'); Member::remove_extension('MemberTest_ViewingAllowedExtension');
Member::add_extension('MemberTest_ViewingDeniedExtension'); Member::add_extension('MemberTest_ViewingDeniedExtension');
$member3 = $this->objFromFixture('Member', 'managementmember'); $member3 = $this->objFromFixture('SilverStripe\\Security\\Member', 'managementmember');
$this->assertFalse($member3->canView()); $this->assertFalse($member3->canView());
$this->assertFalse($member3->canDelete()); $this->assertFalse($member3->canDelete());
@ -572,7 +582,7 @@ class MemberTest extends FunctionalTest {
/* Apply a extension that allows viewing and editing but denies deletion */ /* Apply a extension that allows viewing and editing but denies deletion */
Member::remove_extension('MemberTest_ViewingDeniedExtension'); Member::remove_extension('MemberTest_ViewingDeniedExtension');
Member::add_extension('MemberTest_EditingAllowedDeletingDeniedExtension'); Member::add_extension('MemberTest_EditingAllowedDeletingDeniedExtension');
$member4 = $this->objFromFixture('Member', 'accountingmember'); $member4 = $this->objFromFixture('SilverStripe\\Security\\Member', 'accountingmember');
$this->assertTrue($member4->canView()); $this->assertTrue($member4->canView());
$this->assertFalse($member4->canDelete()); $this->assertFalse($member4->canDelete());
@ -586,7 +596,7 @@ class MemberTest extends FunctionalTest {
* Tests for {@link Member::getName()} and {@link Member::setName()} * Tests for {@link Member::getName()} and {@link Member::setName()}
*/ */
public function testName() { public function testName() {
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$member->setName('Test Some User'); $member->setName('Test Some User');
$this->assertEquals('Test Some User', $member->getName()); $this->assertEquals('Test Some User', $member->getName());
$member->setName('Test'); $member->setName('Test');
@ -597,10 +607,10 @@ class MemberTest extends FunctionalTest {
} }
public function testMembersWithSecurityAdminAccessCantEditAdminsUnlessTheyreAdminsThemselves() { public function testMembersWithSecurityAdminAccessCantEditAdminsUnlessTheyreAdminsThemselves() {
$adminMember = $this->objFromFixture('Member', 'admin'); $adminMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$otherAdminMember = $this->objFromFixture('Member', 'other-admin'); $otherAdminMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'other-admin');
$securityAdminMember = $this->objFromFixture('Member', 'test'); $securityAdminMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$ceoMember = $this->objFromFixture('Member', 'ceomember'); $ceoMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'ceomember');
// Careful: Don't read as english language. // Careful: Don't read as english language.
// More precisely this should read canBeEditedBy() // More precisely this should read canBeEditedBy()
@ -615,9 +625,9 @@ class MemberTest extends FunctionalTest {
} }
public function testOnChangeGroups() { public function testOnChangeGroups() {
$staffGroup = $this->objFromFixture('Group', 'staffgroup'); $staffGroup = $this->objFromFixture('SilverStripe\\Security\\Group', 'staffgroup');
$staffMember = $this->objFromFixture('Member', 'staffmember'); $staffMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember');
$adminMember = $this->objFromFixture('Member', 'admin'); $adminMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$newAdminGroup = new Group(array('Title' => 'newadmin')); $newAdminGroup = new Group(array('Title' => 'newadmin'));
$newAdminGroup->write(); $newAdminGroup->write();
Permission::grant($newAdminGroup->ID, 'ADMIN'); Permission::grant($newAdminGroup->ID, 'ADMIN');
@ -654,8 +664,8 @@ class MemberTest extends FunctionalTest {
* Test Member_GroupSet::add * Test Member_GroupSet::add
*/ */
public function testOnChangeGroupsByAdd() { public function testOnChangeGroupsByAdd() {
$staffMember = $this->objFromFixture('Member', 'staffmember'); $staffMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember');
$adminMember = $this->objFromFixture('Member', 'admin'); $adminMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
// Setup new admin group // Setup new admin group
$newAdminGroup = new Group(array('Title' => 'newadmin')); $newAdminGroup = new Group(array('Title' => 'newadmin'));
@ -704,7 +714,7 @@ class MemberTest extends FunctionalTest {
* Test Member_GroupSet::add * Test Member_GroupSet::add
*/ */
public function testOnChangeGroupsBySetIDList() { public function testOnChangeGroupsBySetIDList() {
$staffMember = $this->objFromFixture('Member', 'staffmember'); $staffMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember');
// Setup new admin group // Setup new admin group
$newAdminGroup = new Group(array('Title' => 'newadmin')); $newAdminGroup = new Group(array('Title' => 'newadmin'));
@ -726,7 +736,7 @@ class MemberTest extends FunctionalTest {
public function testUpdateCMSFields() { public function testUpdateCMSFields() {
Member::add_extension('MemberTest_FieldsExtension'); Member::add_extension('MemberTest_FieldsExtension');
$member = singleton('Member'); $member = singleton('SilverStripe\\Security\\Member');
$fields = $member->getCMSFields(); $fields = $member->getCMSFields();
$this->assertNotNull($fields->dataFieldByName('Email'), 'Scaffolded fields are retained'); $this->assertNotNull($fields->dataFieldByName('Email'), 'Scaffolded fields are retained');
@ -748,11 +758,11 @@ class MemberTest extends FunctionalTest {
* Test that only admin members are returned * Test that only admin members are returned
*/ */
public function testMap_in_groupsReturnsAdmins() { public function testMap_in_groupsReturnsAdmins() {
$adminID = $this->objFromFixture('Group', 'admingroup')->ID; $adminID = $this->objFromFixture('SilverStripe\\Security\\Group', 'admingroup')->ID;
$members = Member::map_in_groups($adminID)->toArray(); $members = Member::map_in_groups($adminID)->toArray();
$admin = $this->objFromFixture('Member', 'admin'); $admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$otherAdmin = $this->objFromFixture('Member', 'other-admin'); $otherAdmin = $this->objFromFixture('SilverStripe\\Security\\Member', 'other-admin');
$this->assertTrue(in_array($admin->getTitle(), $members), $this->assertTrue(in_array($admin->getTitle(), $members),
$admin->getTitle().' should be in the returned list.'); $admin->getTitle().' should be in the returned list.');
@ -822,7 +832,7 @@ class MemberTest extends FunctionalTest {
} }
public function testRememberMeHashGeneration() { public function testRememberMeHashGeneration() {
$m1 = $this->objFromFixture('Member', 'grouplessmember'); $m1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'grouplessmember');
$m1->login(true); $m1->login(true);
$hashes = RememberLoginHash::get()->filter('MemberID', $m1->ID); $hashes = RememberLoginHash::get()->filter('MemberID', $m1->ID);
@ -833,9 +843,10 @@ class MemberTest extends FunctionalTest {
} }
public function testRememberMeHashAutologin() { public function testRememberMeHashAutologin() {
$m1 = $this->objFromFixture('Member', 'noexpiry'); /** @var Member $m1 */
$m1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'noexpiry');
$m1->login(true); $m1->logIn(true);
$firstHash = RememberLoginHash::get()->filter('MemberID', $m1->ID)->First(); $firstHash = RememberLoginHash::get()->filter('MemberID', $m1->ID)->First();
$this->assertNotNull($firstHash); $this->assertNotNull($firstHash);
@ -892,7 +903,7 @@ class MemberTest extends FunctionalTest {
array( array(
'Email' => $m1->Email, 'Email' => $m1->Email,
'Password' => '1nitialPassword', 'Password' => '1nitialPassword',
'AuthenticationMethod' => 'MemberAuthenticator', 'AuthenticationMethod' => 'SilverStripe\\Security\\MemberAuthenticator',
'action_dologin' => 'action_dologin' 'action_dologin' => 'action_dologin'
), ),
null, null,
@ -907,7 +918,7 @@ class MemberTest extends FunctionalTest {
} }
public function testExpiredRememberMeHashAutologin() { public function testExpiredRememberMeHashAutologin() {
$m1 = $this->objFromFixture('Member', 'noexpiry'); $m1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'noexpiry');
$m1->login(true); $m1->login(true);
$firstHash = RememberLoginHash::get()->filter('MemberID', $m1->ID)->First(); $firstHash = RememberLoginHash::get()->filter('MemberID', $m1->ID)->First();
@ -962,7 +973,7 @@ class MemberTest extends FunctionalTest {
} }
public function testRememberMeMultipleDevices() { public function testRememberMeMultipleDevices() {
$m1 = $this->objFromFixture('Member', 'noexpiry'); $m1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'noexpiry');
// First device // First device
$m1->login(true); $m1->login(true);
@ -1021,10 +1032,10 @@ class MemberTest extends FunctionalTest {
); );
$this->assertContains($message, $response->getBody()); $this->assertContains($message, $response->getBody());
$logout_across_devices = Config::inst()->get('RememberLoginHash', 'logout_across_devices'); $logout_across_devices = Config::inst()->get('SilverStripe\\Security\\RememberLoginHash', 'logout_across_devices');
// Logging out from the second device - only one device being logged out // Logging out from the second device - only one device being logged out
Config::inst()->update('RememberLoginHash', 'logout_across_devices', false); Config::inst()->update('SilverStripe\\Security\\RememberLoginHash', 'logout_across_devices', false);
$response = $this->get( $response = $this->get(
'Security/logout', 'Security/logout',
$this->session(), $this->session(),
@ -1040,7 +1051,7 @@ class MemberTest extends FunctionalTest {
); );
// Logging out from any device when all login hashes should be removed // Logging out from any device when all login hashes should be removed
Config::inst()->update('RememberLoginHash', 'logout_across_devices', true); Config::inst()->update('SilverStripe\\Security\\RememberLoginHash', 'logout_across_devices', true);
$m1->login(true); $m1->login(true);
$response = $this->get('Security/logout', $this->session()); $response = $this->get('Security/logout', $this->session());
$this->assertEquals( $this->assertEquals(
@ -1048,14 +1059,14 @@ class MemberTest extends FunctionalTest {
0 0
); );
Config::inst()->update('RememberLoginHash', 'logout_across_devices', $logout_across_devices); Config::inst()->update('SilverStripe\\Security\\RememberLoginHash', 'logout_across_devices', $logout_across_devices);
} }
public function testCanDelete() { public function testCanDelete() {
$admin1 = $this->objFromFixture('Member', 'admin'); $admin1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$admin2 = $this->objFromFixture('Member', 'other-admin'); $admin2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'other-admin');
$member1 = $this->objFromFixture('Member', 'grouplessmember'); $member1 = $this->objFromFixture('SilverStripe\\Security\\Member', 'grouplessmember');
$member2 = $this->objFromFixture('Member', 'noformatmember'); $member2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'noformatmember');
$this->assertTrue( $this->assertTrue(
$admin1->canDelete($admin2), $admin1->canDelete($admin2),
@ -1083,9 +1094,9 @@ class MemberTest extends FunctionalTest {
$maxFailedLoginsAllowed = 3; $maxFailedLoginsAllowed = 3;
//set up the config variables to enable login lockouts //set up the config variables to enable login lockouts
Config::nest(); Config::nest();
Config::inst()->update('Member', 'lock_out_after_incorrect_logins', $maxFailedLoginsAllowed); Config::inst()->update('SilverStripe\\Security\\Member', 'lock_out_after_incorrect_logins', $maxFailedLoginsAllowed);
$member = $this->objFromFixture('Member', 'test'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$failedLoginCount = $member->FailedLoginCount; $failedLoginCount = $member->FailedLoginCount;
for ($i = 1; $i < $maxFailedLoginsAllowed; ++$i) { for ($i = 1; $i < $maxFailedLoginsAllowed; ++$i) {
@ -1107,9 +1118,9 @@ class MemberTest extends FunctionalTest {
public function testMemberValidator() public function testMemberValidator()
{ {
// clear custom requirements for this test // clear custom requirements for this test
Config::inst()->update('Member_Validator', 'customRequired', null); Config::inst()->update('SilverStripe\\Security\\Member_Validator', 'customRequired', null);
$memberA = $this->objFromFixture('Member', 'admin'); $memberA = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$memberB = $this->objFromFixture('Member', 'test'); $memberB = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
// create a blank form // create a blank form
$form = new MemberTest_ValidatorForm(); $form = new MemberTest_ValidatorForm();
@ -1173,7 +1184,7 @@ class MemberTest extends FunctionalTest {
public function testMemberValidatorWithExtensions() public function testMemberValidatorWithExtensions()
{ {
// clear custom requirements for this test // clear custom requirements for this test
Config::inst()->update('Member_Validator', 'customRequired', null); Config::inst()->update('SilverStripe\\Security\\Member_Validator', 'customRequired', null);
// create a blank form // create a blank form
$form = new MemberTest_ValidatorForm(); $form = new MemberTest_ValidatorForm();
@ -1231,9 +1242,9 @@ class MemberTest extends FunctionalTest {
public function testCustomMemberValidator() public function testCustomMemberValidator()
{ {
// clear custom requirements for this test // clear custom requirements for this test
Config::inst()->update('Member_Validator', 'customRequired', null); Config::inst()->update('SilverStripe\\Security\\Member_Validator', 'customRequired', null);
$member = $this->objFromFixture('Member', 'admin'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'admin');
$form = new MemberTest_ValidatorForm(); $form = new MemberTest_ValidatorForm();
$form->loadDataFrom($member); $form->loadDataFrom($member);

View File

@ -1,51 +1,51 @@
Permission: 'SilverStripe\Security\Permission':
admin: admin:
Code: ADMIN Code: ADMIN
security-admin: security-admin:
Code: CMS_ACCESS_SecurityAdmin Code: CMS_ACCESS_SecurityAdmin
Group: 'SilverStripe\Security\Group':
admingroup: admingroup:
Title: Admin Title: Admin
Code: admin Code: admin
Permissions: =>Permission.admin Permissions: '=>SilverStripe\Security\Permission.admin'
securityadminsgroup: securityadminsgroup:
Title: securityadminsgroup Title: securityadminsgroup
Code: securityadminsgroup Code: securityadminsgroup
Permissions: =>Permission.security-admin Permissions: '=>SilverStripe\Security\Permission.security-admin'
staffgroup: staffgroup:
Title: staffgroup Title: staffgroup
Code: staffgroup Code: staffgroup
managementgroup: managementgroup:
Title: managementgroup Title: managementgroup
Code: managementgroup Code: managementgroup
Parent: =>Group.staffgroup Parent: '=>SilverStripe\Security\Group.staffgroup'
accountinggroup: accountinggroup:
Title: accountinggroup Title: accountinggroup
Code: accountinggroup Code: accountinggroup
Parent: =>Group.staffgroup Parent: '=>SilverStripe\Security\Group.staffgroup'
ceogroup: ceogroup:
Title: ceogroup Title: ceogroup
Code: ceogroup Code: ceogroup
Parent: =>Group.managementgroup Parent: '=>SilverStripe\Security\Group.managementgroup'
memberlessgroup: memberlessgroup:
Title: Memberless Group Title: Memberless Group
code: memberless code: memberless
Member: 'SilverStripe\Security\Member':
admin: admin:
FirstName: Admin FirstName: Admin
Email: admin@silverstripe.com Email: admin@silverstripe.com
Groups: =>Group.admingroup Groups: '=>SilverStripe\Security\Group.admingroup'
other-admin: other-admin:
FirstName: OtherAdmin FirstName: OtherAdmin
Email: other-admin@silverstripe.com Email: other-admin@silverstripe.com
Groups: =>Group.admingroup Groups: '=>SilverStripe\Security\Group.admingroup'
test: test:
FirstName: Test FirstName: Test
Surname: User Surname: User
Email: testuser@example.com Email: testuser@example.com
Password: 1nitialPassword Password: 1nitialPassword
PasswordExpiry: 2030-01-01 PasswordExpiry: 2030-01-01
Groups: =>Group.securityadminsgroup Groups: '=>SilverStripe\Security\Group.securityadminsgroup'
expiredpassword: expiredpassword:
FirstName: Test FirstName: Test
Surname: User Surname: User
@ -59,16 +59,16 @@ Member:
Password: 1nitialPassword Password: 1nitialPassword
staffmember: staffmember:
Email: staffmember@test.com Email: staffmember@test.com
Groups: =>Group.staffgroup Groups: '=>SilverStripe\Security\Group.staffgroup'
managementmember: managementmember:
Email: managementmember@test.com Email: managementmember@test.com
Groups: =>Group.managementgroup Groups: '=>SilverStripe\Security\Group.managementgroup'
accountingmember: accountingmember:
Email: accountingmember@test.com Email: accountingmember@test.com
Groups: =>Group.accountinggroup Groups: '=>SilverStripe\Security\Group.accountinggroup'
ceomember: ceomember:
Email: ceomember@test.com Email: ceomember@test.com
Groups: =>Group.ceogroup Groups: '=>SilverStripe\Security\Group.ceogroup'
grouplessmember: grouplessmember:
FirstName: Groupless Member FirstName: Groupless Member
noformatmember: noformatmember:

View File

@ -1,4 +1,8 @@
<?php <?php
use SilverStripe\Security\PasswordEncryptor_Blowfish;
use SilverStripe\Security\PasswordEncryptor;
class PasswordEncryptorTest extends SapphireTest { class PasswordEncryptorTest extends SapphireTest {
/** /**
@ -19,22 +23,28 @@ class PasswordEncryptorTest extends SapphireTest {
} }
public function testCreateForCode() { public function testCreateForCode() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('test'=>array('PasswordEncryptorTest_TestEncryptor'=>null))); 'SilverStripe\\Security\\PasswordEncryptor',
'encryptors',
['test' => ['PasswordEncryptorTest_TestEncryptor' => null]]
);
$e = PasswordEncryptor::create_for_algorithm('test'); $e = PasswordEncryptor::create_for_algorithm('test');
$this->assertInstanceOf('PasswordEncryptorTest_TestEncryptor', $e ); $this->assertInstanceOf('PasswordEncryptorTest_TestEncryptor', $e );
} }
/** /**
* @expectedException PasswordEncryptor_NotFoundException * @expectedException SilverStripe\Security\PasswordEncryptor_NotFoundException
*/ */
public function testCreateForCodeNotFound() { public function testCreateForCodeNotFound() {
PasswordEncryptor::create_for_algorithm('unknown'); PasswordEncryptor::create_for_algorithm('unknown');
} }
public function testRegister() { public function testRegister() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('test'=>array('PasswordEncryptorTest_TestEncryptor'=>null))); 'SilverStripe\\Security\\PasswordEncryptor',
'encryptors',
array('test' => array('PasswordEncryptorTest_TestEncryptor' => null))
);
$encryptors = PasswordEncryptor::get_encryptors(); $encryptors = PasswordEncryptor::get_encryptors();
$this->assertContains('test', array_keys($encryptors)); $this->assertContains('test', array_keys($encryptors));
$encryptor = $encryptors['test']; $encryptor = $encryptors['test'];
@ -42,22 +52,31 @@ class PasswordEncryptorTest extends SapphireTest {
} }
public function testUnregister() { public function testUnregister() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('test'=>array('PasswordEncryptorTest_TestEncryptor'=>null))); 'SilverStripe\\Security\\PasswordEncryptor',
Config::inst()->remove('PasswordEncryptor', 'encryptors', 'test'); 'encryptors',
array('test' => array('PasswordEncryptorTest_TestEncryptor' => null))
);
Config::inst()->remove('SilverStripe\\Security\\PasswordEncryptor', 'encryptors', 'test');
$this->assertNotContains('test', array_keys(PasswordEncryptor::get_encryptors())); $this->assertNotContains('test', array_keys(PasswordEncryptor::get_encryptors()));
} }
public function testEncryptorPHPHashWithArguments() { public function testEncryptorPHPHashWithArguments() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('test_md5'=>array('PasswordEncryptor_PHPHash'=>'md5'))); 'SilverStripe\\Security\\PasswordEncryptor',
'encryptors',
['test_md5' => ['SilverStripe\\Security\\PasswordEncryptor_PHPHash'=>'md5']]
);
$e = PasswordEncryptor::create_for_algorithm('test_md5'); $e = PasswordEncryptor::create_for_algorithm('test_md5');
$this->assertEquals('md5', $e->getAlgorithm()); $this->assertEquals('md5', $e->getAlgorithm());
} }
public function testEncryptorPHPHash() { public function testEncryptorPHPHash() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('test_sha1'=>array('PasswordEncryptor_PHPHash'=>'sha1'))); 'SilverStripe\\Security\\PasswordEncryptor',
'encryptors',
['test_sha1' => ['SilverStripe\\Security\\PasswordEncryptor_PHPHash' => 'sha1']]
);
$e = PasswordEncryptor::create_for_algorithm('test_sha1'); $e = PasswordEncryptor::create_for_algorithm('test_sha1');
$password = 'mypassword'; $password = 'mypassword';
$salt = 'mysalt'; $salt = 'mysalt';
@ -68,8 +87,11 @@ class PasswordEncryptorTest extends SapphireTest {
} }
public function testEncryptorBlowfish() { public function testEncryptorBlowfish() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('test_blowfish'=>array('PasswordEncryptor_Blowfish'=>''))); 'SilverStripe\\Security\\PasswordEncryptor',
'encryptors',
['test_blowfish' => ['SilverStripe\\Security\\PasswordEncryptor_Blowfish' => '']]
);
$e = PasswordEncryptor::create_for_algorithm('test_blowfish'); $e = PasswordEncryptor::create_for_algorithm('test_blowfish');
$password = 'mypassword'; $password = 'mypassword';
@ -114,8 +136,11 @@ class PasswordEncryptorTest extends SapphireTest {
} }
public function testEncryptorPHPHashCheck() { public function testEncryptorPHPHashCheck() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('test_sha1'=>array('PasswordEncryptor_PHPHash'=>'sha1'))); 'SilverStripe\\Security\\PasswordEncryptor',
'encryptors',
['test_sha1' => ['SilverStripe\\Security\\PasswordEncryptor_PHPHash' => 'sha1']]
);
$e = PasswordEncryptor::create_for_algorithm('test_sha1'); $e = PasswordEncryptor::create_for_algorithm('test_sha1');
$this->assertTrue($e->check(sha1('mypassword'), 'mypassword')); $this->assertTrue($e->check(sha1('mypassword'), 'mypassword'));
$this->assertFalse($e->check(sha1('mypassword'), 'mywrongpassword')); $this->assertFalse($e->check(sha1('mypassword'), 'mywrongpassword'));
@ -128,8 +153,11 @@ class PasswordEncryptorTest extends SapphireTest {
* php -r "echo(base_convert(sha1('mypassword'), 16, 36));" * php -r "echo(base_convert(sha1('mypassword'), 16, 36));"
*/ */
public function testEncryptorLegacyPHPHashCheck() { public function testEncryptorLegacyPHPHashCheck() {
Config::inst()->update('PasswordEncryptor', 'encryptors', Config::inst()->update(
array('test_sha1legacy'=>array('PasswordEncryptor_LegacyPHPHash'=>'sha1'))); 'SilverStripe\\Security\\PasswordEncryptor',
'encryptors',
['test_sha1legacy' => ['SilverStripe\\Security\\PasswordEncryptor_LegacyPHPHash' => 'sha1']]
);
$e = PasswordEncryptor::create_for_algorithm('test_sha1legacy'); $e = PasswordEncryptor::create_for_algorithm('test_sha1legacy');
// precomputed hashes for 'mypassword' from different architectures // precomputed hashes for 'mypassword' from different architectures
$amdHash = 'h1fj0a6m4o6k0sosks88oo08ko4gc4s'; $amdHash = 'h1fj0a6m4o6k0sosks88oo08ko4gc4s';

View File

@ -1,4 +1,7 @@
<?php <?php
use SilverStripe\Security\PasswordValidator;
use SilverStripe\Security\Member;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests

View File

@ -1,6 +1,8 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\PermissionCheckboxSetField;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
@ -12,7 +14,7 @@ class PermissionCheckboxSetFieldTest extends SapphireTest {
$f = new PermissionCheckboxSetField( $f = new PermissionCheckboxSetField(
'Permissions', 'Permissions',
'Permissions', 'Permissions',
'Permission', 'SilverStripe\\Security\\Permission',
'GroupID' 'GroupID'
); );
$f->setHiddenPermissions( $f->setHiddenPermissions(
@ -27,19 +29,19 @@ class PermissionCheckboxSetFieldTest extends SapphireTest {
} }
public function testSaveInto() { public function testSaveInto() {
$group = $this->objFromFixture('Group', 'group'); // tested group $group = $this->objFromFixture('SilverStripe\\Security\\Group', 'group'); // tested group
$untouchable = $this->objFromFixture('Group', 'untouchable'); // group that should not change $untouchable = $this->objFromFixture('SilverStripe\\Security\\Group', 'untouchable'); // group that should not change
$field = new PermissionCheckboxSetField( $field = new PermissionCheckboxSetField(
'Permissions', 'Permissions',
'Permissions', 'Permissions',
'Permission', 'SilverStripe\\Security\\Permission',
'GroupID', 'GroupID',
$group $group
); );
// get the number of permissions before we start // get the number of permissions before we start
$baseCount = DataObject::get('Permission')->Count(); $baseCount = DataObject::get('SilverStripe\\Security\\Permission')->Count();
// there are currently no permissions, save empty checkbox // there are currently no permissions, save empty checkbox
$field->saveInto($group); $field->saveInto($group);
@ -51,7 +53,7 @@ class PermissionCheckboxSetFieldTest extends SapphireTest {
$this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1, $this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1,
'The other group has ADMIN permission'); 'The other group has ADMIN permission');
$this->assertEquals(DataObject::get('Permission')->Count(), $baseCount, 'There are no orphaned permissions'); $this->assertEquals(DataObject::get('SilverStripe\\Security\\Permission')->Count(), $baseCount, 'There are no orphaned permissions');
// add some permissions // add some permissions
$field->setValue(array( $field->setValue(array(
@ -74,7 +76,7 @@ class PermissionCheckboxSetFieldTest extends SapphireTest {
$this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1, $this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1,
'The other group has ADMIN permission'); 'The other group has ADMIN permission');
$this->assertEquals(DataObject::get('Permission')->Count(), $baseCount+2, $this->assertEquals(DataObject::get('SilverStripe\\Security\\Permission')->Count(), $baseCount+2,
'There are no orphaned permissions'); 'There are no orphaned permissions');
// remove permission // remove permission
@ -95,7 +97,7 @@ class PermissionCheckboxSetFieldTest extends SapphireTest {
$this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1, $this->assertEquals($untouchable->Permissions()->where("\"Code\"='ADMIN'")->Count(), 1,
'The other group has ADMIN permission'); 'The other group has ADMIN permission');
$this->assertEquals(DataObject::get('Permission')->Count(), $baseCount+1, $this->assertEquals(DataObject::get('SilverStripe\\Security\\Permission')->Count(), $baseCount+1,
'There are no orphaned permissions'); 'There are no orphaned permissions');
} }
} }

View File

@ -1,11 +1,11 @@
Group: 'SilverStripe\Security\Group':
group: group:
Code: group Code: group
untouchable: untouchable:
Code: untouchable Code: untouchable
Permission: 'SilverStripe\Security\Permission':
perm1: perm1:
Code: ADMIN Code: ADMIN
Group: =>Group.untouchable Group: '=>SilverStripe\Security\Group.untouchable'
perm2: perm2:
Code: NON-ADMIN Code: NON-ADMIN

View File

@ -1,6 +1,8 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\PermissionRoleCode;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
@ -9,13 +11,13 @@ class PermissionRoleTest extends FunctionalTest {
protected static $fixture_file = 'PermissionRoleTest.yml'; protected static $fixture_file = 'PermissionRoleTest.yml';
public function testDelete() { public function testDelete() {
$role = $this->objFromFixture('PermissionRole', 'role'); $role = $this->objFromFixture('SilverStripe\\Security\\PermissionRole', 'role');
$role->delete(); $role->delete();
$this->assertEquals(0, DataObject::get('PermissionRole', "\"ID\"={$role->ID}")->count(), $this->assertEquals(0, DataObject::get('SilverStripe\\Security\\PermissionRole', "\"ID\"={$role->ID}")->count(),
'Role is removed'); 'Role is removed');
$this->assertEquals(0, DataObject::get('PermissionRoleCode',"\"RoleID\"={$role->ID}")->count(), $this->assertEquals(0, DataObject::get('SilverStripe\\Security\\PermissionRoleCode',"\"RoleID\"={$role->ID}")->count(),
'Permissions removed along with the role'); 'Permissions removed along with the role');
} }

View File

@ -1,7 +1,7 @@
PermissionRole: 'SilverStripe\Security\PermissionRole':
role: role:
Title: role Title: role
PermissionRoleCode: 'SilverStripe\Security\PermissionRoleCode':
code: code:
Code: ADMIN Code: ADMIN
Role: =>PermissionRole.role Role: '=>SilverStripe\Security\PermissionRole.role'

View File

@ -1,5 +1,9 @@
<?php <?php
use SilverStripe\Security\Permission;
use SilverStripe\Security\Member;
use SilverStripe\Security\PermissionCheckboxSetField;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
@ -19,12 +23,12 @@ class PermissionTest extends SapphireTest {
} }
public function testDirectlyAppliedPermissions() { public function testDirectlyAppliedPermissions() {
$member = $this->objFromFixture('Member', 'author'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'author');
$this->assertTrue(Permission::checkMember($member, "SITETREE_VIEW_ALL")); $this->assertTrue(Permission::checkMember($member, "SITETREE_VIEW_ALL"));
} }
public function testCMSAccess() { public function testCMSAccess() {
$members = Member::get()->byIDs($this->allFixtureIDs('Member')); $members = Member::get()->byIDs($this->allFixtureIDs('SilverStripe\\Security\\Member'));
foreach ($members as $member) { foreach ($members as $member) {
$this->assertTrue(Permission::checkMember($member, 'CMS_ACCESS')); $this->assertTrue(Permission::checkMember($member, 'CMS_ACCESS'));
} }
@ -41,7 +45,7 @@ class PermissionTest extends SapphireTest {
public function testLeftAndMainAccessAll() { public function testLeftAndMainAccessAll() {
//add user and group //add user and group
$member = $this->objFromFixture('Member', 'leftandmain'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'leftandmain');
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin"));
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin"));
@ -49,14 +53,14 @@ class PermissionTest extends SapphireTest {
} }
public function testPermissionAreInheritedFromOneRole() { public function testPermissionAreInheritedFromOneRole() {
$member = $this->objFromFixture('Member', 'author'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'author');
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin"));
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin"));
$this->assertFalse(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin")); $this->assertFalse(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin"));
} }
public function testPermissionAreInheritedFromMultipleRoles() { public function testPermissionAreInheritedFromMultipleRoles() {
$member = $this->objFromFixture('Member', 'access'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'access');
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_MyAdmin"));
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_AssetAdmin"));
$this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin")); $this->assertTrue(Permission::checkMember($member, "CMS_ACCESS_SecurityAdmin"));
@ -65,7 +69,7 @@ class PermissionTest extends SapphireTest {
} }
public function testPermissionsForMember() { public function testPermissionsForMember() {
$member = $this->objFromFixture('Member', 'access'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'access');
$permissions = Permission::permissions_for_member($member->ID); $permissions = Permission::permissions_for_member($member->ID);
$this->assertEquals(4, count($permissions)); $this->assertEquals(4, count($permissions));
$this->assertTrue(in_array('CMS_ACCESS_MyAdmin', $permissions)); $this->assertTrue(in_array('CMS_ACCESS_MyAdmin', $permissions));
@ -73,7 +77,7 @@ class PermissionTest extends SapphireTest {
$this->assertTrue(in_array('CMS_ACCESS_SecurityAdmin', $permissions)); $this->assertTrue(in_array('CMS_ACCESS_SecurityAdmin', $permissions));
$this->assertTrue(in_array('EDIT_PERMISSIONS', $permissions)); $this->assertTrue(in_array('EDIT_PERMISSIONS', $permissions));
$group = $this->objFromFixture("Group", "access"); $group = $this->objFromFixture("SilverStripe\\Security\\Group", "access");
Permission::deny($group->ID, "CMS_ACCESS_MyAdmin"); Permission::deny($group->ID, "CMS_ACCESS_MyAdmin");
$permissions = Permission::permissions_for_member($member->ID); $permissions = Permission::permissions_for_member($member->ID);
@ -82,7 +86,7 @@ class PermissionTest extends SapphireTest {
} }
public function testRolesAndPermissionsFromParentGroupsAreInherited() { public function testRolesAndPermissionsFromParentGroupsAreInherited() {
$member = $this->objFromFixture('Member', 'globalauthor'); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'globalauthor');
// Check that permissions applied to the group are there // Check that permissions applied to the group are there
$this->assertTrue(Permission::checkMember($member, "SITETREE_EDIT_ALL")); $this->assertTrue(Permission::checkMember($member, "SITETREE_EDIT_ALL"));
@ -101,8 +105,8 @@ class PermissionTest extends SapphireTest {
* Ensure the the get_*_by_permission functions are permission role aware * Ensure the the get_*_by_permission functions are permission role aware
*/ */
public function testGettingMembersByPermission() { public function testGettingMembersByPermission() {
$accessMember = $this->objFromFixture('Member', 'access'); $accessMember = $this->objFromFixture('SilverStripe\\Security\\Member', 'access');
$accessAuthor = $this->objFromFixture('Member', 'author'); $accessAuthor = $this->objFromFixture('SilverStripe\\Security\\Member', 'author');
$result = Permission::get_members_by_permission(array('CMS_ACCESS_SecurityAdmin')); $result = Permission::get_members_by_permission(array('CMS_ACCESS_SecurityAdmin'));
$resultIDs = $result ? $result->column() : array(); $resultIDs = $result ? $result->column() : array();
@ -114,14 +118,14 @@ class PermissionTest extends SapphireTest {
public function testHiddenPermissions(){ public function testHiddenPermissions(){
$permissionCheckboxSet = new PermissionCheckboxSetField('Permissions','Permissions','Permission','GroupID'); $permissionCheckboxSet = new PermissionCheckboxSetField('Permissions','Permissions','SilverStripe\\Security\\Permission','GroupID');
$this->assertContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); $this->assertContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field());
Config::inst()->update('Permission', 'hidden_permissions', array('CMS_ACCESS_LeftAndMain')); Config::inst()->update('SilverStripe\\Security\\Permission', 'hidden_permissions', array('CMS_ACCESS_LeftAndMain'));
$this->assertNotContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); $this->assertNotContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field());
Config::inst()->remove('Permission', 'hidden_permissions'); Config::inst()->remove('SilverStripe\\Security\\Permission', 'hidden_permissions');
$this->assertContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); $this->assertContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field());
} }

View File

@ -1,25 +1,25 @@
PermissionRole: 'SilverStripe\Security\PermissionRole':
author: author:
Title: Author Title: Author
access: access:
Title: Access Administrator Title: Access Administrator
PermissionRoleCode: 'SilverStripe\Security\PermissionRoleCode':
author1: author1:
Role: =>PermissionRole.author Role: '=>SilverStripe\Security\PermissionRole.author'
Code: CMS_ACCESS_MyAdmin Code: CMS_ACCESS_MyAdmin
author2: author2:
Role: =>PermissionRole.author Role: '=>SilverStripe\Security\PermissionRole.author'
Code: CMS_ACCESS_AssetAdmin Code: CMS_ACCESS_AssetAdmin
access1: access1:
Role: =>PermissionRole.access Role: '=>SilverStripe\Security\PermissionRole.access'
Code: CMS_ACCESS_SecurityAdmin Code: CMS_ACCESS_SecurityAdmin
access2: access2:
Role: =>PermissionRole.access Role: '=>SilverStripe\Security\PermissionRole.access'
Code: EDIT_PERMISSIONS Code: EDIT_PERMISSIONS
Member: 'SilverStripe\Security\Member':
author: author:
FirstName: Test FirstName: Test
Surname: Author Surname: Author
@ -34,30 +34,30 @@ Member:
Surname: AndMain Surname: AndMain
Email: leftandmain@example.com Email: leftandmain@example.com
Group: 'SilverStripe\Security\Group':
author: author:
Title: Authors Title: Authors
Members: =>Member.author Members: '=>SilverStripe\Security\Member.author'
Roles: =>PermissionRole.author Roles: '=>SilverStripe\Security\PermissionRole.author'
access: access:
Title: Access Administrators + Authors Title: Access Administrators + Authors
Members: =>Member.access Members: '=>SilverStripe\Security\Member.access'
Roles: =>PermissionRole.access,=>PermissionRole.author Roles: '=>SilverStripe\Security\PermissionRole.access,=>SilverStripe\Security\PermissionRole.author'
globalauthor: globalauthor:
Parent: =>Group.author Parent: '=>SilverStripe\Security\Group.author'
Title: Global Authors Title: Global Authors
Members: =>Member.globalauthor Members: '=>SilverStripe\Security\Member.globalauthor'
leftandmain: leftandmain:
Title: LeftAndMain Title: LeftAndMain
Members: =>Member.leftandmain Members: '=>SilverStripe\Security\Member.leftandmain'
Permission: 'SilverStripe\Security\Permission':
extra1: extra1:
Code: SITETREE_VIEW_ALL Code: SITETREE_VIEW_ALL
Group: =>Group.author Group: '=>SilverStripe\Security\Group.author'
globalauthor: globalauthor:
Code: SITETREE_EDIT_ALL Code: SITETREE_EDIT_ALL
Group: =>Group.globalauthor Group: '=>SilverStripe\Security\Group.globalauthor'
leftandmain: leftandmain:
Code: CMS_ACCESS_LeftAndMain Code: CMS_ACCESS_LeftAndMain
Group: =>Group.leftandmain Group: '=>SilverStripe\Security\Group.leftandmain'

View File

@ -1,4 +1,6 @@
<?php <?php
use SilverStripe\Security\RandomGenerator;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests

View File

@ -1,4 +1,8 @@
<?php <?php
use SilverStripe\Security\Security;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Member;
class SecurityDefaultAdminTest extends SapphireTest { class SecurityDefaultAdminTest extends SapphireTest {
protected $usesDatabase = true; protected $usesDatabase = true;
@ -49,7 +53,7 @@ class SecurityDefaultAdminTest extends SapphireTest {
$admin = Security::findAnAdministrator(); $admin = Security::findAnAdministrator();
$this->assertInstanceOf('Member', $admin); $this->assertInstanceOf('SilverStripe\\Security\\Member', $admin);
$this->assertTrue(Permission::checkMember($admin, 'ADMIN')); $this->assertTrue(Permission::checkMember($admin, 'ADMIN'));
$this->assertEquals($admin->Email, Security::default_admin_username()); $this->assertEquals($admin->Email, Security::default_admin_username());
$this->assertNull($admin->Password); $this->assertNull($admin->Password);
@ -64,7 +68,7 @@ class SecurityDefaultAdminTest extends SapphireTest {
$admin = Security::findAnAdministrator(); $admin = Security::findAnAdministrator();
$this->assertInstanceOf('Member', $admin); $this->assertInstanceOf('SilverStripe\\Security\\Member', $admin);
$this->assertTrue(Permission::checkMember($admin, 'ADMIN')); $this->assertTrue(Permission::checkMember($admin, 'ADMIN'));
// User should be blank // User should be blank
@ -78,7 +82,7 @@ class SecurityDefaultAdminTest extends SapphireTest {
$admin = Member::default_admin(); $admin = Member::default_admin();
$this->assertInstanceOf('Member', $admin); $this->assertInstanceOf('SilverStripe\\Security\\Member', $admin);
$this->assertTrue(Permission::checkMember($admin, 'ADMIN')); $this->assertTrue(Permission::checkMember($admin, 'ADMIN'));
$this->assertEquals($admin->Email, Security::default_admin_username()); $this->assertEquals($admin->Email, Security::default_admin_username());
$this->assertNull($admin->Password); $this->assertNull($admin->Password);

View File

@ -6,6 +6,11 @@ use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\FieldType\DBClassName; use SilverStripe\ORM\FieldType\DBClassName;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\Security\Authenticator;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
use SilverStripe\Security\Permission;
/** /**
@ -35,8 +40,8 @@ class SecurityTest extends FunctionalTest {
Authenticator::unregister($authenticator); Authenticator::unregister($authenticator);
} }
Authenticator::register('MemberAuthenticator'); Authenticator::register('SilverStripe\\Security\\MemberAuthenticator');
Authenticator::set_default_authenticator('MemberAuthenticator'); Authenticator::set_default_authenticator('SilverStripe\\Security\\MemberAuthenticator');
// And that the unique identified field is 'Email' // And that the unique identified field is 'Email'
$this->priorUniqueIdentifierField = Member::config()->unique_identifier_field; $this->priorUniqueIdentifierField = Member::config()->unique_identifier_field;
@ -50,8 +55,8 @@ class SecurityTest extends FunctionalTest {
// Restore selected authenticator // Restore selected authenticator
// MemberAuthenticator might not actually be present // MemberAuthenticator might not actually be present
if(!in_array('MemberAuthenticator', $this->priorAuthenticators)) { if(!in_array('SilverStripe\\Security\\MemberAuthenticator', $this->priorAuthenticators)) {
Authenticator::unregister('MemberAuthenticator'); Authenticator::unregister('SilverStripe\\Security\\MemberAuthenticator');
} }
foreach($this->priorAuthenticators as $authenticator) { foreach($this->priorAuthenticators as $authenticator) {
Authenticator::register($authenticator); Authenticator::register($authenticator);
@ -71,7 +76,7 @@ class SecurityTest extends FunctionalTest {
$response = $this->get('SecurityTest_SecuredController'); $response = $this->get('SecurityTest_SecuredController');
$this->assertEquals(302, $response->getStatusCode()); $this->assertEquals(302, $response->getStatusCode());
$this->assertContains( $this->assertContains(
Config::inst()->get('Security', 'login_url'), Config::inst()->get('SilverStripe\\Security\\Security', 'login_url'),
$response->getHeader('Location') $response->getHeader('Location')
); );
@ -94,13 +99,13 @@ class SecurityTest extends FunctionalTest {
$this->assertEquals('Oops, not allowed', Session::get('Security.Message.message')); $this->assertEquals('Oops, not allowed', Session::get('Security.Message.message'));
// Test that config values are used correctly // Test that config values are used correctly
Config::inst()->update('Security', 'default_message_set', 'stringvalue'); Config::inst()->update('SilverStripe\\Security\\Security', 'default_message_set', 'stringvalue');
Security::permissionFailure($controller); Security::permissionFailure($controller);
$this->assertEquals('stringvalue', Session::get('Security.Message.message'), $this->assertEquals('stringvalue', Session::get('Security.Message.message'),
'Default permission failure message value was not present'); 'Default permission failure message value was not present');
Config::inst()->remove('Security', 'default_message_set'); Config::inst()->remove('SilverStripe\\Security\\Security', 'default_message_set');
Config::inst()->update('Security', 'default_message_set', array('default' => 'arrayvalue')); Config::inst()->update('SilverStripe\\Security\\Security', 'default_message_set', array('default' => 'arrayvalue'));
Security::permissionFailure($controller); Security::permissionFailure($controller);
$this->assertEquals('arrayvalue', Session::get('Security.Message.message'), $this->assertEquals('arrayvalue', Session::get('Security.Message.message'),
'Default permission failure message value was not present'); 'Default permission failure message value was not present');
@ -110,7 +115,7 @@ class SecurityTest extends FunctionalTest {
// been fetched and output as part of it, so has been removed from the session // been fetched and output as part of it, so has been removed from the session
$this->logInWithPermission('EDITOR'); $this->logInWithPermission('EDITOR');
Config::inst()->update('Security', 'default_message_set', Config::inst()->update('SilverStripe\\Security\\Security', 'default_message_set',
array('default' => 'default', 'alreadyLoggedIn' => 'You are already logged in!')); array('default' => 'default', 'alreadyLoggedIn' => 'You are already logged in!'));
Security::permissionFailure($controller); Security::permissionFailure($controller);
$this->assertContains('You are already logged in!', $controller->getResponse()->getBody(), $this->assertContains('You are already logged in!', $controller->getResponse()->getBody(),
@ -182,13 +187,13 @@ class SecurityTest extends FunctionalTest {
} }
public function testLogInAsSomeoneElse() { public function testLogInAsSomeoneElse() {
$member = DataObject::get_one('Member'); $member = DataObject::get_one('SilverStripe\\Security\\Member');
/* Log in with any user that we can find */ /* Log in with any user that we can find */
$this->session()->inst_set('loggedInAs', $member->ID); $this->session()->inst_set('loggedInAs', $member->ID);
/* View the Security/login page */ /* View the Security/login page */
$response = $this->get(Config::inst()->get('Security', 'login_url')); $response = $this->get(Config::inst()->get('SilverStripe\\Security\\Security', 'login_url'));
$items = $this->cssParser()->getBySelector('#MemberLoginForm_LoginForm input.action'); $items = $this->cssParser()->getBySelector('#MemberLoginForm_LoginForm input.action');
@ -202,7 +207,7 @@ class SecurityTest extends FunctionalTest {
'MemberLoginForm_LoginForm', 'MemberLoginForm_LoginForm',
null, null,
array( array(
'AuthenticationMethod' => 'MemberAuthenticator', 'AuthenticationMethod' => 'SilverStripe\\Security\\MemberAuthenticator',
'action_dologout' => 1, 'action_dologout' => 1,
) )
); );
@ -222,7 +227,7 @@ class SecurityTest extends FunctionalTest {
$this->autoFollowRedirection = true; $this->autoFollowRedirection = true;
/* Attempt to get into the admin section */ /* Attempt to get into the admin section */
$response = $this->get(Config::inst()->get('Security', 'login_url')); $response = $this->get(Config::inst()->get('SilverStripe\\Security\\Security', 'login_url'));
$items = $this->cssParser()->getBySelector('#MemberLoginForm_LoginForm input.text'); $items = $this->cssParser()->getBySelector('#MemberLoginForm_LoginForm input.text');
@ -239,7 +244,7 @@ class SecurityTest extends FunctionalTest {
// Test that username does not persist // Test that username does not persist
$this->session()->inst_set('SessionForms.MemberLoginForm.Email', 'myuser@silverstripe.com'); $this->session()->inst_set('SessionForms.MemberLoginForm.Email', 'myuser@silverstripe.com');
Security::config()->remember_username = false; Security::config()->remember_username = false;
$this->get(Config::inst()->get('Security', 'login_url')); $this->get(Config::inst()->get('SilverStripe\\Security\\Security', 'login_url'));
$items = $this $items = $this
->cssParser() ->cssParser()
->getBySelector('#MemberLoginForm_LoginForm #MemberLoginForm_LoginForm_Email'); ->getBySelector('#MemberLoginForm_LoginForm #MemberLoginForm_LoginForm_Email');
@ -253,7 +258,7 @@ class SecurityTest extends FunctionalTest {
// Test that username does persist when necessary // Test that username does persist when necessary
$this->session()->inst_set('SessionForms.MemberLoginForm.Email', 'myuser@silverstripe.com'); $this->session()->inst_set('SessionForms.MemberLoginForm.Email', 'myuser@silverstripe.com');
Security::config()->remember_username = true; Security::config()->remember_username = true;
$this->get(Config::inst()->get('Security', 'login_url')); $this->get(Config::inst()->get('SilverStripe\\Security\\Security', 'login_url'));
$items = $this $items = $this
->cssParser() ->cssParser()
->getBySelector('#MemberLoginForm_LoginForm #MemberLoginForm_LoginForm_Email'); ->getBySelector('#MemberLoginForm_LoginForm #MemberLoginForm_LoginForm_Email');
@ -322,7 +327,7 @@ class SecurityTest extends FunctionalTest {
Controller::join_links(Director::absoluteBaseURL(), 'test/link'), Controller::join_links(Director::absoluteBaseURL(), 'test/link'),
$goodResponse->getHeader('Location') $goodResponse->getHeader('Location')
); );
$this->assertEquals($this->idFromFixture('Member', 'test'), $this->session()->inst_get('loggedInAs')); $this->assertEquals($this->idFromFixture('SilverStripe\\Security\\Member', 'test'), $this->session()->inst_get('loggedInAs'));
/* EXPIRED PASSWORDS ARE SENT TO THE CHANGE PASSWORD FORM */ /* EXPIRED PASSWORDS ARE SENT TO THE CHANGE PASSWORD FORM */
$expiredResponse = $this->doTestLoginForm('expired@silverstripe.com' , '1nitialPassword'); $expiredResponse = $this->doTestLoginForm('expired@silverstripe.com' , '1nitialPassword');
@ -331,7 +336,7 @@ class SecurityTest extends FunctionalTest {
Controller::join_links(Director::baseURL(), 'Security/changepassword'), Controller::join_links(Director::baseURL(), 'Security/changepassword'),
$expiredResponse->getHeader('Location') $expiredResponse->getHeader('Location')
); );
$this->assertEquals($this->idFromFixture('Member', 'expiredpassword'), $this->assertEquals($this->idFromFixture('SilverStripe\\Security\\Member', 'expiredpassword'),
$this->session()->inst_get('loggedInAs')); $this->session()->inst_get('loggedInAs'));
// Make sure it redirects correctly after the password has been changed // Make sure it redirects correctly after the password has been changed
@ -355,7 +360,7 @@ class SecurityTest extends FunctionalTest {
Controller::join_links(Director::absoluteBaseURL(), 'test/back'), Controller::join_links(Director::absoluteBaseURL(), 'test/back'),
$changedResponse->getHeader('Location') $changedResponse->getHeader('Location')
); );
$this->assertEquals($this->idFromFixture('Member', 'test'), $this->session()->inst_get('loggedInAs')); $this->assertEquals($this->idFromFixture('SilverStripe\\Security\\Member', 'test'), $this->session()->inst_get('loggedInAs'));
// Check if we can login with the new password // Check if we can login with the new password
$goodResponse = $this->doTestLoginForm('testuser@example.com' , 'changedPassword'); $goodResponse = $this->doTestLoginForm('testuser@example.com' , 'changedPassword');
@ -364,11 +369,11 @@ class SecurityTest extends FunctionalTest {
Controller::join_links(Director::absoluteBaseURL(), 'test/link'), Controller::join_links(Director::absoluteBaseURL(), 'test/link'),
$goodResponse->getHeader('Location') $goodResponse->getHeader('Location')
); );
$this->assertEquals($this->idFromFixture('Member', 'test'), $this->session()->inst_get('loggedInAs')); $this->assertEquals($this->idFromFixture('SilverStripe\\Security\\Member', 'test'), $this->session()->inst_get('loggedInAs'));
} }
public function testChangePasswordFromLostPassword() { public function testChangePasswordFromLostPassword() {
$admin = $this->objFromFixture('Member', 'test'); $admin = $this->objFromFixture('SilverStripe\\Security\\Member', 'test');
$admin->FailedLoginCount = 99; $admin->FailedLoginCount = 99;
$admin->LockedOutUntil = DBDatetime::now()->Format('Y-m-d H:i:s'); $admin->LockedOutUntil = DBDatetime::now()->Format('Y-m-d H:i:s');
$admin->write(); $admin->write();
@ -382,7 +387,7 @@ class SecurityTest extends FunctionalTest {
$this->assertEmailSent('testuser@example.com'); $this->assertEmailSent('testuser@example.com');
// Load password link from email // Load password link from email
$admin = DataObject::get_by_id('Member', $admin->ID); $admin = DataObject::get_by_id('SilverStripe\\Security\\Member', $admin->ID);
$this->assertNotNull($admin->AutoLoginHash, 'Hash has been written after lost password'); $this->assertNotNull($admin->AutoLoginHash, 'Hash has been written after lost password');
// We don't have access to the token - generate a new token and hash pair. // We don't have access to the token - generate a new token and hash pair.
@ -396,14 +401,14 @@ class SecurityTest extends FunctionalTest {
// Follow redirection to form without hash in GET parameter // Follow redirection to form without hash in GET parameter
$response = $this->get('Security/changepassword'); $response = $this->get('Security/changepassword');
$changedResponse = $this->doTestChangepasswordForm('1nitialPassword', 'changedPassword'); $changedResponse = $this->doTestChangepasswordForm('1nitialPassword', 'changedPassword');
$this->assertEquals($this->idFromFixture('Member', 'test'), $this->session()->inst_get('loggedInAs')); $this->assertEquals($this->idFromFixture('SilverStripe\\Security\\Member', 'test'), $this->session()->inst_get('loggedInAs'));
// Check if we can login with the new password // Check if we can login with the new password
$goodResponse = $this->doTestLoginForm('testuser@example.com' , 'changedPassword'); $goodResponse = $this->doTestLoginForm('testuser@example.com' , 'changedPassword');
$this->assertEquals(302, $goodResponse->getStatusCode()); $this->assertEquals(302, $goodResponse->getStatusCode());
$this->assertEquals($this->idFromFixture('Member', 'test'), $this->session()->inst_get('loggedInAs')); $this->assertEquals($this->idFromFixture('SilverStripe\\Security\\Member', 'test'), $this->session()->inst_get('loggedInAs'));
$admin = DataObject::get_by_id('Member', $admin->ID, false); $admin = DataObject::get_by_id('SilverStripe\\Security\\Member', $admin->ID, false);
$this->assertNull($admin->LockedOutUntil); $this->assertNull($admin->LockedOutUntil);
$this->assertEquals(0, $admin->FailedLoginCount); $this->assertEquals(0, $admin->FailedLoginCount);
} }
@ -418,7 +423,7 @@ class SecurityTest extends FunctionalTest {
// Login with a wrong password for more than the defined threshold // Login with a wrong password for more than the defined threshold
for($i = 1; $i <= Member::config()->lock_out_after_incorrect_logins+1; $i++) { for($i = 1; $i <= Member::config()->lock_out_after_incorrect_logins+1; $i++) {
$this->doTestLoginForm('testuser@example.com' , 'incorrectpassword'); $this->doTestLoginForm('testuser@example.com' , 'incorrectpassword');
$member = DataObject::get_by_id("Member", $this->idFromFixture('Member', 'test')); $member = DataObject::get_by_id("SilverStripe\\Security\\Member", $this->idFromFixture('SilverStripe\\Security\\Member', 'test'));
if($i < Member::config()->lock_out_after_incorrect_logins) { if($i < Member::config()->lock_out_after_incorrect_logins) {
$this->assertNull( $this->assertNull(
@ -454,7 +459,7 @@ class SecurityTest extends FunctionalTest {
); );
// (We fake this by re-setting LockedOutUntil) // (We fake this by re-setting LockedOutUntil)
$member = DataObject::get_by_id("Member", $this->idFromFixture('Member', 'test')); $member = DataObject::get_by_id("SilverStripe\\Security\\Member", $this->idFromFixture('SilverStripe\\Security\\Member', 'test'));
$member->LockedOutUntil = date('Y-m-d H:i:s', time() - 30); $member->LockedOutUntil = date('Y-m-d H:i:s', time() - 30);
$member->write(); $member->write();
$this->doTestLoginForm('testuser@example.com' , '1nitialPassword'); $this->doTestLoginForm('testuser@example.com' , '1nitialPassword');
@ -499,8 +504,8 @@ class SecurityTest extends FunctionalTest {
$this->doTestLoginForm('noexpiry@silverstripe.com' , 'incorrectpassword'); $this->doTestLoginForm('noexpiry@silverstripe.com' , 'incorrectpassword');
$this->doTestLoginForm('noexpiry@silverstripe.com' , 'incorrectpassword'); $this->doTestLoginForm('noexpiry@silverstripe.com' , 'incorrectpassword');
$member1 = DataObject::get_by_id("Member", $this->idFromFixture('Member', 'test')); $member1 = DataObject::get_by_id("SilverStripe\\Security\\Member", $this->idFromFixture('SilverStripe\\Security\\Member', 'test'));
$member2 = DataObject::get_by_id("Member", $this->idFromFixture('Member', 'noexpiry')); $member2 = DataObject::get_by_id("SilverStripe\\Security\\Member", $this->idFromFixture('SilverStripe\\Security\\Member', 'noexpiry'));
$this->assertNull($member1->LockedOutUntil); $this->assertNull($member1->LockedOutUntil);
$this->assertNull($member2->LockedOutUntil); $this->assertNull($member2->LockedOutUntil);
@ -509,11 +514,11 @@ class SecurityTest extends FunctionalTest {
// THIS SESSION // THIS SESSION
$this->doTestLoginForm('testuser@example.com' , 'incorrectpassword'); $this->doTestLoginForm('testuser@example.com' , 'incorrectpassword');
$member1 = DataObject::get_by_id("Member", $this->idFromFixture('Member', 'test')); $member1 = DataObject::get_by_id("SilverStripe\\Security\\Member", $this->idFromFixture('SilverStripe\\Security\\Member', 'test'));
$this->assertNotNull($member1->LockedOutUntil); $this->assertNotNull($member1->LockedOutUntil);
$this->doTestLoginForm('noexpiry@silverstripe.com' , 'incorrectpassword'); $this->doTestLoginForm('noexpiry@silverstripe.com' , 'incorrectpassword');
$member2 = DataObject::get_by_id("Member", $this->idFromFixture('Member', 'noexpiry')); $member2 = DataObject::get_by_id("SilverStripe\\Security\\Member", $this->idFromFixture('SilverStripe\\Security\\Member', 'noexpiry'));
$this->assertNotNull($member2->LockedOutUntil); $this->assertNotNull($member2->LockedOutUntil);
} }
@ -522,11 +527,11 @@ class SecurityTest extends FunctionalTest {
/* UNSUCCESSFUL ATTEMPTS WITH WRONG PASSWORD FOR EXISTING USER ARE LOGGED */ /* UNSUCCESSFUL ATTEMPTS WITH WRONG PASSWORD FOR EXISTING USER ARE LOGGED */
$this->doTestLoginForm('testuser@example.com', 'wrongpassword'); $this->doTestLoginForm('testuser@example.com', 'wrongpassword');
$attempt = DataObject::get_one('LoginAttempt', array( $attempt = DataObject::get_one('SilverStripe\\Security\\LoginAttempt', array(
'"LoginAttempt"."Email"' => 'testuser@example.com' '"LoginAttempt"."Email"' => 'testuser@example.com'
)); ));
$this->assertTrue(is_object($attempt)); $this->assertTrue(is_object($attempt));
$member = DataObject::get_one('Member', array( $member = DataObject::get_one('SilverStripe\\Security\\Member', array(
'"Member"."Email"' => 'testuser@example.com' '"Member"."Email"' => 'testuser@example.com'
)); ));
$this->assertEquals($attempt->Status, 'Failure'); $this->assertEquals($attempt->Status, 'Failure');
@ -535,7 +540,7 @@ class SecurityTest extends FunctionalTest {
/* UNSUCCESSFUL ATTEMPTS WITH NONEXISTING USER ARE LOGGED */ /* UNSUCCESSFUL ATTEMPTS WITH NONEXISTING USER ARE LOGGED */
$this->doTestLoginForm('wronguser@silverstripe.com', 'wrongpassword'); $this->doTestLoginForm('wronguser@silverstripe.com', 'wrongpassword');
$attempt = DataObject::get_one('LoginAttempt', array( $attempt = DataObject::get_one('SilverStripe\\Security\\LoginAttempt', array(
'"LoginAttempt"."Email"' => 'wronguser@silverstripe.com' '"LoginAttempt"."Email"' => 'wronguser@silverstripe.com'
)); ));
$this->assertTrue(is_object($attempt)); $this->assertTrue(is_object($attempt));
@ -551,10 +556,10 @@ class SecurityTest extends FunctionalTest {
/* SUCCESSFUL ATTEMPTS ARE LOGGED */ /* SUCCESSFUL ATTEMPTS ARE LOGGED */
$this->doTestLoginForm('testuser@example.com', '1nitialPassword'); $this->doTestLoginForm('testuser@example.com', '1nitialPassword');
$attempt = DataObject::get_one('LoginAttempt', array( $attempt = DataObject::get_one('SilverStripe\\Security\\LoginAttempt', array(
'"LoginAttempt"."Email"' => 'testuser@example.com' '"LoginAttempt"."Email"' => 'testuser@example.com'
)); ));
$member = DataObject::get_one('Member', array( $member = DataObject::get_one('SilverStripe\\Security\\Member', array(
'"Member"."Email"' => 'testuser@example.com' '"Member"."Email"' => 'testuser@example.com'
)); ));
$this->assertTrue(is_object($attempt)); $this->assertTrue(is_object($attempt));
@ -571,6 +576,7 @@ class SecurityTest extends FunctionalTest {
// Assumption: The database has been built correctly by the test runner, // Assumption: The database has been built correctly by the test runner,
// and has all columns present in the ORM // and has all columns present in the ORM
/** @skipUpgrade */
DB::get_schema()->renameField('Member', 'Email', 'Email_renamed'); DB::get_schema()->renameField('Member', 'Email', 'Email_renamed');
// Email column is now missing, which means we're not ready to do permission checks // Email column is now missing, which means we're not ready to do permission checks
@ -588,9 +594,9 @@ class SecurityTest extends FunctionalTest {
* Helper method for the tests above * Helper method for the tests above
*/ */
public function doTestLoginForm($email, $password, $backURL = 'test/link') { public function doTestLoginForm($email, $password, $backURL = 'test/link') {
$this->get(Config::inst()->get('Security', 'logout_url')); $this->get(Config::inst()->get('SilverStripe\\Security\\Security', 'logout_url'));
$this->session()->inst_set('BackURL', $backURL); $this->session()->inst_set('BackURL', $backURL);
$this->get(Config::inst()->get('Security', 'login_url')); $this->get(Config::inst()->get('SilverStripe\\Security\\Security', 'login_url'));
return $this->submitForm( return $this->submitForm(
"MemberLoginForm_LoginForm", "MemberLoginForm_LoginForm",
@ -598,7 +604,7 @@ class SecurityTest extends FunctionalTest {
array( array(
'Email' => $email, 'Email' => $email,
'Password' => $password, 'Password' => $password,
'AuthenticationMethod' => 'MemberAuthenticator', 'AuthenticationMethod' => 'SilverStripe\\Security\\MemberAuthenticator',
'action_dologin' => 1, 'action_dologin' => 1,
) )
); );

View File

@ -1,4 +1,6 @@
<?php <?php
use SilverStripe\Security\SecurityToken;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
@ -41,7 +43,7 @@ class SecurityTokenTest extends SapphireTest {
public function testInst() { public function testInst() {
$inst1 = SecurityToken::inst(); $inst1 = SecurityToken::inst();
$this->assertInstanceOf('SecurityToken', $inst1); $this->assertInstanceOf('SilverStripe\\Security\\SecurityToken', $inst1);
} }
public function testInstReturnsSingleton() { public function testInstReturnsSingleton() {

View File

@ -1,6 +1,8 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
@ -15,7 +17,7 @@ class EncryptAllPasswordsTaskTest extends SapphireTest {
$t = new EncryptAllPasswordsTask(); $t = new EncryptAllPasswordsTask();
$t->run(null); $t->run(null);
$m = DataObject::get_by_id('Member', $m->ID); $m = DataObject::get_by_id('SilverStripe\\Security\\Member', $m->ID);
$this->assertEquals($m->PasswordEncryption, 'blowfish'); $this->assertEquals($m->PasswordEncryption, 'blowfish');
$this->assertNotEquals($m->Password, 'plain'); $this->assertNotEquals($m->Password, 'plain');
$result = $m->checkPassword('plain'); $result = $m->checkPassword('plain');

View File

@ -2,6 +2,10 @@
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\SecurityToken;
use SilverStripe\Security\Permission;
class SSViewerTest extends SapphireTest { class SSViewerTest extends SapphireTest {

View File

@ -2,6 +2,8 @@
use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\Security\Permission;
/** /**