Browse Source

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)
microsub
J. King 7 years ago
parent
commit
574388665a
  1. 2
      lib/RuntimeData.php
  2. 8
      lib/User.php
  3. 24
      lib/User/Driver.php
  4. 13
      lib/User/DriverInternal.php
  5. 7
      lib/User/InternalFunctions.php
  6. 2
      locale/en.php
  7. 0
      tests/Conf/TestConf.php
  8. 0
      tests/Exception/TestException.php
  9. 0
      tests/Lang/TestLang.php
  10. 0
      tests/Lang/TestLangErrors.php
  11. 0
      tests/Lang/testLangComplex.php
  12. 17
      tests/User/TestUser.php
  13. 13
      tests/lib/RuntimeData.php
  14. 89
      tests/lib/User/DriverInternalMock.php
  15. 15
      tests/phpunit.xml

2
lib/RuntimeData.php

@ -5,7 +5,7 @@ namespace JKingWeb\NewsSync;
class RuntimeData {
public $conf;
public $db;
public $auth;
public $user;
public function __construct(Conf $conf) {
$this->conf = $conf;

8
lib/User.php

@ -16,10 +16,10 @@ class User {
$path = __DIR__.$sep."User".$sep;
$classes = [];
foreach(glob($path."Driver?*.php") as $file) {
$name = basename($file, ".php");
$name = NS_BASE."Db\\$name";
if(class_exists($name)) {
$classes[$name] = $name::driverName();
$drv = basename($file, ".php");
$drv = NS_BASE."Db\\$drv";
if(class_exists($drv)) {
$classes[$drv] = $drv::driverName();
}
}
return $classes;

24
lib/User/Driver.php

@ -7,24 +7,38 @@ Interface Driver {
const FUNC_INTERNAL = 1;
const FUNC_EXTERNAL = 2;
const RIGHTS_NONE = 0;
const RIGHTS_DOMAIN_MANAGER = 25;
const RIGHTS_DOMAIN_ADMIN = 50;
const RIGHTS_GLOBAL_MANAGER = 75;
const RIGHTS_GLOBAL_ADMIN = 100;
const RIGHTS_NONE = 0; // normal user
const RIGHTS_DOMAIN_MANAGER = 25; // able to act for any normal users on same domain; cannot elevate other users
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; // able to act for any user below themselves; can elevate users to domain manager or domain admin
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;
// returns a human-friendly name for the driver (for display in installer, for example)
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);
// authenticates a user against their name and password
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;
// checks whether a user exists
function userExists(string $user): bool;
// adds a user
function userAdd(string $user, string $password = null): bool;
// removes a user
function userRemove(string $user): bool;
// lists all users
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;
// gets user metadata (currently not useful)
function userPropertiesGet(string $user): array;
// sets user metadata (currently not useful)
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;
// sets a user's access level
function userRightsSet(string $user, int $level): bool;
}

13
lib/User/DriverInternal.php

@ -1,8 +1,9 @@
<?php
declare(strict_types=1);
namespace JKingWeb\NewsSync\User;
use JKingWeb\NewsSync\Lang;
class DriverInternal implements Driver {
final class DriverInternal implements Driver {
use InternalFunctions;
protected $data;
@ -25,13 +26,9 @@ class DriverInternal implements Driver {
return new static($data);
}
public function __construct(\JKingWeb\NewsSync\RuntimeData $data) {
$this->data = $data;
$this->db = $this->data->db;
}
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) {
@ -42,4 +39,6 @@ class DriverInternal implements Driver {
return Driver::FUNC_NOT_IMPLEMENTED;
}
}
// see InternalFunctions.php for bulk of methods
}

7
lib/User/InternalFunctions.php

@ -4,7 +4,12 @@ namespace JKingWeb\NewsSync\User;
trait InternalFunctions {
protected $actor = [];
public function __construct(\JKingWeb\NewsSync\RuntimeData $data) {
$this->data = $data;
$this->db = $this->data->db;
}
function auth(string $user, string $password): bool {
if(!$this->data->user->exists($user)) return false;
$hash = $this->db->userPasswordGet($user);

2
locale/en.php

@ -1,5 +1,7 @@
<?php
return [
'Driver.User.Internal.Name' => 'Internal',
'Exception.JKingWeb/NewsSync/Exception.uncoded' => 'The specified exception symbol {0} has no code specified in Exception.php',
//this should not usually be encountered
'Exception.JKingWeb/NewsSync/Exception.unknown' => 'An unknown error has occurred',

0
tests/TestConf.php → tests/Conf/TestConf.php

0
tests/TestException.php → tests/Exception/TestException.php

0
tests/TestLang.php → tests/Lang/TestLang.php

0
tests/TestLangErrors.php → tests/Lang/TestLangErrors.php

0
tests/testLangComplex.php → tests/Lang/testLangComplex.php

17
tests/User/TestUser.php

@ -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

@ -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

@ -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;
}
}

15
tests/phpunit.xml

@ -11,13 +11,18 @@
stopOnError="true">
<testsuite name="Localization and exceptions">
<file>TestLang.php</file>
<file>TestLangComplex.php</file>
<file>TestException.php</file>
<file>TestLangErrors.php</file>
<file>Lang/TestLang.php</file>
<file>Lang/TestLangComplex.php</file>
<file>Lang/TestException.php</file>
<file>Lang/TestLangErrors.php</file>
</testsuite>
<testsuite name="Configuration loading and saving">
<file>TestConf.php</file>
<file>Conf/TestConf.php</file>
</testsuite>
<testsuite name="User management">
<file>User/TestUser.php</file>
</testsuite>
</phpunit>
Loading…
Cancel
Save