mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #10666 from creative-commoners/pulls/5/security-extensions
NEW migrate functionality from security-extensions module
This commit is contained in:
commit
5236b0a9df
@ -43,6 +43,8 @@ SilverStripe\Core\Injector\Injector:
|
||||
Authenticators:
|
||||
cms: '%$SilverStripe\Security\MemberAuthenticator\CMSMemberAuthenticator'
|
||||
SilverStripe\Security\IdentityStore: '%$SilverStripe\Security\AuthenticationHandler'
|
||||
SilverStripe\Security\SudoMode\SudoModeServiceInterface:
|
||||
class: SilverStripe\Security\SudoMode\SudoModeService
|
||||
|
||||
SilverStripe\Security\PasswordExpirationMiddleware:
|
||||
default_redirect: Security/changepassword
|
||||
|
@ -228,6 +228,7 @@ da:
|
||||
PLURALS:
|
||||
one: 'En bruger'
|
||||
other: '{count} brugere'
|
||||
RequiresPasswordChangeOnNextLogin: 'Kræver ændring af kodeord næste gang der logges ind'
|
||||
SINGULARNAME: Bruger
|
||||
SUBJECTPASSWORDCHANGED: 'Dit kodeord er blevet ændret'
|
||||
SUBJECTPASSWORDRESET: 'Link til at nulstille dit kodeord'
|
||||
|
@ -135,6 +135,7 @@ de_DE:
|
||||
PLURALS:
|
||||
one: 'Ein Mitglied'
|
||||
other: '{count} Mitglieder'
|
||||
RequiresPasswordChangeOnNextLogin: 'Beim nächsten Login muss das Passwort geändert werden.'
|
||||
SINGULARNAME: Mitglied
|
||||
SURNAME: Nachname
|
||||
YOUROLDPASSWORD: 'Ihr altes Passwort'
|
||||
|
@ -276,6 +276,7 @@ en:
|
||||
PLURALS:
|
||||
one: 'A Member'
|
||||
other: '{count} Members'
|
||||
RequiresPasswordChangeOnNextLogin: 'Requires password change on next log in'
|
||||
SINGULARNAME: Member
|
||||
SUBJECTPASSWORDCHANGED: 'Your password has been changed'
|
||||
SUBJECTPASSWORDRESET: 'Your password reset link'
|
||||
|
@ -277,6 +277,7 @@ eo:
|
||||
PLURALS:
|
||||
one: 'Unu membro'
|
||||
other: '{count} membroj'
|
||||
RequiresPasswordChangeOnNextLogin: 'Bezonas ŝanĝi pasvorton je sekva elsaluto'
|
||||
SINGULARNAME: Membro
|
||||
SUBJECTPASSWORDCHANGED: 'Via pasvorto estas ŝanĝita'
|
||||
SUBJECTPASSWORDRESET: 'Via pasvorto reagordis ligilon'
|
||||
|
@ -275,6 +275,7 @@ nl:
|
||||
PLURALS:
|
||||
one: 'Een lid'
|
||||
other: '{count} leden'
|
||||
RequiresPasswordChangeOnNextLogin: 'Wachtwoord veranderen is verplicht bij volgende aanmelding'
|
||||
SINGULARNAME: Lid
|
||||
SUBJECTPASSWORDCHANGED: 'Je wachtwoord is aangepast'
|
||||
SUBJECTPASSWORDRESET: 'Je wachtwoord opnieuw instellen'
|
||||
|
@ -294,6 +294,7 @@ sl:
|
||||
two: '{count} uporabnika'
|
||||
few: '{count} uporabnikov'
|
||||
other: '{count} uporabnikov'
|
||||
RequiresPasswordChangeOnNextLogin: 'Ob naslednji prijavi zahtevaj spremembo gesla'
|
||||
SINGULARNAME: Uporabnik
|
||||
SUBJECTPASSWORDCHANGED: 'Geslo je bilo spremenjeno'
|
||||
SUBJECTPASSWORDRESET: 'Povezava za resetiranje vašega gesla'
|
||||
|
@ -224,6 +224,7 @@ sv:
|
||||
PLURALS:
|
||||
one: 'En medlem'
|
||||
other: '{count} medlemmar'
|
||||
RequiresPasswordChangeOnNextLogin: 'Kräver ändring av lösenord vid nästa inloggning'
|
||||
SINGULARNAME: Medlem
|
||||
SUBJECTPASSWORDCHANGED: 'Ditt lösenord har ändrats'
|
||||
SUBJECTPASSWORDRESET: 'Din återställningslänk'
|
||||
|
@ -13,6 +13,7 @@ use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Dev\TestMailer;
|
||||
use SilverStripe\Forms\CheckboxField;
|
||||
use SilverStripe\Forms\ConfirmedPasswordField;
|
||||
use SilverStripe\Forms\DropdownField;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
@ -398,7 +399,40 @@ class Member extends DataObject
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isPasswordExpired()
|
||||
/**
|
||||
* Used to get the value for the reset password on next login checkbox
|
||||
*/
|
||||
public function getRequiresPasswordChangeOnNextLogin(): bool
|
||||
{
|
||||
return $this->isPasswordExpired();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set password expiry to "now" to require a change of password next log in
|
||||
*
|
||||
* @param int|null $dataValue 1 is checked, 0/null is not checked {@see CheckboxField::dataValue}
|
||||
*/
|
||||
public function saveRequiresPasswordChangeOnNextLogin(?int $dataValue): static
|
||||
{
|
||||
if (!$this->canEdit()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$currentValue = $this->PasswordExpiry;
|
||||
$currentDate = $this->dbObject('PasswordExpiry');
|
||||
|
||||
if ($dataValue && (!$currentValue || $currentDate->inFuture())) {
|
||||
// Only alter future expiries - this way an admin could see how long ago a password expired still
|
||||
$this->PasswordExpiry = DBDatetime::now()->Rfc2822();
|
||||
} elseif (!$dataValue && $this->isPasswordExpired()) {
|
||||
// Only unset if the expiry date is in the past
|
||||
$this->PasswordExpiry = null;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isPasswordExpired(): bool
|
||||
{
|
||||
if (!$this->PasswordExpiry) {
|
||||
return false;
|
||||
@ -1363,6 +1397,19 @@ class Member extends DataObject
|
||||
if ($permissionsTab) {
|
||||
$permissionsTab->addExtraClass('readonly');
|
||||
}
|
||||
|
||||
$currentUser = Security::getCurrentUser();
|
||||
// We can allow an admin to require a user to change their password. But:
|
||||
// - Don't show a read only field if the user cannot edit this record
|
||||
// - Don't show if a user views their own profile (just let them reset their own password)
|
||||
if ($currentUser && ($currentUser->ID !== $this->ID) && $this->canEdit()) {
|
||||
$requireNewPassword = CheckboxField::create(
|
||||
'RequiresPasswordChangeOnNextLogin',
|
||||
_t(__CLASS__ . '.RequiresPasswordChangeOnNextLogin', 'Requires password change on next log in')
|
||||
);
|
||||
$fields->insertAfter('Password', $requireNewPassword);
|
||||
$fields->dataFieldByName('Password')->addExtraClass('form-field--no-divider mb-0 pb-0');
|
||||
}
|
||||
});
|
||||
|
||||
return parent::getCMSFields();
|
||||
|
@ -6,8 +6,11 @@ use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Control\Cookie;
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\Session;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Security\AuthenticationHandler;
|
||||
use SilverStripe\Security\Member;
|
||||
use SilverStripe\Security\SudoMode\SudoModeServiceInterface;
|
||||
|
||||
/**
|
||||
* Authenticate a member passed on a session cookie
|
||||
@ -72,13 +75,20 @@ class SessionAuthenticationHandler implements AuthenticationHandler
|
||||
{
|
||||
static::regenerateSessionId();
|
||||
$request = $request ?: Controller::curr()->getRequest();
|
||||
$request->getSession()->set($this->getSessionVariable(), $member->ID);
|
||||
$session = $request->getSession();
|
||||
$session->set($this->getSessionVariable(), $member->ID);
|
||||
|
||||
// This lets apache rules detect whether the user has logged in
|
||||
// @todo make this a setting on the authentication handler
|
||||
if (Member::config()->get('login_marker_cookie')) {
|
||||
Cookie::set(Member::config()->get('login_marker_cookie'), 1, 0);
|
||||
}
|
||||
|
||||
// Activate sudo mode on login so the user doesn't have to reauthenticate for sudo
|
||||
// actions until the sudo mode timeout expires
|
||||
/** @var SudoModeServiceInterface $service */
|
||||
$service = Injector::inst()->get(SudoModeServiceInterface::class);
|
||||
$service->activate($session);
|
||||
}
|
||||
|
||||
/**
|
||||
|
52
src/Security/SudoMode/SudoModeService.php
Normal file
52
src/Security/SudoMode/SudoModeService.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Security\SudoMode;
|
||||
|
||||
use SilverStripe\Control\Session;
|
||||
use SilverStripe\Core\Config\Configurable;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
|
||||
class SudoModeService implements SudoModeServiceInterface
|
||||
{
|
||||
use Configurable;
|
||||
|
||||
/**
|
||||
* The lifetime that sudo mode authorization lasts for, in minutes.
|
||||
*
|
||||
* Note that if the PHP session times out before this lifetime is reached, it will automatically be reset.
|
||||
* @see \SilverStripe\Control\Session::$timeout
|
||||
*/
|
||||
private static int $lifetime_minutes = 45;
|
||||
|
||||
/**
|
||||
* The session key that is used to store the timestamp for when sudo mode was last activated
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private const SUDO_MODE_SESSION_KEY = 'sudo-mode-last-activated';
|
||||
|
||||
public function check(Session $session): bool
|
||||
{
|
||||
$lastActivated = $session->get(self::SUDO_MODE_SESSION_KEY);
|
||||
// Not activated at all
|
||||
if (!$lastActivated) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Activated within the last "lifetime" window
|
||||
$nowTimestamp = DBDatetime::now()->getTimestamp();
|
||||
|
||||
return $lastActivated > ($nowTimestamp - $this->getLifetime() * 60);
|
||||
}
|
||||
|
||||
public function activate(Session $session): bool
|
||||
{
|
||||
$session->set(self::SUDO_MODE_SESSION_KEY, DBDatetime::now()->getTimestamp());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLifetime(): int
|
||||
{
|
||||
return (int) static::config()->get('lifetime_minutes');
|
||||
}
|
||||
}
|
31
src/Security/SudoMode/SudoModeServiceInterface.php
Normal file
31
src/Security/SudoMode/SudoModeServiceInterface.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Security\SudoMode;
|
||||
|
||||
use SilverStripe\Control\Session;
|
||||
|
||||
/**
|
||||
* A service class responsible for activating and checking the current status of elevated permission levels
|
||||
* via "sudo mode". This is done by checking a timestamp value in the provided session.
|
||||
*/
|
||||
interface SudoModeServiceInterface
|
||||
{
|
||||
/**
|
||||
* Checks the current session to see if sudo mode was activated within the last section of lifetime allocation.
|
||||
*
|
||||
* @return true if sudo mode is currently active
|
||||
*/
|
||||
public function check(Session $session): bool;
|
||||
|
||||
/**
|
||||
* Register activated sudo mode permission in the provided session, which lasts for the configured lifetime.
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
public function activate(Session $session): bool;
|
||||
|
||||
/**
|
||||
* How long the sudo mode activation lasts for in minutes.
|
||||
*/
|
||||
public function getLifetime(): int;
|
||||
}
|
@ -9,6 +9,9 @@ use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Dev\FunctionalTest;
|
||||
use SilverStripe\Forms\CheckboxField;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\Forms\Form;
|
||||
use SilverStripe\Forms\ListboxField;
|
||||
use SilverStripe\i18n\i18n;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
@ -405,6 +408,161 @@ class MemberTest extends FunctionalTest
|
||||
$this->assertFalse($member->isPasswordExpired());
|
||||
}
|
||||
|
||||
public function testAdminCanRequirePasswordChangeOnNextLogIn()
|
||||
{
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'someone');
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$field = $targetMember->getCMSFields()->dataFieldByName('RequiresPasswordChangeOnNextLogin');
|
||||
$this->assertNotNull($field);
|
||||
$this->assertInstanceOf(CheckboxField::class, $field, 'The field should be an instance of ' . CheckboxField::class);
|
||||
}
|
||||
|
||||
public function testUserCannotRequireTheirOwnPasswordChangeOnNextLogIn()
|
||||
{
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'someone');
|
||||
$this->logInAs($targetMember);
|
||||
$field = $targetMember->getCMSFields()->dataFieldByName('RequiresPasswordChangeOnNextLogin');
|
||||
$this->assertNull($field);
|
||||
}
|
||||
|
||||
public function testUserCannotRequireOthersToPasswordChangeOnNextLogIn()
|
||||
{
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'anyone');
|
||||
$this->logInAs('someone');
|
||||
$field = $targetMember->getCMSFields()->dataFieldByName('RequiresPasswordChangeOnNextLogin');
|
||||
$this->assertNull($field);
|
||||
}
|
||||
|
||||
public function testCheckingRequiresPasswordChangeOnNextLoginWillSetPasswordExpiryToNow()
|
||||
{
|
||||
$mockDate = '2019-03-02 00:00:00';
|
||||
DBDateTime::set_mock_now($mockDate);
|
||||
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'someone');
|
||||
|
||||
$this->assertNull($targetMember->PasswordExpiry);
|
||||
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$fields = $targetMember->getCMSFields();
|
||||
$form = new Form(null, 'SomeForm', $fields, new FieldList());
|
||||
$field = $fields->dataFieldByName('RequiresPasswordChangeOnNextLogin');
|
||||
$field->setValue(1);
|
||||
$form->saveInto($targetMember);
|
||||
|
||||
$this->assertEquals($mockDate, $targetMember->PasswordExpiry);
|
||||
}
|
||||
|
||||
public function testCheckingPasswordChangeUpdatesFutureExpiriesToNow()
|
||||
{
|
||||
$mockDate = '2019-03-02 00:00:00';
|
||||
DBDateTime::set_mock_now($mockDate);
|
||||
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'willexpire');
|
||||
|
||||
$this->assertTrue($targetMember->dbObject('PasswordExpiry')->inFuture());
|
||||
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$fields = $targetMember->getCMSFields();
|
||||
$form = new Form(null, 'SomeForm', $fields, new FieldList());
|
||||
$field = $fields->dataFieldByName('RequiresPasswordChangeOnNextLogin');
|
||||
$field->setValue(1);
|
||||
$form->saveInto($targetMember);
|
||||
|
||||
$this->assertEquals($mockDate, $targetMember->PasswordExpiry);
|
||||
}
|
||||
|
||||
public function testCheckingPasswordChangeDoesNotAlterPastDates()
|
||||
{
|
||||
$mockDate = '2019-03-02 00:00:00';
|
||||
DBDateTime::set_mock_now($mockDate);
|
||||
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'expired');
|
||||
$originalValue = $targetMember->PasswordExpiry;
|
||||
|
||||
$this->assertTrue($targetMember->dbObject('PasswordExpiry')->inPast());
|
||||
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$fields = $targetMember->getCMSFields();
|
||||
$form = new Form(null, 'SomeForm', $fields, new FieldList());
|
||||
$field = $fields->dataFieldByName('RequiresPasswordChangeOnNextLogin');
|
||||
$field->setValue(1);
|
||||
$form->saveInto($targetMember);
|
||||
|
||||
$this->assertEquals($originalValue, $targetMember->PasswordExpiry);
|
||||
}
|
||||
|
||||
public function testSavingUncheckedPasswordChangeNullsPastDates()
|
||||
{
|
||||
$mockDate = '2019-03-02 00:00:00';
|
||||
DBDateTime::set_mock_now($mockDate);
|
||||
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'expired');
|
||||
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$fields = $targetMember->getCMSFields();
|
||||
$form = new Form(null, 'SomeForm', $fields, new FieldList());
|
||||
$field = $fields->dataFieldByName('RequiresPasswordChangeOnNextLogin');
|
||||
$field->setValue(0);
|
||||
$form->saveInto($targetMember);
|
||||
|
||||
$this->assertNull($targetMember->PasswordExpiry);
|
||||
}
|
||||
|
||||
public function testSavingUncheckedPasswordChangeDoesNotAlterFutureDates()
|
||||
{
|
||||
$mockDate = '2019-03-02 00:00:00';
|
||||
DBDateTime::set_mock_now($mockDate);
|
||||
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'willexpire');
|
||||
$originalValue = $targetMember->PasswordExpiry;
|
||||
|
||||
$this->logInWithPermission('ADMIN');
|
||||
$fields = $targetMember->getCMSFields();
|
||||
$form = new Form(null, 'SomeForm', $fields, new FieldList());
|
||||
$field = $fields->dataFieldByName('RequiresPasswordChangeOnNextLogin');
|
||||
$field->setValue(0);
|
||||
$form->saveInto($targetMember);
|
||||
|
||||
$this->assertNotNull($targetMember->PasswordExpiry);
|
||||
$this->assertEquals($originalValue, $targetMember->PasswordExpiry);
|
||||
}
|
||||
|
||||
public function testSavingChangePasswordOnNextLoginIsNotPossibleIfTheCurrentMemberCannotEditTheMemberBeingSaved()
|
||||
{
|
||||
/** @var Member&MemberExtension $targetMember */
|
||||
$targetMember = $this->objFromFixture(Member::class, 'expired');
|
||||
$originalValue = $targetMember->PasswordExpiry;
|
||||
|
||||
$this->logInAs('someone');
|
||||
$fields = $targetMember->saveRequiresPasswordChangeOnNextLogin(0);
|
||||
|
||||
$this->assertEquals($originalValue, $targetMember->PasswordExpiry);
|
||||
}
|
||||
|
||||
public function testGetRequiresPasswordChangeOnNextLogin()
|
||||
{
|
||||
$this->assertTrue(
|
||||
$this->objFromFixture(Member::class, 'expired')->getRequiresPasswordChangeOnNextLogin(),
|
||||
'PasswordExpiry date in the past should require a change'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$this->objFromFixture(Member::class, 'willexpire')->getRequiresPasswordChangeOnNextLogin(),
|
||||
'PasswordExpiry date in the past should NOT require a change'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$this->objFromFixture(Member::class, 'someone')->getRequiresPasswordChangeOnNextLogin(),
|
||||
'PasswordExpiry is NULL should NOT require a change'
|
||||
);
|
||||
}
|
||||
|
||||
public function testInGroups()
|
||||
{
|
||||
/** @var Member $staffmember */
|
||||
@ -872,7 +1030,7 @@ class MemberTest extends FunctionalTest
|
||||
public function testMap_in_groupsReturnsAll()
|
||||
{
|
||||
$members = Member::map_in_groups();
|
||||
$this->assertEquals(13, $members->count(), 'There are 12 members in the mock plus a fake admin');
|
||||
$this->assertEquals(17, $members->count(), 'There are 16 members in the mock plus a fake admin');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,6 +57,20 @@
|
||||
Surname: User
|
||||
Email: noexpiry@silverstripe.com
|
||||
Password: 1nitialPassword
|
||||
someone:
|
||||
FirstName: 'Someone'
|
||||
Email: 'someone@example.com'
|
||||
anyone:
|
||||
FirstName: 'Anyone'
|
||||
Email: 'anyone@example.com'
|
||||
expired:
|
||||
Firstname: 'Expired'
|
||||
Email: 'expired@example.com'
|
||||
PasswordExpiry: '2018-01-01'
|
||||
willexpire:
|
||||
Firstname: 'William'
|
||||
Email: 'william@example.com'
|
||||
PasswordExpiry: '3018-01-01'
|
||||
staffmember:
|
||||
FirstName: Staff
|
||||
Surname: User
|
||||
|
84
tests/php/Security/SudoMode/SudoModeServiceTest.php
Normal file
84
tests/php/Security/SudoMode/SudoModeServiceTest.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Security\SudoMode\Tests;
|
||||
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Control\Session;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
use SilverStripe\Security\SudoMode\SudoModeService;
|
||||
use SilverStripe\Security\SudoMode\SudoModeServiceInterface;
|
||||
|
||||
class SudoModeServiceTest extends SapphireTest
|
||||
{
|
||||
/**
|
||||
* @var Session
|
||||
*/
|
||||
private $session;
|
||||
|
||||
/**
|
||||
* @var SudoModeService
|
||||
*/
|
||||
private $service;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->session = new Session([]);
|
||||
$this->service = new SudoModeService();
|
||||
|
||||
DBDatetime::set_mock_now('2019-03-01 12:00:00');
|
||||
SudoModeService::config()->set('lifetime_minutes', 180);
|
||||
}
|
||||
|
||||
public function testCheckWithoutActivation()
|
||||
{
|
||||
$this->session->clearAll();
|
||||
$this->assertFalse($this->service->check($this->session));
|
||||
}
|
||||
|
||||
public function testCheckWithLastActivationOutsideLifetimeWindow()
|
||||
{
|
||||
// 240 minutes ago
|
||||
$lastActivated = DBDatetime::now()->getTimestamp() - 240 * 60;
|
||||
$this->session->set('sudo-mode-last-activated', $lastActivated);
|
||||
$this->assertFalse($this->service->check($this->session));
|
||||
}
|
||||
|
||||
public function testCheckWithLastActivationInsideLifetimeWindow()
|
||||
{
|
||||
// 25 minutes ago
|
||||
$lastActivated = DBDatetime::now()->getTimestamp() - 25 * 60;
|
||||
$this->session->set('sudo-mode-last-activated', $lastActivated);
|
||||
$this->assertTrue($this->service->check($this->session));
|
||||
}
|
||||
|
||||
public function testActivateAndCheckImmediately()
|
||||
{
|
||||
$this->service->activate($this->session);
|
||||
$this->assertTrue($this->service->check($this->session));
|
||||
}
|
||||
|
||||
public function testSudoModeActivatesOnLogin()
|
||||
{
|
||||
// Sometimes being logged in carries over from other tests
|
||||
$this->logOut();
|
||||
|
||||
/** @var SudoModeServiceInterface $service */
|
||||
$service = Injector::inst()->get(SudoModeServiceInterface::class);
|
||||
$session = Controller::curr()->getRequest()->getSession();
|
||||
|
||||
// Sudo mode should not be enabled automagically when nobody is logged in
|
||||
$this->assertFalse($service->check($session));
|
||||
|
||||
// Ensure sudo mode is activated on login
|
||||
$this->logInWithPermission();
|
||||
$this->assertTrue($service->check($session));
|
||||
|
||||
// Ensure sudo mode is not active after logging out
|
||||
$this->logOut();
|
||||
$this->assertFalse($service->check($session));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user