szurubooru/tests/Tests/ApiTests/ApiPrivilegeTest.php
Marcin Kurczewski e59b7e8b7b Refactored privilege system a bit
- Jobs specify main privilege and sub privileges separately
  Rationale: increase maintenance, restrict what can be done runtime
- Renamed ChangeUser* to EditUser* (consistency with EditPost*)
- Simplified enum names and configuration reading
- IJob interface members must be explicitly implemented
  Rationale: reduce chances of forgetting something, or typos in
  inherited method names
- Invalid privileges names in configuration yield exceptions
2014-05-18 21:59:56 +02:00

253 lines
9.7 KiB
PHP

<?php
class ApiPrivilegeTest extends AbstractFullApiTest
{
public function testPrivilegeTesting()
{
$priv1 = new Privilege(Privilege::ViewPost, 'own');
$priv2 = new Privilege(Privilege::ViewPost, 'own');
$this->assert->areNotEqual($priv1, $priv2);
$this->assert->areEquivalent($priv1, $priv2);
}
public function testRegularPrivileges()
{
$this->testRegularPrivilege(new AcceptUserRegistrationJob(), Privilege::AcceptUserRegistration);
$this->testRegularPrivilege(new ActivateUserEmailJob(), null);
$this->testRegularPrivilege(new AddCommentJob(), Privilege::AddComment);
$this->testRegularPrivilege(new PreviewCommentJob(), Privilege::AddComment);
$this->testRegularPrivilege(new AddPostJob(), Privilege::AddPost);
$this->testRegularPrivilege(new AddUserJob(), Privilege::RegisterAccount);
$this->testRegularPrivilege(new EditUserJob(), null);
$this->testRegularPrivilege(new GetLogJob(), Privilege::ViewLog);
$this->testRegularPrivilege(new GetPropertyJob(), null);
$this->testRegularPrivilege(new ListCommentsJob(), Privilege::ListComments);
$this->testRegularPrivilege(new ListLogsJob(), Privilege::ListLogs);
$this->testRegularPrivilege(new ListPostsJob(), Privilege::ListPosts);
$this->testRegularPrivilege(new ListRelatedTagsJob(), Privilege::ListTags);
$this->testRegularPrivilege(new ListTagsJob(), Privilege::ListTags);
$this->testRegularPrivilege(new ListUsersJob(), Privilege::ListUsers);
$this->testRegularPrivilege(new PasswordResetJob(), null);
$this->testRegularPrivilege(new MergeTagsJob(), Privilege::MergeTags);
$this->testRegularPrivilege(new RenameTagsJob(), Privilege::RenameTags);
}
protected function testRegularPrivilege($job, $expectedPrivilege)
{
$this->testedJobs []= $job;
$this->assert->areEqual($expectedPrivilege, $job->getRequiredMainPrivilege());
$this->assert->isNull($job->getRequiredSubPrivileges());
}
public function testDynamicPostPrivileges()
{
$this->login($this->userMocker->mockSingle());
$this->testDynamicPostPrivilege(new DeletePostJob(), Privilege::DeletePost);
$this->testDynamicPostPrivilege(new EditPostJob(), Privilege::EditPost);
$this->testDynamicPostPrivilege(new EditPostContentJob(), Privilege::EditPostContent);
$this->testDynamicPostPrivilege(new EditPostRelationsJob(), Privilege::EditPostRelations);
$this->testDynamicPostPrivilege(new EditPostSafetyJob(), Privilege::EditPostSafety);
$this->testDynamicPostPrivilege(new EditPostSourceJob(), Privilege::EditPostSource);
$this->testDynamicPostPrivilege(new EditPostTagsJob(), Privilege::EditPostTags);
$this->testDynamicPostPrivilege(new EditPostThumbJob(), Privilege::EditPostThumb);
$ctx = function($job)
{
$job->setContext(AbstractJob::CONTEXT_BATCH_ADD);
return $job;
};
$this->testDynamicPostPrivilege($ctx(new EditPostContentJob), Privilege::AddPostContent);
$this->testDynamicPostPrivilege($ctx(new EditPostRelationsJob), Privilege::AddPostRelations);
$this->testDynamicPostPrivilege($ctx(new EditPostSafetyJob), Privilege::AddPostSafety);
$this->testDynamicPostPrivilege($ctx(new EditPostSourceJob), Privilege::AddPostSource);
$this->testDynamicPostPrivilege($ctx(new EditPostTagsJob), Privilege::AddPostTags);
$this->testDynamicPostPrivilege($ctx(new EditPostThumbJob), Privilege::AddPostThumb);
$this->testDynamicPostPrivilege(new FeaturePostJob(), Privilege::FeaturePost);
$this->testDynamicPostPrivilege(new FlagPostJob(), Privilege::FlagPost);
$this->testDynamicPostPrivilege(new ScorePostJob(), Privilege::ScorePost);
$this->testDynamicPostPrivilege(new TogglePostTagJob(), Privilege::EditPostTags);
$this->testDynamicPostPrivilege(new TogglePostVisibilityJob(), Privilege::HidePost);
$this->testDynamicPostPrivilege(new TogglePostFavoriteJob(), Privilege::FavoritePost);
}
protected function testDynamicPostPrivilege($job, $expectedPrivilege)
{
$this->testedJobs []= $job;
$this->assert->areEqual($expectedPrivilege, $job->getRequiredMainPrivilege());
list ($ownPost, $otherPost) = $this->postMocker->mockMultiple(2);
$ownPost->setUploader(Auth::getCurrentUser());
$otherPost->setUploader($this->userMocker->mockSingle());
PostModel::save([$ownPost, $otherPost]);
$job->setArgument(JobArgs::ARG_POST_ID, $otherPost->getId());
$job->prepare();
$this->assert->areEqual('all', $job->getRequiredSubPrivileges());
$job->setArgument(JobArgs::ARG_POST_ID, $ownPost->getId());
$job->prepare();
$this->assert->areEqual('own', $job->getRequiredSubPrivileges());
}
public function testDynamicPostRetrievalPrivileges()
{
$jobs =
[
new GetPostJob(),
new GetPostContentJob(),
];
$post = $this->postMocker->mockSingle();
foreach ($jobs as $job)
{
$this->testedJobs []= $job;
$post->setHidden(true);
PostModel::save($post);
$job->setArgument(JobArgs::ARG_POST_ID, $post->getId());
$job->setArgument(JobArgs::ARG_POST_NAME, $post->getName());
$job->prepare();
$this->assert->areEqual(Privilege::ViewPost, $job->getRequiredMainPrivilege());
$sub = $job->getRequiredSubPrivileges();
natcasesort($sub);
$this->assert->areEquivalent(['hidden', 'safe'], $sub);
}
}
public function testDynamicPostThumbPrivileges()
{
$job = new GetPostThumbJob();
$this->testedJobs []= $job;
$this->assert->isNull($job->getRequiredMainPrivilege());
}
public function testDynamicUserPrivileges()
{
$ownUser = $this->userMocker->mockSingle();
$this->login($ownUser);
$this->testDynamicUserPrivilege(new DeleteUserJob(), Privilege::DeleteUser);
$this->testDynamicUserPrivilege(new EditUserAccessRankJob(), Privilege::EditUserAccessRank);
$this->testDynamicUserPrivilege(new EditUserEmailJob(), Privilege::EditUserEmail);
$this->testDynamicUserPrivilege(new EditUserNameJob(), Privilege::EditUserName);
$this->testDynamicUserPrivilege(new EditUserPasswordJob(), Privilege::EditUserPassword);
$this->testDynamicUserPrivilege(new EditUserSettingsJob(), Privilege::EditUserSettings);
$ctx = function($job)
{
$job->setContext(AbstractJob::CONTEXT_BATCH_ADD);
return $job;
};
$this->testDynamicUserPrivilege($ctx(new EditUserAccessRankJob()), Privilege::EditUserAccessRank);
$this->testDynamicUserPrivilege($ctx(new EditUserEmailJob()), Privilege::RegisterAccount);
$this->testDynamicUserPrivilege($ctx(new EditUserNameJob()), Privilege::RegisterAccount);
$this->testDynamicUserPrivilege($ctx(new EditUserPasswordJob()), Privilege::RegisterAccount);
$this->testDynamicUserPrivilege($ctx(new EditUserSettingsJob()), Privilege::EditUserSettings);
$this->testDynamicUserPrivilege(new FlagUserJob(), Privilege::FlagUser);
$this->testDynamicUserPrivilege(new GetUserJob(), Privilege::ViewUser);
$this->testDynamicUserPrivilege(new GetUserSettingsJob(), Privilege::EditUserSettings);
$this->testDynamicUserPrivilege(new ToggleUserBanJob(), Privilege::BanUser);
}
protected function testDynamicUserPrivilege($job, $expectedPrivilege)
{
$this->testedJobs []= $job;
$this->assert->areEqual($expectedPrivilege, $job->getRequiredMainPrivilege());
$ownUser = Auth::getCurrentUser();
$otherUser = $this->userMocker->mockSingle();
$otherUser->setName('dummy' . uniqid());
UserModel::save($otherUser);
$job->setArgument(JobArgs::ARG_USER_NAME, $ownUser->getName());
$job->prepare();
$this->assert->areEqual('own', $job->getRequiredSubPrivileges());
$job->setArgument(JobArgs::ARG_USER_NAME, $otherUser->getName());
$job->prepare();
$this->assert->areEqual('all', $job->getRequiredSubPrivileges());
}
public function testDynamicCommentPrivileges()
{
$this->login($this->userMocker->mockSingle());
$this->testDynamicCommentPrivilege(new DeleteCommentJob(), Privilege::DeleteComment);
$this->testDynamicCommentPrivilege(new EditCommentJob(), Privilege::EditComment);
}
protected function testDynamicCommentPrivilege($job, $expectedPrivilege)
{
$this->testedJobs []= $job;
$this->assert->areEqual($expectedPrivilege, $job->getRequiredMainPrivilege());
list ($ownComment, $otherComment) = $this->commentMocker->mockMultiple(2);
$ownComment->setCommenter(Auth::getCurrentUser());
$otherComment->setCommenter($this->userMocker->mockSingle());
CommentModel::save([$ownComment, $otherComment]);
$job->setArgument(JobArgs::ARG_COMMENT_ID, $ownComment->getId());
$job->prepare();
$this->assert->areEqual('own', $job->getRequiredSubPrivileges());
$job->setArgument(JobArgs::ARG_COMMENT_ID, $otherComment->getId());
$job->prepare();
$this->assert->areEqual('all', $job->getRequiredSubPrivileges());
}
public function testPrivilegeEnforcing()
{
$post = $this->postMocker->mockSingle();
Core::getConfig()->registration->needEmailForCommenting = false;
$this->assert->throws(function() use ($post)
{
Api::run(
new AddCommentJob(),
[
JobArgs::ARG_POST_ID => $post->getId(),
JobArgs::ARG_NEW_TEXT => 'alohaaa',
]);
}, 'Insufficient privileges');
}
public function testComplexPrivilegeEnforcing()
{
$post = $this->postMocker->mockSingle();
Core::getConfig()->registration->needEmailForCommenting = false;
$this->grantAccess('editPost.own');
$this->grantAccess('editPostTags.own');
$this->revokeAccess('editPost.all');
$this->revokeAccess('editPostTags.all');
$user = $this->userMocker->mockSingle();
$this->login($user);
$this->assert->throws(function() use ($post)
{
Api::run(
new EditPostTagsJob(),
[
JobArgs::ARG_POST_ID => $post->getId(),
JobArgs::ARG_NEW_TAG_NAMES => ['test1', 'test2'],
]);
}, 'Insufficient privileges');
$post->setUploader($user);
PostModel::save($post);
$this->assert->doesNotThrow(function() use ($post)
{
Api::run(
new EditPostTagsJob(),
[
JobArgs::ARG_POST_ID => $post->getId(),
JobArgs::ARG_NEW_TAG_NAMES => ['test1', 'test2'],
]);
});
}
}