From 91bdf6aaf3cda52a43c35ce22f5e25537684cb56 Mon Sep 17 00:00:00 2001
From: Frederic Guillot <fred@kanboard.net>
Date: Fri, 27 Nov 2015 16:24:21 -0500
Subject: Add generic authorization class

---
 app/Auth/Database.php               | 49 --------------------
 app/Core/Security/AccessMap.php     | 92 +++++++++++++++++++++++++++++++++++++
 app/Core/Security/Authorization.php | 46 +++++++++++++++++++
 app/Core/Security/Role.php          | 21 +++++++++
 4 files changed, 159 insertions(+), 49 deletions(-)
 delete mode 100644 app/Auth/Database.php
 create mode 100644 app/Core/Security/AccessMap.php
 create mode 100644 app/Core/Security/Authorization.php
 create mode 100644 app/Core/Security/Role.php

(limited to 'app')

diff --git a/app/Auth/Database.php b/app/Auth/Database.php
deleted file mode 100644
index c2041d4d..00000000
--- a/app/Auth/Database.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-namespace Kanboard\Auth;
-
-use Kanboard\Core\Base;
-use Kanboard\Model\User;
-use Kanboard\Event\AuthEvent;
-
-/**
- * Database authentication
- *
- * @package  auth
- * @author   Frederic Guillot
- */
-class Database extends Base
-{
-    /**
-     * Backend name
-     *
-     * @var string
-     */
-    const AUTH_NAME = 'Database';
-
-    /**
-     * Authenticate a user
-     *
-     * @access public
-     * @param  string  $username  Username
-     * @param  string  $password  Password
-     * @return boolean
-     */
-    public function authenticate($username, $password)
-    {
-        $user = $this->db
-                    ->table(User::TABLE)
-                    ->eq('username', $username)
-                    ->eq('disable_login_form', 0)
-                    ->eq('is_ldap_user', 0)
-                    ->findOne();
-
-        if (is_array($user) && password_verify($password, $user['password'])) {
-            $this->userSession->initialize($user);
-            $this->container['dispatcher']->dispatch('auth.success', new AuthEvent(self::AUTH_NAME, $user['id']));
-            return true;
-        }
-
-        return false;
-    }
-}
diff --git a/app/Core/Security/AccessMap.php b/app/Core/Security/AccessMap.php
new file mode 100644
index 00000000..10a29e1f
--- /dev/null
+++ b/app/Core/Security/AccessMap.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace Kanboard\Core\Security;
+
+/**
+ * Access Map Definition
+ *
+ * @package  security
+ * @author   Frederic Guillot
+ */
+class AccessMap
+{
+    /**
+     * Default role
+     *
+     * @access private
+     * @var string
+     */
+    private $defaultRole = '';
+
+    /**
+     * Access map
+     *
+     * @access private
+     * @var array
+     */
+    private $map = array();
+
+    /**
+     * Define the default role when nothing match
+     *
+     * @access public
+     * @param  string $role
+     * @return Acl
+     */
+    public function setDefaultRole($role)
+    {
+        $this->defaultRole = $role;
+        return $this;
+    }
+
+    /**
+     * Add new access rules
+     *
+     * @access public
+     * @param  string $controller
+     * @param  string $method
+     * @param  array  $roles
+     * @return Acl
+     */
+    public function add($controller, $method, array $roles)
+    {
+        $controller = strtolower($controller);
+        $method = strtolower($method);
+
+        if (! isset($this->map[$controller])) {
+            $this->map[$controller] = array();
+        }
+
+        if (! isset($this->map[$controller][$method])) {
+            $this->map[$controller][$method] = array();
+        }
+
+        $this->map[$controller][$method] = $roles;
+
+        return $this;
+    }
+
+    /**
+     * Get roles that match the given controller/method
+     *
+     * @access public
+     * @param  string $controller
+     * @param  string $method
+     * @return boolean
+     */
+    public function getRoles($controller, $method)
+    {
+        $controller = strtolower($controller);
+        $method = strtolower($method);
+
+        if (isset($this->map[$controller][$method])) {
+            return $this->map[$controller][$method];
+        }
+
+        if (isset($this->map[$controller]['*'])) {
+            return $this->map[$controller]['*'];
+        }
+
+        return array($this->defaultRole);
+    }
+}
diff --git a/app/Core/Security/Authorization.php b/app/Core/Security/Authorization.php
new file mode 100644
index 00000000..a04b3720
--- /dev/null
+++ b/app/Core/Security/Authorization.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Kanboard\Core\Security;
+
+/**
+ * Authorization Handler
+ *
+ * @package  security
+ * @author   Frederic Guillot
+ */
+class Authorization
+{
+    /**
+     * Access Map
+     *
+     * @access private
+     * @var AccessMap
+     */
+    private $acl;
+
+    /**
+     * Constructor
+     *
+     * @access public
+     * @param  AccessMap  $acl
+     */
+    public function __construct(AccessMap $acl)
+    {
+        $this->acl = $acl;
+    }
+
+    /**
+     * Check if the given role is allowed to access to the specified resource
+     *
+     * @access public
+     * @param  string  $controller
+     * @param  string  $method
+     * @param  string  $role
+     * @return boolean
+     */
+    public function isAllowed($controller, $method, $role)
+    {
+        $roles = $this->acl->getRoles($controller, $method);
+        return in_array($role, $roles);
+    }
+}
diff --git a/app/Core/Security/Role.php b/app/Core/Security/Role.php
new file mode 100644
index 00000000..079ce14b
--- /dev/null
+++ b/app/Core/Security/Role.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Kanboard\Core\Security;
+
+/**
+ * Role Definitions
+ *
+ * @package  security
+ * @author   Frederic Guillot
+ */
+class Role
+{
+    const APP_ADMIN       = 'app-admin';
+    const APP_MANAGER     = 'app-manager';
+    const APP_USER        = 'app-user';
+    const APP_PUBLIC      = 'app-public';
+
+    const PROJECT_MANAGER = 'project-manager';
+    const PROJECT_MEMBER  = 'project-member';
+    const PROJECT_VIEWER  = 'project-viewer';
+}
-- 
cgit v1.2.3