Changed privilege tests to be more generic

This commit is contained in:
Marcin Kurczewski 2014-05-06 18:15:35 +02:00
parent 0ea81b8f69
commit c8e9804a15
13 changed files with 397 additions and 298 deletions

@ -1 +1 @@
Subproject commit 45c662d0a4b32e09399b5b68ac53aaa3f1a29911
Subproject commit 5e78e0a68a1188851d12e26c0f58c1ffe95ffb69

View file

@ -0,0 +1,30 @@
<?php
abstract class AbstractFullApiTest extends AbstractTest
{
protected $testedJobs = [];
public function teardown()
{
$testedJobs = array_map(function($job)
{
return get_class($job);
}, $this->testedJobs);
$allJobs = $this->getAllJobs();
foreach ($allJobs as $x)
{
if (!in_array($x, $testedJobs))
$this->assert->fail($x . ' appears to be untested');
}
}
protected function getAllJobs()
{
$files = glob(getConfig()->rootDir . DS . 'src' . DS . 'Api' . DS . 'Jobs' . DS . '*.php');
\Chibi\Util\Reflection::loadClasses($files);
return array_filter(get_declared_classes(), function($x)
{
$class = new ReflectionClass($x);
return !$class->isAbstract() and $class->isSubClassOf('AbstractJob');
});
}
}

74
tests/Api/ApiAuthTest.php Normal file
View file

@ -0,0 +1,74 @@
<?php
class ApiAuthTest extends AbstractFullApiTest
{
public function testAllAuth()
{
$this->testAuth(new AcceptUserRegistrationJob(), false);
$this->testAuth(new ActivateUserEmailJob(), false);
$this->testAuth(new AddPostJob(), false);
$this->testAuth(new AddCommentJob(), false);
$this->testAuth(new AddUserJob(), false);
$this->testAuth(new DeletePostJob(), true);
$this->testAuth(new DeleteCommentJob(), true);
$this->testAuth(new DeleteUserJob(), false);
$this->testAuth(new EditCommentJob(), true);
$this->testAuth(new EditPostContentJob(), false);
$this->testAuth(new EditPostJob(), false);
$this->testAuth(new EditPostRelationsJob(), false);
$this->testAuth(new EditPostSafetyJob(), false);
$this->testAuth(new EditPostSourceJob(), false);
$this->testAuth(new EditPostTagsJob(), false);
$this->testAuth(new EditPostThumbJob(), false);
$this->testAuth(new EditUserAccessRankJob(), false);
$this->testAuth(new EditUserEmailJob(), false);
$this->testAuth(new EditUserJob(), false);
$this->testAuth(new EditUserNameJob(), false);
$this->testAuth(new EditUserPasswordJob(), false);
$this->testAuth(new FeaturePostJob(), true);
$this->testAuth(new FlagPostJob(), false);
$this->testAuth(new FlagUserJob(), false);
$this->testAuth(new GetLogJob(), false);
$this->testAuth(new GetPostContentJob(), false);
$this->testAuth(new GetPostJob(), false);
$this->testAuth(new GetPostThumbJob(), false);
$this->testAuth(new GetUserJob(), false);
$this->testAuth(new ListCommentsJob(), false);
$this->testAuth(new ListLogsJob(), false);
$this->testAuth(new ListPostsJob(), false);
$this->testAuth(new ListRelatedTagsJob(), false);
$this->testAuth(new ListTagsJob(), false);
$this->testAuth(new ListUsersJob(), false);
$this->testAuth(new MergeTagsJob(), false);
$this->testAuth(new PasswordResetJob(), false);
$this->testAuth(new PreviewCommentJob(), false);
$this->testAuth(new RenameTagsJob(), false);
$this->testAuth(new ScorePostJob(), true);
$this->testAuth(new TogglePostFavoriteJob(), true);
$this->testAuth(new TogglePostTagJob(), false);
$this->testAuth(new TogglePostVisibilityJob(), false);
$this->testAuth(new ToggleUserBanJob(), false);
}
protected function testAuth($job, $expectedAuth)
{
$this->testedJobs []= $job;
$this->assert->areEqual($expectedAuth, $job->requiresAuthentication());
}
public function testAuthEnforcing()
{
getConfig()->registration->needEmailForCommenting = false;
$this->grantAccess('addComment');
$comment = $this->mockComment(Auth::getCurrentUser());
$this->assert->throws(function() use ($comment)
{
return Api::run(
new DeleteCommentJob(),
[
DeleteCommentJob::COMMENT_ID => $comment->getId(),
]);
}, 'Not logged in');
}
}

View file

