Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created UnityPerms Class #92

Merged
merged 5 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions resources/lib/UnityPerms.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

namespace UnityWebPortal\lib;

class UnityPerms
{
private $SQL;
private $USER;

public function __construct($SQL, $USER)
{
$this->SQL = $SQL;
$this->USER = $USER;
}

public function checkApproveUser($uid, $operated_on, $group)
{
if (!$this->USER->isInGroup($uid, $group)) {
return false;
}

$role = $this->SQL->getRole($uid, $group);

if ($this->SQL->hasPerm($role, 'unity.admin') || $this->SQL->hasPerm($role, 'unity.admin_no_grant')) {
return true;
}

if (!$this->SQL->hasPerm($role, 'unity.approve_user')) {
return false;
}

$operated_on_role = $this->SQL->getRole($operated_on, $group);

if ($this->SQL->getPriority($operated_on_role) >= $this->SQL->getPriority($role)) {
return false;
}

return true;
}

public function checkDenyUser($uid, $operated_on, $group)
{
if (!$this->USER->isInGroup($uid, $group)) {
return false;
}

$role = $this->SQL->getRole($uid, $group);

if ($this->SQL->hasPerm($role, 'unity.admin') || $this->SQL->hasPerm($role, 'unity.admin_no_grant')) {
return true;
}

if (!$this->SQL->hasPerm($role, 'unity.deny_user')) {
return false;
}

$operated_on_role = $this->SQL->getRole($operated_on, $group);

if ($this->SQL->getPriority($operated_on_role) >= $this->SQL->getPriority($role)) {
return false;
}

return true;
}

public function checkGrantRole($uid, $group, $role)
{
if (!$this->USER->isInGroup($uid, $group)) {
return false;
}

if (!$this->SQL->roleAvailableInGroup($uid, $group, $role)) {
return false;
}

$user_role = $this->SQL->getRole($uid, $group);

if ($this->SQL->hasPerm($user_role, 'unity.admin') || $this->SQL->hasPerm($user_role, 'unity.admin_no_grant')) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unity.admin_no_grant should not be able to grant the admin role, so you need a check here that doesn't return true if admin is the role trying to be granted.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added check

return true;
}

if (!$this->SQL->hasPerm($user_role, 'unity.grant_role')) {
return false;
}

$role_to_grant = $this->SQL->getRole($role, $group);

if ($this->SQL->getPriority($role_to_grant) >= $this->SQL->getPriority($user_role)) {
return false;
}

return true;
}

public function checkRevokeRole($uid, $group, $role)
{
if (!$this->USER->isInGroup($uid, $group)) {
return false;
}

if (!$this->SQL->roleAvailableInGroup($uid, $group, $role)) {
return false;
}

$user_role = $this->SQL->getRole($uid, $group);

if ($this->SQL->hasPerm($user_role, 'unity.admin') || $this->SQL->hasPerm($user_role, 'unity.admin_no_grant')) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, admin_no_grant should not be able to revoke admin roles.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

return true;
}

if (!$this->SQL->hasPerm($user_role, 'unity.revoke_role')) {
return false;
}

$role_to_revoke = $this->SQL->getRole($role, $group);

if ($this->SQL->getPriority($role_to_revoke) >= $this->SQL->getPriority($user_role)) {
return false;
}

return true;
}
}
72 changes: 72 additions & 0 deletions resources/lib/UnitySQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ class UnitySQL
private const TABLE_AUDIT_LOG = "audit_log";
private const TABLE_ACCOUNT_DELETION_REQUESTS = "account_deletion_requests";
private const TABLE_SITEVARS = "sitevars";
private const TABLE_GROUP_ROLES = "groupRoles";
private const TABLE_GROUP_TYPES = "groupTypes";
private const TABLE_GROUP_ROLE_ASSIGNMENTS = "groupRoleAssignments";
private const TABLE_GROUP_REQUESTS = "groupRequests";
private const TABLE_GROUP_JOIN_REQUESTS = "groupJoinRequests";


private const REQUEST_ADMIN = "admin";

Expand Down Expand Up @@ -299,4 +305,70 @@ public function updateSiteVar($name, $value)

$stmt->execute();
}

public function getRole($uid, $group)
{
$stmt = $this->conn->prepare(
"SELECT * FROM " . self::TABLE_GROUP_ROLE_ASSIGNMENTS . " WHERE user=:uid AND `group`=:group"
);
$stmt->bindParam(":uid", $uid);
$stmt->bindParam(":group", $group);

$stmt->execute();

return $stmt->fetchAll()[0]['role'];
}

public function hasPerm($role, $perm)
{
$stmt = $this->conn->prepare(
"SELECT * FROM " . self::TABLE_GROUP_ROLES . " WHERE slug=:role"
);
$stmt->bindParam(":role", $role);

$stmt->execute();

$row = $stmt->fetchAll()[0];
$perms = explode(",", $row['perms']);
return in_array($perm, $perms);
}

public function getPriority($role)
{
$stmt = $this->conn->prepare(
"SELECT * FROM " . self::TABLE_GROUP_ROLES . " WHERE slug=:role"
);
$stmt->bindParam(":role", $role);

$stmt->execute();

$row = $stmt->fetchAll()[0];
return $row['priority'];
}

