/**
  * Tries to logon using the credentials in the SilverStripe database
  *
  * @access public
  *
  * @param  string $source Authentication source to be used 
  * @param  string $external_uid    The ID entered
  * @param  string $external_passwd The password of the user
  *
  * @return boolean  True if the authentication was a success, false 
  *                  otherwise
  */
 public function Authenticate($RAW_source, $RAW_external_uid, $RAW_external_passwd)
 {
     $SQL_identity = Convert::raw2sql($RAW_external_uid);
     // Default login (see Security::setDefaultAdmin())
     if (Security::check_default_admin($RAW_external_uid, $RAW_external_passwd)) {
         ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - Logging on with an Administrator account');
         $member = Security::findAnAdministrator();
     } else {
         $SQL_source = Convert::raw2sql($RAW_source);
         ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - Searching for user with source ' . $SQL_source . ' in database');
         $member = DataObject::get_one("Member", "\"Member\".\"External_UserID\" = '{$SQL_identity}'" . " AND \"Member\".\"External_SourceID\" = '{$SQL_source}'" . " AND \"Password\" IS NOT NULL");
         if ($member) {
             ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - User was found in database');
             if ($member->checkPassword($RAW_external_passwd) == false) {
                 ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - Password authentication failed');
                 $member = null;
             } else {
                 ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - Password authentication succeeded');
             }
         } else {
             ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - User was NOT found in database');
         }
     }
     if ($member) {
         return true;
     } else {
         ExternalAuthenticator::setAuthMessage(_t('ExternalAuthenticator.Failed'));
         return false;
     }
 }
 public function testCheckDefaultAdmin()
 {
     $this->assertTrue(Security::has_default_admin());
     $this->assertTrue(Security::check_default_admin('admin', 'password'), 'Succeeds with correct username and password');
     $this->assertFalse(Security::check_default_admin('wronguser', 'password'), 'Fails with incorrect username');
     $this->assertFalse(Security::check_default_admin('admin', 'wrongpassword'), 'Fails with incorrect password');
 }
 /**
  * Attempt to find and authenticate member if possible from the given data.
  *
  * @param array $data
  * @param Form $form
  * @param bool &$success Success flag
  * @return Member Found member, regardless of successful login
  * @see MemberAuthenticator::authenticate_member()
  */
 protected static function authenticate_member($data, $form, &$success)
 {
     // Default success to false
     $success = false;
     // Attempt to identify by temporary ID
     $member = null;
     $email = null;
     if (!empty($data['tempid'])) {
         // Find user by tempid, in case they are re-validating an existing session
         $member = Member::member_from_tempid($data['tempid']);
         if ($member) {
             $email = $member->Email;
         }
     }
     // Otherwise, get email from posted value instead
     if (!$member && !empty($data['Email'])) {
         $email = $data['Email'];
     }
     // Check default login (see Security::setDefaultAdmin()) the standard way and the "extension"-way :-)
     $asDefaultAdmin = $email === Security::default_admin_username();
     if ($asDefaultAdmin || isset($GLOBALS['_DEFAULT_ADMINS']) && array_key_exists($email, $GLOBALS['_DEFAULT_ADMINS'])) {
         // If logging is as default admin, ensure record is setup correctly
         $member = Member::default_admin();
         $success = Security::check_default_admin($email, $data['Password']);
         // If not already true check if one of the extra admins match
         if (!$success) {
             $success = $GLOBALS['_DEFAULT_ADMINS'][$email] == $data['Password'];
         }
         if ($success) {
             return $member;
         }
     }
     // Attempt to identify user by email
     if (!$member && $email) {
         // Find user by email
         $member = Member::get()->filter(Member::config()->unique_identifier_field, $email)->first();
     }
     // Validate against member if possible
     if ($member && !$asDefaultAdmin) {
         $result = $member->checkPassword($data['Password']);
         $success = $result->valid();
     } else {
         $result = new ValidationResult(false, _t('Member.ERRORWRONGCRED'));
     }
     // Emit failure to member and form (if available)
     if (!$success) {
         if ($member) {
             $member->registerFailedLogin();
         }
         if ($form) {
             $form->sessionMessage($result->message(), 'bad');
         }
     } else {
         if ($member) {
             $member->registerSuccessfulLogin();
         }
     }
     return $member;
 }
 public function testCheckDefaultAdmin()
 {
     if (Security::has_default_admin()) {
         $this->markTestSkipped('Default admin present. There\'s no way to inspect default admin state, ' . 'so we don\'t override existing settings');
     }
     Security::setDefaultAdmin('admin', 'password');
     $this->assertTrue(Security::has_default_admin());
     $this->assertTrue(Security::check_default_admin('admin', 'password'), 'Succeeds with correct username and password');
     $this->assertFalse(Security::check_default_admin('wronguser', 'password'), 'Fails with incorrect username');
     $this->assertFalse(Security::check_default_admin('admin', 'wrongpassword'), 'Fails with incorrect password');
     Security::setDefaultAdmin(null, null);
 }
