Ejemplo n.º 1
0
 /**
  * Event handler called before writing to the database.
  */
 public function onBeforeWrite()
 {
     if ($this->SetPassword) {
         $this->Password = $this->SetPassword;
     }
     // If a member with the same "unique identifier" already exists with a different ID, don't allow merging.
     // Note: This does not a full replacement for safeguards in the controller layer (e.g. in a registration form),
     // but rather a last line of defense against data inconsistencies.
     $identifierField = Member::config()->unique_identifier_field;
     if ($this->{$identifierField}) {
         // Note: Same logic as Member_Validator class
         $filter = array("\"{$identifierField}\"" => $this->{$identifierField});
         if ($this->ID) {
             $filter[] = array('"Member"."ID" <> ?' => $this->ID);
         }
         $existingRecord = DataObject::get_one('SilverStripe\\Security\\Member', $filter);
         if ($existingRecord) {
             throw new ValidationException(ValidationResult::create(false, _t('Member.ValidationIdentifierFailed', 'Can\'t overwrite existing member #{id} with identical identifier ({name} = {value}))', 'Values in brackets show "fieldname = value", usually denoting an existing email address', array('id' => $existingRecord->ID, 'name' => $identifierField, 'value' => $this->{$identifierField}))));
         }
     }
     // We don't send emails out on dev/tests sites to prevent accidentally spamming users.
     // However, if TestMailer is in use this isn't a risk.
     if ((Director::isLive() || Email::mailer() instanceof TestMailer) && $this->isChanged('Password') && $this->record['Password'] && $this->config()->notify_password_change) {
         /** @var Email $e */
         $e = Email::create();
         $e->setSubject(_t('Member.SUBJECTPASSWORDCHANGED', "Your password has been changed", 'Email subject'));
         $e->setTemplate('ChangePasswordEmail');
         $e->populateTemplate($this);
         $e->setTo($this->Email);
         $e->send();
     }
     // The test on $this->ID is used for when records are initially created.
     // Note that this only works with cleartext passwords, as we can't rehash
     // existing passwords.
     if (!$this->ID && $this->Password || $this->isChanged('Password')) {
         //reset salt so that it gets regenerated - this will invalidate any persistant login cookies
         // or other information encrypted with this Member's settings (see self::encryptWithUserSettings)
         $this->Salt = '';
         // Password was changed: encrypt the password according the settings
         $encryption_details = Security::encrypt_password($this->Password, $this->Salt, $this->PasswordEncryption ? $this->PasswordEncryption : Security::config()->password_encryption_algorithm, $this);
         // Overwrite the Password property with the hashed value
         $this->Password = $encryption_details['password'];
         $this->Salt = $encryption_details['salt'];
         $this->PasswordEncryption = $encryption_details['algorithm'];
         // If we haven't manually set a password expiry
         if (!$this->isChanged('PasswordExpiry')) {
             // then set it for us
             if (self::config()->password_expiry_days) {
                 $this->PasswordExpiry = date('Y-m-d', time() + 86400 * self::config()->password_expiry_days);
             } else {
                 $this->PasswordExpiry = null;
             }
         }
     }
     // save locale
     if (!$this->Locale) {
         $this->Locale = i18n::get_locale();
     }
     parent::onBeforeWrite();
 }
 /**
  * Forgot password form handler method.
  * Called when the user clicks on "I've lost my password".
  * Extensions can use the 'forgotPassword' method to veto executing
  * the logic, by returning FALSE. In this case, the user will be redirected back
  * to the form without further action. It is recommended to set a message
  * in the form detailing why the action was denied.
  *
  * @skipUpgrade
  * @param array $data Submitted data
  * @return HTTPResponse
  */
 public function forgotPassword($data)
 {
     // Ensure password is given
     if (empty($data['Email'])) {
         $this->sessionMessage(_t('Member.ENTEREMAIL', 'Please enter an email address to get a password reset link.'), 'bad');
         return $this->controller->redirect('Security/lostpassword');
     }
     // Find existing member
     /** @var Member $member */
     $member = Member::get()->filter("Email", $data['Email'])->first();
     // Allow vetoing forgot password requests
     $results = $this->extend('forgotPassword', $member);
     if ($results && is_array($results) && in_array(false, $results, true)) {
         return $this->controller->redirect('Security/lostpassword');
     }
     if ($member) {
         $token = $member->generateAutologinTokenAndStoreHash();
         /** @var Email $e */
         $e = Email::create();
         $e->setSubject(_t('Member.SUBJECTPASSWORDRESET', "Your password reset link", 'Email subject'));
         $e->setTemplate('ForgotPasswordEmail');
         $e->populateTemplate($member);
         $e->populateTemplate(array('PasswordResetLink' => Security::getPasswordResetLink($member, $token)));
         $e->setTo($member->Email);
         $e->send();
         return $this->controller->redirect('Security/passwordsent/' . urlencode($data['Email']));
     } elseif ($data['Email']) {
         // Avoid information disclosure by displaying the same status,
         // regardless wether the email address actually exists
         return $this->controller->redirect('Security/passwordsent/' . rawurlencode($data['Email']));
     } else {
         $this->sessionMessage(_t('Member.ENTEREMAIL', 'Please enter an email address to get a password reset link.'), 'bad');
         return $this->controller->redirect('Security/lostpassword');
     }
 }