mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Tidy up tests and User stuff
- Skeleton of mock internal driver - Skeleton of test suite - Re-arranged lots of code - Made drive name localized (improves #37)
This commit is contained in:
parent
8db31cf3e4
commit
574388665a
15 changed files with 167 additions and 23 deletions
|
@ -5,7 +5,7 @@ namespace JKingWeb\NewsSync;
|
||||||
class RuntimeData {
|
class RuntimeData {
|
||||||
public $conf;
|
public $conf;
|
||||||
public $db;
|
public $db;
|
||||||
public $auth;
|
public $user;
|
||||||
|
|
||||||
public function __construct(Conf $conf) {
|
public function __construct(Conf $conf) {
|
||||||
$this->conf = $conf;
|
$this->conf = $conf;
|
||||||
|
|
|
@ -16,10 +16,10 @@ class User {
|
||||||
$path = __DIR__.$sep."User".$sep;
|
$path = __DIR__.$sep."User".$sep;
|
||||||
$classes = [];
|
$classes = [];
|
||||||
foreach(glob($path."Driver?*.php") as $file) {
|
foreach(glob($path."Driver?*.php") as $file) {
|
||||||
$name = basename($file, ".php");
|
$drv = basename($file, ".php");
|
||||||
$name = NS_BASE."Db\\$name";
|
$drv = NS_BASE."Db\\$drv";
|
||||||
if(class_exists($name)) {
|
if(class_exists($drv)) {
|
||||||
$classes[$name] = $name::driverName();
|
$classes[$drv] = $drv::driverName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $classes;
|
return $classes;
|
||||||
|
|
|
@ -7,24 +7,38 @@ Interface Driver {
|
||||||
const FUNC_INTERNAL = 1;
|
const FUNC_INTERNAL = 1;
|
||||||
const FUNC_EXTERNAL = 2;
|
const FUNC_EXTERNAL = 2;
|
||||||
|
|
||||||
const RIGHTS_NONE = 0;
|
const RIGHTS_NONE = 0; // normal user
|
||||||
const RIGHTS_DOMAIN_MANAGER = 25;
|
const RIGHTS_DOMAIN_MANAGER = 25; // able to act for any normal users on same domain; cannot elevate other users
|
||||||
const RIGHTS_DOMAIN_ADMIN = 50;
|
const RIGHTS_DOMAIN_ADMIN = 50; // able to act for any users on same domain not above themselves; may elevate users on same domain to domain manager or domain admin
|
||||||
const RIGHTS_GLOBAL_MANAGER = 75;
|
const RIGHTS_GLOBAL_MANAGER = 75; // able to act for any user below themselves; can elevate users to domain manager or domain admin
|
||||||
const RIGHTS_GLOBAL_ADMIN = 100;
|
const RIGHTS_GLOBAL_ADMIN = 100; // is completely unrestricted
|
||||||
|
|
||||||
|
// returns an instance of a class implementing this interface. Implemented as a static method for consistency with database classes
|
||||||
static function create(\JKingWeb\NewsSync\RuntimeData $data): Driver;
|
static function create(\JKingWeb\NewsSync\RuntimeData $data): Driver;
|
||||||
|
// returns a human-friendly name for the driver (for display in installer, for example)
|
||||||
static function driverName(): string;
|
static function driverName(): string;
|
||||||
|
// returns an array (or single queried member of same) of methods defined by this interface and whether the class implements the internal function or a custom version
|
||||||
function driverFunctions(string $function = null);
|
function driverFunctions(string $function = null);
|
||||||
|
// authenticates a user against their name and password
|
||||||
function auth(string $user, string $password): bool;
|
function auth(string $user, string $password): bool;
|
||||||
|
// checks whether the logged in user is authorized to act for the affected user (used especially when granting rights)
|
||||||
function authorize(string $affectedUser, string $action): bool;
|
function authorize(string $affectedUser, string $action): bool;
|
||||||
|
// checks whether a user exists
|
||||||
function userExists(string $user): bool;
|
function userExists(string $user): bool;
|
||||||
|
// adds a user
|
||||||
function userAdd(string $user, string $password = null): bool;
|
function userAdd(string $user, string $password = null): bool;
|
||||||
|
// removes a user
|
||||||
function userRemove(string $user): bool;
|
function userRemove(string $user): bool;
|
||||||
|
// lists all users
|
||||||
function userList(string $domain = null): array;
|
function userList(string $domain = null): array;
|
||||||
|
// sets a user's password; if the driver does not require the old password, it may be ignored
|
||||||
function userPasswordSet(string $user, string $newPassword, string $oldPassword): bool;
|
function userPasswordSet(string $user, string $newPassword, string $oldPassword): bool;
|
||||||
|
// gets user metadata (currently not useful)
|
||||||
function userPropertiesGet(string $user): array;
|
function userPropertiesGet(string $user): array;
|
||||||
|
// sets user metadata (currently not useful)
|
||||||
function userPropertiesSet(string $user, array $properties): array;
|
function userPropertiesSet(string $user, array $properties): array;
|
||||||
|
// returns a user's access level according to RIGHTS_* constants (or some custom semantics, if using custom implementation of authorize())
|
||||||
function userRightsGet(string $user): int;
|
function userRightsGet(string $user): int;
|
||||||
|
// sets a user's access level
|
||||||
function userRightsSet(string $user, int $level): bool;
|
function userRightsSet(string $user, int $level): bool;
|
||||||
}
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
namespace JKingWeb\NewsSync\User;
|
namespace JKingWeb\NewsSync\User;
|
||||||
|
use JKingWeb\NewsSync\Lang;
|
||||||
|
|
||||||
class DriverInternal implements Driver {
|
final class DriverInternal implements Driver {
|
||||||
use InternalFunctions;
|
use InternalFunctions;
|
||||||
|
|
||||||
protected $data;
|
protected $data;
|
||||||
|
@ -25,13 +26,9 @@ class DriverInternal implements Driver {
|
||||||
return new static($data);
|
return new static($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct(\JKingWeb\NewsSync\RuntimeData $data) {
|
|
||||||
$this->data = $data;
|
|
||||||
$this->db = $this->data->db;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function driverName(): string {
|
static public function driverName(): string {
|
||||||
return "Internal";
|
$name = str_replace(Driver::class, "", static::class);
|
||||||
|
return Lang::msg("Driver.User.$name.Name");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function driverFunctions(string $function = null) {
|
public function driverFunctions(string $function = null) {
|
||||||
|
@ -42,4 +39,6 @@ class DriverInternal implements Driver {
|
||||||
return Driver::FUNC_NOT_IMPLEMENTED;
|
return Driver::FUNC_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// see InternalFunctions.php for bulk of methods
|
||||||
}
|
}
|
|
@ -5,6 +5,11 @@ namespace JKingWeb\NewsSync\User;
|
||||||
trait InternalFunctions {
|
trait InternalFunctions {
|
||||||
protected $actor = [];
|
protected $actor = [];
|
||||||
|
|
||||||
|
public function __construct(\JKingWeb\NewsSync\RuntimeData $data) {
|
||||||
|
$this->data = $data;
|
||||||
|
$this->db = $this->data->db;
|
||||||
|
}
|
||||||
|
|
||||||
function auth(string $user, string $password): bool {
|
function auth(string $user, string $password): bool {
|
||||||
if(!$this->data->user->exists($user)) return false;
|
if(!$this->data->user->exists($user)) return false;
|
||||||
$hash = $this->db->userPasswordGet($user);
|
$hash = $this->db->userPasswordGet($user);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
return [
|
return [
|
||||||
|
'Driver.User.Internal.Name' => 'Internal',
|
||||||
|
|
||||||
'Exception.JKingWeb/NewsSync/Exception.uncoded' => 'The specified exception symbol {0} has no code specified in Exception.php',
|
'Exception.JKingWeb/NewsSync/Exception.uncoded' => 'The specified exception symbol {0} has no code specified in Exception.php',
|
||||||
//this should not usually be encountered
|
//this should not usually be encountered
|
||||||
'Exception.JKingWeb/NewsSync/Exception.unknown' => 'An unknown error has occurred',
|
'Exception.JKingWeb/NewsSync/Exception.unknown' => 'An unknown error has occurred',
|
||||||
|
|
17
tests/User/TestUser.php
Normal file
17
tests/User/TestUser.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\NewsSync;
|
||||||
|
|
||||||
|
|
||||||
|
class TestUser extends \PHPUnit\Framework\TestCase {
|
||||||
|
use Test\Tools;
|
||||||
|
|
||||||
|
protected $data;
|
||||||
|
|
||||||
|
function setUp() {
|
||||||
|
$conf = new Conf();
|
||||||
|
$conf->userDriver = Test\User\DriverInternalMock::class;
|
||||||
|
$this->data = new Test\RuntimeData($conf);
|
||||||
|
$this->data->user = new User($this->data);
|
||||||
|
}
|
||||||
|
}
|
13
tests/lib/RuntimeData.php
Normal file
13
tests/lib/RuntimeData.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\NewsSync\Test;
|
||||||
|
|
||||||
|
class RuntimeData extends \JKingWeb\NewsSync\RuntimeData {
|
||||||
|
public $conf;
|
||||||
|
public $db;
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
public function __construct(\JKingWeb\NewsSync\Conf $conf = null) {
|
||||||
|
$this->conf = $conf;
|
||||||
|
}
|
||||||
|
}
|
89
tests/lib/User/DriverInternalMock.php
Normal file
89
tests/lib/User/DriverInternalMock.php
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\NewsSync\Test\User;
|
||||||
|
use JKingWeb\NewsSync\Lang, JKingWeb\NewsSync\User\Driver;
|
||||||
|
|
||||||
|
final class DriverInternalMock implements Driver {
|
||||||
|
|
||||||
|
protected $data;
|
||||||
|
protected $db;
|
||||||
|
protected $functions = [
|
||||||
|
"auth" => Driver::FUNC_INTERNAL,
|
||||||
|
"authorize" => 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,
|
||||||
|
];
|
||||||
|
|
||||||
|
static public function create(\JKingWeb\NewsSync\RuntimeData $data): Driver {
|
||||||
|
return new static($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public 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(\JKingWeb\NewsSync\RuntimeData $data) {
|
||||||
|
$this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function auth(string $user, string $password): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function authorize(string $affectedUser, string $action, int $newRightsLevel = 0): bool {
|
||||||
|
if($affectedUser==$this->data->user->id) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function userExists(string $user): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function userAdd(string $user, string $password = null): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function userRemove(string $user): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function userList(string $domain = null): array {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function userPasswordSet(string $user, string $newPassword, string $oldPassword): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function userPropertiesGet(string $user): array {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function userPropertiesSet(string $user, array $properties): array {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function userRightsGet(string $user): int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function userRightsSet(string $user, int $level): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,13 +11,18 @@
|
||||||
stopOnError="true">
|
stopOnError="true">
|
||||||
|
|
||||||
<testsuite name="Localization and exceptions">
|
<testsuite name="Localization and exceptions">
|
||||||
<file>TestLang.php</file>
|
<file>Lang/TestLang.php</file>
|
||||||
<file>TestLangComplex.php</file>
|
<file>Lang/TestLangComplex.php</file>
|
||||||
<file>TestException.php</file>
|
<file>Lang/TestException.php</file>
|
||||||
<file>TestLangErrors.php</file>
|
<file>Lang/TestLangErrors.php</file>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
|
||||||
<testsuite name="Configuration loading and saving">
|
<testsuite name="Configuration loading and saving">
|
||||||
<file>TestConf.php</file>
|
<file>Conf/TestConf.php</file>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
|
||||||
|
<testsuite name="User management">
|
||||||
|
<file>User/TestUser.php</file>
|
||||||
|
</testsuite>
|
||||||
|
|
||||||
</phpunit>
|
</phpunit>
|
Loading…
Reference in a new issue