/**
  * 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
  */
 public static function clear(Member $member, $alcDevice = null)
 {
     if (!$member->exists()) {
         return;
     }
     $filter = array('MemberID' => $member->ID);
     if (Config::inst()->get('RememberLoginHash', 'logout_across_devices') == false && $alcDevice) {
         $filter['DeviceID'] = $alcDevice;
     }
     RememberLoginHash::get()->filter($filter)->removeAll();
 }
 public function testRememberMeMultipleDevices()
 {
     $m1 = $this->objFromFixture('Member', 'noexpiry');
     // First device
     $m1->login(true);
     Cookie::set('alc_device', null);
     // Second device
     $m1->login(true);
     // Hash of first device
     $firstHash = RememberLoginHash::get()->filter('MemberID', $m1->ID)->First();
     $this->assertNotNull($firstHash);
     // Hash of second device
     $secondHash = RememberLoginHash::get()->filter('MemberID', $m1->ID)->Last();
     $this->assertNotNull($secondHash);
     // DeviceIDs are different
     $this->assertNotEquals($firstHash->DeviceID, $secondHash->DeviceID);
     // re-generates the hashes so we can get the tokens
     $firstHash->Hash = $firstHash->getNewHash($m1);
     $firstToken = $firstHash->getToken();
     $firstHash->write();
     $secondHash->Hash = $secondHash->getNewHash($m1);
     $secondToken = $secondHash->getToken();
     $secondHash->write();
     // Accessing the login page should show the user's name straight away
     $response = $this->get('Security/login', $this->session(), null, array('alc_enc' => $m1->ID . ':' . $firstToken, 'alc_device' => $firstHash->DeviceID));
     $message = _t('Member.LOGGEDINAS', "You're logged in as {name}.", array('name' => $m1->FirstName));
     $this->assertContains($message, $response->getBody());
     $this->session()->inst_set('loggedInAs', null);
     // Accessing the login page from the second device
     $response = $this->get('Security/login', $this->session(), null, array('alc_enc' => $m1->ID . ':' . $secondToken, 'alc_device' => $secondHash->DeviceID));
     $this->assertContains($message, $response->getBody());
     $logout_across_devices = Config::inst()->get('RememberLoginHash', 'logout_across_devices');
     // Logging out from the second device - only one device being logged out
     Config::inst()->update('RememberLoginHash', 'logout_across_devices', false);
     $response = $this->get('Security/logout', $this->session(), null, array('alc_enc' => $m1->ID . ':' . $secondToken, 'alc_device' => $secondHash->DeviceID));
     $this->assertEquals(RememberLoginHash::get()->filter(array('MemberID' => $m1->ID, 'DeviceID' => $firstHash->DeviceID))->Count(), 1);
     // Logging out from any device when all login hashes should be removed
     Config::inst()->update('RememberLoginHash', 'logout_across_devices', true);
     $m1->login(true);
     $response = $this->get('Security/logout', $this->session());
     $this->assertEquals(RememberLoginHash::get()->filter('MemberID', $m1->ID)->Count(), 0);
     Config::inst()->update('RememberLoginHash', 'logout_across_devices', $logout_across_devices);
 }
예제 #3
0
 /**
  * Logs this member out.
  */
 public function logOut()
 {
     $this->extend('beforeMemberLoggedOut');
     Session::clear("loggedInAs");
     if (Member::config()->login_marker_cookie) {
         Cookie::set(Member::config()->login_marker_cookie, null, 0);
     }
     Session::destroy();
     $this->extend('memberLoggedOut');
     // Clears any potential previous hashes for this member
     RememberLoginHash::clear($this, Cookie::get('alc_device'));
     Cookie::set('alc_enc', null);
     // // Clear the Remember Me cookie
     Cookie::force_expiry('alc_enc');
     Cookie::set('alc_device', null);
     Cookie::force_expiry('alc_device');
     // Switch back to live in order to avoid infinite loops when
     // redirecting to the login screen (if this login screen is versioned)
     Session::clear('readingMode');
     $this->write();
     // Audit logging hook
     $this->extend('memberLoggedOut');
 }