public function roleAvailableInGroup($uid, $group, $role)
{
$stmt = $this->conn->prepare(
"SELECT * FROM " . self::TABLE_GROUP_ROLE_ASSIGNMENTS . " WHERE user=:uid AND `group`=:group"
);
$stmt->bindParam(":uid", $uid);
$stmt->bindParam(":group", $group);

$stmt->execute();
$row = $stmt->fetchAll()[0];

$group_slug = $row['group'];

$stmt = $this->conn->prepare(
"SELECT * FROM " . self::TABLE_GROUP_TYPES . " WHERE slug=:slug"
);

$stmt->bindParam(":slug", $group_slug);
$stmt->execute();

$row = $stmt->fetchAll()[0];
$roles = explode(",", $row['roles']);

return in_array($role, $roles);
}
}
18 changes: 18 additions & 0 deletions resources/lib/UnityUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -671,4 +671,22 @@ public function hasRequestedAccountDeletion()
{
return $this->SQL->accDeletionRequestExists($this->getUID());
}

/**
* Checks whether a user is in a group or not
*/

public function isInGroup($uid, $group)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if this method accepted both a string for $group, and the object itself. You can check the type of the variable and act accordingly using gettype() in php.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

{
$group = new UnityGroup(
$group,
$this->LDAP,
$this->SQL,
$this->MAILER,
$this->REDIS,
$this->WEBHOOK
);

return in_array($uid, $group->getGroupMemberUIDs());
}
}
140 changes: 137 additions & 3 deletions tools/docker-dev/sql/bootstrap.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Jul 11, 2023 at 04:05 PM
-- Server version: 10.3.37-MariaDB-0ubuntu0.20.04.1
-- PHP Version: 7.4.3-4ubuntu2.17
-- Generation Time: Jul 13, 2023 at 02:29 AM
-- Server version: 10.3.38-MariaDB-0ubuntu0.20.04.1
-- PHP Version: 7.4.3-4ubuntu2.19

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
Expand Down Expand Up @@ -65,6 +65,80 @@ CREATE TABLE `events` (

-- --------------------------------------------------------

--
-- Table structure for table `groupJoinRequests`
--

CREATE TABLE `groupJoinRequests` (
`id` int(11) NOT NULL,
`group_name` varchar(1000) NOT NULL,
`requestor` varchar(1000) NOT NULL,
`requested_on` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- --------------------------------------------------------

--
-- Table structure for table `groupRequests`
--

CREATE TABLE `groupRequests` (
`id` int(11) NOT NULL,
`group_type` varchar(1000) NOT NULL,
`group_name` varchar(1000) NOT NULL,
`requestor` varchar(1000) NOT NULL,
`requested_on` timestamp NOT NULL DEFAULT current_timestamp(),
`start_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`end_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- --------------------------------------------------------

--
-- Table structure for table `groupRoleAssignments`
--

CREATE TABLE `groupRoleAssignments` (
`id` int(11) NOT NULL,
`user` varchar(1000) NOT NULL,
`role` varchar(1000) NOT NULL,
`group` varchar(1000) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- --------------------------------------------------------

--
-- Table structure for table `groupRoles`
--

CREATE TABLE `groupRoles` (
`id` int(11) NOT NULL,
`name` varchar(1000) NOT NULL,
`slug` varchar(1000) NOT NULL,
`priority` int(11) NOT NULL,
`color` varchar(1000) NOT NULL,
`perms` varchar(1000) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- --------------------------------------------------------

--
-- Table structure for table `groupTypes`
--

CREATE TABLE `groupTypes` (
`id` int(11) NOT NULL,
`name` varchar(1000) NOT NULL,
`slug` varchar(1000) NOT NULL,
`color` varchar(1000) NOT NULL,
`time_limited` tinyint(1) NOT NULL,
`def_role` varchar(1000) NOT NULL,
`av_roles` varchar(1000) NOT NULL,
`can_request` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- --------------------------------------------------------

--
-- Table structure for table `notices`
--
Expand Down Expand Up @@ -166,6 +240,36 @@ ALTER TABLE `audit_log`
ALTER TABLE `events`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `groupJoinRequests`
--
ALTER TABLE `groupJoinRequests`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `groupRequests`
--
ALTER TABLE `groupRequests`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `groupRoleAssignments`
--
ALTER TABLE `groupRoleAssignments`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `groupRoles`
--
ALTER TABLE `groupRoles`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `groupTypes`
--
ALTER TABLE `groupTypes`
ADD PRIMARY KEY (`id`);

--
-- Indexes for table `notices`
--
Expand Down Expand Up @@ -218,6 +322,36 @@ ALTER TABLE `audit_log`
ALTER TABLE `events`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `groupJoinRequests`
--
ALTER TABLE `groupJoinRequests`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `groupRequests`
--
ALTER TABLE `groupRequests`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `groupRoleAssignments`
--
ALTER TABLE `groupRoleAssignments`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `groupRoles`
--
ALTER TABLE `groupRoles`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `groupTypes`
--
ALTER TABLE `groupTypes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `notices`
--
Expand Down