finished forum permission system
This commit is contained in:
parent
31f3652690
commit
57b1d9ce55
6 changed files with 35 additions and 158 deletions
|
@ -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>";
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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];
|
||||
|
|
142
app/Perms.php
142
app/Perms.php
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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];
|
||||
|
|
|
@ -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>
|
||||
|
|
Reference in a new issue