Ejemplo n.º 5
0
 function testCheckDefaultAdmin()
 {
     // TODO There's currently no way to inspect default admin state,
     //  hence we don't override existing settings
     if (Security::has_default_admin()) {
         return;
     }
     Security::setDefaultAdmin('admin', 'password');
     $this->assertTrue(Security::has_default_admin());
     $this->assertTrue(Security::check_default_admin('admin', 'password'), 'Succeeds with correct username and password');
     $this->assertFalse(Security::check_default_admin('wronguser', 'password'), 'Fails with incorrect username');
     $this->assertFalse(Security::check_default_admin('admin', 'wrongpassword'), 'Fails with incorrect password');
     Security::setDefaultAdmin(null, null);
 }
Ejemplo n.º 6
0
 /**
  * Method to authenticate an user
  *
  * @param array $RAW_data Raw data to authenticate the user
  * @param Form $form Optional: If passed, better error messages can be
  *                             produced by using
  *                             {@link Form::sessionMessage()}
  * @return bool|Member Returns FALSE if authentication fails, otherwise
  *                     the member object
  * @see Security::setDefaultAdmin()
  */
 public static function authenticate($RAW_data, Form $form = null)
 {
     $SQL_user = Convert::raw2sql($RAW_data['Email']);
     // Default login (see Security::setDefaultAdmin())
     if (Security::check_default_admin($RAW_data['Email'], $RAW_data['Password'])) {
         $member = Security::findAnAdministrator();
     } else {
         $member = DataObject::get_one("Member", "Email = '{$SQL_user}' AND Password IS NOT NULL");
         if ($member && $member->checkPassword($RAW_data['Password']) == false) {
             $member = null;
         }
     }
     if ($member) {
         Session::clear("BackURL");
     } else {
         if (!is_null($form)) {
             $form->sessionMessage(_t('Member.ERRORWRONGCRED', "That doesn't seem to be the right e-mail address or password. Please try again."), "bad");
         }
     }
     return $member;
 }
 /**
  * Method to authenticate an user
  *
  * @param array $RAW_data Raw data to authenticate the user
  * @param Form $form Optional: If passed, better error messages can be
  *                             produced by using
  *                             {@link Form::sessionMessage()}
  * @return bool|Member Returns FALSE if authentication fails, otherwise
  *                     the member object
  * @see Security::setDefaultAdmin()
  */
 public static function authenticate($RAW_data, Form $form = null)
 {
     if (array_key_exists('Email', $RAW_data) && $RAW_data['Email']) {
         $SQL_user = Convert::raw2sql($RAW_data['Email']);
     } else {
         return false;
     }
     $isLockedOut = false;
     $result = null;
     // Default login (see Security::setDefaultAdmin())
     if (Security::check_default_admin($RAW_data['Email'], $RAW_data['Password'])) {
         $member = Security::findAnAdministrator();
     } else {
         $member = DataObject::get_one("Member", "\"" . Member::get_unique_identifier_field() . "\" = '{$SQL_user}' AND \"Password\" IS NOT NULL");
         if ($member) {
             $result = $member->checkPassword($RAW_data['Password']);
         } else {
             $result = new ValidationResult(false, _t('Member.ERRORWRONGCRED'));
         }
         if ($member && !$result->valid()) {
             $member->registerFailedLogin();
             $member = false;
         }
     }
     // Optionally record every login attempt as a {@link LoginAttempt} object
     /**
      * TODO We could handle this with an extension
      */
     if (Security::login_recording()) {
         $attempt = new LoginAttempt();
         if ($member) {
             // 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)
             $existingMember = DataObject::get_one("Member", "\"" . Member::get_unique_identifier_field() . "\" = '{$SQL_user}'");
             if ($existingMember) {
                 $attempt->MemberID = $existingMember->ID;
                 // Audit logging hook
                 $existingMember->extend('authenticationFailed');
             } else {
                 // Audit logging hook
                 singleton('Member')->extend('authenticationFailedUnknownUser', $RAW_data);
             }
             $attempt->Status = 'Failure';
         }
         if (is_array($RAW_data['Email'])) {
             user_error("Bad email passed to MemberAuthenticator::authenticate(): {$RAW_data['Email']}", E_USER_WARNING);
             return false;
         }
         $attempt->Email = $RAW_data['Email'];
         $attempt->IP = Controller::curr()->getRequest()->getIP();
         $attempt->write();
     }
     // Legacy migration to precision-safe password hashes.
     // A login-event with cleartext passwords is the only time
     // when we can rehash passwords to a different hashing algorithm,
     // bulk-migration doesn't work due to the nature of hashing.
     // See PasswordEncryptor_LegacyPHPHash class.
     if ($member && self::$migrate_legacy_hashes && array_key_exists($member->PasswordEncryption, self::$migrate_legacy_hashes)) {
         $member->Password = $RAW_data['Password'];
         $member->PasswordEncryption = self::$migrate_legacy_hashes[$member->PasswordEncryption];
         $member->write();
     }
     if ($member) {
         Session::clear('BackURL');
     } else {
         if ($form && $result) {
             $form->sessionMessage($result->message(), 'bad');
         }
     }
     return $member;
 }
