Better privilege checking for batch operations
This commit is contained in:
parent
cd437ca036
commit
410237d678
30 changed files with 314 additions and 85 deletions
|
@ -73,7 +73,6 @@ passwordResetEmailBody = "Hello,{nl}{nl}You received this e-mail because someone
|
|||
registerAccount=anonymous
|
||||
;registerAccount=nobody
|
||||
|
||||
uploadPost=registered
|
||||
listPosts=anonymous
|
||||
listPosts.sketchy=registered
|
||||
listPosts.unsafe=registered
|
||||
|
@ -84,6 +83,16 @@ viewPost.unsafe=registered
|
|||
viewPost.hidden=moderator
|
||||
retrievePost=anonymous
|
||||
favoritePost=registered
|
||||
|
||||
addPost=registered
|
||||
addPostSafety=registered
|
||||
addPostTags=registered
|
||||
addPostThumb=power-user
|
||||
addPostSource=registered
|
||||
addPostRelations=power-user
|
||||
addPostContent=registered
|
||||
|
||||
editPost=registered
|
||||
editPostSafety.own=registered
|
||||
editPostSafety.all=moderator
|
||||
editPostTags=registered
|
||||
|
@ -92,6 +101,7 @@ editPostSource=moderator
|
|||
editPostRelations.own=registered
|
||||
editPostRelations.all=moderator
|
||||
editPostContent=moderator
|
||||
|
||||
massTag.own=registered
|
||||
massTag.all=power-user
|
||||
hidePost=moderator
|
||||
|
|
|
@ -86,7 +86,7 @@ class Access
|
|||
public static function assert(Privilege $privilege, $user = null)
|
||||
{
|
||||
if (!self::check($privilege, $user))
|
||||
self::fail();
|
||||
self::fail('Insufficient privileges (' . $privilege->toString() . ')');
|
||||
}
|
||||
|
||||
public static function assertEmailConfirmation($user = null)
|
||||
|
@ -95,9 +95,9 @@ class Access
|
|||
self::fail('Need e-mail address confirmation to continue');
|
||||
}
|
||||
|
||||
public static function fail($message = 'Insufficient privileges')
|
||||
public static function fail($message)
|
||||
{
|
||||
throw new SimpleException($message);
|
||||
throw new AccessException($message);
|
||||
}
|
||||
|
||||
public static function getIdentity($user)
|
||||
|
|
4
src/AccessException.php
Normal file
4
src/AccessException.php
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
class AccessException extends SimpleException
|
||||
{
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
<?php
|
||||
abstract class AbstractJob
|
||||
{
|
||||
const CONTEXT_NORMAL = 1;
|
||||
const CONTEXT_BATCH_EDIT = 2;
|
||||
const CONTEXT_BATCH_ADD = 3;
|
||||
|
||||
const COMMENT_ID = 'comment-id';
|
||||
const LOG_ID = 'log-id';
|
||||
|
||||
|
@ -21,6 +25,7 @@ abstract class AbstractJob
|
|||
const STATE = 'state';
|
||||
|
||||
protected $arguments = [];
|
||||
protected $context = self::CONTEXT_NORMAL;
|
||||
|
||||
public function prepare()
|
||||
{
|
||||
|
@ -28,6 +33,11 @@ abstract class AbstractJob
|
|||
|
||||
public abstract function execute();
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function requiresAuthentication()
|
||||
{
|
||||
return false;
|
||||
|
@ -43,6 +53,16 @@ abstract class AbstractJob
|
|||
return false;
|
||||
}
|
||||
|
||||
public function getContext()
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
public function setContext($context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
public function getArgument($key)
|
||||
{
|
||||
if (!$this->hasArgument($key))
|
||||
|
|
|
@ -8,6 +8,10 @@ final class Api
|
|||
return \Chibi\Database::transaction(function() use ($job, $jobArgs)
|
||||
{
|
||||
$job->setArguments($jobArgs);
|
||||
|
||||
if (!$job->isSatisfied())
|
||||
throw new ApiJobUnsatisfiedException($job);
|
||||
|
||||
$job->prepare();
|
||||
|
||||
self::checkPrivileges($job);
|
||||
|
|
8
src/Api/ApiJobUnsatisfiedException.php
Normal file
8
src/Api/ApiJobUnsatisfiedException.php
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
class ApiJobUnsatisfiedException extends SimpleException
|
||||
{
|
||||
public function __construct(AbstractJob $job)
|
||||
{
|
||||
parent::__construct(get_class($job) . ' cannot be run due to unsatisfied execution conditions.');
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
abstract class AbstractPostEditJob extends AbstractPostJob
|
||||
{
|
||||
protected $skipSaving = false;
|
||||
|
||||
public function skipSaving()
|
||||
{
|
||||
$this->skipSaving = true;
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
abstract class AbstractUserEditJob extends AbstractUserJob
|
||||
{
|
||||
protected $skipSaving = false;
|
||||
|
||||
public function skipSaving()
|
||||
{
|
||||
$this->skipSaving = true;
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ class AddPostJob extends AbstractJob
|
|||
public function execute()
|
||||
{
|
||||
$post = PostModel::spawn();
|
||||
Logger::bufferChanges();
|
||||
|
||||
//basic stuff
|
||||
$anonymous = $this->getArgument(self::ANONYMOUS);
|
||||
|
@ -20,14 +19,16 @@ class AddPostJob extends AbstractJob
|
|||
//warning: it uses internally the same privileges as post editing
|
||||
$arguments = $this->getArguments();
|
||||
$arguments[EditPostJob::POST_ENTITY] = $post;
|
||||
Api::run((new EditPostJob)->skipSaving(), $arguments);
|
||||
|
||||
Logger::bufferChanges();
|
||||
$job = new EditPostJob();
|
||||
$job->setContext(AbstractJob::CONTEXT_BATCH_ADD);
|
||||
Api::run($job, $arguments);
|
||||
Logger::setBuffer([]);
|
||||
|
||||
//save to db
|
||||
PostModel::save($post);
|
||||
|
||||
//clean edit log
|
||||
Logger::setBuffer([]);
|
||||
|
||||
//log
|
||||
Logger::log('{user} added {post} (tags: {tags}, safety: {safety}, source: {source})', [
|
||||
'user' => ($anonymous and !getConfig()->misc->logAnonymousUploads)
|
||||
|
@ -46,7 +47,7 @@ class AddPostJob extends AbstractJob
|
|||
|
||||
public function requiresPrivilege()
|
||||
{
|
||||
return new Privilege(Privilege::UploadPost);
|
||||
return new Privilege(Privilege::AddPost);
|
||||
}
|
||||
|
||||
public function requiresConfirmedEmail()
|
||||
|
|
|
@ -20,7 +20,9 @@ class AddUserJob extends AbstractJob
|
|||
|
||||
Logger::bufferChanges();
|
||||
Access::disablePrivilegeChecking();
|
||||
Api::run((new EditUserJob)->skipSaving(), $arguments);
|
||||
$job = new EditUserJob();
|
||||
$job->setContext(self::CONTEXT_BATCH_ADD);
|
||||
Api::run($job, $arguments);
|
||||
Access::enablePrivilegeChecking();
|
||||
Logger::setBuffer([]);
|
||||
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
<?php
|
||||
class EditPostContentJob extends AbstractPostEditJob
|
||||
class EditPostContentJob extends AbstractPostJob
|
||||
{
|
||||
const POST_CONTENT = 'post-content';
|
||||
const POST_CONTENT_URL = 'post-content-url';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::POST_CONTENT)
|
||||
or $this->hasArgument(self::POST_CONTENT_URL);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$post = $this->post;
|
||||
|
@ -19,7 +25,7 @@ class EditPostContentJob extends AbstractPostEditJob
|
|||
$post->setContentFromPath($file->filePath, $file->fileName);
|
||||
}
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
PostModel::save($post);
|
||||
|
||||
Logger::log('{user} changed contents of {post}', [
|
||||
|
@ -32,7 +38,9 @@ class EditPostContentJob extends AbstractPostEditJob
|
|||
public function requiresPrivilege()
|
||||
{
|
||||
return new Privilege(
|
||||
Privilege::EditPostContent,
|
||||
$this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? Privilege::AddPostContent
|
||||
: Privilege::EditPostContent,
|
||||
Access::getIdentity($this->post->getUploader()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
class EditPostJob extends AbstractPostEditJob
|
||||
class EditPostJob extends AbstractPostJob
|
||||
{
|
||||
public function execute()
|
||||
{
|
||||
|
@ -19,8 +19,9 @@ class EditPostJob extends AbstractPostEditJob
|
|||
|
||||
foreach ($subJobs as $subJob)
|
||||
{
|
||||
if ($this->skipSaving)
|
||||
$subJob->skipSaving();
|
||||
$subJob->setContext($this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? self::CONTEXT_BATCH_ADD
|
||||
: self::CONTEXT_BATCH_EDIT);
|
||||
|
||||
$args = $this->getArguments();
|
||||
$args[self::POST_ENTITY] = $post;
|
||||
|
@ -28,15 +29,24 @@ class EditPostJob extends AbstractPostEditJob
|
|||
{
|
||||
Api::run($subJob, $args);
|
||||
}
|
||||
catch (ApiMissingArgumentException $e)
|
||||
catch (ApiJobUnsatisfiedException $e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == AbstractJob::CONTEXT_NORMAL)
|
||||
PostModel::save($post);
|
||||
|
||||
Logger::flush();
|
||||
return $post;
|
||||
}
|
||||
|
||||
public function requiresPrivilege()
|
||||
{
|
||||
return new Privilege(
|
||||
$this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? Privilege::AddPost
|
||||
: Privilege::EditPost,
|
||||
Access::getIdentity($this->post->getUploader()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
class EditPostRelationsJob extends AbstractPostEditJob
|
||||
class EditPostRelationsJob extends AbstractPostJob
|
||||
{
|
||||
const RELATED_POST_IDS = 'related-post-ids';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::RELATED_POST_IDS);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$post = $this->post;
|
||||
|
@ -12,7 +17,7 @@ class EditPostRelationsJob extends AbstractPostEditJob
|
|||
$post->setRelationsFromText($relations);
|
||||
$newRelatedIds = array_map(function($post) { return $post->getId(); }, $post->getRelations());
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
PostModel::save($post);
|
||||
|
||||
foreach (array_diff($oldRelatedIds, $newRelatedIds) as $post2id)
|
||||
|
@ -37,7 +42,9 @@ class EditPostRelationsJob extends AbstractPostEditJob
|
|||
public function requiresPrivilege()
|
||||
{
|
||||
return new Privilege(
|
||||
Privilege::EditPostRelations,
|
||||
$this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? Privilege::AddPostRelations
|
||||
: Privilege::EditPostRelations,
|
||||
Access::getIdentity($this->post->getUploader()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
class EditPostSafetyJob extends AbstractPostEditJob
|
||||
class EditPostSafetyJob extends AbstractPostJob
|
||||
{
|
||||
const SAFETY = 'safety';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::SAFETY);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$post = $this->post;
|
||||
|
@ -11,7 +16,7 @@ class EditPostSafetyJob extends AbstractPostEditJob
|
|||
$oldSafety = $post->getSafety();
|
||||
$post->setSafety($newSafety);
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
PostModel::save($post);
|
||||
|
||||
if ($oldSafety != $newSafety)
|
||||
|
@ -28,7 +33,9 @@ class EditPostSafetyJob extends AbstractPostEditJob
|
|||
public function requiresPrivilege()
|
||||
{
|
||||
return new Privilege(
|
||||
Privilege::EditPostSafety,
|
||||
$this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? Privilege::AddPostSafety
|
||||
: Privilege::EditPostSafety,
|
||||
Access::getIdentity($this->post->getUploader()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
class EditPostSourceJob extends AbstractPostEditJob
|
||||
class EditPostSourceJob extends AbstractPostJob
|
||||
{
|
||||
const SOURCE = 'source';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::SOURCE);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$post = $this->post;
|
||||
|
@ -11,7 +16,7 @@ class EditPostSourceJob extends AbstractPostEditJob
|
|||
$oldSource = $post->source;
|
||||
$post->setSource($newSource);
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
PostModel::save($post);
|
||||
|
||||
if ($oldSource != $newSource)
|
||||
|
@ -28,7 +33,9 @@ class EditPostSourceJob extends AbstractPostEditJob
|
|||
public function requiresPrivilege()
|
||||
{
|
||||
return new Privilege(
|
||||
Privilege::EditPostSource,
|
||||
$this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? Privilege::AddPostSource
|
||||
: Privilege::EditPostSource,
|
||||
Access::getIdentity($this->post->getUploader()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
<?php
|
||||
class EditPostTagsJob extends AbstractPostEditJob
|
||||
class EditPostTagsJob extends AbstractPostJob
|
||||
{
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::TAG_NAMES);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$post = $this->post;
|
||||
|
@ -10,7 +15,7 @@ class EditPostTagsJob extends AbstractPostEditJob
|
|||
$post->setTagsFromText($tags);
|
||||
$newTags = array_map(function($tag) { return $tag->getName(); }, $post->getTags());
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
{
|
||||
PostModel::save($post);
|
||||
TagModel::removeUnused();
|
||||
|
@ -38,7 +43,9 @@ class EditPostTagsJob extends AbstractPostEditJob
|
|||
public function requiresPrivilege()
|
||||
{
|
||||
return new Privilege(
|
||||
Privilege::EditPostTags,
|
||||
$this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? Privilege::AddPostTags
|
||||
: Privilege::EditPostTags,
|
||||
Access::getIdentity($this->post->getUploader()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
class EditPostThumbJob extends AbstractPostEditJob
|
||||
class EditPostThumbJob extends AbstractPostJob
|
||||
{
|
||||
const THUMB_CONTENT = 'thumb-content';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::THUMB_CONTENT);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$post = $this->post;
|
||||
|
@ -10,7 +15,7 @@ class EditPostThumbJob extends AbstractPostEditJob
|
|||
|
||||
$post->setCustomThumbnailFromPath($file->filePath);
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
PostModel::save($post);
|
||||
|
||||
Logger::log('{user} changed thumb of {post}', [
|
||||
|
@ -23,7 +28,9 @@ class EditPostThumbJob extends AbstractPostEditJob
|
|||
public function requiresPrivilege()
|
||||
{
|
||||
return new Privilege(
|
||||
Privilege::EditPostThumb,
|
||||
$this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? Privilege::AddPostThumb
|
||||
: Privilege::EditPostThumb,
|
||||
Access::getIdentity($this->post->getUploader()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
class EditUserAccessRankJob extends AbstractUserEditJob
|
||||
class EditUserAccessRankJob extends AbstractUserJob
|
||||
{
|
||||
const NEW_ACCESS_RANK = 'new-access-rank';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::NEW_ACCESS_RANK);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$user = $this->user;
|
||||
|
@ -14,7 +19,7 @@ class EditUserAccessRankJob extends AbstractUserEditJob
|
|||
|
||||
$user->setAccessRank($newAccessRank);
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
UserModel::save($user);
|
||||
|
||||
Logger::log('{user} changed {subject}\'s access rank to {rank}', [
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
class EditUserEmailJob extends AbstractUserEditJob
|
||||
class EditUserEmailJob extends AbstractUserJob
|
||||
{
|
||||
const NEW_EMAIL = 'new-email';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::NEW_EMAIL);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
if (getConfig()->registration->needEmailForRegistering)
|
||||
|
@ -29,7 +34,7 @@ class EditUserEmailJob extends AbstractUserEditJob
|
|||
$user->confirmEmail();
|
||||
}
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
UserModel::save($user);
|
||||
|
||||
Logger::log('{user} changed {subject}\'s e-mail to {mail}', [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
class EditUserJob extends AbstractUserEditJob
|
||||
class EditUserJob extends AbstractUserJob
|
||||
{
|
||||
protected $subJobs;
|
||||
|
||||
|
@ -25,7 +25,7 @@ class EditUserJob extends AbstractUserEditJob
|
|||
Api::checkPrivileges($subJob);
|
||||
return true;
|
||||
}
|
||||
catch (SimpleException $e)
|
||||
catch (AccessException $e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,9 @@ class EditUserJob extends AbstractUserEditJob
|
|||
|
||||
foreach ($this->subJobs as $subJob)
|
||||
{
|
||||
if ($this->skipSaving)
|
||||
$subJob->skipSaving();
|
||||
$subJob->setContext($this->getContext() == self::CONTEXT_BATCH_ADD
|
||||
? self::CONTEXT_BATCH_ADD
|
||||
: self::CONTEXT_BATCH_EDIT);
|
||||
|
||||
$args = $this->getArguments();
|
||||
$args[self::USER_ENTITY] = $user;
|
||||
|
@ -49,12 +50,12 @@ class EditUserJob extends AbstractUserEditJob
|
|||
{
|
||||
Api::run($subJob, $args);
|
||||
}
|
||||
catch (ApiMissingArgumentException $e)
|
||||
catch (ApiJobUnsatisfiedException $e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
UserModel::save($user);
|
||||
|
||||
Logger::flush();
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
class EditUserNameJob extends AbstractUserEditJob
|
||||
class EditUserNameJob extends AbstractUserJob
|
||||
{
|
||||
const NEW_USER_NAME = 'new-user-name';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::NEW_USER_NAME);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$user = $this->user;
|
||||
|
@ -15,7 +20,7 @@ class EditUserNameJob extends AbstractUserEditJob
|
|||
$user->setName($newName);
|
||||
UserModel::validateUserName($user);
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
UserModel::save($user);
|
||||
|
||||
Logger::log('{user} renamed {old} to {new}', [
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
class EditUserPasswordJob extends AbstractUserEditJob
|
||||
class EditUserPasswordJob extends AbstractUserJob
|
||||
{
|
||||
const NEW_PASSWORD = 'new-password';
|
||||
|
||||
public function isSatisfied()
|
||||
{
|
||||
return $this->hasArgument(self::NEW_PASSWORD);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$user = $this->user;
|
||||
|
@ -15,7 +20,7 @@ class EditUserPasswordJob extends AbstractUserEditJob
|
|||
|
||||
$user->passHash = $newPasswordHash;
|
||||
|
||||
if (!$this->skipSaving)
|
||||
if ($this->getContext() == self::CONTEXT_NORMAL)
|
||||
UserModel::save($user);
|
||||
|
||||
Logger::log('{user} changed {subject}\'s password', [
|
||||
|
|
|
@ -13,7 +13,7 @@ abstract class Enum
|
|||
public function toDisplayString()
|
||||
{
|
||||
return TextCaseConverter::convert($this->toString(),
|
||||
TextCaseConverter::SNAKE_CASE,
|
||||
TextCaseConverter::CAMEL_CASE,
|
||||
TextCaseConverter::BLANK_CASE);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,21 +2,30 @@
|
|||
class Privilege extends Enum
|
||||
{
|
||||
const ListPosts = 1;
|
||||
const UploadPost = 2;
|
||||
const ViewPost = 3;
|
||||
const RetrievePost = 4;
|
||||
const FavoritePost = 5;
|
||||
const HidePost = 9;
|
||||
const DeletePost = 10;
|
||||
const FeaturePost = 25;
|
||||
const ScorePost = 31;
|
||||
const FlagPost = 34;
|
||||
|
||||
const EditPost = 45;
|
||||
const EditPostSafety = 6;
|
||||
const EditPostTags = 7;
|
||||
const EditPostThumb = 8;
|
||||
const EditPostSource = 26;
|
||||
const EditPostRelations = 30;
|
||||
const EditPostContent = 36;
|
||||
const HidePost = 9;
|
||||
const DeletePost = 10;
|
||||
const FeaturePost = 25;
|
||||
const ScorePost = 31;
|
||||
const FlagPost = 34;
|
||||
|
||||
const AddPost = 2;
|
||||
const AddPostSafety = 39;
|
||||
const AddPostTags = 40;
|
||||
const AddPostThumb = 41;
|
||||
const AddPostSource = 42;
|
||||
const AddPostRelations = 43;
|
||||
const AddPostContent = 44;
|
||||
|
||||
const RegisterAccount = 38;
|
||||
const ListUsers = 11;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
$activeController == 'post' and $activeAction != 'upload');
|
||||
}
|
||||
|
||||
if (Access::check(new Privilege(Privilege::UploadPost)))
|
||||
if (Access::check(new Privilege(Privilege::AddPost)))
|
||||
{
|
||||
$registerNavItem(
|
||||
'Upload',
|
||||
|
|
|
@ -59,4 +59,9 @@ class AbstractTest
|
|||
getConfig()->privileges->$privilege = 'nobody';
|
||||
Access::init();
|
||||
}
|
||||
|
||||
protected function getPath($name)
|
||||
{
|
||||
return getConfig()->rootDir . DS . 'tests' . DS . 'TestFiles' . DS . $name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,8 @@ class ApiPrivilegeTest extends AbstractFullApiTest
|
|||
$this->testRegularPrivilege(new ActivateUserEmailJob(), false);
|
||||
$this->testRegularPrivilege(new AddCommentJob(), new Privilege(Privilege::AddComment));
|
||||
$this->testRegularPrivilege(new PreviewCommentJob(), new Privilege(Privilege::AddComment));
|
||||
$this->testRegularPrivilege(new AddPostJob(), new Privilege(Privilege::UploadPost));
|
||||
$this->testRegularPrivilege(new AddPostJob(), new Privilege(Privilege::AddPost));
|
||||
$this->testRegularPrivilege(new AddUserJob(), new Privilege(Privilege::RegisterAccount));
|
||||
$this->testRegularPrivilege(new EditPostJob(), false);
|
||||
$this->testRegularPrivilege(new EditUserJob(), false);
|
||||
$this->testRegularPrivilege(new GetLogJob(), new Privilege(Privilege::ViewLog));
|
||||
$this->testRegularPrivilege(new ListCommentsJob(), new Privilege(Privilege::ListComments));
|
||||
|
@ -42,12 +41,27 @@ class ApiPrivilegeTest extends AbstractFullApiTest
|
|||
$this->login($this->mockUser());
|
||||
|
||||
$this->testDynamicPostPrivilege(new DeletePostJob(), new Privilege(Privilege::DeletePost));
|
||||
$this->testDynamicPostPrivilege(new EditPostJob(), new Privilege(Privilege::EditPost));
|
||||
$this->testDynamicPostPrivilege(new EditPostContentJob(), new Privilege(Privilege::EditPostContent));
|
||||
$this->testDynamicPostPrivilege(new EditPostRelationsJob(), new Privilege(Privilege::EditPostRelations));
|
||||
$this->testDynamicPostPrivilege(new EditPostSafetyJob(), new Privilege(Privilege::EditPostSafety));
|
||||
$this->testDynamicPostPrivilege(new EditPostSourceJob(), new Privilege(Privilege::EditPostSource));
|
||||
$this->testDynamicPostPrivilege(new EditPostTagsJob(), new Privilege(Privilege::EditPostTags));
|
||||
$this->testDynamicPostPrivilege(new EditPostThumbJob(), new Privilege(Privilege::EditPostThumb));
|
||||
|
||||
$ctx = function($job)
|
||||
{
|
||||
$job->setContext(AbstractJob::CONTEXT_BATCH_ADD);
|
||||
return $job;
|
||||
};
|
||||
$this->testDynamicPostPrivilege($ctx(new EditPostJob), new Privilege(Privilege::AddPost));
|
||||
$this->testDynamicPostPrivilege($ctx(new EditPostContentJob), new Privilege(Privilege::AddPostContent));
|
||||
$this->testDynamicPostPrivilege($ctx(new EditPostRelationsJob), new Privilege(Privilege::AddPostRelations));
|
||||
$this->testDynamicPostPrivilege($ctx(new EditPostSafetyJob), new Privilege(Privilege::AddPostSafety));
|
||||
$this->testDynamicPostPrivilege($ctx(new EditPostSourceJob), new Privilege(Privilege::AddPostSource));
|
||||
$this->testDynamicPostPrivilege($ctx(new EditPostTagsJob), new Privilege(Privilege::AddPostTags));
|
||||
$this->testDynamicPostPrivilege($ctx(new EditPostThumbJob), new Privilege(Privilege::AddPostThumb));
|
||||
|
||||
$this->testDynamicPostPrivilege(new FeaturePostJob(), new Privilege(Privilege::FeaturePost));
|
||||
$this->testDynamicPostPrivilege(new FlagPostJob(), new Privilege(Privilege::FlagPost));
|
||||
$this->testDynamicPostPrivilege(new ScorePostJob(), new Privilege(Privilege::ScorePost));
|
||||
|
|
55
tests/JobTests/AddPostJobTest.php
Normal file
55
tests/JobTests/AddPostJobTest.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
class AddPostJobTest extends AbstractTest
|
||||
{
|
||||
public function testSaving()
|
||||
{
|
||||
$this->prepare();
|
||||
|
||||
$this->grantAccess('addPost');
|
||||
$this->grantAccess('addPostSafety');
|
||||
$this->grantAccess('addPostTags');
|
||||
$this->grantAccess('addPostSource');
|
||||
$this->grantAccess('addPostContent');
|
||||
|
||||
$args =
|
||||
[
|
||||
AddPostJob::ANONYMOUS => false,
|
||||
EditPostSafetyJob::SAFETY => PostSafety::Safe,
|
||||
EditPostSourceJob::SOURCE => '',
|
||||
EditPostContentJob::POST_CONTENT => new ApiFileInput($this->getPath('image.jpg'), 'test.jpg'),
|
||||
];
|
||||
|
||||
$this->assert->doesNotThrow(function() use ($args)
|
||||
{
|
||||
Api::run(new AddPostJob(), $args);
|
||||
});
|
||||
}
|
||||
|
||||
public function testPrivilegeFail()
|
||||
{
|
||||
$this->prepare();
|
||||
|
||||
$this->grantAccess('addPost');
|
||||
$this->grantAccess('addPostSafety');
|
||||
$this->grantAccess('addPostTags');
|
||||
$this->grantAccess('addPostContent');
|
||||
|
||||
$args =
|
||||
[
|
||||
AddPostJob::ANONYMOUS => false,
|
||||
EditPostSafetyJob::SAFETY => PostSafety::Safe,
|
||||
EditPostSourceJob::SOURCE => '',
|
||||
EditPostContentJob::POST_CONTENT => new ApiFileInput($this->getPath('image.jpg'), 'test.jpg'),
|
||||
];
|
||||
|
||||
$this->assert->throws(function() use ($args)
|
||||
{
|
||||
Api::run(new AddPostJob(), $args);
|
||||
}, 'Insufficient privilege');
|
||||
}
|
||||
|
||||
protected function prepare()
|
||||
{
|
||||
getConfig()->registration->needEmailForUploading = false;
|
||||
}
|
||||
}
|
|
@ -162,9 +162,4 @@ class EditPostContentJobTest extends AbstractTest
|
|||
|
||||
return $post;
|
||||
}
|
||||
|
||||
protected function getPath($name)
|
||||
{
|
||||
return getConfig()->rootDir . DS . 'tests' . DS . 'TestFiles' . DS . $name;
|
||||
}
|
||||
}
|
||||
|
|
50
tests/JobTests/EditPostJobTest.php
Normal file
50
tests/JobTests/EditPostJobTest.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
class EditPostJobTest extends AbstractTest
|
||||
{
|
||||
public function testSaving()
|
||||
{
|
||||
$this->grantAccess('editPost');
|
||||
$this->grantAccess('editPostSafety');
|
||||
$this->grantAccess('editPostTags');
|
||||
$this->grantAccess('editPostSource');
|
||||
$this->grantAccess('editPostContent');
|
||||
|
||||
$post = $this->mockPost(Auth::getCurrentUser());
|
||||
|
||||
$args =
|
||||
[
|
||||
EditPostJob::POST_ID => $post->getId(),
|
||||
EditPostSafetyJob::SAFETY => PostSafety::Safe,
|
||||
EditPostSourceJob::SOURCE => '',
|
||||
EditPostContentJob::POST_CONTENT => new ApiFileInput($this->getPath('image.jpg'), 'test.jpg'),
|
||||
];
|
||||
|
||||
$this->assert->doesNotThrow(function() use ($args)
|
||||
{
|
||||
Api::run(new EditPostJob(), $args);
|
||||
});
|
||||
}
|
||||
|
||||
public function testPrivilegeFail()
|
||||
{
|
||||
$this->grantAccess('editPost');
|
||||
$this->grantAccess('editPostSafety');
|
||||
$this->grantAccess('editPostTags');
|
||||
$this->grantAccess('editPostContent');
|
||||
|
||||
$post = $this->mockPost(Auth::getCurrentUser());
|
||||
|
||||
$args =
|
||||
[
|
||||
EditPostJob::POST_ID => $post->getId(),
|
||||
EditPostSafetyJob::SAFETY => PostSafety::Safe,
|
||||
EditPostSourceJob::SOURCE => '',
|
||||
EditPostContentJob::POST_CONTENT => new ApiFileInput($this->getPath('image.jpg'), 'test.jpg'),
|
||||
];
|
||||
|
||||
$this->assert->throws(function() use ($args)
|
||||
{
|
||||
Api::run(new EditPostJob(), $args);
|
||||
}, 'Insufficient privilege');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue