AlexWebDevelop

RBAC class

Feb 11th, 2019
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.90 KB | None | 0 0
  1. <?php
  2.  
  3. /*  ROLE-BASED ACCESS CONTROL CLASS */
  4.  
  5.  
  6. /**
  7.  *  Database tables. Copy/paste the SQL code to create the tables on your own database.
  8.  */
  9.  
  10.  
  11. /* Accounts table. */
  12. /*
  13. CREATE TABLE `accounts` (
  14.   `account_id` int(11) NOT NULL,
  15.   `account_name` varchar(128) NOT NULL,
  16.   `account_pwd` varchar(128) NOT NULL
  17. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  18.  
  19. ALTER TABLE `accounts`
  20.   ADD PRIMARY KEY (`account_id`),
  21.   ADD UNIQUE KEY `account_name` (`account_name`);
  22.  
  23. ALTER TABLE `accounts`
  24.   MODIFY `account_id` int(11) NOT NULL AUTO_INCREMENT;
  25. */
  26.  
  27. /* Roles table. */
  28. /*
  29. CREATE TABLE `roles` (
  30.   `role_id` int(10) UNSIGNED NOT NULL,
  31.   `role_name` varchar(128) NOT NULL,
  32.   `role_desc` varchar(128) NOT NULL
  33. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  34.  
  35. ALTER TABLE `roles`
  36.   ADD PRIMARY KEY (`role_id`),
  37.   ADD UNIQUE KEY `role_name` (`role_name`);
  38.  
  39. ALTER TABLE `roles`
  40.   MODIFY `role_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
  41. */
  42.  
  43. /* Account-roles relation table. */
  44. /*
  45.  CREATE TABLE `account_roles` (
  46.   `ar_id` int(10) UNSIGNED NOT NULL,
  47.   `ar_account_id` int(10) UNSIGNED NOT NULL,
  48.   `ar_role_id` int(10) UNSIGNED NOT NULL
  49. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  50.  
  51. ALTER TABLE `account_roles`
  52.   ADD PRIMARY KEY (`ar_id`),
  53.   ADD UNIQUE KEY `ar_account_id` (`ar_account_id`,`ar_role_id`);
  54.  
  55. ALTER TABLE `account_roles`
  56.   MODIFY `ar_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
  57. */
  58.  
  59. /* Permissions table. */
  60. /*
  61. CREATE TABLE `permissions` (
  62.   `permission_id` int(10) UNSIGNED NOT NULL,
  63.   `permission_name` varchar(128) NOT NULL,
  64.   `permission_desc` varchar(128) NOT NULL
  65. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  66.  
  67. ALTER TABLE `permissions`
  68.   ADD PRIMARY KEY (`permission_id`),
  69.   ADD UNIQUE KEY `permission_name` (`permission_name`);
  70.  
  71. ALTER TABLE `permissions`
  72.   MODIFY `permission_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
  73. */
  74.  
  75. /* Role-permissions relation table. */
  76. /*
  77.  CREATE TABLE `role_permissions` (
  78.   `rp_id` int(10) UNSIGNED NOT NULL,
  79.   `rp_role_id` int(10) UNSIGNED NOT NULL,
  80.   `rp_permission_id` int(10) UNSIGNED NOT NULL
  81. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  82.  
  83. ALTER TABLE `role_permissions`
  84.   ADD PRIMARY KEY (`rp_id`),
  85.   ADD UNIQUE KEY `rp_role_id` (`rp_role_id`,`rp_permission_id`);
  86.  
  87. ALTER TABLE `role_permissions`
  88.   MODIFY `rp_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
  89. */
  90.  
  91.  
  92.  
  93. /* Class. */
  94. class RBAC
  95. {
  96.      /* PDO object for class database operations. */
  97.     private $db;
  98.    
  99.    
  100.     /* Constructor. Takes a PDO resource link as argument. */
  101.     public function __construct(PDO &$db)
  102.     {
  103.          $this->db = $db;
  104.     }
  105.  
  106.     /* Destructor. */
  107.     public function __destruct() {}
  108.    
  109.    
  110.     /**
  111.      *  ROLES-RELATED FUNCTIONS
  112.      */
  113.    
  114.     /* Add a new role. Returns the new role ID or 0 if the name already exists. */
  115.     public function addRole(string $name, string $desc = ''): int
  116.     {
  117.         $ret = 0;
  118.        
  119.         /* Query to check whether a role with the same name exists. */
  120.         $check_query = 'SELECT * FROM roles WHERE (role_name = :name)';
  121.         $check_params = array(':name' => $name);
  122.        
  123.         try
  124.         {
  125.             $check_res = $this->db->prepare($check_query);
  126.             $check_res->execute($check_params);
  127.         }
  128.         catch (PDOException $e)
  129.         {
  130.             $this->pdo_exception($e);
  131.         }
  132.        
  133.         if (!is_array($check_res->fetch()))
  134.         {
  135.             /* A role with the same name does not exist; we can add one. */
  136.            
  137.             $add_query = 'INSERT INTO roles (role_name, role_desc) VALUES (:name, :desc)';
  138.             $add_params = array(':name' => $name, ':desc' => $desc);
  139.            
  140.             try
  141.             {
  142.                 $add_res = $this->db->prepare($add_query);
  143.                 $add_res->execute($add_params);
  144.             }
  145.             catch (PDOException $e)
  146.             {
  147.                 $this->pdo_exception($e);
  148.             }
  149.            
  150.             $ret = $this->getRoleId($name);
  151.         }
  152.        
  153.         return $ret;
  154.     }
  155.    
  156.     /* Deletes a role from the database. */
  157.     public function deleteRole(int $role_id)
  158.     {
  159.         $query = 'DELETE FROM roles WHERE (role_id = :role_id) LIMIT 1';
  160.         $params = array(':role_id' => $role_id);
  161.        
  162.         $res = $this->db->prepare($query);
  163.         $res->execute($params);
  164.     }
  165.    
  166.     /* Returns a role ID by its name, or 0 if no role with that name exists. */
  167.     public function getRoleId(string $name): int
  168.     {
  169.         $id = 0;
  170.        
  171.         $query = 'SELECT * FROM roles WHERE (role_name = :name)';
  172.         $params = array(':name' => $name);
  173.        
  174.         $res = $this->db->prepare($query);
  175.         $res->execute($params);
  176.        
  177.         if (is_array($row = $res->fetch(PDO::FETCH_ASSOC)))
  178.         {
  179.             $id = intval($row['role_id'], 10);
  180.         }
  181.        
  182.         return $id;
  183.     }
  184.    
  185.     /* Returns an array with a role info. */
  186.     public function getRoleInfo(int $role_id): array
  187.     {
  188.         $info =
  189.         [
  190.             'id' => NULL,
  191.             'name' => NULL,
  192.             'desc' => NULL
  193.         ];
  194.        
  195.         $query = 'SELECT * FROM roles WHERE (role_id = :role_id)';
  196.         $params = array(':role_id' => $role_id);
  197.        
  198.         $res = $this->db->prepare($query);
  199.         $res->execute($params);
  200.        
  201.         if (is_array($row = $res->fetch(PDO::FETCH_ASSOC)))
  202.         {
  203.             $info['id'] = $role_id;
  204.             $info['name'] = $row['role_name'];
  205.             $info['desc'] = $row['role_desc'];
  206.         }
  207.        
  208.         return $info;
  209.     }
  210.    
  211.     /* Edits a role info from its ID. */
  212.     public function editRoleInfo(int $role_id, string $name, string $desc)
  213.     {
  214.         $query = 'UPDATE roles SET role_name = :name, role_desc = :desc WHERE (role_id = :role_id) LIMIT 1';
  215.         $params = array(':name' => $name, ':desc' => $desc, ':role_id' => $role_id);
  216.        
  217.         $res = $this->db->prepare($query);
  218.         $res->execute($params);
  219.     }
  220.    
  221.     /* Adds a role to an account. */
  222.     public function addAccountRole(int $account_id, int $role_id)
  223.     {
  224.         $query = 'REPLACE INTO account_roles (ar_account_id, ar_role_id) VALUES (:account_id, :role_id)';
  225.         $params = array(':account_id' => $account_id, ':role_id' => $role_id);
  226.        
  227.         $res = $this->db->prepare($query);
  228.         $res->execute($params);
  229.     }
  230.    
  231.     /* Removes a role from an account. */
  232.     public function deleteAccountRole(int $account_id, int $role_id)
  233.     {
  234.         $query = 'DELETE FROM account_roles WHERE (ar_account_id = :account_id) AND (ar_role_id = :role_id) LIMIT 1';
  235.         $params = array(':account_id' => $account_id, ':role_id' => $role_id);
  236.        
  237.         $res = $this->db->prepare($query);
  238.         $res->execute($params);
  239.     }
  240.    
  241.     /* Returns an array of role IDs for a specific account. */
  242.     public function getAccountRoles(int $account_id): array
  243.     {
  244.         $roles = array();
  245.        
  246.         $query = 'SELECT * FROM account_roles WHERE (ar_account_id = :account_id)';
  247.         $params = array(':account_id' => $account_id);
  248.        
  249.         try
  250.         {
  251.             $res = $this->db->prepare($query);
  252.             $res->execute($params);
  253.         }
  254.         catch (PDOException $e)
  255.         {
  256.             $this->pdo_exception($e);
  257.         }
  258.        
  259.         while (is_array($row = $res->fetch(PDO::FETCH_ASSOC)))
  260.         {
  261.             $roles[] = $row['role_id'];
  262.         }
  263.        
  264.         return $roles;
  265.     }
  266.    
  267.    
  268.      /**
  269.      *  PERMISSIONS-RELATED FUNCTIONS
  270.      */
  271.    
  272.     /* Add a new permission. Returns the new permission ID or 0 if the name already exists. */
  273.     public function addPermission(string $name, string $desc = ''): int
  274.     {
  275.         $ret = 0;
  276.        
  277.         /* Query to check whether a permission with the same name exists. */
  278.         $check_query = 'SELECT * FROM permissions WHERE (permission_name = :name)';
  279.         $check_params = array(':name' => $name);
  280.        
  281.         try
  282.         {
  283.             $check_res = $this->db->prepare($check_query);
  284.             $check_res->execute($check_params);
  285.         }
  286.         catch (PDOException $e)
  287.         {
  288.             $this->pdo_exception($e);
  289.         }
  290.        
  291.         if (!is_array($check_res->fetch()))
  292.         {
  293.             /* A permission with the same name does not exist; we can add one. */
  294.            
  295.             $add_query = 'INSERT INTO permissions (permission_name, permission_desc) VALUES (:name, :desc)';
  296.             $add_params = array(':name' => $name, ':desc' => $desc);
  297.            
  298.             try
  299.             {
  300.                 $add_res = $this->db->prepare($add_query);
  301.                 $add_res->execute($add_params);
  302.             }
  303.             catch (PDOException $e)
  304.             {
  305.                 $this->pdo_exception($e);
  306.             }
  307.            
  308.             $ret = $this->getPermissionId($name);
  309.         }
  310.        
  311.         return $ret;
  312.     }
  313.    
  314.     /* Deletes a permission from the database. */
  315.     public function deletePermission(int $permission_id)
  316.     {
  317.         $query = 'DELETE FROM permissions WHERE (permission_id = :permission_id) LIMIT 1';
  318.         $params = array(':permission_id' => $permission_id);
  319.        
  320.         $res = $this->db->prepare($query);
  321.         $res->execute($params);
  322.     }
  323.    
  324.     /* Returns a permission ID by its name, or 0 if no permission with that name exists. */
  325.     public function getPermissionId(string $name): int
  326.     {
  327.         $id = 0;
  328.        
  329.         $query = 'SELECT * FROM permissions WHERE (permission_name = :name)';
  330.         $params = array(':name' => $name);
  331.        
  332.         $res = $this->db->prepare($query);
  333.         $res->execute($params);
  334.        
  335.         if (is_array($row = $res->fetch(PDO::FETCH_ASSOC)))
  336.         {
  337.             $id = intval($row['permission_id'], 10);
  338.         }
  339.        
  340.         return $id;
  341.     }
  342.    
  343.     /* Returns an array with a permission info. */
  344.     public function getPermissionInfo(int $permission_id): array
  345.     {
  346.         $info =
  347.         [
  348.             'id' => NULL,
  349.             'name' => NULL,
  350.             'desc' => NULL
  351.         ];
  352.        
  353.         $query = 'SELECT * FROM permissions WHERE (permission_id = :permission_id)';
  354.         $params = array(':permission_id' => $permission_id);
  355.        
  356.         $res = $this->db->prepare($query);
  357.         $res->execute($params);
  358.        
  359.         if (is_array($row = $res->fetch(PDO::FETCH_ASSOC)))
  360.         {
  361.             $info['id'] = $permission_id;
  362.             $info['name'] = $row['permission_name'];
  363.             $info['desc'] = $row['permission_desc'];
  364.         }
  365.        
  366.         return $info;
  367.     }
  368.    
  369.     /* Edits a permission info from its ID. */
  370.     public function editPermissionInfo(int $permission_id, string $name, string $desc)
  371.     {
  372.         $query = 'UPDATE permissions SET permission_name = :name, permission_desc = :desc WHERE (permission_id = :permission_id) LIMIT 1';
  373.         $params = array(':name' => $name, ':desc' => $desc, ':permission_id' => $permission_id);
  374.        
  375.         $res = $this->db->prepare($query);
  376.         $res->execute($params);
  377.     }
  378.    
  379.     /* Adds a permission to an role. */
  380.     public function addRolePermission(int $role_id, int $permission_id)
  381.     {
  382.         $query = 'REPLACE INTO role_permissions (rp_role_id, rp_permission_id) VALUES (:role_id, :permission_id)';
  383.         $params = array(':role_id' => $role_id, ':permission_id' => $permission_id);
  384.        
  385.         $res = $this->db->prepare($query);
  386.         $res->execute($params);
  387.     }
  388.    
  389.     /* Removes a permission from an role. */
  390.     public function deleteRolePermission(int $role_id, int $permission_id)
  391.     {
  392.         $query = 'DELETE FROM role_permissions WHERE (rp_role_id = :role_id) AND (rp_permission_id = :permission_id) LIMIT 1';
  393.         $params = array(':role_id' => $role_id, ':permission_id' => $permission_id);
  394.        
  395.         $res = $this->db->prepare($query);
  396.         $res->execute($params);
  397.     }
  398.    
  399.     /* Returns an array of permission IDs for a specific role. */
  400.     public function getRolePermissions(int $role_id): array
  401.     {
  402.         $permissions = array();
  403.        
  404.         $query = 'SELECT * FROM role_permissions WHERE (rp_role_id = :role_id)';
  405.         $params = array(':role_id' => $role_id);
  406.        
  407.         try
  408.         {
  409.             $res = $this->db->prepare($query);
  410.             $res->execute($params);
  411.         }
  412.         catch (PDOException $e)
  413.         {
  414.             $this->pdo_exception($e);
  415.         }
  416.        
  417.         while (is_array($row = $res->fetch(PDO::FETCH_ASSOC)))
  418.         {
  419.             $permissions[] = $row['permission_id'];
  420.         }
  421.        
  422.         return $permissions;
  423.     }
  424.    
  425.    
  426.     /**
  427.      *  ACCOUNT-RELATED FUNCTIONS
  428.      */
  429.    
  430.    /* Returns true if a specific account has a specific role. */
  431.    public function accountHasRole(int $account_id, int $role_id)
  432.    {
  433.        $ret = FALSE;
  434.        
  435.        $account_roles = $this->getAccountRoles($account_id);
  436.        
  437.        if (in_array($role_id, $account_roles))
  438.        {
  439.            $ret = TRUE;
  440.        }
  441.        
  442.        return $ret;
  443.    }
  444.    
  445.    /* Returns true if a specific account has a specific permission. */
  446.    public function accountHasPermission(int $account_id, int $permission_id)
  447.    {
  448.        $ret = FALSE;
  449.        
  450.        $account_roles = $this->getAccountRoles($account_id);
  451.        
  452.        foreach ($account_roles as $role_id)
  453.        {
  454.            $role_permissions = $this->getRolePermissions($role_id);
  455.            
  456.            if (in_array($permission_id, $role_permissions))
  457.            {
  458.                $ret = TRUE;
  459.                break 1;
  460.            }
  461.        }
  462.        
  463.        return $ret;
  464.    }
  465.    
  466.    
  467.    /*
  468.    * PRIVATE FUNCTIONS
  469.    */
  470.    
  471.     /* Function for handling database exceptions. */
  472.     private function pdo_exception(PDOException $e)
  473.     {
  474.         echo 'PDO exception. Error message: "' . $e->getMessage() . '". Error code: ' . strval($e->getCode()) . '.';
  475.         die();
  476.     }
  477. }
Add Comment
Please, Sign In to add comment