From bb9ab81fed543ae3f60b7b370c7a98cae9550ad6 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 7 Oct 2013 23:17:33 +0200 Subject: [PATCH] Safety-related privileges; internals --- config.ini | 7 ++++++ src/Controllers/PostController.php | 17 ++++++------- src/Enum.php | 10 ++++++++ src/Helpers/PrivilegesHelper.php | 39 ++++++++++++++++++++++-------- src/Helpers/TextHelper.php | 24 +++++++++++++++--- src/Models/AccessRank.php | 2 +- src/Models/PostSafety.php | 2 +- src/Models/PostType.php | 2 +- src/Models/Privilege.php | 11 ++++++--- src/Views/layout-normal.phtml | 9 ++++--- src/Views/post-list.phtml | 14 +++++++---- src/Views/post-view.phtml | 2 +- 12 files changed, 99 insertions(+), 40 deletions(-) create mode 100644 src/Enum.php diff --git a/config.ini b/config.ini index 248663aa..3f7f7be9 100644 --- a/config.ini +++ b/config.ini @@ -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 diff --git a/src/Controllers/PostController.php b/src/Controllers/PostController.php index ab5f1da2..238be13e 100644 --- a/src/Controllers/PostController.php +++ b/src/Controllers/PostController.php @@ -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)) diff --git a/src/Enum.php b/src/Enum.php new file mode 100644 index 00000000..fed2f980 --- /dev/null +++ b/src/Enum.php @@ -0,0 +1,10 @@ +getConstants(); + return array_search($constant, $constants); + } +} diff --git a/src/Helpers/PrivilegesHelper.php b/src/Helpers/PrivilegesHelper.php index 99afcc26..74bac2bc 100644 --- a/src/Helpers/PrivilegesHelper.php +++ b/src/Helpers/PrivilegesHelper.php @@ -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'); } diff --git a/src/Helpers/TextHelper.php b/src/Helpers/TextHelper.php index 6f74b16f..f8915a8b 100644 --- a/src/Helpers/TextHelper.php +++ b/src/Helpers/TextHelper.php @@ -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; diff --git a/src/Models/AccessRank.php b/src/Models/AccessRank.php index 9f158e0e..e00cdff7 100644 --- a/src/Models/AccessRank.php +++ b/src/Models/AccessRank.php @@ -1,5 +1,5 @@ context->user, Privilege::ListPosts)) + $nav []= ['Browse', \Chibi\UrlHelper::route('post', 'list')]; + + if (PrivilegesHelper::confirm($this->context->user, Privilege::ListComments)) + $nav []= ['Comments', \Chibi\UrlHelper::route('comment', 'list')]; if (PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts)) - { - $nav []= ['Comments', \Chibi\UrlHelper::route('comment', 'list')]; $nav []= ['Favorites', \Chibi\UrlHelper::route('post', 'favorites')]; - } if (PrivilegesHelper::confirm($this->context->user, Privilege::UploadPost)) $nav []= ['Upload', \Chibi\UrlHelper::route('post', 'upload')]; diff --git a/src/Views/post-list.phtml b/src/Views/post-list.phtml index d910acd3..bfec607c 100644 --- a/src/Views/post-list.phtml +++ b/src/Views/post-list.phtml @@ -1,5 +1,9 @@ -context->transport->posts as $post): ?> - - Post id; ?> - - +context->transport->errorMessage)): ?> +

context->transport->errorMessage ?>

+ + context->transport->posts as $post): ?> + + Post id; ?> + + + diff --git a/src/Views/post-view.phtml b/src/Views/post-view.phtml index 7c5b750d..44932a90 100644 --- a/src/Views/post-view.phtml +++ b/src/Views/post-view.phtml @@ -1,5 +1,5 @@ context->transport->errorMessage)): ?>

context->transport->errorMessage ?>

- <?php echo $this->context->transport->post->name ?> + <?php echo $this->context->transport->post->name ?>