Ejemplo n.º 8
0
 /**
  * Check if the passed password matches the stored one (if the member is not locked out).
  *
  * @param string $password
  * @return ValidationResult
  */
 public function checkPassword($password)
 {
     $result = $this->canLogIn();
     // Short-circuit the result upon failure, no further checks needed.
     if (!$result->valid()) {
         return $result;
     }
     // Allow default admin to login as self
     if ($this->isDefaultAdmin() && Security::check_default_admin($this->Email, $password)) {
         return $result;
     }
     // Check a password is set on this member
     if (empty($this->Password) && $this->exists()) {
         $result->error(_t('Member.NoPassword', 'There is no password on this member.'));
         return $result;
     }
     $e = PasswordEncryptor::create_for_algorithm($this->PasswordEncryption);
     if (!$e->check($this->Password, $password, $this->Salt, $this)) {
         $result->error(_t('Member.ERRORWRONGCRED', 'The provided details don\'t seem to be correct. Please try again.'));
     }
     return $result;
 }
Ejemplo n.º 9
0
 /**
  * Method to authenticate an user
  *
  * @param array $RAW_data Raw data to authenticate the user
  * @param Form $form Optional: If passed, better error messages can be
  *                             produced by using
  *                             {@link Form::sessionMessage()}
  * @return bool|Member Returns FALSE if authentication fails, otherwise
  *                     the member object
  * @see Security::setDefaultAdmin()
  */
 public static function authenticate($RAW_data, Form $form = null)
 {
     $SQL_user = Convert::raw2sql($RAW_data['Email']);
     $isLockedOut = false;
     // Default login (see Security::setDefaultAdmin())
     if (Security::check_default_admin($RAW_data['Email'], $RAW_data['Password'])) {
         $member = Security::findAnAdministrator();
     } else {
         $member = DataObject::get_one("Member", "Email = '{$SQL_user}' AND Password IS NOT NULL");
         if ($member && $member->checkPassword($RAW_data['Password']) == false) {
             if ($member->isLockedOut()) {
                 $isLockedOut = true;
             }
             $member->registerFailedLogin();
             $member = null;
         }
     }
     // Optionally record every login attempt as a {@link LoginAttempt} object
     /**
      * TODO We could handle this with an extension
      */
     if (Security::login_recording()) {
         $attempt = new LoginAttempt();
         if ($member) {
             // 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)
             $existingMember = DataObject::get_one("Member", "Email = '{$SQL_user}'");
             if ($existingMember) {
                 $attempt->MemberID = $existingMember->ID;
                 // Audit logging hook
                 $existingMember->extend('authenticationFailed');
             } else {
                 // Audit logging hook
                 singleton('Member')->extend('authenticationFailedUnknownUser', $RAW_data);
             }
             $attempt->Status = 'Failure';
         }
         if (is_array($RAW_data['Email'])) {
             user_error("Bad email passed to MemberAuthenticator::authenticate(): {$RAW_data['Email']}", E_USER_WARNING);
             return false;
         }
         $attempt->Email = $RAW_data['Email'];
         $attempt->IP = Controller::curr()->getRequest()->getIP();
         $attempt->write();
     }
     if ($member) {
         Session::clear("BackURL");
     } else {
         if ($isLockedOut) {
             if ($form) {
                 $form->sessionMessage(_t('Member.ERRORLOCKEDOUT', "Your account has been temporarily disabled because of too many failed attempts at logging in. Please try again in 20 minutes."), "bad");
             }
         } else {
             if ($form) {
                 $form->sessionMessage(_t('Member.ERRORWRONGCRED', "That doesn't seem to be the right e-mail address or password. Please try again."), "bad");
             }
         }
     }
     return $member;
 }