Integrate yesterday's AccessChecker progress and tests upgrade.
diff --git a/app/melange/request/access.py b/app/melange/request/access.py
index a44f92c..8c3f191 100644
--- a/app/melange/request/access.py
+++ b/app/melange/request/access.py
@@ -19,9 +19,12 @@
from melange.request import exception
from soc.logic import links
-_DEF_NOT_HOST = translation.ugettext(
+_MESSAGE_NOT_PROGRAM_ADMINISTRATOR = translation.ugettext(
'You need to be a program administrator to access this page.')
+_MESSAGE_NOT_DEVELOPER = translation.ugettext(
+ 'This page is only accessible to developers.')
+
def ensureLoggedIn(self):
"""Ensures that the user is logged in.
@@ -97,6 +100,20 @@
elif not data.gae_user:
raise exception.LoginRequired()
elif not data.is_host:
- raise exception.Forbidden(message=_DEF_NOT_HOST)
+ raise exception.Forbidden(message=_MESSAGE_NOT_PROGRAM_ADMINISTRATOR)
PROGRAM_ADMINISTRATOR_ACCESS_CHECKER = ProgramAdministratorAccessChecker()
+
+
+# TODO(nathaniel): Eliminate this or make it a
+# "SiteAdministratorAccessChecker" - there should be no aspects of Melange
+# that require developer action or are limited only to developers.
+class DeveloperAccessChecker(AccessChecker):
+ """AccessChecker that ensures that the user is a developer."""
+
+ def checkAccess(self, data, check, mutator):
+ """See AccessChecker.checkAccess for specification."""
+ if not data.is_developer:
+ raise exception.Forbidden(message=_MESSAGE_NOT_DEVELOPER)
+
+DEVELOPER_ACCESS_CHECKER = DeveloperAccessChecker()
diff --git a/app/soc/views/site.py b/app/soc/views/site.py
index 7cb0c30..b232e5d 100644
--- a/app/soc/views/site.py
+++ b/app/soc/views/site.py
@@ -24,6 +24,7 @@
from django.forms import widgets as django_widgets
from django.utils.translation import ugettext
+from melange.request import access
from melange.request import exception
from soc.logic import cleaning
from soc.logic import site as site_logic
@@ -70,6 +71,11 @@
class EditSitePage(base.RequestHandler):
"""View for the participant profile."""
+ # TODO(nathaniel): This page should use something like a "site admin
+ # access checker" - there should be no pages accessible only to
+ # developers.
+ access_checker = access.DEVELOPER_ACCESS_CHECKER
+
def djangoURLPatterns(self):
return [
django_url(r'^site/edit$', self, name='edit_site_settings'),
@@ -85,10 +91,6 @@
return {'data': json_data}
- def checkAccess(self, data, check, mutator):
- if not data.is_developer:
- raise exception.Forbidden(message=DEF_NO_DEVELOPER)
-
def templatePath(self):
# TODO: make this specific to the current active program
return 'soc/site/base.html'
diff --git a/tests/app/melange/request/test_access.py b/tests/app/melange/request/test_access.py
index 54c492b..6b2984e 100644
--- a/tests/app/melange/request/test_access.py
+++ b/tests/app/melange/request/test_access.py
@@ -19,6 +19,8 @@
from nose.plugins import skip
from melange.request import access
+from melange.request import exception
+from soc.views.helper import request_data
class Explosive(object):
@@ -65,3 +67,24 @@
def testAnonymousDeniedAccess(self):
"""Tests that logged-out users are denied access."""
raise skip.SkipTest()
+
+
+class DeveloperAccessCheckerTest(unittest.TestCase):
+ """Tests the DeveloperAccessChecker class."""
+
+ def testDeveloperAccessAllowed(self):
+ data = request_data.RequestData(None, None, None)
+ # TODO(nathaniel): Reaching around RequestHandler public API.
+ data._is_developer = True
+
+ access_checker = access.DeveloperAccessChecker()
+ access_checker.checkAccess(data, None, None)
+
+ def testNonDeveloperAccessDenied(self):
+ data = request_data.RequestData(None, None, None)
+ # TODO(nathaniel): Reaching around RequestHandler public API.
+ data._is_developer = False
+
+ access_checker = access.DeveloperAccessChecker()
+ with self.assertRaises(exception.UserError):
+ access_checker.checkAccess(data, None, None)
diff --git a/tests/app/soc/modules/gci/views/test_homepage.py b/tests/app/soc/modules/gci/views/test_homepage.py
index 90668a3..976a583 100644
--- a/tests/app/soc/modules/gci/views/test_homepage.py
+++ b/tests/app/soc/modules/gci/views/test_homepage.py
@@ -104,4 +104,4 @@
# TOOD
#apply_tmpl = response.context['apply']
#self.assertTrue(apply_tmpl.data.profile)
- #self.assertFalse('profile_link' in apply_tmpl.context())
+ #self.assertNotIn('profile_link', apply_tmpl.context())
diff --git a/tests/app/soc/modules/gci/views/test_task.py b/tests/app/soc/modules/gci/views/test_task.py
index 39117c9..13f026d 100644
--- a/tests/app/soc/modules/gci/views/test_task.py
+++ b/tests/app/soc/modules/gci/views/test_task.py
@@ -500,7 +500,7 @@
self.profile_helper.createMentor(self.org)
profile = self.profile_helper.profile
- self.assertFalse(profile.key() in self.task.subscribers)
+ self.assertNotIn(profile.key(), self.task.subscribers)
url = self._taskPageUrl(self.task)
response = self.buttonPost(url, 'button_subscribe')
@@ -524,7 +524,7 @@
task = task_model.GCITask.get(self.task.key())
self.assertResponseRedirect(response)
- self.assertFalse(profile.key() in task.subscribers)
+ self.assertNotIn(profile.key(), task.subscribers)
def testPostSubmitWork(self):
"""Tests for submitting work.
diff --git a/tests/app/soc/modules/gsoc/views/test_homepage.py b/tests/app/soc/modules/gsoc/views/test_homepage.py
index d9511dd..9749dd5 100644
--- a/tests/app/soc/modules/gsoc/views/test_homepage.py
+++ b/tests/app/soc/modules/gsoc/views/test_homepage.py
@@ -122,4 +122,4 @@
self.assertHomepageTemplatesUsed(response)
apply_tmpl = response.context['apply']
self.assertTrue(apply_tmpl.data.profile)
- self.assertFalse('profile_link' in apply_tmpl.context())
+ self.assertNotIn('profile_link', apply_tmpl.context())
diff --git a/tests/app/soc/modules/gsoc/views/test_org_home.py b/tests/app/soc/modules/gsoc/views/test_org_home.py
index 8c1126a..89b0834 100644
--- a/tests/app/soc/modules/gsoc/views/test_org_home.py
+++ b/tests/app/soc/modules/gsoc/views/test_org_home.py
@@ -105,17 +105,17 @@
return response.context
def assertNoStudent(self, context):
- self.assertFalse('student_apply_block' in context)
- self.assertFalse('student_profile_link' in context)
- self.assertFalse('submit_proposal_link' in context)
+ self.assertNotIn('student_apply_block', context)
+ self.assertNotIn('student_profile_link', context)
+ self.assertNotIn('submit_proposal_link', context)
def assertNoMentor(self, context):
- self.assertFalse('mentor_apply_block' in context)
- self.assertFalse('mentor_profile_link' in context)
- self.assertFalse('role' in context)
- self.assertFalse('mentor_applied' in context)
- self.assertFalse('invited_role' in context)
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('mentor_apply_block', context)
+ self.assertNotIn('mentor_profile_link', context)
+ self.assertNotIn('role', context)
+ self.assertNotIn('mentor_applied', context)
+ self.assertNotIn('invited_role', context)
+ self.assertNotIn('mentor_request_link', context)
def assertMentor(self):
self.profile_helper.createMentor(self.org)
@@ -123,11 +123,11 @@
self.assertNoStudent(context)
self.assertIn('mentor_apply_block', context)
- self.assertFalse('mentor_profile_link' in context)
+ self.assertNotIn('mentor_profile_link', context)
self.assertEqual('a mentor', context['role'])
- self.assertFalse('mentor_applied' in context)
- self.assertFalse('invited_role' in context)
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('mentor_applied', context)
+ self.assertNotIn('invited_role', context)
+ self.assertNotIn('mentor_request_link', context)
def testAnonymousPreSignup(self):
self.timeline_helper.orgSignup()
@@ -136,24 +136,24 @@
self.assertIn('mentor_apply_block', context)
self.assertIn('mentor_profile_link', context)
- self.assertFalse('role' in context)
- self.assertFalse('mentor_applied' in context)
- self.assertFalse('invited_role' in context)
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('role', context)
+ self.assertNotIn('mentor_applied', context)
+ self.assertNotIn('invited_role', context)
+ self.assertNotIn('mentor_request_link', context)
def testAnonymousDuringSignup(self):
self.timeline_helper.studentSignup()
context = self.homepageContext()
self.assertIn('student_apply_block', context)
self.assertIn('student_profile_link', context)
- self.assertFalse('submit_proposal_link' in context)
+ self.assertNotIn('submit_proposal_link', context)
- self.assertFalse('mentor_apply_block' in context)
+ self.assertNotIn('mentor_apply_block', context)
self.assertIn('mentor_profile_link', context)
- self.assertFalse('role' in context)
- self.assertFalse('mentor_applied' in context)
- self.assertFalse('invited_role' in context)
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('role', context)
+ self.assertNotIn('mentor_applied', context)
+ self.assertNotIn('invited_role', context)
+ self.assertNotIn('mentor_request_link', context)
def testAnonymousPostSignup(self):
self.timeline_helper.postStudentSignup()
@@ -162,22 +162,22 @@
self.assertIn('mentor_apply_block', context)
self.assertIn('mentor_profile_link', context)
- self.assertFalse('role' in context)
- self.assertFalse('mentor_applied' in context)
- self.assertFalse('invited_role' in context)
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('role', context)
+ self.assertNotIn('mentor_applied', context)
+ self.assertNotIn('invited_role', context)
+ self.assertNotIn('mentor_request_link', context)
def testAnonymousStudentsAnnounced(self):
self.timeline_helper.studentsAnnounced()
context = self.homepageContext()
self.assertNoStudent(context)
- self.assertFalse('mentor_apply_block' in context)
- self.assertFalse('mentor_profile_link' in context)
- self.assertFalse('role' in context)
- self.assertFalse('mentor_applied' in context)
- self.assertFalse('invited_role' in context)
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('mentor_apply_block', context)
+ self.assertNotIn('mentor_profile_link', context)
+ self.assertNotIn('role', context)
+ self.assertNotIn('mentor_applied', context)
+ self.assertNotIn('invited_role', context)
+ self.assertNotIn('mentor_request_link', context)
def testMentorPreSignup(self):
self.timeline_helper.orgSignup()
@@ -201,11 +201,11 @@
self.assertNoStudent(context)
self.assertIn('mentor_apply_block', context)
- self.assertFalse('mentor_profile_link' in context)
+ self.assertNotIn('mentor_profile_link', context)
self.assertEqual('an administrator', context['role'])
- self.assertFalse('mentor_applied' in context)
- self.assertFalse('invited_role' in context)
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('mentor_applied', context)
+ self.assertNotIn('invited_role', context)
+ self.assertNotIn('mentor_request_link', context)
def testAppliedMentor(self):
self.profile_helper.createMentorRequest(self.org)
@@ -213,11 +213,11 @@
self.assertNoStudent(context)
self.assertIn('mentor_apply_block', context)
- self.assertFalse('mentor_profile_link' in context)
- self.assertFalse('role' in context)
+ self.assertNotIn('mentor_profile_link', context)
+ self.assertNotIn('role', context)
self.assertIn('mentor_applied', context)
- self.assertFalse('invited_role' in context)
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('invited_role', context)
+ self.assertNotIn('mentor_request_link', context)
def testInvitedMentor(self):
self.profile_helper.createInvitation(self.org, 'mentor')
@@ -225,11 +225,11 @@
self.assertNoStudent(context)
self.assertIn('mentor_apply_block', context)
- self.assertFalse('mentor_profile_link' in context)
- self.assertFalse('role' in context)
- self.assertFalse('mentor_applied' in context)
+ self.assertNotIn('mentor_profile_link', context)
+ self.assertNotIn('role', context)
+ self.assertNotIn('mentor_applied', context)
self.assertEqual('a mentor', context['invited_role'])
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('mentor_request_link', context)
def testInvitedOrgAdmin(self):
self.profile_helper.createInvitation(self.org, 'org_admin')
@@ -237,18 +237,18 @@
self.assertNoStudent(context)
self.assertIn('mentor_apply_block', context)
- self.assertFalse('mentor_profile_link' in context)
- self.assertFalse('role' in context)
- self.assertFalse('mentor_applied' in context)
+ self.assertNotIn('mentor_profile_link', context)
+ self.assertNotIn('role', context)
+ self.assertNotIn('mentor_applied', context)
self.assertEqual('an administrator', context['invited_role'])
- self.assertFalse('mentor_request_link' in context)
+ self.assertNotIn('mentor_request_link', context)
def testStudentDuringSignup(self):
self.timeline_helper.studentSignup()
self.profile_helper.createStudent()
context = self.homepageContext()
self.assertIn('student_apply_block', context)
- self.assertFalse('student_profile_link' in context)
+ self.assertNotIn('student_profile_link', context)
self.assertIn('submit_proposal_link', context)
self.assertNoMentor(context)
diff --git a/tests/app/soc/modules/gsoc/views/test_org_profile.py b/tests/app/soc/modules/gsoc/views/test_org_profile.py
index 9f9de11..83b317b 100644
--- a/tests/app/soc/modules/gsoc/views/test_org_profile.py
+++ b/tests/app/soc/modules/gsoc/views/test_org_profile.py
@@ -229,7 +229,7 @@
self.assertEqual(context['page_name'], 'Organization profile')
self.assertIn('org_home_page_link', context)
self.assertIn('page_name', context)
- self.assertFalse('slot_transfer_page_link' in context)
+ self.assertNotIn('slot_transfer_page_link', context)
self.gsoc.allocations_visible = True
self.gsoc.put()
@@ -242,7 +242,7 @@
response = self.get(url)
self.assertResponseOK(response)
self.assertOrgProfilePageTemplatesUsed(response)
- self.assertFalse('slot_transfer_page_link' in response.context)
+ self.assertNotIn('slot_transfer_page_link', response.context)
def test404IsReturnedWhenOrgDoesNotExists(self):
"""Tests that when an org admin tries to access the profile page for an
diff --git a/tests/app/soc/modules/gsoc/views/test_profile_show.py b/tests/app/soc/modules/gsoc/views/test_profile_show.py
index 4941f5e..06b195d 100644
--- a/tests/app/soc/modules/gsoc/views/test_profile_show.py
+++ b/tests/app/soc/modules/gsoc/views/test_profile_show.py
@@ -77,8 +77,8 @@
self.assertIn('program_name', context)
self.assertIn('profile', context)
self.assertIn('css_prefix', context)
- self.assertFalse('submit_tax_link' in context)
- self.assertFalse('submit_enrollment_link' in context)
+ self.assertNotIn('submit_tax_link', context)
+ self.assertNotIn('submit_enrollment_link', context)
expected_page_name = '%s Profile - %s' % (
self.profile_helper.program.short_name,
diff --git a/tests/app/soc/modules/gsoc/views/test_proposal_review.py b/tests/app/soc/modules/gsoc/views/test_proposal_review.py
index 1f326ca..6d000b7 100644
--- a/tests/app/soc/modules/gsoc/views/test_proposal_review.py
+++ b/tests/app/soc/modules/gsoc/views/test_proposal_review.py
@@ -274,7 +274,7 @@
response = self.get(url)
proposal = GSoCProposal.get(proposal.key())
- self.assertFalse(other_mentor.profile.key() in proposal.possible_mentors)
+ self.assertNotIn(other_mentor.profile.key(), proposal.possible_mentors)
def testPubliclyVisibleButton(self):
self.profile_helper.createStudent()