Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor test_permissions.py #3603

Merged
merged 4 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions perma_web/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ def _create_server(self, connections_override=None):
HTTPSLiveServerThread._create_server = _create_server


# shadow this fixture from pytest_django_liveserver_ssl so that it doesn't request the admin client (which doesn't work with our fixture situation)
@pytest.fixture()
def live_server_ssl_clients_for_patch(client):
return [client]


@pytest.fixture(scope="session")
def set_up_certs():
certs = [
Expand Down Expand Up @@ -518,6 +512,11 @@ def org_user(org_user_factory):
return org_user_factory()


@pytest.fixture
def admin_user(link_user_factory):
return link_user_factory(is_staff=True)


@pytest.fixture
def perma_client():
"""
Expand Down
7 changes: 6 additions & 1 deletion perma_web/perma/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,12 @@ def can_edit_registrar(self, registrar):
return self.is_staff or self.registrar == registrar

def can_edit_organization(self, organization):
return self.organizations.filter(pk=organization.pk).exists()
if self.is_staff:
return True
elif self.registrar:
return self.registrar == organization.registrar
else:
return self.organizations.filter(pk=organization.pk).exists()


### subscriptions ###
Expand Down
317 changes: 176 additions & 141 deletions perma_web/perma/tests/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,144 +3,179 @@

from perma.urls import urlpatterns

from .utils import PermaTestCase


class PermissionsTestCase(PermaTestCase):

@override_settings(SECURE_SSL_REDIRECT=False)
def test_permissions(self):
"""Test who can log into restricted pages."""
all_users = {
'test_admin_user@example.com',
'test_registrar_user@example.com',
'test_org_user@example.com',
'test_user@example.com'
}
views = [
{
'urls': [
['user_management_stats'],
['user_management_manage_admin_user'],
['user_management_admin_user_add_user'],
['user_management_manage_single_admin_user_delete', {'kwargs':{'user_id': 1}}],
['user_management_manage_single_admin_user_remove', {'kwargs':{'user_id': 1}}],
['user_management_manage_registrar'],
['user_management_manage_single_registrar_user', {'kwargs':{'user_id': 2}}],
['user_management_manage_single_registrar_user_delete', {'kwargs':{'user_id': 2}}],
['user_management_manage_single_registrar_user_reactivate', {'kwargs':{'user_id': 2}}],
['user_management_approve_pending_registrar', {'kwargs':{'registrar_id': 2}}],
['user_management_manage_user'],
['user_management_user_add_user'],
['user_management_manage_single_user', {'kwargs':{'user_id': 4}}],
['user_management_manage_single_user_delete', {'kwargs':{'user_id': 4}}],
['user_management_manage_single_organization_user_delete', {'kwargs':{'user_id': 3}}],
['user_management_manage_single_organization_user_reactivate', {'kwargs':{'user_id': 3}}],
['user_management_manage_single_user_reactivate', {'kwargs':{'user_id': 4}}],
['user_management_manage_single_sponsored_user_delete', {'kwargs':{'user_id': 20}}],
['user_management_manage_single_sponsored_user_reactivate', {'kwargs':{'user_id': 20}}]
],
'allowed': {'test_admin_user@example.com'},
},
{
'urls': [
['user_management_manage_registrar_user'],
['user_management_registrar_user_add_user'],
['user_management_manage_single_registrar', {'kwargs':{'registrar_id': 1}}],
['user_management_manage_sponsored_user'],
['user_management_manage_sponsored_user_export_user_list'],
['user_management_sponsored_user_add_user'],
['user_management_manage_single_sponsored_user', {'kwargs':{'user_id': 20}}],
['user_management_manage_single_sponsored_user_remove', {'kwargs':{'user_id': 20, 'registrar_id': 1}}],
['user_management_manage_single_sponsored_user_readd', {'kwargs':{'user_id': 20, 'registrar_id': 1}}],
['user_management_manage_single_sponsored_user_links', {'kwargs':{'user_id': 20, 'registrar_id': 1}}]
],
'allowed': {'test_admin_user@example.com', 'test_registrar_user@example.com'},
},
{
'urls': [
['user_management_manage_single_organization_user', {'kwargs':{'user_id': 3}}],
['user_management_manage_organization_user'],
['user_management_manage_organization'],
['user_management_manage_single_organization', {'kwargs':{'org_id':1}}],
['user_management_manage_single_organization_export_user_list', {'kwargs': {'org_id': 1}}],
['user_management_manage_single_organization_delete', {'kwargs':{'org_id':1}}],
['user_management_organization_user_add_user'],
['user_management_manage_single_organization_user_remove', {'kwargs':{'user_id': 3},
'success_status': 302}],
],
'allowed': {'test_admin_user@example.com', 'test_registrar_user@example.com',
'test_org_user@example.com'},
},
{
'urls': [
['user_management_manage_single_registrar_user_remove', {'kwargs':{'user_id': 2}}],
],
'allowed': {'test_registrar_user@example.com'}
},

{
'urls': [
['user_management_organization_user_leave_organization', {'kwargs':{'org_id': 1}}],
],
'allowed': {'test_org_user@example.com'}
},

{
'urls': [
['user_management_settings_profile'],
['user_management_settings_password'],
['user_management_settings_tools'],
['create_link'],
['user_delete_link', {'kwargs':{'guid':'1234-1234'},'success_status':404}],
],
'allowed': {'test_user@example.com'},
'disallowed': set(),
},
]

views_tested = set()
for view in views:
for url in view['urls']:
view_name = url[0]
opts = url[1] if len(url)>1 else {}
views_tested.add(view_name)
url = reverse(view_name, kwargs=opts.get('kwargs', None))
success_status = opts.get('success_status', 200)
success_test = opts.get('success_test', None)

# try while logged out
self.client.logout()
resp = self.client.get(url)
self.assertRedirects(resp, f"{reverse('user_management_limited_login')}?next={url}")

# try with valid users
for user in view['allowed']:
self.log_in_user(user)
resp = self.client.get(url, secure=True)
if success_test:
success_test(resp)
else:
self.assertEqual(resp.status_code, success_status,
"View %s returned status %s for user %s; expected %s." % (view_name, resp.status_code, user, success_status))

# try with invalid users
for user in view.get('disallowed', all_users - view['allowed']):
self.log_in_user(user)
resp = self.client.get(url)
self.assertEqual(resp.status_code, 403,
"View %s returned status %s for user %s; expected %s." % (view_name, resp.status_code, user, success_status))
# self.assertRedirects(resp, settings.LOGIN_URL+"?next="+url, target_status_code=302,
# msg_prefix="Error while confirming that %s can't view %s: " % (user, view_name))

# make sure that all ^manage/ views were tested
for urlpattern in urlpatterns:

# Things that are no longer needed and have become redirects or other special cases
excluded_names = ['create_link_with_org',
'link_browser',
'user_management_resend_activation']

if urlpattern.pattern._regex.startswith(r'^manage/') and urlpattern.pattern._regex != '^manage/?$' and urlpattern.name not in excluded_names:
self.assertTrue(urlpattern.name in views_tested,
"Permissions not checked for view '%s' -- add to 'views' or 'any_user_allowed'." % urlpattern.name)
import pytest


@override_settings(SECURE_SSL_REDIRECT=False)
@pytest.mark.django_db
def test_permissions(client, admin_user, registrar_user, org_user, link_user_factory, sponsored_user, pending_registrar):
"""Test who can log into restricted pages."""

regular_user = link_user_factory()

# Nickname for convenience
org_user_org = org_user.organizations.first()
registrar_user_registrar = registrar_user.registrar
sponsored_user_registrar = sponsored_user.sponsorships.first().registrar

# Retrieve the registrar user who supports the sponsored user
sponsored_user_registrar_user = sponsored_user_registrar.users.first()
assert sponsored_user_registrar_user

# Create the registrar user who supports the org user
assert not org_user_org.registrar.users.first()
org_user_org.registrar.users.add(link_user_factory())
org_user_registrar_user = org_user_org.registrar.users.first()
assert org_user_registrar_user

all_users = {
admin_user,
registrar_user,
org_user_registrar_user,
sponsored_user_registrar_user,
org_user,
sponsored_user,
regular_user
}

views = [
{
'urls': [
['user_management_stats'],
['user_management_manage_admin_user'],
['user_management_admin_user_add_user'],
['user_management_manage_single_admin_user_delete', {'kwargs':{'user_id': admin_user.id}}],
['user_management_manage_single_admin_user_remove', {'kwargs':{'user_id': admin_user.id}}],
['user_management_manage_registrar'],
['user_management_manage_single_registrar_user', {'kwargs':{'user_id': registrar_user.id}}],
['user_management_manage_single_registrar_user_delete', {'kwargs':{'user_id': registrar_user.id}}],
['user_management_manage_single_registrar_user_reactivate', {'kwargs':{'user_id': registrar_user.id}}],
['user_management_approve_pending_registrar', {'kwargs':{'registrar_id': pending_registrar.id}}],
['user_management_manage_user'],
['user_management_user_add_user'],
['user_management_manage_single_user', {'kwargs':{'user_id': regular_user.id}}],
['user_management_manage_single_user_delete', {'kwargs':{'user_id': regular_user.id}}],
['user_management_manage_single_organization_user_delete', {'kwargs':{'user_id': org_user.id}}],
['user_management_manage_single_organization_user_reactivate', {'kwargs':{'user_id': org_user.id}}],
['user_management_manage_single_user_reactivate', {'kwargs':{'user_id': regular_user.id}}],
['user_management_manage_single_sponsored_user_delete', {'kwargs':{'user_id': sponsored_user.id}}],
['user_management_manage_single_sponsored_user_reactivate', {'kwargs':{'user_id': sponsored_user.id}}]
],
'allowed': {admin_user},
},
{
'urls': [
['user_management_manage_registrar_user'],
['user_management_registrar_user_add_user'],
['user_management_manage_sponsored_user'],
['user_management_manage_sponsored_user_export_user_list'],
['user_management_sponsored_user_add_user']
],
'allowed': {admin_user, registrar_user, org_user_registrar_user, sponsored_user_registrar_user},
},
{
'urls': [
['user_management_manage_single_registrar', {'kwargs':{'registrar_id': registrar_user_registrar.id}}],
],
'allowed': {admin_user, registrar_user},
},
{
'urls': [
['user_management_manage_single_sponsored_user', {'kwargs':{'user_id': sponsored_user.id}}],
['user_management_manage_single_sponsored_user_remove', {'kwargs':{'user_id': sponsored_user.id, 'registrar_id': sponsored_user_registrar.id}}],
['user_management_manage_single_sponsored_user_readd', {'kwargs':{'user_id': sponsored_user.id, 'registrar_id': sponsored_user_registrar.id}}],
['user_management_manage_single_sponsored_user_links', {'kwargs':{'user_id': sponsored_user.id, 'registrar_id': sponsored_user_registrar.id}}]
],
'allowed': {admin_user, sponsored_user_registrar_user},
},
{
'urls': [
['user_management_manage_organization_user'],
['user_management_manage_organization'],
['user_management_organization_user_add_user'],
],
'allowed': {admin_user, registrar_user, org_user_registrar_user, sponsored_user_registrar_user, org_user},
},
{
'urls': [
['user_management_manage_single_organization_user', {'kwargs':{'user_id': org_user.id}}],
['user_management_manage_single_organization', {'kwargs':{'org_id': org_user_org.id}}],
['user_management_manage_single_organization_export_user_list', {'kwargs': {'org_id': org_user_org.id}}],
['user_management_manage_single_organization_delete', {'kwargs':{'org_id': org_user_org.id}}],
['user_management_manage_single_organization_user_remove', {'kwargs':{'user_id': org_user.id},
'success_status': 302}],
],
'allowed': {admin_user, org_user_registrar_user, org_user},
},
{
'urls': [
['user_management_manage_single_registrar_user_remove', {'kwargs':{'user_id': registrar_user.id}}],
],
'allowed': {registrar_user}
},

{
'urls': [
['user_management_organization_user_leave_organization', {'kwargs':{'org_id': org_user_org.id}}],
],
'allowed': {org_user}
},

{
'urls': [
['user_management_settings_profile'],
['user_management_settings_password'],
['user_management_settings_tools'],
['create_link'],
['user_delete_link', {'kwargs':{'guid':'1234-1234'},'success_status':404}],
],
'allowed': {regular_user, sponsored_user},
'disallowed': set(),
},
]

views_tested = set()
for view in views:
for url in view['urls']:
view_name = url[0]
opts = url[1] if len(url)>1 else {}
views_tested.add(view_name)
url = reverse(view_name, kwargs=opts.get('kwargs', None))
success_status = opts.get('success_status', 200)
success_test = opts.get('success_test', None)

# try while logged out
client.logout()
resp = client.get(url)

assert resp.status_code == 302
assert resp['Location'] == f"{reverse('user_management_limited_login')}?next={url}"

# try with valid users
for user in view['allowed']:
client.force_login(user)
resp = client.get(url, secure=True)
if success_test:
success_test(resp)
else:
assert resp.status_code == success_status, \
"View %s returned status %s for user %s; expected %s." % (view_name, resp.status_code, user, success_status)

# try with invalid users
for user in view.get('disallowed', all_users - view['allowed']):
client.force_login(user)
resp = client.get(url)
assert resp.status_code == 403, \
"View %s returned status %s for user %s; expected %s." % (view_name, resp.status_code, user, 403)

# make sure that all ^manage/ views were tested
for urlpattern in urlpatterns:

# Things that are no longer needed and have become redirects or other special cases
excluded_names = ['create_link_with_org',
'link_browser',
'user_management_resend_activation']

if urlpattern.pattern._regex.startswith(r'^manage/') and urlpattern.pattern._regex != '^manage/?$' and urlpattern.name not in excluded_names:
assert urlpattern.name in views_tested, \
"Permissions not checked for view '%s' -- add to 'views' or 'any_user_allowed'." % urlpattern.name
Loading
Loading