public function testRun()
 {
     $m = new Member();
     $m->Password = '******';
     $m->PasswordEncryption = 'none';
     $m->write();
     $t = new EncryptAllPasswordsTask();
     $t->run(null);
     $m = DataObject::get_by_id('SilverStripe\\Security\\Member', $m->ID);
     $this->assertEquals($m->PasswordEncryption, 'blowfish');
     $this->assertNotEquals($m->Password, 'plain');
     $result = $m->checkPassword('plain');
     $this->assertTrue($result->valid());
 }
 public function testOverwriteExistingImport()
 {
     $author1 = new Member();
     $author1->FirstName = 'author1_first_old';
     $author1->Email = '*****@*****.**';
     $author1->write();
     $loader = new MemberCsvBulkLoader();
     $results = $loader->load($this->getCurrentRelativePath() . '/MemberCsvBulkLoaderTest.csv');
     $created = $results->Created()->toArray();
     $this->assertEquals(count($created), 1);
     $updated = $results->Updated()->toArray();
     $this->assertEquals(count($updated), 1);
     $this->assertEquals($created[0]->Email, '*****@*****.**');
     $this->assertEquals($updated[0]->Email, '*****@*****.**');
     $this->assertEquals($updated[0]->FirstName, 'author1_first');
 }
 /**
  * Member object of the person who last published this record
  *
  * @return Member
  */
 public function Publisher()
 {
     if (!$this->record['WasPublished']) {
         return null;
     }
     return Member::get()->byID($this->record['PublisherID']);
 }
 public function testHashHidden()
 {
     $field = new ConfirmedPasswordField('Password', 'Password', 'valueA');
     $field->setCanBeEmpty(true);
     $this->assertEquals('valueA', $field->Value());
     $this->assertEquals('valueA', $field->children->fieldByName($field->getName() . '[_Password]')->Value());
     $this->assertEquals('valueA', $field->children->fieldByName($field->getName() . '[_ConfirmPassword]')->Value());
     $member = new Member();
     $member->Password = "******";
     $member->write();
     $form = new Form($this, 'Form', new FieldList($field), new FieldList());
     $form->loadDataFrom($member);
     $this->assertEquals('', $field->Value());
     $this->assertEquals('', $field->children->fieldByName($field->getName() . '[_Password]')->Value());
     $this->assertEquals('', $field->children->fieldByName($field->getName() . '[_ConfirmPassword]')->Value());
 }
 /**
  * Get the locale of the Member, or if we're not logged in or don't have a locale, use the default one
  * @return string
  */
 protected function locale()
 {
     if (($member = Member::currentUser()) && $member->Locale) {
         return $member->Locale;
     }
     return i18n::get_locale();
 }
 public function getEditForm($id = null, $fields = null)
 {
     // TODO Duplicate record fetching (see parent implementation)
     if (!$id) {
         $id = $this->currentPageID();
     }
     $form = parent::getEditForm($id);
     // TODO Duplicate record fetching (see parent implementation)
     $record = $this->getRecord($id);
     if ($record && !$record->canView()) {
         return Security::permissionFailure($this);
     }
     $memberList = GridField::create('Members', false, Member::get(), $memberListConfig = GridFieldConfig_RecordEditor::create()->addComponent(new GridFieldButtonRow('after'))->addComponent(new GridFieldExportButton('buttons-after-left')))->addExtraClass("members_grid");
     if ($record && method_exists($record, 'getValidator')) {
         $validator = $record->getValidator();
     } else {
         $validator = Member::singleton()->getValidator();
     }
     $memberListConfig->getComponentByType('GridFieldDetailForm')->setValidator($validator);
     $groupList = GridField::create('Groups', false, Group::get(), GridFieldConfig_RecordEditor::create());
     $columns = $groupList->getConfig()->getComponentByType('GridFieldDataColumns');
     $columns->setDisplayFields(array('Breadcrumbs' => singleton('SilverStripe\\Security\\Group')->fieldLabel('Title')));
     $columns->setFieldFormatting(array('Breadcrumbs' => function ($val, $item) {
         return Convert::raw2xml($item->getBreadcrumbs(' > '));
     }));
     $fields = new FieldList($root = new TabSet('Root', $usersTab = new Tab('Users', _t('SecurityAdmin.Users', 'Users'), new LiteralField('MembersCautionText', sprintf('<div class="alert alert-warning" role="alert">%s</div>', _t('SecurityAdmin.MemberListCaution', 'Caution: Removing members from this list will remove them from all groups and the database'))), $memberList), $groupsTab = new Tab('Groups', singleton('SilverStripe\\Security\\Group')->i18n_plural_name(), $groupList)), new HiddenField('ID', false, 0));
     // Add import capabilities. Limit to admin since the import logic can affect assigned permissions
     if (Permission::check('ADMIN')) {
         $fields->addFieldsToTab('Root.Users', array(new HeaderField(_t('SecurityAdmin.IMPORTUSERS', 'Import users'), 3), new LiteralField('MemberImportFormIframe', sprintf('<iframe src="%s" id="MemberImportFormIframe" width="100%%" height="250px" frameBorder="0">' . '</iframe>', $this->Link('memberimport')))));
         $fields->addFieldsToTab('Root.Groups', array(new HeaderField(_t('SecurityAdmin.IMPORTGROUPS', 'Import groups'), 3), new LiteralField('GroupImportFormIframe', sprintf('<iframe src="%s" id="GroupImportFormIframe" width="100%%" height="250px" frameBorder="0">' . '</iframe>', $this->Link('groupimport')))));
     }
     // Tab nav in CMS is rendered through separate template
     $root->setTemplate('CMSTabSet');
     // Add roles editing interface
     if (Permission::check('APPLY_ROLES')) {
         $rolesField = GridField::create('Roles', false, PermissionRole::get(), GridFieldConfig_RecordEditor::create());
         $rolesTab = $fields->findOrMakeTab('Root.Roles', _t('SecurityAdmin.TABROLES', 'Roles'));
         $rolesTab->push($rolesField);
     }
     $actionParam = $this->getRequest()->param('Action');
     if ($actionParam == 'groups') {
         $groupsTab->addExtraClass('ui-state-active');
     } elseif ($actionParam == 'users') {
         $usersTab->addExtraClass('ui-state-active');
     } elseif ($actionParam == 'roles') {
         $rolesTab->addExtraClass('ui-state-active');
     }
     $actions = new FieldList();
     $form = Form::create($this, 'EditForm', $fields, $actions)->setHTMLID('Form_EditForm');
     $form->addExtraClass('cms-edit-form');
     $form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
     // Tab nav in CMS is rendered through separate template
     if ($form->Fields()->hasTabset()) {
         $form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
     }
     $form->addExtraClass('center ss-tabset cms-tabset ' . $this->BaseCSSClasses());
     $form->setAttribute('data-pjax-fragment', 'CurrentForm');
     $this->extend('updateEditForm', $form);
     return $form;
 }
 public function run($request)
 {
     $algo = Security::config()->password_encryption_algorithm;
     if ($algo == 'none') {
         $this->debugMessage('Password encryption disabled');
         return;
     }
     // Are there members with a clear text password?
     $members = Member::get()->where(array('"Member"."PasswordEncryption"' => 'none', '"Member"."Password" IS NOT NULL'));
     if (!$members) {
         $this->debugMessage('No passwords to encrypt');
         return;
     }
     // Encrypt the passwords...
     $this->debugMessage('Encrypting all passwords');
     $this->debugMessage(sprintf('The passwords will be encrypted using the %s algorithm', $algo));
     foreach ($members as $member) {
         // Force the update of the member record, as new passwords get
         // automatically encrypted according to the settings, this will do all
         // the work for us
         $member->PasswordEncryption = $algo;
         $member->forceChange();
         $member->write();
         $this->debugMessage(sprintf('Encrypted credentials for member #%d;', $member->ID));
     }
 }
 /**
  * Change the password
  *
  * @param array $data The user submitted data
  * @return SS_HTTPResponse
  */
 public function doChangePassword(array $data)
 {
     if ($member = Member::currentUser()) {
         // The user was logged in, check the current password
         if (empty($data['OldPassword']) || !$member->checkPassword($data['OldPassword'])->valid()) {
             $this->clearMessage();
             $this->sessionMessage(_t('Member.ERRORPASSWORDNOTMATCH', "Your current password does not match, please try again"), "bad");
             // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
             return $this->controller->redirect($this->controller->Link('changepassword'));
         }
     }
     if (!$member) {
         if (Session::get('AutoLoginHash')) {
             $member = Member::member_from_autologinhash(Session::get('AutoLoginHash'));
         }
         // The user is not logged in and no valid auto login hash is available
         if (!$member) {
             Session::clear('AutoLoginHash');
             return $this->controller->redirect($this->controller->Link('login'));
         }
     }
     // Check the new password
     if (empty($data['NewPassword1'])) {
         $this->clearMessage();
         $this->sessionMessage(_t('Member.EMPTYNEWPASSWORD', "The new password can't be empty, please try again"), "bad");
         // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
         return $this->controller->redirect($this->controller->Link('changepassword'));
     } else {
         if ($data['NewPassword1'] == $data['NewPassword2']) {
             $isValid = $member->changePassword($data['NewPassword1']);
             if ($isValid->valid()) {
                 $member->logIn();
                 // TODO Add confirmation message to login redirect
                 Session::clear('AutoLoginHash');
                 // Clear locked out status
                 $member->LockedOutUntil = null;
                 $member->FailedLoginCount = null;
                 $member->write();
                 if (!empty($_REQUEST['BackURL']) && Director::is_site_url($_REQUEST['BackURL'])) {
                     $url = Director::absoluteURL($_REQUEST['BackURL']);
                     return $this->controller->redirect($url);
                 } else {
                     // Redirect to default location - the login form saying "You are logged in as..."
                     $redirectURL = HTTP::setGetVar('BackURL', Director::absoluteBaseURL(), $this->controller->Link('login'));
                     return $this->controller->redirect($redirectURL);
                 }
             } else {
                 $this->clearMessage();
                 $this->sessionMessage(_t('Member.INVALIDNEWPASSWORD', "We couldn't accept that password: {password}", array('password' => nl2br("\n" . Convert::raw2xml($isValid->starredList())))), "bad", false);
                 // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
                 return $this->controller->redirect($this->controller->Link('changepassword'));
             }
         } else {
             $this->clearMessage();
             $this->sessionMessage(_t('Member.ERRORNEWPASSWORD', "You have entered your new password differently, try again"), "bad");
             // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
             return $this->controller->redirect($this->controller->Link('changepassword'));
         }
     }
 }
 public function testDefaultAdmin()
 {
     $adminMembers = Permission::get_members_by_permission('ADMIN');
     $this->assertEquals(0, $adminMembers->count());
     $admin = Member::default_admin();
     $this->assertInstanceOf('SilverStripe\\Security\\Member', $admin);
     $this->assertTrue(Permission::checkMember($admin, 'ADMIN'));
     $this->assertEquals($admin->Email, Security::default_admin_username());
     $this->assertNull($admin->Password);
 }
 /**
  * Require basic authentication.  Will request a username and password if none is given.
  *
  * Used by {@link Controller::init()}.
  *
  * @throws HTTPResponse_Exception
  *
  * @param string $realm
  * @param string|array $permissionCode Optional
  * @param boolean $tryUsingSessionLogin If true, then the method with authenticate against the
  *  session log-in if those credentials are disabled.
  * @return Member|bool $member
  */
 public static function requireLogin($realm, $permissionCode = null, $tryUsingSessionLogin = true)
 {
     $isRunningTests = class_exists('SilverStripe\\Dev\\SapphireTest', false) && SapphireTest::is_running_test();
     if (!Security::database_is_ready() || Director::is_cli() && !$isRunningTests) {
         return true;
     }
     /*
      * Enable HTTP Basic authentication workaround for PHP running in CGI mode with Apache
      * Depending on server configuration the auth header may be in HTTP_AUTHORIZATION or
      * REDIRECT_HTTP_AUTHORIZATION
      *
      * The follow rewrite rule must be in the sites .htaccess file to enable this workaround
      * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
      */
     $authHeader = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) ? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] : null);
     $matches = array();
     if ($authHeader && preg_match('/Basic\\s+(.*)$/i', $authHeader, $matches)) {
         list($name, $password) = explode(':', base64_decode($matches[1]));
         $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
         $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
     }
     $member = null;
     if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
         $member = MemberAuthenticator::authenticate(array('Email' => $_SERVER['PHP_AUTH_USER'], 'Password' => $_SERVER['PHP_AUTH_PW']), null);
     }
     if (!$member && $tryUsingSessionLogin) {
         $member = Member::currentUser();
     }
     // If we've failed the authentication mechanism, then show the login form
     if (!$member) {
         $response = new HTTPResponse(null, 401);
         $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\"");
         if (isset($_SERVER['PHP_AUTH_USER'])) {
             $response->setBody(_t('BasicAuth.ERRORNOTREC', "That username / password isn't recognised"));
         } else {
             $response->setBody(_t('BasicAuth.ENTERINFO', "Please enter a username and password."));
         }
         // Exception is caught by RequestHandler->handleRequest() and will halt further execution
         $e = new HTTPResponse_Exception(null, 401);
         $e->setResponse($response);
         throw $e;
     }
     if ($permissionCode && !Permission::checkMember($member->ID, $permissionCode)) {
         $response = new HTTPResponse(null, 401);
         $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\"");
         if (isset($_SERVER['PHP_AUTH_USER'])) {
             $response->setBody(_t('BasicAuth.ERRORNOTADMIN', "That user is not an administrator."));
         }
         // Exception is caught by RequestHandler->handleRequest() and will halt further execution
         $e = new HTTPResponse_Exception(null, 401);
         $e->setResponse($response);
         throw $e;
     }
     return $member;
 }
 public function testExtendedPermissionsStopEditingOwnProfile()
 {
     $existingExtensions = Member::config()->get('extensions');
     Member::config()->update('extensions', array('CMSProfileControllerTestExtension'));
     $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'user1');
     $this->session()->inst_set('loggedInAs', $member->ID);
     $response = $this->post('admin/myprofile/EditForm', array('action_save' => 1, 'ID' => $member->ID, 'FirstName' => 'JoeEdited', 'Surname' => 'BloggsEdited', 'Email' => $member->Email, 'Locale' => $member->Locale, 'Password[_Password]' => 'password', 'Password[_ConfirmPassword]' => 'password'));
     $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'user1');
     $this->assertNotEquals($member->FirstName, 'JoeEdited', 'FirstName field was NOT changed because we modified canEdit');
     Member::config()->remove('extensions')->update('extensions', $existingExtensions);
 }
 public function testShowEditLinks()
 {
     if (Member::currentUser()) {
         Member::currentUser()->logOut();
     }
     $content = new CSSContentParser($this->gridField->FieldHolder());
     // Check that there are content
     $this->assertEquals(3, count($content->getBySelector('.ss-gridfield-item')));
     // Make sure that there are edit links, even though the user doesn't have "edit" permissions
     // (they can still view the records)
     $this->assertEquals(2, count($content->getBySelector('.edit-link')), 'Edit links should show when not logged in.');
 }
 public function testDeleteActionWithoutCorrectPermission()
 {
     if (Member::currentUser()) {
         Member::currentUser()->logOut();
     }
     $this->setExpectedException('SilverStripe\\ORM\\ValidationException');
     $stateID = 'testGridStateActionField';
     Session::set($stateID, array('grid' => '', 'actionName' => 'deleterecord', 'args' => array('RecordID' => $this->idFromFixture('GridFieldAction_Delete_Team', 'team1'))));
     $token = SecurityToken::inst();
     $request = new SS_HTTPRequest('POST', 'url', array(), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $token->getName() => $token->getValue()));
     $this->gridField->gridFieldAlterAction(array('StateID' => $stateID), $this->form, $request);
     $this->assertEquals(3, $this->list->count(), 'User should\'t be able to delete records without correct permissions.');
 }
 public function save($data, $form)
 {
     $member = Member::get()->byID($data['ID']);
     if (!$member) {
         return $this->httpError(404);
     }
     $origLocale = $member->Locale;
     if (!$member->canEdit()) {
         $form->sessionMessage(_t('Member.CANTEDIT', 'You don\'t have permission to do that'), 'bad');
         return $this->redirectBack();
     }
     $response = parent::save($data, $form);
     if ($origLocale != $data['Locale']) {
         $response->addHeader('X-Reload', true);
         $response->addHeader('X-ControllerURL', $this->Link());
     }
     return $response;
 }
 /**
  * Returns true if the member is allowed to do the given action.
  * See {@link extendedCan()} for a more versatile tri-state permission control.
  *
  * @param string $perm The permission to be checked, such as 'View'.
  * @param Member $member The member whose permissions need checking.  Defaults to the currently logged
  * in user.
  * @param array $context Additional $context to pass to extendedCan()
  *
  * @return boolean True if the the member is allowed to do the given action
  */
 public function can($perm, $member = null, $context = array())
 {
     if (!isset($member)) {
         $member = Member::currentUser();
     }
     if (Permission::checkMember($member, "ADMIN")) {
         return true;
     }
     if ($this->getSchema()->manyManyComponent(static::class, 'Can' . $perm)) {
         if ($this->ParentID && $this->SecurityType == 'Inherit') {
             if (!($p = $this->Parent)) {
                 return false;
             }
             return $this->Parent->can($perm, $member);
         } else {
             $permissionCache = $this->uninherited('permissionCache');
             $memberID = $member ? $member->ID : 'none';
             if (!isset($permissionCache[$memberID][$perm])) {
                 if ($member->ID) {
                     $groups = $member->Groups();
                 }
                 $groupList = implode(', ', $groups->column("ID"));
                 // TODO Fix relation table hardcoding
                 $query = new SQLSelect("\"Page_Can{$perm}\".PageID", array("\"Page_Can{$perm}\""), "GroupID IN ({$groupList})");
                 $permissionCache[$memberID][$perm] = $query->execute()->column();
                 if ($perm == "View") {
                     // TODO Fix relation table hardcoding
                     $query = new SQLSelect("\"SiteTree\".\"ID\"", array("\"SiteTree\"", "LEFT JOIN \"Page_CanView\" ON \"Page_CanView\".\"PageID\" = \"SiteTree\".\"ID\""), "\"Page_CanView\".\"PageID\" IS NULL");
                     $unsecuredPages = $query->execute()->column();
                     if ($permissionCache[$memberID][$perm]) {
                         $permissionCache[$memberID][$perm] = array_merge($permissionCache[$memberID][$perm], $unsecuredPages);
                     } else {
                         $permissionCache[$memberID][$perm] = $unsecuredPages;
                     }
                 }
                 Config::inst()->update($this->class, 'permissionCache', $permissionCache);
             }
             if ($permissionCache[$memberID][$perm]) {
                 return in_array($this->ID, $permissionCache[$memberID][$perm]);
             }
         }
     } else {
         return parent::can($perm, $member);
     }
 }
 /**
  * Validate this field
  *
  * @param Validator $validator
  * @return bool
  */
 public function validate($validator)
 {
     $name = $this->name;
     // if field isn't visible, don't validate
     if (!$this->isSaveable()) {
         return true;
     }
     $this->passwordField->setValue($this->value);
     $this->confirmPasswordfield->setValue($this->confirmValue);
     $value = $this->passwordField->Value();
     // both password-fields should be the same
     if ($value != $this->confirmPasswordfield->Value()) {
         $validator->validationError($name, _t('Form.VALIDATIONPASSWORDSDONTMATCH', "Passwords don't match"), "validation");
         return false;
     }
     if (!$this->canBeEmpty) {
         // both password-fields shouldn't be empty
         if (!$value || !$this->confirmPasswordfield->Value()) {
             $validator->validationError($name, _t('Form.VALIDATIONPASSWORDSNOTEMPTY', "Passwords can't be empty"), "validation");
             return false;
         }
     }
     // lengths
     if ($this->minLength || $this->maxLength) {
         $errorMsg = null;
         $limit = null;
         if ($this->minLength && $this->maxLength) {
             $limit = "{{$this->minLength},{$this->maxLength}}";
             $errorMsg = _t('ConfirmedPasswordField.BETWEEN', 'Passwords must be {min} to {max} characters long.', array('min' => $this->minLength, 'max' => $this->maxLength));
         } elseif ($this->minLength) {
             $limit = "{{$this->minLength}}.*";
             $errorMsg = _t('ConfirmedPasswordField.ATLEAST', 'Passwords must be at least {min} characters long.', array('min' => $this->minLength));
         } elseif ($this->maxLength) {
             $limit = "{0,{$this->maxLength}}";
             $errorMsg = _t('ConfirmedPasswordField.MAXIMUM', 'Passwords must be at most {max} characters long.', array('max' => $this->maxLength));
         }
         $limitRegex = '/^.' . $limit . '$/';
         if (!empty($value) && !preg_match($limitRegex, $value)) {
             $validator->validationError($name, $errorMsg, "validation");
         }
     }
     if ($this->requireStrongPassword) {
         if (!preg_match('/^(([a-zA-Z]+\\d+)|(\\d+[a-zA-Z]+))[a-zA-Z0-9]*$/', $value)) {
             $validator->validationError($name, _t('Form.VALIDATIONSTRONGPASSWORD', "Passwords must have at least one digit and one alphanumeric character"), "validation");
             return false;
         }
     }
     // Check if current password is valid
     if (!empty($value) && $this->getRequireExistingPassword()) {
         if (!$this->currentPasswordValue) {
             $validator->validationError($name, _t('ConfirmedPasswordField.CURRENT_PASSWORD_MISSING', "You must enter your current password."), "validation");
             return false;
         }
         // Check this password is valid for the current user
         $member = Member::currentUser();
         if (!$member) {
             $validator->validationError($name, _t('ConfirmedPasswordField.LOGGED_IN_ERROR', "You must be logged in to change your password."), "validation");
             return false;
         }
         // With a valid user and password, check the password is correct
         $checkResult = $member->checkPassword($this->currentPasswordValue);
         if (!$checkResult->valid()) {
             $validator->validationError($name, _t('ConfirmedPasswordField.CURRENT_PASSWORD_ERROR', "The current password you have entered is not correct."), "validation");
             return false;
         }
     }
     return true;
 }
 /**
  * Default permissions for this ChangeSetItem
  *
  * @param string $perm
  * @param Member $member
  * @param array $context
  * @return bool
  */
 public function can($perm, $member = null, $context = array())
 {
     if (!$member) {
         $member = Member::currentUser();
     }
     // Allow extensions to bypass default permissions, but only if
     // each change can be individually published.
     $extended = $this->extendedCan($perm, $member, $context);
     if ($extended !== null) {
         return $extended;
     }
     // Default permissions
     return (bool) Permission::checkMember($member, ChangeSet::config()->required_permission);
 }
 /**
  * Generate a CSV import form for a single {@link DataObject} subclass.
  *
  * @return Form
  */
 public function ImportForm()
 {
     $modelSNG = singleton($this->modelClass);
     $modelName = $modelSNG->i18n_singular_name();
     // check if a import form should be generated
     if (!$this->showImportForm || is_array($this->showImportForm) && !in_array($this->modelClass, $this->showImportForm)) {
         return false;
     }
     $importers = $this->getModelImporters();
     if (!$importers || !isset($importers[$this->modelClass])) {
         return false;
     }
     if (!$modelSNG->canCreate(Member::currentUser())) {
         return false;
     }
     $fields = new FieldList(new HiddenField('ClassName', _t('ModelAdmin.CLASSTYPE'), $this->modelClass), new FileField('_CsvFile', false));
     // get HTML specification for each import (column names etc.)
     $importerClass = $importers[$this->modelClass];
     $importer = new $importerClass($this->modelClass);
     $spec = $importer->getImportSpec();
     $specFields = new ArrayList();
     foreach ($spec['fields'] as $name => $desc) {
         $specFields->push(new ArrayData(array('Name' => $name, 'Description' => $desc)));
     }
     $specRelations = new ArrayList();
     foreach ($spec['relations'] as $name => $desc) {
         $specRelations->push(new ArrayData(array('Name' => $name, 'Description' => $desc)));
     }
     $specHTML = $this->customise(array('ClassName' => $this->sanitiseClassName($this->modelClass), 'ModelName' => Convert::raw2att($modelName), 'Fields' => $specFields, 'Relations' => $specRelations))->renderWith('Includes/ModelAdmin_ImportSpec');
     $fields->push(new LiteralField("SpecFor{$modelName}", $specHTML));
     $fields->push(new CheckboxField('EmptyBeforeImport', _t('ModelAdmin.EMPTYBEFOREIMPORT', 'Replace data'), false));
     $actions = new FieldList(new FormAction('import', _t('ModelAdmin.IMPORT', 'Import from CSV')));
     $form = new Form($this, "ImportForm", $fields, $actions);
     $form->setFormAction(Controller::join_links($this->Link($this->sanitiseClassName($this->modelClass)), 'ImportForm'));
     $this->extend('updateImportForm', $form);
     return $form;
 }
 /**
  * Create a member and group with the given permission code, and log in with it.
  * Returns the member ID.
  *
  * @param string|array $permCode Either a permission, or list of permissions
  * @return int Member ID
  */
 public function logInWithPermission($permCode = "ADMIN")
 {
     if (is_array($permCode)) {
         $permArray = $permCode;
         $permCode = implode('.', $permCode);
     } else {
         $permArray = array($permCode);
     }
     // Check cached member
     if (isset($this->cache_generatedMembers[$permCode])) {
         $member = $this->cache_generatedMembers[$permCode];
     } else {
         // Generate group with these permissions
         $group = Group::create();
         $group->Title = "{$permCode} group";
         $group->write();
         // Create each individual permission
         foreach ($permArray as $permArrayItem) {
             $permission = Permission::create();
             $permission->Code = $permArrayItem;
             $permission->write();
             $group->Permissions()->add($permission);
         }
         $member = DataObject::get_one('SilverStripe\\Security\\Member', array('"Member"."Email"' => "{$permCode}@example.org"));
         if (!$member) {
             $member = Member::create();
         }
         $member->FirstName = $permCode;
         $member->Surname = "User";
         $member->Email = "{$permCode}@example.org";
         $member->write();
         $group->Members()->add($member);
         $this->cache_generatedMembers[$permCode] = $member;
     }
     $member->logIn();
     return $member->ID;
 }
 /**
  * Returns the main menu of the CMS.  This is also used by init()
  * to work out which sections the user has access to.
  *
  * @param bool $cached
  * @return SS_List
  */
 public function MainMenu($cached = true)
 {
     if (!isset($this->_cache_MainMenu) || !$cached) {
         // Don't accidentally return a menu if you're not logged in - it's used to determine access.
         if (!Member::currentUser()) {
             return new ArrayList();
         }
         // Encode into DO set
         $menu = new ArrayList();
         $menuItems = CMSMenu::get_viewable_menu_items();
         // extra styling for custom menu-icons
         $menuIconStyling = '';
         if ($menuItems) {
             /** @var CMSMenuItem $menuItem */
             foreach ($menuItems as $code => $menuItem) {
                 // alternate permission checks (in addition to LeftAndMain->canView())
                 if (isset($menuItem->controller) && $this->hasMethod('alternateMenuDisplayCheck') && !$this->alternateMenuDisplayCheck($menuItem->controller)) {
                     continue;
                 }
                 $linkingmode = "link";
                 if ($menuItem->controller && get_class($this) == $menuItem->controller) {
                     $linkingmode = "current";
                 } else {
                     if (strpos($this->Link(), $menuItem->url) !== false) {
                         if ($this->Link() == $menuItem->url) {
                             $linkingmode = "current";
                             // default menu is the one with a blank {@link url_segment}
                         } else {
                             if (singleton($menuItem->controller)->stat('url_segment') == '') {
                                 if ($this->Link() == AdminRootController::admin_url()) {
                                     $linkingmode = "current";
                                 }
                             } else {
                                 $linkingmode = "current";
                             }
                         }
                     }
                 }
                 // already set in CMSMenu::populate_menu(), but from a static pre-controller
                 // context, so doesn't respect the current user locale in _t() calls - as a workaround,
                 // we simply call LeftAndMain::menu_title() again
                 // if we're dealing with a controller
                 if ($menuItem->controller) {
                     $title = LeftAndMain::menu_title($menuItem->controller);
                 } else {
                     $title = $menuItem->title;
                 }
                 // Provide styling for custom $menu-icon. Done here instead of in
                 // CMSMenu::populate_menu(), because the icon is part of
                 // the CMS right pane for the specified class as well...
                 if ($menuItem->controller) {
                     $menuIcon = LeftAndMain::menu_icon_for_class($menuItem->controller);
                     if (!empty($menuIcon)) {
                         $menuIconStyling .= $menuIcon;
                     }
                 }
                 $menu->push(new ArrayData(array("MenuItem" => $menuItem, "AttributesHTML" => $menuItem->getAttributesHTML(), "Title" => Convert::raw2xml($title), "Code" => $code, "Icon" => strtolower($code), "Link" => $menuItem->url, "LinkingMode" => $linkingmode)));
             }
         }
         if ($menuIconStyling) {
             Requirements::customCSS($menuIconStyling);
         }
         $this->_cache_MainMenu = $menu;
     }
     return $this->_cache_MainMenu;
 }
예제 #21
0
 /**
  * Return an existing member with administrator privileges, or create one of necessary.
  *
  * Will create a default 'Administrators' group if no group is found
  * with an ADMIN permission. Will create a new 'Admin' member with administrative permissions
  * if no existing Member with these permissions is found.
  *
  * Important: Any newly created administrator accounts will NOT have valid
  * login credentials (Email/Password properties), which means they can't be used for login
  * purposes outside of any default credentials set through {@link Security::setDefaultAdmin()}.
  *
  * @return Member
  */
 public static function findAnAdministrator()
 {
     // coupling to subsites module
     $origSubsite = null;
     if (is_callable('Subsite::changeSubsite')) {
         $origSubsite = \Subsite::currentSubsiteID();
         \Subsite::changeSubsite(0);
     }
     $member = null;
     // find a group with ADMIN permission
     $adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
     if (is_callable('Subsite::changeSubsite')) {
         \Subsite::changeSubsite($origSubsite);
     }
     if ($adminGroup) {
         $member = $adminGroup->Members()->First();
     }
     if (!$adminGroup) {
         Group::singleton()->requireDefaultRecords();
         $adminGroup = Permission::get_groups_by_permission('ADMIN')->first();
     }
     if (!$member) {
         Member::singleton()->requireDefaultRecords();
         $member = Permission::get_members_by_permission('ADMIN')->first();
     }
     if (!$member) {
         $member = Member::default_admin();
     }
     if (!$member) {
         // Failover to a blank admin
         $member = Member::create();
         $member->FirstName = _t('Member.DefaultAdminFirstname', 'Default Admin');
         $member->write();
         // Add member to group instead of adding group to member
         // This bypasses the privilege escallation code in Member_GroupSet
         $adminGroup->DirectMembers()->add($member);
     }
     return $member;
 }
예제 #22
0
 /**
  * Return a date formatted as per a CMS user's settings.
  *
  * @param Member $member
  * @return boolean | string A date formatted as per user-defined settings.
  */
 public function FormatFromSettings($member = null)
 {
     require_once 'Zend/Date.php';
     if (!$member) {
         if (!Member::currentUserID()) {
             return false;
         }
         $member = Member::currentUser();
     }
     $formatD = $member->getDateFormat();
     $zendDate = new Zend_Date($this->getValue(), 'y-MM-dd');
     return $zendDate->toString($formatD);
 }
 /**
  * Returns all members for a specific permission.
  *
  * @param $code String|array Either a single permission code, or a list of permission codes
  * @return SS_List Returns a set of member that have the specified
  *                       permission.
  */
 public static function get_members_by_permission($code)
 {
     $toplevelGroups = self::get_groups_by_permission($code);
     if (!$toplevelGroups) {
         return new ArrayList();
     }
     $groupIDs = array();
     foreach ($toplevelGroups as $group) {
         $familyIDs = $group->collateFamilyIDs();
         if (is_array($familyIDs)) {
             $groupIDs = array_merge($groupIDs, array_values($familyIDs));
         }
     }
     if (empty($groupIDs)) {
         return new ArrayList();
     }
     $groupClause = DB::placeholders($groupIDs);
     /** @skipUpgrade */
     $members = Member::get()->where(array("\"Group\".\"ID\" IN ({$groupClause})" => $groupIDs))->leftJoin("Group_Members", '"Member"."ID" = "Group_Members"."MemberID"')->leftJoin("Group", '"Group_Members"."GroupID" = "Group"."ID"');
     return $members;
 }
 /**
  * Returns true if the member is allowed to do the given action. Defaults to the currently logged
  * in user.
  *
  * @param string $perm
  * @param null|member $member
  *
  * @return bool
  */
 public function can($perm, $member = null)
 {
     if (!$member) {
         $member = Member::currentUser();
     }
     if (is_array($perm)) {
         $perm = array_map(array($this, 'can'), $perm, array_fill(0, count($perm), $member));
         return min($perm);
     }
     if ($this->hasMethod($methodName = 'can' . $perm)) {
         return $this->{$methodName}($member);
     } else {
         return true;
     }
 }
 public function testEmptyMemberFails()
 {
     $member = new Member();
     $this->assertFalse($member->exists());
     $this->logInWithPermission('ADMIN');
     $this->assertFalse(Permission::checkMember($member, 'ADMIN'));
     $this->assertFalse(Permission::checkMember($member, 'CMS_ACCESS_LeftAndMain'));
 }