@ -0,0 +1,105 @@
<?php
class ApiEmailRequirementsTest extends AbstractFullApiTest
{
public function testRegularEmailRequirements()
{
getConfig()->registration->needEmailForCommenting = true;
getConfig()->registration->needEmailForUploading = true;
$this->testRegularEmailRequirement(new AcceptUserRegistrationJob());
$this->testRegularEmailRequirement(new ActivateUserEmailJob());
$this->testRegularEmailRequirement(new AddUserJob());
$this->testRegularEmailRequirement(new DeletePostJob());
$this->testRegularEmailRequirement(new DeleteCommentJob());
$this->testRegularEmailRequirement(new DeleteUserJob());
$this->testRegularEmailRequirement(new EditCommentJob());
$this->testRegularEmailRequirement(new EditPostContentJob());
$this->testRegularEmailRequirement(new EditPostJob());
$this->testRegularEmailRequirement(new EditPostRelationsJob());
$this->testRegularEmailRequirement(new EditPostSafetyJob());
$this->testRegularEmailRequirement(new EditPostSourceJob());
$this->testRegularEmailRequirement(new EditPostTagsJob());
$this->testRegularEmailRequirement(new EditPostThumbJob());
$this->testRegularEmailRequirement(new EditUserAccessRankJob());
$this->testRegularEmailRequirement(new EditUserEmailJob());
$this->testRegularEmailRequirement(new EditUserJob());
$this->testRegularEmailRequirement(new EditUserNameJob());
$this->testRegularEmailRequirement(new EditUserPasswordJob());
$this->testRegularEmailRequirement(new FeaturePostJob());
$this->testRegularEmailRequirement(new FlagPostJob());
$this->testRegularEmailRequirement(new FlagUserJob());
$this->testRegularEmailRequirement(new GetLogJob());
$this->testRegularEmailRequirement(new GetPostContentJob());
$this->testRegularEmailRequirement(new GetPostJob());
$this->testRegularEmailRequirement(new GetPostThumbJob());
$this->testRegularEmailRequirement(new GetUserJob());
$this->testRegularEmailRequirement(new ListCommentsJob());
$this->testRegularEmailRequirement(new ListLogsJob());
$this->testRegularEmailRequirement(new ListPostsJob());
$this->testRegularEmailRequirement(new ListRelatedTagsJob());
$this->testRegularEmailRequirement(new ListTagsJob());
$this->testRegularEmailRequirement(new ListUsersJob());
$this->testRegularEmailRequirement(new MergeTagsJob());
$this->testRegularEmailRequirement(new PasswordResetJob());
$this->testRegularEmailRequirement(new RenameTagsJob());
$this->testRegularEmailRequirement(new ScorePostJob());
$this->testRegularEmailRequirement(new TogglePostFavoriteJob());
$this->testRegularEmailRequirement(new TogglePostTagJob());
$this->testRegularEmailRequirement(new TogglePostVisibilityJob());
$this->testRegularEmailRequirement(new ToggleUserBanJob());
}
protected function testRegularEmailRequirement($job)
{
$this->testedJobs []= $job;
$this->assert->areEqual(false, $job->requiresConfirmedEmail());
}
public function testCommentsEmailRequirements()
{
$this->testCommentEmailRequirement(new AddCommentJob());
$this->testCommentEmailRequirement(new PreviewCommentJob());
}
protected function testCommentEmailRequirement($job)
{
$this->testedJobs []= $job;
getConfig()->registration->needEmailForCommenting = false;
$this->assert->areEqual(false, $job->requiresConfirmedEmail());
getConfig()->registration->needEmailForCommenting = true;
$this->assert->areEqual(true, $job->requiresConfirmedEmail());
}
public function testPostingEmailRequirement()
{
$job = new AddPostJob();
$this->testedJobs []= $job;
getConfig()->registration->needEmailForUploading = false;
$this->assert->areEqual(false, $job->requiresConfirmedEmail());
getConfig()->registration->needEmailForUploading = true;
$this->assert->areEqual(true, $job->requiresConfirmedEmail());
}
public function testEnforcing()
{
$this->grantAccess('addComment');
$this->login($this->mockUser());
getConfig()->registration->needEmailForCommenting = true;
$this->assert->throws(function()
{
$post = $this->mockPost(Auth::getCurrentUser());
return Api::run(
new AddCommentJob(),
[
AddCommentJob::POST_ID => $post->getId(),
AddCommentJob::TEXT => 'alohaaa',
]);
}, 'Need e-mail');
}
}

View file

