J. King
6 years ago
23 changed files with 54 additions and 1505 deletions
@ -1,338 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\TestCase\User; |
|
||||
|
|
||||
use JKingWeb\Arsse\Arsse; |
|
||||
use JKingWeb\Arsse\Conf; |
|
||||
use JKingWeb\Arsse\User; |
|
||||
use JKingWeb\Arsse\User\Driver; |
|
||||
use Phake; |
|
||||
|
|
||||
/** @covers \JKingWeb\Arsse\User */ |
|
||||
class TestAuthorization extends \JKingWeb\Arsse\Test\AbstractTest { |
|
||||
const USERS = [ |
|
||||
'user@example.com' => Driver::RIGHTS_NONE, |
|
||||
'user@example.org' => Driver::RIGHTS_NONE, |
|
||||
'dman@example.com' => Driver::RIGHTS_DOMAIN_MANAGER, |
|
||||
'dman@example.org' => Driver::RIGHTS_DOMAIN_MANAGER, |
|
||||
'dadm@example.com' => Driver::RIGHTS_DOMAIN_ADMIN, |
|
||||
'dadm@example.org' => Driver::RIGHTS_DOMAIN_ADMIN, |
|
||||
'gman@example.com' => Driver::RIGHTS_GLOBAL_MANAGER, |
|
||||
'gman@example.org' => Driver::RIGHTS_GLOBAL_MANAGER, |
|
||||
'gadm@example.com' => Driver::RIGHTS_GLOBAL_ADMIN, |
|
||||
'gadm@example.org' => Driver::RIGHTS_GLOBAL_ADMIN, |
|
||||
// invalid rights levels |
|
||||
'bad1@example.com' => Driver::RIGHTS_NONE+1, |
|
||||
'bad1@example.org' => Driver::RIGHTS_NONE+1, |
|
||||
'bad2@example.com' => Driver::RIGHTS_DOMAIN_MANAGER+1, |
|
||||
'bad2@example.org' => Driver::RIGHTS_DOMAIN_MANAGER+1, |
|
||||
'bad3@example.com' => Driver::RIGHTS_DOMAIN_ADMIN+1, |
|
||||
'bad3@example.org' => Driver::RIGHTS_DOMAIN_ADMIN+1, |
|
||||
'bad4@example.com' => Driver::RIGHTS_GLOBAL_MANAGER+1, |
|
||||
'bad4@example.org' => Driver::RIGHTS_GLOBAL_MANAGER+1, |
|
||||
'bad5@example.com' => Driver::RIGHTS_GLOBAL_ADMIN+1, |
|
||||
'bad5@example.org' => Driver::RIGHTS_GLOBAL_ADMIN+1, |
|
||||
|
|
||||
]; |
|
||||
const LEVELS = [ |
|
||||
Driver::RIGHTS_NONE, |
|
||||
Driver::RIGHTS_DOMAIN_MANAGER, |
|
||||
Driver::RIGHTS_DOMAIN_ADMIN, |
|
||||
Driver::RIGHTS_GLOBAL_MANAGER, |
|
||||
Driver::RIGHTS_GLOBAL_ADMIN, |
|
||||
]; |
|
||||
const DOMAINS = [ |
|
||||
'@example.com', |
|
||||
'@example.org', |
|
||||
"", |
|
||||
]; |
|
||||
|
|
||||
protected $data; |
|
||||
|
|
||||
public function setUp(string $drv = \JkingWeb\Arsse\Test\User\DriverInternalMock::class, string $db = null) { |
|
||||
$this->clearData(); |
|
||||
$conf = new Conf(); |
|
||||
$conf->userDriver = $drv; |
|
||||
$conf->userPreAuth = false; |
|
||||
Arsse::$conf = $conf; |
|
||||
if ($db !== null) { |
|
||||
Arsse::$db = new $db(); |
|
||||
} |
|
||||
Arsse::$user = Phake::partialMock(User::class); |
|
||||
Phake::when(Arsse::$user)->authorize->thenReturn(true); |
|
||||
foreach (self::USERS as $user => $level) { |
|
||||
Arsse::$user->add($user, ""); |
|
||||
Arsse::$user->rightsSet($user, $level); |
|
||||
} |
|
||||
Phake::reset(Arsse::$user); |
|
||||
} |
|
||||
|
|
||||
public function tearDown() { |
|
||||
$this->clearData(); |
|
||||
} |
|
||||
|
|
||||
public function testToggleLogic() { |
|
||||
$this->assertTrue(Arsse::$user->authorizationEnabled()); |
|
||||
$this->assertTrue(Arsse::$user->authorizationEnabled(true)); |
|
||||
$this->assertFalse(Arsse::$user->authorizationEnabled(false)); |
|
||||
$this->assertFalse(Arsse::$user->authorizationEnabled(false)); |
|
||||
$this->assertFalse(Arsse::$user->authorizationEnabled(true)); |
|
||||
$this->assertTrue(Arsse::$user->authorizationEnabled(true)); |
|
||||
} |
|
||||
|
|
||||
public function testSelfActionLogic() { |
|
||||
foreach (array_keys(self::USERS) as $user) { |
|
||||
Arsse::$user->auth($user, ""); |
|
||||
// users should be able to do basic actions for themselves |
|
||||
$this->assertTrue(Arsse::$user->authorize($user, "userExists"), "User $user could not act for themselves."); |
|
||||
$this->assertTrue(Arsse::$user->authorize($user, "userRemove"), "User $user could not act for themselves."); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function testRegularUserLogic() { |
|
||||
foreach (self::USERS as $actor => $rights) { |
|
||||
if ($rights != Driver::RIGHTS_NONE) { |
|
||||
continue; |
|
||||
} |
|
||||
Arsse::$user->auth($actor, ""); |
|
||||
foreach (array_keys(self::USERS) as $affected) { |
|
||||
// regular users should only be able to act for themselves |
|
||||
if ($actor==$affected) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userExists"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userExists"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
} |
|
||||
// they should never be able to set rights |
|
||||
foreach (self::LEVELS as $level) { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted improperly for $affected settings rights level $level, but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
// they should not be able to list users |
|
||||
foreach (self::DOMAINS as $domain) { |
|
||||
$this->assertFalse(Arsse::$user->authorize($domain, "userList"), "User $actor improperly checked user list for domain '$domain', but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function testDomainManagerLogic() { |
|
||||
foreach (self::USERS as $actor => $actorRights) { |
|
||||
if ($actorRights != Driver::RIGHTS_DOMAIN_MANAGER) { |
|
||||
continue; |
|
||||
} |
|
||||
$actorDomain = substr($actor, strrpos($actor, "@")+1); |
|
||||
Arsse::$user->auth($actor, ""); |
|
||||
foreach (self::USERS as $affected => $affectedRights) { |
|
||||
$affectedDomain = substr($affected, strrpos($affected, "@")+1); |
|
||||
// domain managers should be able to check any user on the same domain |
|
||||
if ($actorDomain==$affectedDomain) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userExists"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userExists"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
} |
|
||||
// they should only be able to act for regular users on the same domain |
|
||||
if ($actor==$affected || ($actorDomain==$affectedDomain && $affectedRights==User\Driver::RIGHTS_NONE)) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
} |
|
||||
// and they should only be able to set their own rights to regular user |
|
||||
foreach (self::LEVELS as $level) { |
|
||||
if ($actor==$affected && in_array($level, [User\Driver::RIGHTS_NONE, Driver::RIGHTS_DOMAIN_MANAGER])) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted properly for $affected settings rights level $level, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted improperly for $affected settings rights level $level, but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
// they should also be able to list all users on their own domain |
|
||||
foreach (self::DOMAINS as $domain) { |
|
||||
if ($domain=="@".$actorDomain) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($domain, "userList"), "User $actor properly checked user list for domain '$domain', but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($domain, "userList"), "User $actor improperly checked user list for domain '$domain', but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function testDomainAdministratorLogic() { |
|
||||
foreach (self::USERS as $actor => $actorRights) { |
|
||||
if ($actorRights != Driver::RIGHTS_DOMAIN_ADMIN) { |
|
||||
continue; |
|
||||
} |
|
||||
$actorDomain = substr($actor, strrpos($actor, "@")+1); |
|
||||
Arsse::$user->auth($actor, ""); |
|
||||
$allowed = [User\Driver::RIGHTS_NONE,User\Driver::RIGHTS_DOMAIN_MANAGER,User\Driver::RIGHTS_DOMAIN_ADMIN]; |
|
||||
foreach (self::USERS as $affected => $affectedRights) { |
|
||||
$affectedDomain = substr($affected, strrpos($affected, "@")+1); |
|
||||
// domain admins should be able to check any user on the same domain |
|
||||
if ($actorDomain==$affectedDomain) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userExists"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userExists"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
} |
|
||||
// they should be able to act for any user on the same domain who is not a global manager or admin |
|
||||
if ($actorDomain==$affectedDomain && in_array($affectedRights, $allowed)) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
} |
|
||||
// they should be able to set rights for any user on their domain who is not a global manager or admin, up to domain admin level |
|
||||
foreach (self::LEVELS as $level) { |
|
||||
if ($actorDomain==$affectedDomain && in_array($affectedRights, $allowed) && in_array($level, $allowed)) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted properly for $affected settings rights level $level, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted improperly for $affected settings rights level $level, but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
// they should also be able to list all users on their own domain |
|
||||
foreach (self::DOMAINS as $domain) { |
|
||||
if ($domain=="@".$actorDomain) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($domain, "userList"), "User $actor properly checked user list for domain '$domain', but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($domain, "userList"), "User $actor improperly checked user list for domain '$domain', but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function testGlobalManagerLogic() { |
|
||||
foreach (self::USERS as $actor => $actorRights) { |
|
||||
if ($actorRights != Driver::RIGHTS_GLOBAL_MANAGER) { |
|
||||
continue; |
|
||||
} |
|
||||
$actorDomain = substr($actor, strrpos($actor, "@")+1); |
|
||||
Arsse::$user->auth($actor, ""); |
|
||||
foreach (self::USERS as $affected => $affectedRights) { |
|
||||
$affectedDomain = substr($affected, strrpos($affected, "@")+1); |
|
||||
// global managers should be able to check any user |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userExists"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
// they should only be able to act for regular users |
|
||||
if ($actor==$affected || $affectedRights==User\Driver::RIGHTS_NONE) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
} |
|
||||
// and they should only be able to set their own rights to regular user |
|
||||
foreach (self::LEVELS as $level) { |
|
||||
if ($actor==$affected && in_array($level, [User\Driver::RIGHTS_NONE, Driver::RIGHTS_GLOBAL_MANAGER])) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted properly for $affected settings rights level $level, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted improperly for $affected settings rights level $level, but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
// they should also be able to list all users |
|
||||
foreach (self::DOMAINS as $domain) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($domain, "userList"), "User $actor properly checked user list for domain '$domain', but the action was denied."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function testGlobalAdministratorLogic() { |
|
||||
foreach (self::USERS as $actor => $actorRights) { |
|
||||
if ($actorRights != Driver::RIGHTS_GLOBAL_ADMIN) { |
|
||||
continue; |
|
||||
} |
|
||||
Arsse::$user->auth($actor, ""); |
|
||||
// global admins can do anything |
|
||||
foreach (self::USERS as $affected => $affectedRights) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userExists"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
foreach (self::LEVELS as $level) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted properly for $affected settings rights level $level, but the action was denied."); |
|
||||
} |
|
||||
} |
|
||||
foreach (self::DOMAINS as $domain) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($domain, "userList"), "User $actor properly checked user list for domain '$domain', but the action was denied."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function testInvalidLevelLogic() { |
|
||||
foreach (self::USERS as $actor => $rights) { |
|
||||
if (in_array($rights, self::LEVELS)) { |
|
||||
continue; |
|
||||
} |
|
||||
Arsse::$user->auth($actor, ""); |
|
||||
foreach (array_keys(self::USERS) as $affected) { |
|
||||
// users with unknown/invalid rights should be treated just like regular users and only be able to act for themselves |
|
||||
if ($actor==$affected) { |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userExists"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
$this->assertTrue(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted properly for $affected, but the action was denied."); |
|
||||
} else { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userExists"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRemove"), "User $actor acted improperly for $affected, but the action was allowed."); |
|
||||
} |
|
||||
// they should never be able to set rights |
|
||||
foreach (self::LEVELS as $level) { |
|
||||
$this->assertFalse(Arsse::$user->authorize($affected, "userRightsSet", $level), "User $actor acted improperly for $affected settings rights level $level, but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
// they should not be able to list users |
|
||||
foreach (self::DOMAINS as $domain) { |
|
||||
$this->assertFalse(Arsse::$user->authorize($domain, "userList"), "User $actor improperly checked user list for domain '$domain', but the action was allowed."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function testInternalExceptionLogic() { |
|
||||
$tests = [ |
|
||||
// methods of User class to test, with parameters besides affected user |
|
||||
'exists' => [], |
|
||||
'remove' => [], |
|
||||
'add' => [''], |
|
||||
'passwordSet' => [''], |
|
||||
'propertiesGet' => [], |
|
||||
'propertiesSet' => [[]], |
|
||||
'rightsGet' => [], |
|
||||
'rightsSet' => [User\Driver::RIGHTS_GLOBAL_ADMIN], |
|
||||
'list' => [], |
|
||||
]; |
|
||||
// try first with a global admin (there should be no exception) |
|
||||
Arsse::$user->auth("gadm@example.com", ""); |
|
||||
$this->assertCount(0, $this->checkExceptions("user@example.org", $tests)); |
|
||||
// next try with a regular user acting on another user (everything should fail) |
|
||||
Arsse::$user->auth("user@example.com", ""); |
|
||||
$this->assertCount(sizeof($tests), $this->checkExceptions("user@example.org", $tests)); |
|
||||
} |
|
||||
|
|
||||
public function testExternalExceptionLogic() { |
|
||||
// set up the test for an external driver |
|
||||
$this->setUp(\JKingWeb\Arsse\Test\User\DriverExternalMock::class, \JKingWeb\Arsse\Test\User\Database::class); |
|
||||
// run the previous test with the external driver set up |
|
||||
$this->testInternalExceptionLogic(); |
|
||||
} |
|
||||
|
|
||||
// meat of testInternalExceptionLogic and testExternalExceptionLogic |
|
||||
// calls each requested function with supplied arguments, catches authorization exceptions, and returns an array of caught failed calls |
|
||||
protected function checkExceptions(string $user, $tests): array { |
|
||||
$err = []; |
|
||||
foreach ($tests as $func => $args) { |
|
||||
// list method does not take an affected user, so do not unshift for that one |
|
||||
if ($func != "list") { |
|
||||
array_unshift($args, $user); |
|
||||
} |
|
||||
try { |
|
||||
call_user_func_array(array(Arsse::$user, $func), $args); |
|
||||
} catch (\JKingWeb\Arsse\User\ExceptionAuthz $e) { |
|
||||
$err[] = $func; |
|
||||
} |
|
||||
} |
|
||||
return $err; |
|
||||
} |
|
||||
|
|
||||
public function testMissingUserLogic() { |
|
||||
Arsse::$user->auth("gadm@example.com", ""); |
|
||||
$this->assertTrue(Arsse::$user->authorize("user@example.com", "someFunction")); |
|
||||
$this->assertException("doesNotExist", "User"); |
|
||||
Arsse::$user->authorize("this_user_does_not_exist@example.org", "someFunction"); |
|
||||
} |
|
||||
} |
|
@ -1,17 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\TestCase\User; |
|
||||
|
|
||||
/** @covers \JKingWeb\Arsse\User */ |
|
||||
class TestMockExternal extends \JKingWeb\Arsse\Test\AbstractTest { |
|
||||
use \JKingWeb\Arsse\Test\User\CommonTests; |
|
||||
|
|
||||
const USER1 = "john.doe@example.com"; |
|
||||
const USER2 = "jane.doe@example.com"; |
|
||||
|
|
||||
public $drv = \JKingWeb\Arsse\Test\User\DriverExternalMock::class; |
|
||||
} |
|
@ -1,23 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\TestCase\User; |
|
||||
|
|
||||
use JKingWeb\Arsse\Arsse; |
|
||||
|
|
||||
/** @covers \JKingWeb\Arsse\User */ |
|
||||
class TestMockInternal extends \JKingWeb\Arsse\Test\AbstractTest { |
|
||||
use \JKingWeb\Arsse\Test\User\CommonTests; |
|
||||
|
|
||||
const USER1 = "john.doe@example.com"; |
|
||||
const USER2 = "jane.doe@example.com"; |
|
||||
|
|
||||
public $drv = \JKingWeb\Arsse\Test\User\DriverInternalMock::class; |
|
||||
|
|
||||
public function setUpSeries() { |
|
||||
Arsse::$db = null; |
|
||||
} |
|
||||
} |
|
@ -1,20 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\TestCase\User; |
|
||||
|
|
||||
/** |
|
||||
* @covers \JKingWeb\Arsse\User |
|
||||
* @covers \JKingWeb\Arsse\User\Internal\Driver |
|
||||
* @covers \JKingWeb\Arsse\User\Internal\InternalFunctions */ |
|
||||
class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest { |
|
||||
use \JKingWeb\Arsse\Test\User\CommonTests; |
|
||||
|
|
||||
const USER1 = "john.doe@example.com"; |
|
||||
const USER2 = "jane.doe@example.com"; |
|
||||
|
|
||||
public $drv = \JKingWeb\Arsse\User\Internal\Driver::class; |
|
||||
} |
|
@ -1,154 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\Test\User; |
|
||||
|
|
||||
use JKingWeb\Arsse\Arsse; |
|
||||
use JKingWeb\Arsse\Conf; |
|
||||
use JKingWeb\Arsse\User; |
|
||||
use JKingWeb\Arsse\User\Driver; |
|
||||
use Phake; |
|
||||
|
|
||||
trait CommonTests { |
|
||||
public function setUp() { |
|
||||
$this->clearData(); |
|
||||
$conf = new Conf(); |
|
||||
$conf->userDriver = $this->drv; |
|
||||
$conf->userPreAuth = false; |
|
||||
Arsse::$conf = $conf; |
|
||||
Arsse::$db = new Database(); |
|
||||
Arsse::$user = Phake::partialMock(User::class); |
|
||||
Phake::when(Arsse::$user)->authorize->thenReturn(true); |
|
||||
$_SERVER['PHP_AUTH_USER'] = self::USER1; |
|
||||
$_SERVER['PHP_AUTH_PW'] = "secret"; |
|
||||
// call the additional setup method if it exists |
|
||||
if (method_exists($this, "setUpSeries")) { |
|
||||
$this->setUpSeries(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function tearDown() { |
|
||||
$this->clearData(); |
|
||||
// call the additional teardiwn method if it exists |
|
||||
if (method_exists($this, "tearDownSeries")) { |
|
||||
$this->tearDownSeries(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function testListUsers() { |
|
||||
$this->assertCount(0, Arsse::$user->list()); |
|
||||
} |
|
||||
|
|
||||
public function testCheckIfAUserDoesNotExist() { |
|
||||
$this->assertFalse(Arsse::$user->exists(self::USER1)); |
|
||||
} |
|
||||
|
|
||||
public function testAddAUser() { |
|
||||
Arsse::$user->add(self::USER1, ""); |
|
||||
$this->assertCount(1, Arsse::$user->list()); |
|
||||
} |
|
||||
|
|
||||
public function testCheckIfAUserDoesExist() { |
|
||||
Arsse::$user->add(self::USER1, ""); |
|
||||
$this->assertTrue(Arsse::$user->exists(self::USER1)); |
|
||||
} |
|
||||
|
|
||||
public function testAddADuplicateUser() { |
|
||||
Arsse::$user->add(self::USER1, ""); |
|
||||
$this->assertException("alreadyExists", "User"); |
|
||||
Arsse::$user->add(self::USER1, ""); |
|
||||
} |
|
||||
|
|
||||
public function testAddMultipleUsers() { |
|
||||
Arsse::$user->add(self::USER1, ""); |
|
||||
Arsse::$user->add(self::USER2, ""); |
|
||||
$this->assertCount(2, Arsse::$user->list()); |
|
||||
} |
|
||||
|
|
||||
public function testRemoveAUser() { |
|
||||
Arsse::$user->add(self::USER1, ""); |
|
||||
$this->assertCount(1, Arsse::$user->list()); |
|
||||
Arsse::$user->remove(self::USER1); |
|
||||
$this->assertCount(0, Arsse::$user->list()); |
|
||||
} |
|
||||
|
|
||||
public function testRemoveAMissingUser() { |
|
||||
$this->assertException("doesNotExist", "User"); |
|
||||
Arsse::$user->remove(self::USER1); |
|
||||
} |
|
||||
|
|
||||
/** @group slow */ |
|
||||
public function testAuthenticateAUser() { |
|
||||
$_SERVER['PHP_AUTH_USER'] = self::USER1; |
|
||||
$_SERVER['PHP_AUTH_PW'] = "secret"; |
|
||||
Arsse::$user->add(self::USER1, "secret"); |
|
||||
Arsse::$user->add(self::USER2, ""); |
|
||||
$this->assertTrue(Arsse::$user->auth()); |
|
||||
$this->assertTrue(Arsse::$user->auth(self::USER1, "secret")); |
|
||||
$this->assertFalse(Arsse::$user->auth(self::USER1, "superman")); |
|
||||
$this->assertTrue(Arsse::$user->auth(self::USER2, "")); |
|
||||
} |
|
||||
|
|
||||
/** @group slow */ |
|
||||
public function testChangeAPassword() { |
|
||||
Arsse::$user->add(self::USER1, "secret"); |
|
||||
$this->assertEquals("superman", Arsse::$user->passwordSet(self::USER1, "superman")); |
|
||||
$this->assertTrue(Arsse::$user->auth(self::USER1, "superman")); |
|
||||
$this->assertFalse(Arsse::$user->auth(self::USER1, "secret")); |
|
||||
$this->assertEquals("", Arsse::$user->passwordSet(self::USER1, "")); |
|
||||
$this->assertTrue(Arsse::$user->auth(self::USER1, "")); |
|
||||
$this->assertEquals(Arsse::$conf->userTempPasswordLength, strlen(Arsse::$user->passwordSet(self::USER1))); |
|
||||
} |
|
||||
|
|
||||
public function testChangeAPasswordForAMissingUser() { |
|
||||
$this->assertException("doesNotExist", "User"); |
|
||||
Arsse::$user->passwordSet(self::USER1, "superman"); |
|
||||
} |
|
||||
|
|
||||
public function testGetThePropertiesOfAUser() { |
|
||||
Arsse::$user->add(self::USER1, "secret"); |
|
||||
$p = Arsse::$user->propertiesGet(self::USER1); |
|
||||
$this->assertArrayHasKey('id', $p); |
|
||||
$this->assertArrayHasKey('name', $p); |
|
||||
$this->assertArrayHasKey('domain', $p); |
|
||||
$this->assertArrayHasKey('rights', $p); |
|
||||
$this->assertArrayNotHasKey('password', $p); |
|
||||
$this->assertEquals(self::USER1, $p['name']); |
|
||||
} |
|
||||
|
|
||||
public function testSetThePropertiesOfAUser() { |
|
||||
$pSet = [ |
|
||||
'name' => 'John Doe', |
|
||||
'id' => 'invalid', |
|
||||
'domain' => 'localhost', |
|
||||
'rights' => Driver::RIGHTS_GLOBAL_ADMIN, |
|
||||
'password' => 'superman', |
|
||||
]; |
|
||||
$pGet = [ |
|
||||
'name' => 'John Doe', |
|
||||
'id' => self::USER1, |
|
||||
'domain' => 'example.com', |
|
||||
'rights' => Driver::RIGHTS_NONE, |
|
||||
]; |
|
||||
Arsse::$user->add(self::USER1, "secret"); |
|
||||
Arsse::$user->propertiesSet(self::USER1, $pSet); |
|
||||
$p = Arsse::$user->propertiesGet(self::USER1); |
|
||||
$this->assertArraySubset($pGet, $p); |
|
||||
$this->assertArrayNotHasKey('password', $p); |
|
||||
$this->assertFalse(Arsse::$user->auth(self::USER1, "superman")); |
|
||||
} |
|
||||
|
|
||||
public function testGetTheRightsOfAUser() { |
|
||||
Arsse::$user->add(self::USER1, ""); |
|
||||
$this->assertEquals(Driver::RIGHTS_NONE, Arsse::$user->rightsGet(self::USER1)); |
|
||||
} |
|
||||
|
|
||||
public function testSetTheRightsOfAUser() { |
|
||||
Arsse::$user->add(self::USER1, ""); |
|
||||
Arsse::$user->rightsSet(self::USER1, Driver::RIGHTS_GLOBAL_ADMIN); |
|
||||
$this->assertEquals(Driver::RIGHTS_GLOBAL_ADMIN, Arsse::$user->rightsGet(self::USER1)); |
|
||||
} |
|
||||
} |
|
@ -1,133 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\Test\User; |
|
||||
|
|
||||
use JKingWeb\Arsse\Arsse; |
|
||||
use JKingWeb\Arsse\User\Driver; |
|
||||
use JKingWeb\Arsse\User\Exception; |
|
||||
use JKingWeb\Arsse\User\ExceptionAuthz; |
|
||||
use PasswordGenerator\Generator as PassGen; |
|
||||
|
|
||||
class Database extends DriverSkeleton { |
|
||||
public $db = []; |
|
||||
|
|
||||
public function __construct() { |
|
||||
} |
|
||||
|
|
||||
public function userExists(string $user): bool { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return parent::userExists($user); |
|
||||
} |
|
||||
|
|
||||
public function userAdd(string $user, string $password = null): string { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if ($this->userExists($user)) { |
|
||||
throw new Exception("alreadyExists", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if ($password===null) { |
|
||||
$password = (new PassGen)->length(Arsse::$conf->userTempPasswordLength)->get(); |
|
||||
} |
|
||||
return parent::userAdd($user, $password); |
|
||||
} |
|
||||
|
|
||||
public function userRemove(string $user): bool { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return parent::userRemove($user); |
|
||||
} |
|
||||
|
|
||||
public function userList(string $domain = null): array { |
|
||||
if ($domain===null) { |
|
||||
if (!Arsse::$user->authorize("", __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => "global"]); |
|
||||
} |
|
||||
return parent::userList(); |
|
||||
} else { |
|
||||
$suffix = '@'.$domain; |
|
||||
if (!Arsse::$user->authorize($suffix, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $domain]); |
|
||||
} |
|
||||
return parent::userList($domain); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function userPasswordSet(string $user, string $newPassword = null, string $oldPassword = null): string { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if ($newPassword===null) { |
|
||||
$newPassword = (new PassGen)->length(Arsse::$conf->userTempPasswordLength)->get(); |
|
||||
} |
|
||||
return parent::userPasswordSet($user, $newPassword); |
|
||||
} |
|
||||
|
|
||||
public function userPropertiesGet(string $user): array { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
$out = parent::userPropertiesGet($user); |
|
||||
unset($out['password']); |
|
||||
return $out; |
|
||||
} |
|
||||
|
|
||||
public function userPropertiesSet(string $user, array $properties): array { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
parent::userPropertiesSet($user, $properties); |
|
||||
return $this->userPropertiesGet($user); |
|
||||
} |
|
||||
|
|
||||
public function userRightsGet(string $user): int { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return parent::userRightsGet($user); |
|
||||
} |
|
||||
|
|
||||
public function userRightsSet(string $user, int $level): bool { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return parent::userRightsSet($user, $level); |
|
||||
} |
|
||||
|
|
||||
// specific to mock database |
|
||||
|
|
||||
public function userPasswordGet(string $user): string { |
|
||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) { |
|
||||
throw new ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return $this->db[$user]['password']; |
|
||||
} |
|
||||
} |
|
@ -1,127 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\Test\User; |
|
||||
|
|
||||
use JKingWeb\Arsse\Arsse; |
|
||||
use JKingWeb\Arsse\User\Driver; |
|
||||
use JKingWeb\Arsse\User\Exception; |
|
||||
use PasswordGenerator\Generator as PassGen; |
|
||||
|
|
||||
class DriverExternalMock extends DriverSkeleton implements Driver { |
|
||||
public $db = []; |
|
||||
protected $functions = [ |
|
||||
"auth" => Driver::FUNC_EXTERNAL, |
|
||||
"userList" => Driver::FUNC_EXTERNAL, |
|
||||
"userExists" => Driver::FUNC_EXTERNAL, |
|
||||
"userAdd" => Driver::FUNC_EXTERNAL, |
|
||||
"userRemove" => Driver::FUNC_EXTERNAL, |
|
||||
"userPasswordSet" => Driver::FUNC_EXTERNAL, |
|
||||
"userPropertiesGet" => Driver::FUNC_EXTERNAL, |
|
||||
"userPropertiesSet" => Driver::FUNC_EXTERNAL, |
|
||||
"userRightsGet" => Driver::FUNC_EXTERNAL, |
|
||||
"userRightsSet" => Driver::FUNC_EXTERNAL, |
|
||||
]; |
|
||||
|
|
||||
public static function driverName(): string { |
|
||||
return "Mock External Driver"; |
|
||||
} |
|
||||
|
|
||||
public function driverFunctions(string $function = null) { |
|
||||
if ($function===null) { |
|
||||
return $this->functions; |
|
||||
} |
|
||||
if (array_key_exists($function, $this->functions)) { |
|
||||
return $this->functions[$function]; |
|
||||
} else { |
|
||||
return Driver::FUNC_NOT_IMPLEMENTED; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function __construct() { |
|
||||
} |
|
||||
|
|
||||
public function auth(string $user, string $password): bool { |
|
||||
if (!$this->userExists($user)) { |
|
||||
return false; |
|
||||
} |
|
||||
if ($password==="" && $this->db[$user]['password']==="") { |
|
||||
return true; |
|
||||
} |
|
||||
if (password_verify($password, $this->db[$user]['password'])) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
public function userExists(string $user): bool { |
|
||||
return parent::userExists($user); |
|
||||
} |
|
||||
|
|
||||
public function userAdd(string $user, string $password = null): string { |
|
||||
if ($this->userExists($user)) { |
|
||||
throw new Exception("alreadyExists", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if ($password===null) { |
|
||||
$password = (new PassGen)->length(Arsse::$conf->userTempPasswordLength)->get(); |
|
||||
} |
|
||||
return parent::userAdd($user, $password); |
|
||||
} |
|
||||
|
|
||||
public function userRemove(string $user): bool { |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return parent::userRemove($user); |
|
||||
} |
|
||||
|
|
||||
public function userList(string $domain = null): array { |
|
||||
if ($domain===null) { |
|
||||
return parent::userList(); |
|
||||
} else { |
|
||||
return parent::userList($domain); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function userPasswordSet(string $user, string $newPassword = null, string $oldPassword = null): string { |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
if ($newPassword===null) { |
|
||||
$newPassword = (new PassGen)->length(Arsse::$conf->userTempPasswordLength)->get(); |
|
||||
} |
|
||||
return parent::userPasswordSet($user, $newPassword); |
|
||||
} |
|
||||
|
|
||||
public function userPropertiesGet(string $user): array { |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return parent::userPropertiesGet($user); |
|
||||
} |
|
||||
|
|
||||
public function userPropertiesSet(string $user, array $properties): array { |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
parent::userPropertiesSet($user, $properties); |
|
||||
return $this->userPropertiesGet($user); |
|
||||
} |
|
||||
|
|
||||
public function userRightsGet(string $user): int { |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return parent::userRightsGet($user); |
|
||||
} |
|
||||
|
|
||||
public function userRightsSet(string $user, int $level): bool { |
|
||||
if (!$this->userExists($user)) { |
|
||||
throw new Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]); |
|
||||
} |
|
||||
return parent::userRightsSet($user, $level); |
|
||||
} |
|
||||
} |
|
@ -1,56 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\Test\User; |
|
||||
|
|
||||
use JKingWeb\Arsse\User\Driver; |
|
||||
|
|
||||
class DriverInternalMock extends Database implements Driver { |
|
||||
public $db = []; |
|
||||
protected $functions = [ |
|
||||
"auth" => Driver::FUNC_INTERNAL, |
|
||||
"userList" => Driver::FUNC_INTERNAL, |
|
||||
"userExists" => Driver::FUNC_INTERNAL, |
|
||||
"userAdd" => Driver::FUNC_INTERNAL, |
|
||||
"userRemove" => Driver::FUNC_INTERNAL, |
|
||||
"userPasswordSet" => Driver::FUNC_INTERNAL, |
|
||||
"userPropertiesGet" => Driver::FUNC_INTERNAL, |
|
||||
"userPropertiesSet" => Driver::FUNC_INTERNAL, |
|
||||
"userRightsGet" => Driver::FUNC_INTERNAL, |
|
||||
"userRightsSet" => Driver::FUNC_INTERNAL, |
|
||||
]; |
|
||||
|
|
||||
public static function driverName(): string { |
|
||||
return "Mock Internal Driver"; |
|
||||
} |
|
||||
|
|
||||
public function driverFunctions(string $function = null) { |
|
||||
if ($function===null) { |
|
||||
return $this->functions; |
|
||||
} |
|
||||
if (array_key_exists($function, $this->functions)) { |
|
||||
return $this->functions[$function]; |
|
||||
} else { |
|
||||
return Driver::FUNC_NOT_IMPLEMENTED; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function __construct() { |
|
||||
} |
|
||||
|
|
||||
public function auth(string $user, string $password): bool { |
|
||||
if (!$this->userExists($user)) { |
|
||||
return false; |
|
||||
} |
|
||||
if ($password==="" && $this->db[$user]['password']==="") { |
|
||||
return true; |
|
||||
} |
|
||||
if (password_verify($password, $this->db[$user]['password'])) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
@ -1,72 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2017 J. King, Dustin Wilson et al. |
|
||||
* See LICENSE and AUTHORS files for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace JKingWeb\Arsse\Test\User; |
|
||||
|
|
||||
use JKingWeb\Arsse\Lang; |
|
||||
use JKingWeb\Arsse\User\Driver; |
|
||||
use JKingWeb\Arsse\User\Exception; |
|
||||
use JKingWeb\Arsse\User\ExceptionAuthz; |
|
||||
use PasswordGenerator\Generator as PassGen; |
|
||||
|
|
||||
abstract class DriverSkeleton { |
|
||||
protected $db = []; |
|
||||
|
|
||||
public function userExists(string $user): bool { |
|
||||
return array_key_exists($user, $this->db); |
|
||||
} |
|
||||
|
|
||||
public function userAdd(string $user, string $password = null): string { |
|
||||
$u = [ |
|
||||
'password' => $password ? password_hash($password, \PASSWORD_DEFAULT) : "", |
|
||||
'rights' => Driver::RIGHTS_NONE, |
|
||||
]; |
|
||||
$this->db[$user] = $u; |
|
||||
return $password; |
|
||||
} |
|
||||
|
|
||||
public function userRemove(string $user): bool { |
|
||||
unset($this->db[$user]); |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
public function userList(string $domain = null): array { |
|
||||
$list = array_keys($this->db); |
|
||||
if ($domain===null) { |
|
||||
return $list; |
|
||||
} else { |
|
||||
$suffix = '@'.$domain; |
|
||||
$len = -1 * strlen($suffix); |
|
||||
return array_filter($list, function ($user) use ($suffix, $len) { |
|
||||
return substr_compare($user, $suffix, $len); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function userPasswordSet(string $user, string $newPassword = null, string $oldPassword = null): string { |
|
||||
$this->db[$user]['password'] = password_hash($newPassword, \PASSWORD_DEFAULT); |
|
||||
return $newPassword; |
|
||||
} |
|
||||
|
|
||||
public function userPropertiesGet(string $user): array { |
|
||||
$out = $this->db[$user]; |
|
||||
return $out; |
|
||||
} |
|
||||
|
|
||||
public function userPropertiesSet(string $user, array $properties): array { |
|
||||
$this->db[$user] = array_merge($this->db[$user], $properties); |
|
||||
return $this->userPropertiesGet($user); |
|
||||
} |
|
||||
|
|
||||
public function userRightsGet(string $user): int { |
|
||||
return $this->db[$user]['rights']; |
|
||||
} |
|
||||
|
|
||||
public function userRightsSet(string $user, int $level): bool { |
|
||||
$this->db[$user]['rights'] = $level; |
|
||||
return true; |
|
||||
} |
|
||||
} |
|
Loading…
Reference in new issue