finished forum permission system

This commit is contained in:
flash 2016-12-04 20:12:39 +01:00
parent 31f3652690
commit 57b1d9ce55
6 changed files with 35 additions and 158 deletions

View file

@ -8,6 +8,7 @@ namespace Sakura\BBCode\Tags;
use Sakura\BBCode\TagBase;
use Sakura\Forum\Forum;
use Sakura\Forum\ForumPerms;
use Sakura\Forum\Post;
use Sakura\User;
@ -35,8 +36,9 @@ class NamedQuote extends TagBase
if ($matches[1] === '#') {
$post = new Post(intval($matches[2]));
$forum = new Forum($post->forum);
$user_perms = new ForumPerms($forum, $poster);
if ($post->id !== 0 && $forum->perms->view) {
if ($post->id !== 0 && $user_perms->view) {
$link = route('forums.post', $post->id);
$quoting = "<a href='{$link}' style='color: {$post->poster->colour}' class='bbcode__quote-post'>{$post->poster->username}</a>";

View file

@ -244,11 +244,6 @@ class SetupCommand extends Command
'perm_edit' => true,
'perm_delete' => true,
],
[
'forum_id' => 3,
'rank_id' => config('rank.regular'),
'perm_view' => false,
],
[
'forum_id' => 1,
'rank_id' => config('rank.mod'),

View file

@ -6,8 +6,10 @@
namespace Sakura\Forum;
use Illuminate\Database\Query\Builder;
use Sakura\DB;
use Sakura\User;
use Traversable;
/**
* Forum permission handler.
@ -25,11 +27,25 @@ class ForumPerms
public function __construct(Forum $forum, User $user)
{
$this->forums = [0, $forum->id, $forum->category]; // make this inherit everything before release
$this->forums = iterator_to_array($this->getForumIds($forum->id));
$this->user = $user->id;
$this->ranks = array_keys($user->ranks);
}
public function getForumIds(int $id): Traversable
{
// yield the initial id
yield $id;
while ($id > 0) {
$id = DB::table('forums')
->where('forum_id', $id)
->value('forum_category');
yield $id;
}
}
public function __get(string $name): bool
{
return $this->check($name);
@ -55,15 +71,17 @@ class ForumPerms
if (!array_key_exists($name, $this->permCache)) {
$column = 'perm_' . camel_to_snake($name);
$result = array_column(DB::table(static::$table)
$result = DB::table(static::$table)
->whereIn('forum_id', $this->forums)
->where(function ($query) {
->where(function (Builder $query) {
$query->whereIn('rank_id', $this->ranks)
->orWhere('user_id', $this->user);
})
->get([$column]), $column);
->whereNotNull($column)
->groupBy($column)
->min($column);
$this->permCache[$name] = !in_array('0', $result, true) && in_array('1', $result, true);
$this->permCache[$name] = intval($result) === 1;
}
return $this->permCache[$name];

View file

@ -1,142 +0,0 @@
<?php
/**
* Holds the old permissions handler, only still here for reference while fixing the forum permission backend.
* @package Sakura
*/
namespace Sakura;
/**
* Old permissions handler.
* @package Sakura
* @author Julian van de Groep <me@flash.moe>
*/
class Perms
{
/**
* FORUM permission mode, used per forum.
*/
const FORUM = 'forum_permissions\forum_perms';
/**
* The table containing the permissions.
* @var string
*/
protected $table = '';
/**
* The column containing the permissions.
* @var string
*/
protected $column = '';
/**
* Constructor.
* @param string $mode
*/
public function __construct($mode)
{
$this->mode($mode);
}
/**
* Set a permission mode.
* @param string $mode
*/
public function mode($mode)
{
// Split the mode variable
$mode = explode('\\', $mode);
// Assign $table, $column and $selectors
$this->table = $mode[0];
$this->column = $mode[1];
}
/**
* Compare a permission flag.
* @param int $flag
* @param int $perm
* @return bool
*/
public function check($flag, $perm)
{
return ($flag & $perm) > 0;
}
/**
* Get the permissions from a rank.
* @param int $rid
* @param array $conditions
* @param int $perm
* @return int
*/
public function rank($rid, $conditions = [], $perm = 0)
{
// Build statement
$get = DB::table($this->table)
->where('rank_id', $rid)
->where('user_id', 0);
// Append additional conditionals (DBWrapper v1 format, except OR is ignored)
foreach ($conditions as $column => $value) {
$get->where($column, $value[1], $value[0]);
}
// Fetch from the db
$get = $get->first();
// Check if anything was returned
if ($get) {
if (property_exists($get, $this->column) && $get->rank_id) {
// Perform a bitwise OR
$perm = $perm | bindec((string) $get->{$this->column});
}
}
// Return the value
return $perm;
}
/**
* Get the permissions from a user.
* @param int $uid
* @param array $conditions
* @param int $perm
* @return int
*/
public function user($uid, $conditions = [], $perm = 0)
{
// Create a user object
$user = User::construct($uid);
// Get data from ranks
foreach (array_keys($user->ranks) as $rank) {
$perm = $perm | $this->rank($rank, $conditions, $perm);
}
// Build statement
$get = DB::table($this->table)
->where('rank_id', 0)
->where('user_id', $uid);
// Append additional conditionals (DBWrapper v1 format, except OR is ignored)
foreach ($conditions as $column => $value) {
$get->where($column, $value[1], $value[0]);
}
// Fetch from the db
$get = $get->first();
// Check if anything was returned
if ($get) {
if (property_exists($get, $this->column) && $get->user_id) {
// Perform a bitwise OR
$perm = $perm | bindec((string) $get->{$this->column});
}
}
// Return the value
return $perm;
}
}

View file

@ -6,6 +6,8 @@
namespace Sakura;
use Illuminate\Database\Query\Builder;
/**
* User permission handler.
* @package Sakura
@ -50,14 +52,16 @@ class UserPerms
if (!array_key_exists($name, $this->permCache)) {
$column = 'perm_' . camel_to_snake($name);
$result = array_column(DB::table(static::$table)
->where(function ($query) {
$result = DB::table(static::$table)
->where(function (Builder $query) {
$query->whereIn('rank_id', $this->ranks)
->orWhere('user_id', $this->user);
})
->get([$column]), $column);
->whereNotNull($column)
->groupBy($column)
->min($column);
$this->permCache[$name] = !in_array('0', $result, true) && in_array('1', $result, true);
$this->permCache[$name] = intval($result) === 1;
}
return $this->permCache[$name];

View file

@ -4,7 +4,7 @@
{% block content %}
<div class="auth content content--auth">
{% if not config('user.disable_registration') %}
{% if config('user.disable_registration') %}
<div class="fa fa-remove fa-5x auth__blocked"></div>
<h1>Registration is disabled.</h1>
<p>Please try again later.</p>