diff --git a/lib/RuntimeData.php b/lib/RuntimeData.php
index 42ac9b99..7140d485 100644
--- a/lib/RuntimeData.php
+++ b/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;
diff --git a/lib/User.php b/lib/User.php
index 87300121..5360981b 100644
--- a/lib/User.php
+++ b/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;
diff --git a/lib/User/Driver.php b/lib/User/Driver.php
index eed2e25c..598d2f83 100644
--- a/lib/User/Driver.php
+++ b/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;
}
\ No newline at end of file
diff --git a/lib/User/DriverInternal.php b/lib/User/DriverInternal.php
index 7e85cf36..da81947f 100644
--- a/lib/User/DriverInternal.php
+++ b/lib/User/DriverInternal.php
@@ -1,8 +1,9 @@
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
}
\ No newline at end of file
diff --git a/lib/User/InternalFunctions.php b/lib/User/InternalFunctions.php
index 43fc285d..65a97f14 100644
--- a/lib/User/InternalFunctions.php
+++ b/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);
diff --git a/locale/en.php b/locale/en.php
index e6eb3b7a..a2f82162 100644
--- a/locale/en.php
+++ b/locale/en.php
@@ -1,5 +1,7 @@
'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',
diff --git a/tests/TestConf.php b/tests/Conf/TestConf.php
similarity index 100%
rename from tests/TestConf.php
rename to tests/Conf/TestConf.php
diff --git a/tests/TestException.php b/tests/Exception/TestException.php
similarity index 100%
rename from tests/TestException.php
rename to tests/Exception/TestException.php
diff --git a/tests/TestLang.php b/tests/Lang/TestLang.php
similarity index 100%
rename from tests/TestLang.php
rename to tests/Lang/TestLang.php
diff --git a/tests/TestLangErrors.php b/tests/Lang/TestLangErrors.php
similarity index 100%
rename from tests/TestLangErrors.php
rename to tests/Lang/TestLangErrors.php
diff --git a/tests/testLangComplex.php b/tests/Lang/testLangComplex.php
similarity index 100%
rename from tests/testLangComplex.php
rename to tests/Lang/testLangComplex.php
diff --git a/tests/User/TestUser.php b/tests/User/TestUser.php
new file mode 100644
index 00000000..aef45757
--- /dev/null
+++ b/tests/User/TestUser.php
@@ -0,0 +1,17 @@
+userDriver = Test\User\DriverInternalMock::class;
+ $this->data = new Test\RuntimeData($conf);
+ $this->data->user = new User($this->data);
+ }
+}
diff --git a/tests/lib/RuntimeData.php b/tests/lib/RuntimeData.php
new file mode 100644
index 00000000..bfdb2e4e
--- /dev/null
+++ b/tests/lib/RuntimeData.php
@@ -0,0 +1,13 @@
+conf = $conf;
+ }
+}
\ No newline at end of file
diff --git a/tests/lib/User/DriverInternalMock.php b/tests/lib/User/DriverInternalMock.php
new file mode 100644
index 00000000..2403a7f2
--- /dev/null
+++ b/tests/lib/User/DriverInternalMock.php
@@ -0,0 +1,89 @@
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
index a7167ed1..5b31655a 100644
--- a/tests/phpunit.xml
+++ b/tests/phpunit.xml
@@ -11,13 +11,18 @@
stopOnError="true">
- TestLang.php
- TestLangComplex.php
- TestException.php
- TestLangErrors.php
+ Lang/TestLang.php
+ Lang/TestLangComplex.php
+ Lang/TestException.php
+ Lang/TestLangErrors.php
- TestConf.php
+ Conf/TestConf.php
+
+
+ User/TestUser.php
+
+
\ No newline at end of file