@ -0,0 +1,186 @@
<?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(), new Privilege(Privilege::AcceptUserRegistration));
$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 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));
$this->testRegularPrivilege(new ListLogsJob(), new Privilege(Privilege::ListLogs));
$this->testRegularPrivilege(new ListPostsJob(), new Privilege(Privilege::ListPosts));
$this->testRegularPrivilege(new ListRelatedTagsJob(), new Privilege(Privilege::ListTags));
$this->testRegularPrivilege(new ListTagsJob(), new Privilege(Privilege::ListTags));
$this->testRegularPrivilege(new ListUsersJob(), new Privilege(Privilege::ListUsers));
$this->testRegularPrivilege(new PasswordResetJob(), false);
$this->testRegularPrivilege(new MergeTagsJob(), new Privilege(Privilege::MergeTags));
$this->testRegularPrivilege(new RenameTagsJob(), new Privilege(Privilege::RenameTags));
}
protected function testRegularPrivilege($job, $expectedPrivilege)
{
$this->testedJobs []= $job;
$this->assert->areEquivalent($expectedPrivilege, $job->requiresPrivilege());
}
public function testDynamicPostPrivileges()
{
$this->login($this->mockUser());
$this->testDynamicPostPrivilege(new DeletePostJob(), new Privilege(Privilege::DeletePost));
$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));
$this->testDynamicPostPrivilege(new FeaturePostJob(), new Privilege(Privilege::FeaturePost));
$this->testDynamicPostPrivilege(new FlagPostJob(), new Privilege(Privilege::FlagPost));
$this->testDynamicPostPrivilege(new ScorePostJob(), new Privilege(Privilege::ScorePost));
$this->testDynamicPostPrivilege(new TogglePostTagJob(), new Privilege(Privilege::EditPostTags));
$this->testDynamicPostPrivilege(new TogglePostVisibilityJob(), new Privilege(Privilege::HidePost));
$this->testDynamicPostPrivilege(new TogglePostFavoriteJob(), new Privilege(Privilege::FavoritePost));
}
protected function testDynamicPostPrivilege($job, $expectedPrivilege)
{
$this->testedJobs []= $job;
$ownPost = $this->mockPost(Auth::getCurrentUser());
$otherPost = $this->mockPost($this->mockUser());
$expectedPrivilege->secondary = 'all';
$job->setArgument(AbstractJob::POST_ID, $otherPost->getId());
$job->prepare();
$this->assert->areEquivalent($expectedPrivilege, $job->requiresPrivilege());
$expectedPrivilege->secondary = 'own';
$job->setArgument(AbstractJob::POST_ID, $ownPost->getId());
$job->prepare();
$this->assert->areEquivalent($expectedPrivilege, $job->requiresPrivilege());
}
public function testDynamicPostRetrievalPrivileges()
{
$jobs =
[
new GetPostJob(),
new GetPostContentJob(),
];
$post = $this->mockPost($this->mockUser());
foreach ($jobs as $job)
{
$this->testedJobs []= $job;
$post->setHidden(true);
PostModel::save($post);
$job->setArgument(AbstractJob::POST_ID, $post->getId());
$job->setArgument(AbstractJob::POST_NAME, $post->getName());
$job->prepare();
$this->assert->areEquivalent([
new Privilege(Privilege::ViewPost, 'hidden'),
new Privilege(Privilege::ViewPost, 'safe')], $job->requiresPrivilege());
}
}
public function testDynamicPostThumbPrivileges()
{
$job = new GetPostThumbJob();
$this->testedJobs []= $job;
$this->assert->areEquivalent(false, $job->requiresPrivilege());
}
public function testDynamicUserPrivileges()
{
$ownUser = $this->mockUser();
$this->login($ownUser);
$this->testDynamicUserPrivilege(new DeleteUserJob(), new Privilege(Privilege::DeleteUser));
$this->testDynamicUserPrivilege(new EditUserAccessRankJob(), new Privilege(Privilege::ChangeUserAccessRank));
$this->testDynamicUserPrivilege(new EditUserEmailJob(), new Privilege(Privilege::ChangeUserEmail));
$this->testDynamicUserPrivilege(new EditUserNameJob(), new Privilege(Privilege::ChangeUserName));
$this->testDynamicUserPrivilege(new EditUserPasswordJob(), new Privilege(Privilege::ChangeUserPassword));
$this->testDynamicUserPrivilege(new FlagUserJob(), new Privilege(Privilege::FlagUser));
$this->testDynamicUserPrivilege(new GetUserJob(), new Privilege(Privilege::ViewUser));
$this->testDynamicUserPrivilege(new ToggleUserBanJob(), new Privilege(Privilege::BanUser));
}
protected function testDynamicUserPrivilege($job, $expectedPrivilege)
{
$ownUser = Auth::getCurrentUser();
$otherUser = $this->mockUser($this->mockUser());
$otherUser->setName('somebody-else');
UserModel::save($otherUser);
$this->testedJobs []= $job;
$expectedPrivilege->secondary = 'own';
$job->setArgument(AbstractJob::USER_NAME, $ownUser->getName());
$job->prepare();
$this->assert->areEquivalent($expectedPrivilege, $job->requiresPrivilege());
$expectedPrivilege->secondary = 'all';
$job->setArgument(AbstractJob::USER_NAME, $otherUser->getName());
$job->prepare();
$this->assert->areEquivalent($expectedPrivilege, $job->requiresPrivilege());
}
public function testDynamicCommentPrivileges()
{
$this->login($this->mockUser());
$this->testDynamicCommentPrivilege(new DeleteCommentJob(), new Privilege(Privilege::DeleteComment));
$this->testDynamicCommentPrivilege(new EditCommentJob(), new Privilege(Privilege::EditComment));
}
protected function testDynamicCommentPrivilege($job, $expectedPrivilege)
{
$ownComment = $this->mockComment(Auth::getCurrentUser());
$otherComment = $this->mockComment($this->mockUser());
$this->testedJobs []= $job;
$expectedPrivilege->secondary = 'own';
$job->setArgument(AbstractJob::COMMENT_ID, $ownComment->getId());
$job->prepare();
$this->assert->areEquivalent($expectedPrivilege, $job->requiresPrivilege());
$expectedPrivilege->secondary = 'all';
$job->setArgument(AbstractJob::COMMENT_ID, $otherComment->getId());
$job->prepare();
$this->assert->areEquivalent($expectedPrivilege, $job->requiresPrivilege());
}
public function testPrivilegeEnforcing()
{
$this->assert->throws(function()
{
$post = $this->mockPost(Auth::getCurrentUser());
getConfig()->registration->needEmailForCommenting = false;
return Api::run(
new AddCommentJob(),
[
AddCommentJob::POST_ID => $post->getId(),
AddCommentJob::TEXT => 'alohaaa',
]);
}, 'Insufficient privileges');
}
}

