Safety-related privileges; internals
This commit is contained in:
parent
bc01fd7dce
commit
bb9ab81fed
12 changed files with 99 additions and 40 deletions
|
@ -28,5 +28,12 @@ Kind regards,
|
|||
|
||||
[privileges]
|
||||
uploadPost=registered
|
||||
viewPost=anonymous
|
||||
viewPost.sketchy=registered
|
||||
viewPost.unsafe=registered
|
||||
listPosts=anonymous
|
||||
listPosts.sketchy=registered
|
||||
listPosts.unsafe=registered
|
||||
listUsers=registered
|
||||
listComments=registered
|
||||
retrievePost=anonymous
|
||||
|
|
|
@ -34,7 +34,8 @@ class PostController
|
|||
$params[':limit'] = 20;
|
||||
$params[':offset'] = ($page - 1) * $params[':limit'];
|
||||
|
||||
//todo safety
|
||||
//todo safety [user choice]
|
||||
//todo safety [user privileges]
|
||||
//todo construct WHERE based on filters
|
||||
$whereSql = '';
|
||||
|
||||
|
@ -138,8 +139,8 @@ class PostController
|
|||
if (!$post)
|
||||
throw new SimpleException('Invalid post ID "' . $id . '"');
|
||||
|
||||
//todo: verify access rank...?
|
||||
//todo: verify sketchy, nsfw, sfw
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost);
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
|
||||
|
||||
$this->context->subTitle = 'showing @' . $post->id;
|
||||
$this->context->transport->post = $post;
|
||||
|
@ -147,9 +148,9 @@ class PostController
|
|||
|
||||
/**
|
||||
* Action that renders the requested file itself and sends it to user.
|
||||
* @route /post/send/{name}
|
||||
* @route /post/retrieve/{name}
|
||||
*/
|
||||
public function sendAction($name)
|
||||
public function retrieveAction($name)
|
||||
{
|
||||
$this->context->layoutName = 'layout-file';
|
||||
|
||||
|
@ -157,10 +158,8 @@ class PostController
|
|||
if (!$post)
|
||||
throw new SimpleException('Invalid post name "' . $name . '"');
|
||||
|
||||
//I guess access rank shouldn't be verified here. If someone arrives
|
||||
//here, they already know the full name of the post (not just the ID)
|
||||
//either by visiting the HTML container page or by having hotlink.
|
||||
//Such users should be trusted.
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::RetrievePost);
|
||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::RetrievePost, PostSafety::toString($post->safety));
|
||||
|
||||
$path = $this->config->main->filesPath . DIRECTORY_SEPARATOR . $post->name;
|
||||
if (!file_exists($path))
|
||||
|
|
10
src/Enum.php
Normal file
10
src/Enum.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
class Enum
|
||||
{
|
||||
public static function toString($constant)
|
||||
{
|
||||
$cls = new ReflectionClass(get_called_class());
|
||||
$constants = $cls->getConstants();
|
||||
return array_search($constant, $constants);
|
||||
}
|
||||
}
|
|
@ -5,26 +5,45 @@ class PrivilegesHelper
|
|||
|
||||
public static function init()
|
||||
{
|
||||
$privileges = \Chibi\Registry::getConfig()->privileges;
|
||||
foreach ($privileges as $privilegeName => $minAccessRankName)
|
||||
self::$privileges = [];
|
||||
foreach (\Chibi\Registry::getConfig()->privileges as $key => $minAccessRankName)
|
||||
{
|
||||
$privilege = TextHelper::resolveConstant($privilegeName, 'Privilege');
|
||||
if (strpos($key, '.') === false)
|
||||
$key .= '.';
|
||||
list ($privilegeName, $flag) = explode('.', $key);
|
||||
$privilegeName = TextHelper::camelCaseToKebabCase($privilegeName);
|
||||
$flag = TextHelper::camelCaseToKebabCase($flag);
|
||||
$key = rtrim($privilegeName . '.' . $flag, '.');
|
||||
|
||||
$minAccessRank = TextHelper::resolveConstant($minAccessRankName, 'AccessRank');
|
||||
self::$privileges[$privilege] = $minAccessRank;
|
||||
self::$privileges[$key] = $minAccessRank;
|
||||
}
|
||||
}
|
||||
|
||||
public static function confirm($user, $privilege)
|
||||
public static function confirm($user, $privilege, $flag = null)
|
||||
{
|
||||
$minAccessRank = isset(self::$privileges[$privilege])
|
||||
? self::$privileges[$privilege]
|
||||
: AccessRank::Admin;
|
||||
$minAccessRank = AccessRank::Admin;
|
||||
|
||||
$key = TextHelper::camelCaseToKebabCase(Privilege::toString($privilege));
|
||||
if (isset(self::$privileges[$key]))
|
||||
{
|
||||
$minAccessRank = self::$privileges[$key];
|
||||
}
|
||||
if ($flag != null)
|
||||
{
|
||||
$key2 = $key . '.' . strtolower($flag);
|
||||
if (isset(self::$privileges[$key2]))
|
||||
{
|
||||
$minAccessRank = self::$privileges[$key2];
|
||||
}
|
||||
}
|
||||
|
||||
return intval($user->access_rank) >= $minAccessRank;
|
||||
}
|
||||
|
||||
public static function confirmWithException($user, $privilege)
|
||||
public static function confirmWithException($user, $privilege, $flag = null)
|
||||
{
|
||||
if (!self::confirm($user, $privilege))
|
||||
if (!self::confirm($user, $privilege, $flag))
|
||||
{
|
||||
throw new SimpleException('Insufficient privileges');
|
||||
}
|
||||
|
|
|
@ -17,13 +17,29 @@ class TextHelper
|
|||
return $text;
|
||||
}
|
||||
|
||||
public static function kebabCaseToCamelCase($string)
|
||||
{
|
||||
$string = preg_split('/-/', $string);
|
||||
$string = array_map('trim', $string);
|
||||
$string = array_map('ucfirst', $string);
|
||||
$string = join('', $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
public static function camelCaseToKebabCase($string)
|
||||
{
|
||||
$string = preg_replace_callback('/[A-Z]/', function($x)
|
||||
{
|
||||
return '-' . strtolower($x[0]);
|
||||
}, $string);
|
||||
$string = trim($string, '-');
|
||||
return $string;
|
||||
}
|
||||
|
||||
public static function resolveConstant($constantName, $className = null)
|
||||
{
|
||||
$constantName = self::kebabCaseToCamelCase($constantName);
|
||||
//convert from kebab-case to CamelCase
|
||||
$constantName = preg_split('/-/', $constantName);
|
||||
$constantName = array_map('trim', $constantName);
|
||||
$constantName = array_map('ucfirst', $constantName);
|
||||
$constantName = join('', $constantName);
|
||||
if ($className !== null)
|
||||
{
|
||||
$constantName = $className . '::' . $constantName;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
class AccessRank
|
||||
class AccessRank extends Enum
|
||||
{
|
||||
const Anonymous = 0;
|
||||
const Registered = 1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
class PostSafety
|
||||
class PostSafety extends Enum
|
||||
{
|
||||
const Safe = 1;
|
||||
const Sketchy = 2;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
class PostType
|
||||
class PostType extends Enum
|
||||
{
|
||||
const Image = 1;
|
||||
const Flash = 2;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
class Privilege
|
||||
class Privilege extends Enum
|
||||
{
|
||||
const UploadPost = 1;
|
||||
const ListPosts = 2;
|
||||
const ListUsers = 3;
|
||||
const ListPosts = 1;
|
||||
const UploadPost = 2;
|
||||
const ViewPost = 3;
|
||||
const RetrievePost = 4;
|
||||
const ListUsers = 5;
|
||||
const ListComments = 6;
|
||||
}
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
$nav = [];
|
||||
|
||||
$nav []= ['Home', \Chibi\UrlHelper::route('index', 'index')];
|
||||
if (PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts))
|
||||
$nav []= ['Browse', \Chibi\UrlHelper::route('post', 'list')];
|
||||
|
||||
if (PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts))
|
||||
{
|
||||
if (PrivilegesHelper::confirm($this->context->user, Privilege::ListComments))
|
||||
$nav []= ['Comments', \Chibi\UrlHelper::route('comment', 'list')];
|
||||
|
||||
if (PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts))
|
||||
$nav []= ['Favorites', \Chibi\UrlHelper::route('post', 'favorites')];
|
||||
}
|
||||
|
||||
if (PrivilegesHelper::confirm($this->context->user, Privilege::UploadPost))
|
||||
$nav []= ['Upload', \Chibi\UrlHelper::route('post', 'upload')];
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<?php if (!empty($this->context->transport->errorMessage)): ?>
|
||||
<p class="alert alert-error"><?php echo $this->context->transport->errorMessage ?></p>
|
||||
<?php else: ?>
|
||||
<?php foreach ($this->context->transport->posts as $post): ?>
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $post->id]) ?>">
|
||||
Post <?php echo $post->id; ?>
|
||||
</a>
|
||||
<?php endforeach ?>
|
||||
<?php endif ?>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php if (!empty($this->context->transport->errorMessage)): ?>
|
||||
<p class="alert alert-error"><?php echo $this->context->transport->errorMessage ?></p>
|
||||
<?php else: ?>
|
||||
<img src="<?php echo \Chibi\UrlHelper::route('post', 'send', ['name' => $this->context->transport->post->name]) ?>" alt="<?php echo $this->context->transport->post->name ?>"/>
|
||||
<img src="<?php echo \Chibi\UrlHelper::route('post', 'retrieve', ['name' => $this->context->transport->post->name]) ?>" alt="<?php echo $this->context->transport->post->name ?>"/>
|
||||
<?php endif ?>
|
||||
|
|
Loading…
Reference in a new issue