예제 #26
0
 /**
  * Make sure the file has a name
  */
 protected function onBeforeWrite()
 {
     // Set default owner
     if (!$this->isInDB() && !$this->OwnerID) {
         $this->OwnerID = Member::currentUserID();
     }
     // Set default name
     if (!$this->getField('Name')) {
         $this->Name = "new-" . strtolower($this->class);
     }
     // Propegate changes to the AssetStore and update the DBFile field
     $this->updateFilesystem();
     parent::onBeforeWrite();
 }
 /**
  * Check default state of this record
  *
  * @param DataObject $record
  * @return string One of AssetManipulationList::STATE_* constants
  */
 protected function getRecordState($record)
 {
     if ($this->isVersioned()) {
         // Check stage this record belongs to
         $stage = $record->getSourceQueryParam('Versioned.stage') ?: Versioned::get_stage();
         // Non-live stages are automatically non-public
         if ($stage !== Versioned::LIVE) {
             return AssetManipulationList::STATE_PROTECTED;
         }
     }
     // Check if canView permits anonymous viewers
     return $record->canView(Member::create()) ? AssetManipulationList::STATE_PUBLIC : AssetManipulationList::STATE_PROTECTED;
 }
 /**
  * Log login attempt
  * TODO We could handle this with an extension
  *
  * @param array $data
  * @param Member $member
  * @param bool $success
  */
 protected static function record_login_attempt($data, $member, $success)
 {
     if (!Security::config()->login_recording) {
         return;
     }
     // Check email is valid
     $email = isset($data['Email']) ? $data['Email'] : null;
     if (is_array($email)) {
         throw new InvalidArgumentException("Bad email passed to MemberAuthenticator::authenticate(): {$email}");
     }
     $attempt = new LoginAttempt();
     if ($success) {
         // successful login (member is existing with matching password)
         $attempt->MemberID = $member->ID;
         $attempt->Status = 'Success';
         // Audit logging hook
         $member->extend('authenticated');
     } else {
         // Failed login - we're trying to see if a user exists with this email (disregarding wrong passwords)
         $attempt->Status = 'Failure';
         if ($member) {
             // Audit logging hook
             $attempt->MemberID = $member->ID;
             $member->extend('authenticationFailed');
         } else {
             // Audit logging hook
             Member::singleton()->extend('authenticationFailedUnknownUser', $data);
         }
     }
     $attempt->Email = $email;
     $attempt->IP = Controller::curr()->getRequest()->getIP();
     $attempt->write();
 }
 /**
  * Deletes existing tokens for this member
  * if logout_across_devices is true, all tokens are deleted, otherwise
  * 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)
 {
     if (!$member->exists()) {
         return;
     }
     $filter = array('MemberID' => $member->ID);
     if (!static::config()->logout_across_devices && $alcDevice) {
         $filter['DeviceID'] = $alcDevice;
     }
     RememberLoginHash::get()->filter($filter)->removeAll();
 }
 /**
  * @covers GridFieldDataColumns::setDisplayFields
  * @covers GridFieldDataColumns::getDisplayFields
  */
 public function testGridFieldDisplayFieldsWithBadArguments()
 {
     $this->setExpectedException('InvalidArgumentException');
     $obj = new GridField('testfield', 'testfield', Member::get());
     $columns = $obj->getConfig()->getComponentByType('GridFieldDataColumns');
     $columns->setDisplayFields(new stdClass());
 }