Commit 2458f055 authored by Chris Lamb's avatar Chris Lamb
Browse files

Completely rework permission logic for viewing a job to make it clearer (with tests). (Ref; #39)

parent 3509a999
from django.urls import reverse
from django.contrib.auth import get_user_model
from freenodejobs.utils.test import TestCase
from freenodejobs.jobs.enums import JobTypeEnum, StateEnum
UserModel = get_user_model()
class ViewTest(TestCase):
def test_view(self):
......@@ -32,31 +35,88 @@ class ViewTest(TestCase):
self.assertGET(200, '{}?q=foo'.format(reverse('jobs:full-time')))
class JobTest(TestCase):
def test_new(self):
self.job.set_state(StateEnum.NEW, self.user, "")
self.job.save()
self.assertStatusCode(404, self.client.get, self.job)
class BaseJobTestCase(TestCase):
def setUp(self, state):
super().setUp()
def test_new_to_waiting_for_approval(self):
self.job.set_state(StateEnum.WAITING_FOR_APPROVAL, self.user, "")
self.job.set_state(state, self.user, "")
self.job.save()
self.assertStatusCode(404, self.client.get, self.job)
def test_waiting_for_approval_to_new(self):
self.job.set_state(StateEnum.WAITING_FOR_APPROVAL, self.user, "")
self.job.save()
self.assertStatusCode(404, self.client.get, self.job)
self.other = UserModel.objects.create_user(
'other@example.com',
'password',
)
def test_waiting_to_live(self):
self.job.set_state(StateEnum.LIVE, self.user, "")
self.job.save()
self.assertGET(200, self.job)
def assertJobStatusCode(self, status, user):
self.assertStatusCode(status, self.client.get, self.job, login=user)
def test_live_to_removed(self):
self.job.set_state(StateEnum.REMOVED, self.user, "")
self.job.save()
self.assertStatusCode(404, self.client.get, self.job)
class NewJobTest(BaseJobTestCase):
def setUp(self):
super().setUp(StateEnum.NEW)
def test_anonymous(self):
self.assertJobStatusCode(404, None)
def test_creator(self):
self.assertJobStatusCode(200, self.user)
def test_other_user(self):
self.assertJobStatusCode(404, self.other)
def test_staff(self):
self.assertJobStatusCode(200, self.admin)
class WaitingForApprovalJobTest(BaseJobTestCase):
def setUp(self):
super().setUp(StateEnum.WAITING_FOR_APPROVAL)
def test_anonymous(self):
self.assertJobStatusCode(404, None)
def test_creator(self):
self.assertJobStatusCode(200, self.user)
def test_other_user(self):
self.assertJobStatusCode(404, self.other)
def test_staff(self):
self.assertJobStatusCode(200, self.admin)
class LiveJobTest(BaseJobTestCase):
def setUp(self):
super().setUp(StateEnum.LIVE)
def test_anonymous(self):
self.assertJobStatusCode(200, None)
def test_creator(self):
self.assertJobStatusCode(200, self.user)
def test_other_user(self):
self.assertJobStatusCode(200, self.other)
def test_staff(self):
self.assertJobStatusCode(200, self.admin)
class RemovedJobTest(BaseJobTestCase):
def setUp(self):
super().setUp(StateEnum.REMOVED)
def test_anonymous(self):
self.assertJobStatusCode(410, None)
def test_creator(self):
self.assertJobStatusCode(410, self.user)
def test_other_user(self):
self.assertJobStatusCode(410, self.other)
def test_staff(self):
self.assertJobStatusCode(410, self.admin)
class FeedTest(TestCase):
......
......@@ -28,12 +28,27 @@ def view(request, job_type=None):
def job(request, slug, prefix=None):
job = get_object_or_404(Job, slug=slug)
if not (job.state == StateEnum.LIVE or request.user == job.user or
request.user.is_staff):
raise Http404()
# Removed jobs are not visible by anyone
if job.state == StateEnum.REMOVED:
return render(request, 'jobs/removed.html')
return render(request, 'jobs/removed.html', status=410)
def can_view():
# Live jobs are always viewable
if job.state == StateEnum.LIVE:
return True
# You can always view your "own" jobs
if request.user == job.user:
return True
# Staff members can view any job
if request.user.is_staff:
return True
return False
if not can_view():
raise Http404()
if request.path != job.get_absolute_url():
return redirect(job.get_absolute_url())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment