Browse Source

Groups & Stuff

Roman Hergenreder 4 years ago
parent
commit
d9a20ae62e

+ 14 - 8
core/Api/Request.class.php

@@ -16,24 +16,27 @@ class Request {
   protected bool $variableParamCount;
   protected bool $isDisabled;
   protected bool $apiKeyAllowed;
+  protected int $requiredGroup;
 
   private array $aDefaultParams;
   private array $allowedMethods;
-  private bool $externCall;
+  private bool $externalCall;
 
   public function __construct(User $user, bool $externalCall = false, array $params = array()) {
     $this->user = $user;
     $this->aDefaultParams = $params;
-    $this->lastError = '';
+
     $this->success = false;
     $this->result = array();
-    $this->externCall = $externalCall;
+    $this->externalCall = $externalCall;
     $this->isPublic = true;
     $this->isDisabled = false;
     $this->loginRequired = false;
     $this->variableParamCount = false;
     $this->apiKeyAllowed = true;
     $this->allowedMethods = array("GET", "POST");
+    $this->requiredGroup = 0;
+    $this->lastError = "";
   }
 
   protected function forbidMethod($method) {
@@ -82,7 +85,7 @@ class Request {
       $this->result['logoutIn'] = $this->user->getSession()->getExpiresSeconds();
     }
 
-    if($this->externCall) {
+    if($this->externalCall) {
       $values = $_REQUEST;
       if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER["CONTENT_TYPE"]) && in_array("application/json", explode(";", $_SERVER["CONTENT_TYPE"]))) {
         $jsonData = json_decode(file_get_contents('php://input'), true);
@@ -95,7 +98,7 @@ class Request {
       return false;
     }
 
-    if($this->externCall && !$this->isPublic) {
+    if($this->externalCall && !$this->isPublic) {
       $this->lastError = 'This function is private.';
       header('HTTP 1.1 403 Forbidden');
       return false;
@@ -107,8 +110,7 @@ class Request {
       return false;
     }
 
-
-    if($this->loginRequired) {
+    if($this->loginRequired || $this->requiredGroup > 0) {
       $authorized = false;
       if(isset($values['api_key']) && $this->apiKeyAllowed) {
         $apiKey = $values['api_key'];
@@ -119,6 +121,10 @@ class Request {
         $this->lastError = 'You are not logged in.';
         header('HTTP 1.1 401 Unauthorized');
         return false;
+      } else if($this->requiredGroup > 0 && !$this->user->hasGroup($this->requiredGroup)) {
+        $this->lastError = "Insufficient permissions. Required group: ". GroupName($this->requiredGroup);
+        header('HTTP 1.1 401 Unauthorized');
+        return false;
       }
     }
 
@@ -151,7 +157,7 @@ class Request {
   public function getResult() { return $this->result; }
   public function success() { return $this->success; }
   public function loginRequired() { return $this->loginRequired; }
-  public function isExternalCall() { return $this->externCall; }
+  public function isExternalCall() { return $this->externalCall; }
 
   public function getJsonResult() {
     $this->result['success'] = $this->success;

+ 53 - 0
core/Api/User/Fetch.class.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace Api\User;
+
+use \Api\Request;
+
+class Fetch extends Request {
+
+  public function __construct($user, $externalCall = false) {
+    parent::__construct($user, $externalCall, array());
+    $this->loginRequired = true;
+    // $this->requiredGroup = USER_GROUP_ADMIN;
+  }
+
+  public function execute($values = array()) {
+    if(!parent::execute($values)) {
+      return false;
+    }
+
+    $sql = $this->user->getSQL();
+    $res = $sql->select("User.uid as userId", "User.name", "User.email", "Group.uid as groupId", "Group.name as groupName")
+      ->from("User")
+      ->leftJoin("UserGroup", "User.uid", "UserGroup.user_id")
+      ->leftJoin("Group", "Group.uid", "UserGroup.group_id")
+      ->execute();
+
+    $this->success = ($res !== FALSE);
+    $this->lastError = $sql->getLastError();
+
+    if($this->success) {
+      $this->result["users"] = array();
+      foreach($res as $row) {
+        $userId = $row["userId"];
+        $groupId = $row["groupId"];
+        $groupName = $row["groupName"];
+        if (!isset($this->result["users"][$userId])) {
+          $this->result["users"][$userId] = array(
+            "uid" => $userId,
+            "name" => $row["name"],
+            "email" => $row["email"],
+            "groups" => array(),
+          );
+        }
+
+        if(!is_null($groupId)) {
+          $this->result["users"][$userId]["groups"][$groupId] = $groupName;
+        }
+      }
+    }
+
+    return $this->success;
+  }
+}

+ 2 - 2
core/Configuration/CreateDatabase.class.php

@@ -63,8 +63,8 @@ class CreateDatabase {
       ->unique("name");
 
     $queries[] = $sql->insert("Group", array("uid", "name"))
-      ->addRow(USER_GROUP_DEFAULT, "Default")
-      ->addRow(USER_GROUP_ADMIN, "Administrator");
+      ->addRow(USER_GROUP_DEFAULT, USER_GROUP_DEFAULT_NAME)
+      ->addRow(USER_GROUP_ADMIN, USER_GROUP_ADMIN_NAME);
 
     $queries[] = $sql->createTable("UserGroup")
       ->addInt("user_id")

+ 1 - 0
core/Documents/Install.class.php

@@ -331,6 +331,7 @@ namespace Documents\Install {
           ->returning("uid")
           ->execute()
           && $sql->insert("UserGroup", array("group_id", "user_id"))
+          ->addRow(USER_GROUP_DEFAULT, $sql->getLastInsertId())
           ->addRow(USER_GROUP_ADMIN, $sql->getLastInsertId())
           ->execute();
 

+ 1 - 2
core/Driver/SQL/MySQL.class.php

@@ -13,7 +13,6 @@ use \Driver\SQL\Column\DateTimeColumn;
 use Driver\SQL\Column\BoolColumn;
 use Driver\SQL\Column\JsonColumn;
 
-use Driver\SQL\Query\Insert;
 use Driver\SQL\Strategy\Strategy;
 use \Driver\SQL\Strategy\UpdateStrategy;
 
@@ -31,7 +30,7 @@ class MySQL extends SQL {
     return 'mysqli';
   }
 
-  // Connection Managment
+  // Connection Management
   public function connect() {
 
     if(!is_null($this->connection)) {

+ 1 - 6
core/Driver/SQL/PostgreSQL.class.php

@@ -4,7 +4,6 @@ namespace Driver\SQL;
 
 use \Api\Parameter\Parameter;
 
-use \Driver\SQL\Column\Column;
 use \Driver\SQL\Column\IntColumn;
 use \Driver\SQL\Column\SerialColumn;
 use \Driver\SQL\Column\StringColumn;
@@ -13,11 +12,7 @@ use \Driver\SQL\Column\DateTimeColumn;
 use Driver\SQL\Column\BoolColumn;
 use Driver\SQL\Column\JsonColumn;
 
-use \Driver\SQL\Strategy\CascadeStrategy;
-use \Driver\SQL\Strategy\SetDefaultStrategy;
-use \Driver\SQL\Strategy\SetNullStrategy;
 use Driver\SQL\Strategy\Strategy;
-use \Driver\SQL\Strategy\UpdateStrategy;
 
 class PostgreSQL extends SQL {
 
@@ -33,7 +28,7 @@ class PostgreSQL extends SQL {
     return 'pgsql';
   }
 
-  // Connection Managment
+  // Connection Management
   public function connect() {
     if(!is_null($this->connection)) {
       return true;

+ 11 - 1
core/Objects/User.class.php

@@ -19,6 +19,7 @@ class User extends ApiObject {
   private int $uid;
   private string $username;
   private Language $language;
+  private array $groups;
 
   public function __construct($configuration) {
     session_start();
@@ -52,6 +53,8 @@ class User extends ApiObject {
   public function setLanguage(Language $language) { $this->language = $language; $language->load(); }
   public function getSession() { return $this->session; }
   public function getConfiguration() { return $this->configuration; }
+  public function getGroups() { return $this->groups; }
+  public function hasGroup(int $group) { return isset($this->groups[$group]); }
 
   public function __debugInfo() {
     $debugInfo = array(
@@ -113,10 +116,12 @@ class User extends ApiObject {
   public function readData($userId, $sessionId, $sessionUpdate = true) {
 
     $res = $this->sql->select("User.name", "Language.uid as langId", "Language.code as langCode", "Language.name as langName",
-        "Session.data", "Session.stay_logged_in")
+        "Session.data", "Session.stay_logged_in", "Group.uid as groupId", "Group.name as groupName")
         ->from("User")
         ->innerJoin("Session", "Session.user_id", "User.uid")
         ->leftJoin("Language", "User.language_id", "Language.uid")
+        ->leftJoin("UserGroup", "UserGroup.user_id", "User.uid")
+        ->leftJoin("Group", "UserGroup.group_id", "Group.uid")
         ->where(new Compare("User.uid", $userId))
         ->where(new Compare("Session.uid", $sessionId))
         ->where(new Compare("Session.active", true))
@@ -136,9 +141,14 @@ class User extends ApiObject {
         $this->session->stayLoggedIn($row["stay_logged_in"]);
         if($sessionUpdate) $this->session->update();
         $this->loggedIn = true;
+
         if(!is_null($row['langId'])) {
           $this->setLanguage(Language::newInstance($row['langId'], $row['langCode'], $row['langName']));
         }
+
+        foreach($res as $row) {
+          $this->groups[$row["groupId"]] = $row["groupName"];
+        }
       }
     }
 

+ 11 - 0
core/constants.php

@@ -1,4 +1,15 @@
 <?php
 
 const USER_GROUP_DEFAULT = 1;
+const USER_GROUP_DEFAULT_NAME = "Default";
 const USER_GROUP_ADMIN = 2;
+const USER_GROUP_ADMIN_NAME = "Administrator";
+
+function GroupName($index) {
+  $groupNames = array(
+    USER_GROUP_DEFAULT => USER_GROUP_DEFAULT_NAME,
+    USER_GROUP_ADMIN => USER_GROUP_ADMIN_NAME,
+  );
+
+  return ($groupNames[$index] ?? "Unknown Group");
+}

+ 9 - 6
index.php

@@ -1,5 +1,9 @@
 <?php
 
+use Api\Request;
+use Documents\Document404;
+use Elements\Document;
+
 include_once 'core/core.php';
 include_once 'core/datetime.php';
 include_once 'core/constants.php';
@@ -37,9 +41,9 @@ if(isset($_GET["api"]) && is_string($_GET["api"])) {
       if(!file_exists($file)) {
         header("404 Not Found");
         $response = createError("Not found");
-      } else if(!is_subclass_of($class, \Api\Request::class)) {
+      } else if(!is_subclass_of($class, Request::class)) {
         header("400 Bad Request");
-        $response = createError("Inalid Method");
+        $response = createError("Invalid Method");
       } else {
         $request = new $class($user, true);
         $success = $request->execute();
@@ -69,8 +73,8 @@ if(isset($_GET["api"]) && is_string($_GET["api"])) {
     $documentName = str_replace("/", "\\", $documentName);
     $class = "\\Documents\\$documentName";
     $file = getClassPath($class);
-    if(!file_exists($file) || !is_subclass_of($class, \Elements\Document::class)) {
-      $document = new \Documents\Document404($user);
+    if(!file_exists($file) || !is_subclass_of($class, Document::class)) {
+      $document = new Document404($user);
     } else {
       $document = new $class($user);
     }
@@ -80,5 +84,4 @@ if(isset($_GET["api"]) && is_string($_GET["api"])) {
 }
 
 $user->sendCookies();
-die($response);
-?>
+die($response);