Source of file RememberLoginHash .php
Size: 5,279 Bytes - Last Modified: 2021-12-23T10:01:26+00:00
/var/www/docs.ssmods.com/process/src/code/RememberLoginHash .php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 | <?php /** * Persists a token associated with a device for users who opted for the "Remember Me" * feature when logging in. * By default, logging out will discard all existing tokens for this user * The device ID is a temporary ID associated with the device when the user logged in * and chose to get the login state remembered on this device. When logging out, the ID * is discarded as well. * * @property string $DeviceID * @property string $RememberLoginHash */ class RememberLoginHash extends DataObject { private static $db = array( 'DeviceID' => 'Varchar(40)', 'Hash' => 'Varchar(160)', 'ExpiryDate' => 'SS_Datetime' ); private static $has_one = array( 'Member' => 'Member', ); private static $indexes = array( 'DeviceID' => true, 'Hash' => true ); /** * Determines if logging out on one device also clears existing login tokens * on all other devices owned by the member. * If set to false, there is no way for users to revoke a login, unless additional * code (custom or with a module) is provided by the developer * * @config * @var bool */ private static $logout_across_devices = true; /** * Number of days the token will be valid for * * @config * @var int */ private static $token_expiry_days = 90; /** * Number of days the device ID will be valid for * * @config * @var int */ private static $device_expiry_days = 365; /** * If true, user can only use auto login on one device. A user can still login from multiple * devices, but previous tokens from other devices will become invalid. * * @config * @var bool */ private static $force_single_token = false; /** * The token used for the hash */ private $token = null; public function getToken() { return $this->token; } public function setToken($token) { $this->token = $token; } /** * Randomly generates a new ID used for the device * @return string A device ID */ protected function getNewDeviceID() { $generator = new RandomGenerator(); return $generator->randomToken('sha1'); } /** * Creates a new random token and hashes it using the * member information * @param Member The logged in user * @return string The hash to be stored in the database */ public function getNewHash(Member $member) { $generator = new RandomGenerator(); $this->setToken($generator->randomToken('sha1')); return $member->encryptWithUserSettings($this->token); } /** * Generates a new login hash associated with a device * The device is assigned a globally unique device ID * The returned login hash stores the hashed token in the * database, for this device and this member * @param Member The logged in user * @return RememberLoginHash The generated login hash */ public static function generate(Member $member) { if (!$member->exists()) { return; } if (Config::inst()->get('RememberLoginHash', 'force_single_token') == true) { $rememberLoginHash = RememberLoginHash::get()->filter('MemberID', $member->ID)->removeAll(); } $rememberLoginHash = RememberLoginHash::create(); do { $deviceID = $rememberLoginHash->getNewDeviceID(); } while (RememberLoginHash::get()->filter('DeviceID', $deviceID)->Count()); $rememberLoginHash->DeviceID = $deviceID; $rememberLoginHash->Hash = $rememberLoginHash->getNewHash($member); $rememberLoginHash->MemberID = $member->ID; $now = SS_Datetime::now(); $expiryDate = new DateTime($now->Rfc2822()); $tokenExpiryDays = Config::inst()->get('RememberLoginHash', 'token_expiry_days'); $expiryDate->add(new DateInterval('P' . $tokenExpiryDays . 'D')); $rememberLoginHash->ExpiryDate = $expiryDate->format('Y-m-d H:i:s'); $rememberLoginHash->extend('onAfterGenerateToken'); $rememberLoginHash->write(); return $rememberLoginHash; } /** * Generates a new hash for this member but keeps the device ID intact * @param Member the logged in user * @return RememberLoginHash */ public function renew() { $hash = $this->getNewHash($this->Member()); $this->Hash = $hash; $this->extend('onAfterRenewToken'); $this->write(); return $this; } /** * 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(); } } |