View file

@ -24,16 +24,6 @@ class AddCommentJobTest extends AbstractTest
});
}
public function testEmailActivation()
{
$this->prepare();
getConfig()->registration->needEmailForCommenting = true;
$this->assert->throws(function()
{
$this->runApi('alohaaaa');
}, 'Need e-mail');
}
public function testAlmostTooShortText()
{
$this->prepare();
@ -70,28 +60,6 @@ class AddCommentJobTest extends AbstractTest
}, 'Comment must have at most');
}
public function testNoAuth()
{
$this->prepare();
Auth::setCurrentUser(null);
$this->assert->doesNotThrow(function()
{
$this->runApi('alohaaaaaaa');
});
}
public function testAccessDenial()
{
$this->prepare();
$this->revokeAccess('addComment');
$this->assert->throws(function()
{
$this->runApi('alohaaaaaaa');
}, 'Insufficient privileges');
}
public function testAnonymous()
{
$this->prepare();

View file

@ -14,57 +14,6 @@ class DeleteCommentJobTest extends AbstractTest
$this->assert->areEqual(0, CommentModel::getCount());
}
public function testNoAuth()
{
$this->prepare();
Auth::setCurrentUser(null);
$this->assert->throws(function()
{
$this->runApi();
}, 'Not logged in');
}
public function testOwnAccessDenial()
{
$this->prepare();
$this->assert->throws(function()
{
$this->runApi();
}, 'Insufficient privileges');
}
public function testOtherAccessGrant()
{
$this->prepare();
$this->grantAccess('deleteComment.all');
$comment = $this->mockComment(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
$this->assert->doesNotThrow(function() use ($comment)
{
$this->runApi($comment);
});
}
public function testOtherAccessDenial()
{
$this->prepare();
$this->grantAccess('deleteComment.own');
$comment = $this->mockComment(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
$this->assert->throws(function() use ($comment)
{
$this->runApi($comment);
}, 'Insufficient privileges');
}
public function testWrongCommentId()
{
$this->prepare();

View file

@ -62,70 +62,6 @@ class EditCommentJobTest extends AbstractTest
}, 'Comment must have at most');
}
public function testNoAuth()
{
$this->prepare();
$this->grantAccess('editComment');
Auth::setCurrentUser(null);
$this->assert->throws(function()
{
$this->runApi('alohaaaaaaa');
}, 'Not logged in');
}
public function testOwnAccessDenial()
{
$this->prepare();
$this->assert->throws(function()
{
$this->runApi('alohaaaaaaa');
}, 'Insufficient privileges');
}
public function testOtherAccessGrant()
{
$this->prepare();
$this->grantAccess('editComment.all');
$comment = $this->mockComment(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
$this->assert->doesNotThrow(function() use ($comment)
{
Api::run(
new EditCommentJob(),
[
EditCommentJob::COMMENT_ID => $comment->getId(),
EditCommentJob::TEXT => 'alohaa',
]);
});
}
public function testOtherAccessDenial()
{
$this->prepare();
$this->grantAccess('editComment.own');
$comment = $this->mockComment(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
$this->assert->throws(function() use ($comment)
{
Api::run(
new EditCommentJob(),
[
EditCommentJob::COMMENT_ID => $comment->getId(),
EditCommentJob::TEXT => 'alohaa',
]);
}, 'Insufficient privileges');
}
public function testWrongCommentId()
{
$this->prepare();

View file

@ -103,61 +103,6 @@ class EditPostContentJobTest extends AbstractTest
});
}
public function testNoAuth()
{
$this->prepare();
$this->grantAccess('editPostContent');
Auth::setCurrentUser(null);
$this->assert->doesNotThrow(function()
{
$this->uploadFromFile('image.jpg');
});
}
public function testOwnAccessDenial()
{
$this->prepare();
$this->assert->throws(function()
{
$this->uploadFromFile('image.jpg');
}, 'Insufficient privileges');
}
public function testOtherAccessGrant()
{
$this->prepare();
$this->grantAccess('editPostContent.all');
$post = $this->mockPost(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
$this->assert->doesNotThrow(function() use ($post)
{
$this->uploadFromFile('image.jpg', $post);
});
}
public function testOtherAccessDenial()
{
$this->prepare();
$this->grantAccess('editPostContent.own');
$post = $this->mockPost(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
$this->assert->throws(function() use ($post)
{
$this->uploadFromFile('image.jpg', $post);
}, 'Insufficient privileges');
}
public function testWrongPostId()
{
$this->assert->throws(function()

View file

@ -37,70 +37,6 @@ class EditPostSourceJobTest extends AbstractTest
}, 'Source must have at most');
}
public function testNoAuth()
{
$this->prepare();
$this->grantAccess('editPostSource');
Auth::setCurrentUser(null);
$this->assert->doesNotThrow(function()
{
$this->runApi('alohaaaaaaa');
});
}
public function testOwnAccessDenial()
{
$this->prepare();
$this->assert->throws(function()
{
$this->runApi('alohaaaaaaa');
}, 'Insufficient privileges');
}
public function testOtherAccessGrant()
{
$this->prepare();
$this->grantAccess('editPostSource.all');
$post = $this->mockPost(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
$this->assert->doesNotThrow(function() use ($post)
{
Api::run(
new EditPostSourceJob(),
[
EditPostSourceJob::POST_ID => $post->getId(),
EditPostSourceJob::SOURCE => 'alohaa',
]);
});
}
public function testOtherAccessDenial()
{
$this->prepare();
$this->grantAccess('editPostSource.own');
$post = $this->mockPost(Auth::getCurrentUser());
//login as someone else
$this->login($this->mockUser());
$this->assert->throws(function() use ($post)
{
Api::run(
new EditPostSourceJob(),
[
EditPostSourceJob::POST_ID => $post->getId(),
EditPostSourceJob::SOURCE => 'alohaa',
]);
}, 'Insufficient privileges');
}
public function testWrongPostId()
{
$this->prepare();

View file

@ -55,14 +55,6 @@ class ListCommentJobTest extends AbstractTest
$this->assert->areEqual(1, count($ret->entities));
}
public function testAccessDenial()
{
$this->assert->throws(function()
{
$this->runApi(1);
}, 'Insufficient privileges');
}
protected function runApi($page)
{
return Api::run(

View file

@ -57,28 +57,6 @@ class PreviewCommentJobTest extends AbstractTest
}, 'Comment must have at most');
}
public function testNoAuth()
{
$this->prepare();
Auth::setCurrentUser(null);
$this->assert->doesNotThrow(function()
{
return $this->runApi('alohaaaaaaa');
});
}
public function testAccessDenial()
{
$this->prepare();
$this->revokeAccess('addComment');
$this->assert->throws(function()
{
return $this->runApi('alohaaaaaaa');
}, 'Insufficient privileges');
}
protected function runApi($text)
{

View file

@ -1,5 +1,5 @@
<?php
class BasicAuthTest extends AbstractTest
class AuthTest extends AbstractTest
{
public function testValidPassword()
{