1
0
mirror of https://github.com/peeringdb/peeringdb.git synced 2024-05-11 05:55:09 +00:00
Files
peeringdb-peeringdb/tests/test_orgadmin.py

667 lines
23 KiB
Python
Raw Normal View History

2018-11-08 19:45:21 +00:00
import pytest
import json
from django.test import Client, TestCase, RequestFactory
from django.contrib.auth.models import Group
from django.conf import settings
2018-11-08 19:45:21 +00:00
import peeringdb_server.models as models
import peeringdb_server.org_admin_views as org_admin
import peeringdb_server.views as views
from django_namespace_perms.constants import PERM_CREATE, PERM_DELETE
from .util import override_group_id
2018-11-08 19:45:21 +00:00
class OrgAdminTests(TestCase):
"""
Test organization administration functionality, such as
org admins permissioning users and approving or denying
affiliation requests
"""
entities = ["ix", "net", "fac"]
@classmethod
def setUpTestData(cls):
# create user and guest group
cls.guest_group = Group.objects.create(name="guest", id=settings.GUEST_GROUP_ID)
cls.user_group = Group.objects.create(name="user", id=settings.USER_GROUP_ID)
settings.USER_GROUP_ID = cls.user_group.id
settings.GUEST_GROUP_ID = cls.guest_group.id
2018-11-08 19:45:21 +00:00
# create test users
for name in [
2019-12-05 16:57:52 +00:00
"org_admin",
"user_a",
"user_b",
"user_c",
"user_d",
"user_e",
"user_f",
2018-11-08 19:45:21 +00:00
]:
2019-12-05 16:57:52 +00:00
setattr(
cls,
name,
models.User.objects.create_user(name, "%s@localhost" % name, name),
)
2018-11-08 19:45:21 +00:00
getattr(cls, name).set_password(name)
# create test org
2019-12-05 16:57:52 +00:00
cls.org = models.Organization.objects.create(name="Test org", status="ok")
2018-11-08 19:45:21 +00:00
cls.org_other = models.Organization.objects.create(
2019-12-05 16:57:52 +00:00
name="Test org other", status="ok"
)
2018-11-08 19:45:21 +00:00
# create test entities
for tag in cls.entities:
kwargs = {"name": "Test %s" % tag, "status": "ok", "org": cls.org}
if tag == "net":
kwargs.update(asn=1)
setattr(cls, tag, models.REFTAG_MAP[tag].objects.create(**kwargs))
# add org_admin user to org as admin
cls.org.admin_usergroup.user_set.add(cls.org_admin)
# add user_a user to org as member
cls.org.usergroup.user_set.add(cls.user_a)
cls.org_other.usergroup.user_set.add(cls.user_b)
def setUp(self):
self.factory = RequestFactory()
def test_users(self):
"""
Tests the result of org_admin_views.users
"""
# test #1 - return a json response with the user we added to the org's member
# usergroup
2019-12-05 16:57:52 +00:00
request = self.factory.get("/org-admin/users?org_id=%d" % (self.org.id))
2018-11-08 19:45:21 +00:00
request.user = self.org_admin
resp = json.loads(org_admin.users(request).content)
self.assertEqual(resp["status"], "ok")
2019-12-05 16:57:52 +00:00
self.assertEqual(
resp["users"],
[
{
"id": self.user_a.id,
"name": "%s <%s, %s>"
% (self.user_a.full_name, self.user_a.email, self.user_a.username),
}
],
)
2018-11-08 19:45:21 +00:00
# test #2 - return 403 response when trying to access the org where org_admin
# is not administrator
2019-12-05 16:57:52 +00:00
request = self.factory.get("/org-admin/users?org_id=%d" % (self.org_other.id))
2018-11-08 19:45:21 +00:00
request.user = self.org_admin
resp = org_admin.users(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
def test_load_all_user_permissions(self):
"""
Test the result of org_admin_views.load_all_user_permissions
"""
uid = self.user_a.id
perms = {
uid: {
2019-12-05 16:57:52 +00:00
"perms": {"net.%d" % self.net.id: 0x01, "fac": 0x03},
2018-11-08 19:45:21 +00:00
"id": self.user_a.id,
2019-12-05 16:57:52 +00:00
"name": "%s <%s> %s"
% (self.user_a.full_name, self.user_a.email, self.user_a.username),
2018-11-08 19:45:21 +00:00
}
}
2019-12-05 16:57:52 +00:00
org_admin.save_user_permissions(self.org, self.user_a, perms[uid]["perms"])
2018-11-08 19:45:21 +00:00
perms_all = org_admin.load_all_user_permissions(self.org)
self.assertEqual(perms_all, perms)
def test_user_permissions_update_remove(self):
"""
Test the result of org_admin_views.user_permissions_update
Test the result of org_admin_views.user_permissions_remove
"""
# Test #1 - test updating a user a's permission to the org
url = "/org-admin/user_permissions/update?org_id=%d&user_id=%d" % (
2019-12-05 16:57:52 +00:00
self.org.id,
self.user_a.id,
)
request = self.factory.post(
url, data={"entity": "net.%d" % self.net.id, "perms": 0x03}
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.user_permission_update(request)
self.assertEqual(json.loads(resp.content).get("status"), "ok")
# test that the perms we just updated saved correctly
uperms, perms = org_admin.load_user_permissions(self.org, self.user_a)
self.assertEqual(perms, {"net.%d" % self.net.id: 0x03})
# Test #2 - should not be allowed to update user b's perms as he is not a member of
# the org
url = "/org-admin/user_permissions/update?org_id=%d&user_id=%d" % (
2019-12-05 16:57:52 +00:00
self.org.id,
self.user_b.id,
)
request = self.factory.post(
url, data={"entity": "net.%d" % self.net.id, "perms": 0x03}
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.user_permission_update(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
# Test #3 - should not be allowed to update user b's perms because we are not
# the admin of his org
url = "/org-admin/user_permissions/update?org_id=%d&user_id=%d" % (
2019-12-05 16:57:52 +00:00
self.org_other.id,
self.user_b.id,
)
request = self.factory.post(
url, data={"entity": "net.%d" % self.net.id, "perms": 0x03}
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.user_permission_update(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
# Test #4 - remove the permissions we just added
url = "/org-admin/user_permissions/remove?org_id=%d&user_id=%d" % (
2019-12-05 16:57:52 +00:00
self.org.id,
self.user_a.id,
)
request = self.factory.post(url, data={"entity": "net.%d" % self.net.id})
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.user_permission_remove(request)
self.assertEqual(json.loads(resp.content).get("status"), "ok")
# test that the perms we just removed saved correctly
uperms, perms = org_admin.load_user_permissions(self.org, self.user_a)
self.assertEqual(perms, {})
# Test #5 - should not be allowed remove user b's permissions as he
# is not a member of the org
url = "/org-admin/user_permissions/remove?org_id=%d&user_id=%d" % (
2019-12-05 16:57:52 +00:00
self.org.id,
self.user_b.id,
)
request = self.factory.post(url, data={"entity": "net.%d" % self.net.id})
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.user_permission_remove(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
# Test #6 - should not be allowed to remove user b's permissions as we
# are not the admin of his org
url = "/org-admin/user_permissions/remove?org_id=%d&user_id=%d" % (
2019-12-05 16:57:52 +00:00
self.org_other.id,
self.user_b.id,
)
request = self.factory.post(url, data={"entity": "net.%d" % self.net.id})
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.user_permission_remove(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
def test_user_permissions(self):
"""
Test the result of org_admin_views.user_permissions
Test org_admin_views.save_user_permissions
Test org_admin_views.load_user_permissions
"""
# Test #1 - test user a's permission to the org
request = self.factory.get(
2019-12-05 16:57:52 +00:00
"/org-admin/user_permissions?org_id=%d" % (self.org.id)
)
2018-11-08 19:45:21 +00:00
request.user = self.org_admin
uid = str(self.user_a.id)
# we make some temporary perms for user_a
perms = {uid: {"net.%d" % self.net.id: 0x01, "fac": 0x03}}
org_admin.save_user_permissions(self.org, self.user_a, perms[uid])
resp = json.loads(org_admin.user_permissions(request).content)
self.assertEqual(resp["status"], "ok")
self.assertEqual(resp["user_permissions"], perms)
# Test #2 - clear the perms we just made for this test
org_admin.save_user_permissions(self.org, self.user_a, {})
resp = json.loads(org_admin.user_permissions(request).content)
self.assertEqual(resp["status"], "ok")
self.assertEqual(resp["user_permissions"], {uid: {}})
# Test #5 - no permissions to org
request = self.factory.get(
2019-12-05 16:57:52 +00:00
"/org-admin/user_permissions?org_id=%d" % (self.org_other.id)
)
2018-11-08 19:45:21 +00:00
request.user = self.org_admin
resp = org_admin.user_permissions(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
def test_org_admin_tools(self):
"""
Test that users with create / delete permissions have access to the tools
on the org management page
"""
for tag in ["fac", "net", "ix"]:
2019-12-05 16:57:52 +00:00
org_admin.save_user_permissions(self.org, self.user_a, {tag: PERM_CREATE})
2018-11-08 19:45:21 +00:00
c = Client()
c.login(username=self.user_a.username, password="user_a")
resp = c.get("/org/%d" % self.org.id, follow=True)
print(resp)
2018-11-08 19:45:21 +00:00
for _tag in ["fac", "net", "ix"]:
if _tag != tag:
July updates (#762) * Change label from primary ASN to ASN * Raise validation error when trying to update ASN * first steps for dotf importer procotol (#697) * migrations (#697) * Add translation to error meessage * Make ASN readonly in table * Add test now that ASN should not be able to update * Set fac.rencode to '' for all entries and make it readonly in serializer * Add unique constraints to network ixlan ip addresses * Add migration to null out duplicate ipaddresses for deleted netixlans * Add unique constraints to network ixlan ip addresses * Add migration to null out duplicate ipaddresses for deleted netixlans * remove old migrations (#697) * fix netixlan ipaddr dedupe migration (#268) add netixlan ipaddr unique constraint migration (#268) * ixf_member_data migrations (#697) * fix table name (#697) * importer protocol (#697) * fix netixlan ipaddr dedupe migration (#268) add netixlan ipaddr unique constraint migration (#268) * ixf proposed changes notifications (#697) * Delete repeated query * Add a test to show rencode is readonly * Blank out rencode when mocking data * Remove validator now that constraint exists * Add back unique field validator w Check Deleted true * conflict resolving (#697) * UniqueFieldValidator raise error with code "unique" (#268) * conflict resolution (#697) * Add fixme comment to tests * conflict resolution (#697) * Remove now invalid undelete tests * UniqueFieldValidator raise error with code "unique" (#268) * delete admin tools for duplicate ip addresses * Make migration to delete duplicateipnetworkixlan * Add ixlan-ixpfx status matching validation, add corresponding test * delete redundant checking in test * resolve conflict ui (#697) * fix migrations hierarchy * squash migrations for ixf member data * clean up preview and post-mortem tools * remove non-sensical permission check when undeleting soft-deleted objects through unique integrity error handling * only include the ix-f data url in notifications to admincom (#697) * resolve on --skip-import (#697) * ac conflict resolution (#697) * Define more accurately the incompatible statuses for ixlan and ixpfx * Add another status test * Preventing disrupting changes (#697) * fix tests (#697) * Stop allow_ixp_update from being write only and add a global stat for automated networks * Add tests for global stats that appear in footer * Change how timezone is called with datetime, to get test_stats.py/test_generate_for_current_date to pass * test for protected entities (#697) * admincom conflict resolution refine readonly fields (#697) network notifications only if the problem is actually actionable by the network (#697) * ixp / ac notifcation when ix-f source cannot be parsed (#697) fix issue with ixlan prefix protection (#697) * migrations (#697) * code documentation (#697) * ux tweaks (#697) * UX tweaks (#697) * Fix typo * fix netixlan returned in IXFMemberData.apply when adding a new one (#697) * fix import log incosistencies (#697) * Add IXFMemberData to test * Update test data * Add protocol tests * Add tests for views * always persist changes to remote data on set_conflict (#697) * More tests * always persist changes to remote data on set_conflict (#697) * suggest-add test * net_present_at_ix should check status (#697) * Add more protocol tests * Edit language of some tests * django-peeringdb to 2.1.1 relock pipfile, pin django-ratelimit to <3 as it breaks stuff * Add net_count_ixf field to ix object (#683) * Add the IX-F Member Export URL to the ixlan API endpoint (#249) * Lock some objects from being deleted by the owner (#696) * regenerate api docs (#249) * always persist changes to remote data on set_add and set_update (#697) * IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field * always persist changes to remote data on set_add and set_update (#697) * Fix suggest-add tests * IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field * IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field * fix issue with deletion when ixfmemberdata for entry existed previously (#697) * fix test_suggest_delete_local_ixf_no_flag (#697 tests) * fix issue with deletion when ixfmemberdata for entry existed previously (#697) * invalid ips get logged and notified to the ix via notify_error (#697) * Fix more tests * issue with previous_data when running without save (#697) properly track speed errors (#697) * reset errors on ixfmemberdata that go into pending_save (#697) * add remote_data to admin view (#697) * fix error reset inconsistency (#697) * Refine invalid data tests * remove debug output * for notifications to ac include contact points for net and ix in the message (#697) * settings to toggle ix-f tickets / emails (#697) * allow turning off ix-f notifications for net and ix separately (#697) * add jsonschema test * Add idempotent tests to updater * remove old ixf member tests * Invalid data tests when ixp_updates are enabled * fix speed error validation (#697) * fix issue with rollback (#697) * fix migration hierarchy * fix ixfmemberdata _email * django-peeringdb to 2.2 and relock * add ixf rollback tests * ixf email notifications off by default * black formatted * pyupgrade Co-authored-by: egfrank <egfrank@20c.com> Co-authored-by: Stefan Pratter <stefan@20c.com>
2020-07-15 02:07:01 -05:00
assert f"#add_{_tag}" not in resp.content.decode()
assert f"#add_{tag}" in resp.content.decode()
2018-11-08 19:45:21 +00:00
def test_manage_user_delete(self):
"""
Test the result of org_admin_views.manager_user_delete
"""
self.org.admin_usergroup.user_set.add(self.user_e)
self.org.usergroup.user_set.add(self.user_f)
# make sure that user f is currently member and not admin
self.assertEqual(self.user_f.is_org_member(self.org), True)
self.assertEqual(self.user_f.is_org_admin(self.org), False)
self.assertEqual(self.user_e.is_org_member(self.org), False)
self.assertEqual(self.user_e.is_org_admin(self.org), True)
# test #1 - remove user f (member) from org
2019-12-05 16:57:52 +00:00
request = self.factory.post(
"/org-admin/manage_user/delete",
{"org_id": self.org.id, "user_id": self.user_f.id},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.manage_user_delete(request)
self.assertEqual(json.loads(resp.content), {"status": "ok"})
self.user_a.refresh_from_db()
self.assertEqual(self.user_f.is_org_member(self.org), False)
self.assertEqual(self.user_f.is_org_admin(self.org), False)
# test #2 - remove user e (admin) from org
2019-12-05 16:57:52 +00:00
request = self.factory.post(
"/org-admin/manage_user/delete",
{"org_id": self.org.id, "user_id": self.user_e.id},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.manage_user_delete(request)
self.assertEqual(json.loads(resp.content), {"status": "ok"})
self.user_a.refresh_from_db()
self.assertEqual(self.user_e.is_org_member(self.org), False)
self.assertEqual(self.user_e.is_org_admin(self.org), False)
# test #3 - fail on user that is not currently in org
2019-12-05 16:57:52 +00:00
request = self.factory.post(
"/org-admin/manage_user/delete",
{"org_id": self.org.id, "user_id": self.user_d.id},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.manage_user_delete(request)
self.assertEqual(resp.status_code, 403)
# test #3 - fail on org that you are not an admin of
2019-12-05 16:57:52 +00:00
request = self.factory.post(
"/org-admin/manage_user/delete",
{"org_id": self.org_other.id, "user_id": self.user_d.id},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.manage_user_delete(request)
self.assertEqual(resp.status_code, 403)
def test_manage_user_update(self):
"""
Test the result of org_admin_views.manage_user_update
"""
# make sure that user a is currently member and not admin
self.assertEqual(self.user_a.is_org_member(self.org), True)
self.assertEqual(self.user_a.is_org_admin(self.org), False)
# test #1 - move user a to admin group
2019-12-05 16:57:52 +00:00
request = self.factory.post(
"/org-admin/manage_user/update",
{"org_id": self.org.id, "user_id": self.user_a.id, "group": "admin"},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.manage_user_update(request)
self.assertEqual(json.loads(resp.content), {"status": "ok"})
self.user_a.refresh_from_db()
self.assertEqual(self.user_a.is_org_member(self.org), False)
self.assertEqual(self.user_a.is_org_admin(self.org), True)
# test #2 move back to member group
2019-12-05 16:57:52 +00:00
request = self.factory.post(
"/org-admin/manage_user/update",
{"org_id": self.org.id, "user_id": self.user_a.id, "group": "member"},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.manage_user_update(request)
self.assertEqual(json.loads(resp.content), {"status": "ok"})
self.user_a.refresh_from_db()
self.assertEqual(self.user_a.is_org_member(self.org), True)
self.assertEqual(self.user_a.is_org_admin(self.org), False)
# test #3 - fail on user that is not currently in org
2019-12-05 16:57:52 +00:00
request = self.factory.post(
"/org-admin/manage_user/update",
{"org_id": self.org.id, "user_id": self.user_d.id, "group": "member"},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.manage_user_update(request)
self.assertEqual(resp.status_code, 403)
# test #3 - fail on org that you are not an admin of
request = self.factory.post(
2019-12-05 16:57:52 +00:00
"/org-admin/manage_user/update",
{"org_id": self.org_other.id, "user_id": self.user_d.id, "group": "admin"},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.manage_user_update(request)
self.assertEqual(resp.status_code, 403)
def test_permissions(self):
"""
Test the result of org_admin_views.permissions
"""
# Test #1 - retrieve permissioning ids for org
2019-12-05 16:57:52 +00:00
request = self.factory.get("/org-admin/permissions?org_id=%d" % self.org.id)
2018-11-08 19:45:21 +00:00
request.user = self.org_admin
resp = json.loads(org_admin.permissions(request).content)
self.assertEqual(resp["status"], "ok")
July updates (#762) * Change label from primary ASN to ASN * Raise validation error when trying to update ASN * first steps for dotf importer procotol (#697) * migrations (#697) * Add translation to error meessage * Make ASN readonly in table * Add test now that ASN should not be able to update * Set fac.rencode to '' for all entries and make it readonly in serializer * Add unique constraints to network ixlan ip addresses * Add migration to null out duplicate ipaddresses for deleted netixlans * Add unique constraints to network ixlan ip addresses * Add migration to null out duplicate ipaddresses for deleted netixlans * remove old migrations (#697) * fix netixlan ipaddr dedupe migration (#268) add netixlan ipaddr unique constraint migration (#268) * ixf_member_data migrations (#697) * fix table name (#697) * importer protocol (#697) * fix netixlan ipaddr dedupe migration (#268) add netixlan ipaddr unique constraint migration (#268) * ixf proposed changes notifications (#697) * Delete repeated query * Add a test to show rencode is readonly * Blank out rencode when mocking data * Remove validator now that constraint exists * Add back unique field validator w Check Deleted true * conflict resolving (#697) * UniqueFieldValidator raise error with code "unique" (#268) * conflict resolution (#697) * Add fixme comment to tests * conflict resolution (#697) * Remove now invalid undelete tests * UniqueFieldValidator raise error with code "unique" (#268) * delete admin tools for duplicate ip addresses * Make migration to delete duplicateipnetworkixlan * Add ixlan-ixpfx status matching validation, add corresponding test * delete redundant checking in test * resolve conflict ui (#697) * fix migrations hierarchy * squash migrations for ixf member data * clean up preview and post-mortem tools * remove non-sensical permission check when undeleting soft-deleted objects through unique integrity error handling * only include the ix-f data url in notifications to admincom (#697) * resolve on --skip-import (#697) * ac conflict resolution (#697) * Define more accurately the incompatible statuses for ixlan and ixpfx * Add another status test * Preventing disrupting changes (#697) * fix tests (#697) * Stop allow_ixp_update from being write only and add a global stat for automated networks * Add tests for global stats that appear in footer * Change how timezone is called with datetime, to get test_stats.py/test_generate_for_current_date to pass * test for protected entities (#697) * admincom conflict resolution refine readonly fields (#697) network notifications only if the problem is actually actionable by the network (#697) * ixp / ac notifcation when ix-f source cannot be parsed (#697) fix issue with ixlan prefix protection (#697) * migrations (#697) * code documentation (#697) * ux tweaks (#697) * UX tweaks (#697) * Fix typo * fix netixlan returned in IXFMemberData.apply when adding a new one (#697) * fix import log incosistencies (#697) * Add IXFMemberData to test * Update test data * Add protocol tests * Add tests for views * always persist changes to remote data on set_conflict (#697) * More tests * always persist changes to remote data on set_conflict (#697) * suggest-add test * net_present_at_ix should check status (#697) * Add more protocol tests * Edit language of some tests * django-peeringdb to 2.1.1 relock pipfile, pin django-ratelimit to <3 as it breaks stuff * Add net_count_ixf field to ix object (#683) * Add the IX-F Member Export URL to the ixlan API endpoint (#249) * Lock some objects from being deleted by the owner (#696) * regenerate api docs (#249) * always persist changes to remote data on set_add and set_update (#697) * IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field * always persist changes to remote data on set_add and set_update (#697) * Fix suggest-add tests * IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field * IXFMemberData: always persist remote data changes during set_add and set_update, also allow for saving without touching the updated field * fix issue with deletion when ixfmemberdata for entry existed previously (#697) * fix test_suggest_delete_local_ixf_no_flag (#697 tests) * fix issue with deletion when ixfmemberdata for entry existed previously (#697) * invalid ips get logged and notified to the ix via notify_error (#697) * Fix more tests * issue with previous_data when running without save (#697) properly track speed errors (#697) * reset errors on ixfmemberdata that go into pending_save (#697) * add remote_data to admin view (#697) * fix error reset inconsistency (#697) * Refine invalid data tests * remove debug output * for notifications to ac include contact points for net and ix in the message (#697) * settings to toggle ix-f tickets / emails (#697) * allow turning off ix-f notifications for net and ix separately (#697) * add jsonschema test * Add idempotent tests to updater * remove old ixf member tests * Invalid data tests when ixp_updates are enabled * fix speed error validation (#697) * fix issue with rollback (#697) * fix migration hierarchy * fix ixfmemberdata _email * django-peeringdb to 2.2 and relock * add ixf rollback tests * ixf email notifications off by default * black formatted * pyupgrade Co-authored-by: egfrank <egfrank@20c.com> Co-authored-by: Stefan Pratter <stefan@20c.com>
2020-07-15 02:07:01 -05:00
ids = {r["id"]: r["name"] for r in resp["permissions"]}
2018-11-08 19:45:21 +00:00
self.assertEqual(len(ids), 7)
self.assertIn("org.%d" % self.org.id, ids)
self.assertIn("ix.%d" % self.ix.id, ids)
self.assertIn("net.%d" % self.net.id, ids)
self.assertIn("fac.%d" % self.fac.id, ids)
# Test #2 - cannot retrieve ids for other org as we are not admin
request = self.factory.get(
2019-12-05 16:57:52 +00:00
"/org-admin/permissions?org_id=%d" % self.org_other.id
)
2018-11-08 19:45:21 +00:00
request.user = self.org_admin
resp = org_admin.permissions(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
def test_permission_ids(self):
"""
Test the result of org_admin_views.permission_ids
"""
ids = org_admin.permission_ids(self.org)
self.assertEqual(type(ids), dict)
self.assertEqual(len(ids), 7)
self.assertIn("org.%d" % self.org.id, ids)
self.assertIn("ix.%d" % self.ix.id, ids)
self.assertIn("net.%d" % self.net.id, ids)
self.assertIn("fac.%d" % self.fac.id, ids)
def test_extract_permission_id(self):
"""
Test the result of org_admin_views.extract_permission_id
"""
# extract permission ids to here
dest = {}
# prepare source dict with nsp namespaces
source = {
self.net.nsp_namespace: 0x01,
self.ix.nsp_namespace: 0x01,
2019-12-05 16:57:52 +00:00
self.fac.nsp_namespace: 0x01,
2018-11-08 19:45:21 +00:00
}
# extract ids
org_admin.extract_permission_id(source, dest, self.net, self.org)
org_admin.extract_permission_id(source, dest, self.ix, self.org)
org_admin.extract_permission_id(source, dest, self.fac, self.org)
2019-12-05 16:57:52 +00:00
self.assertEqual(
{
"net.%d" % self.net.id: 0x01,
"ix.%d" % self.ix.id: 0x01,
"fac.%d" % self.fac.id: 0x01,
},
dest,
)
2018-11-08 19:45:21 +00:00
# test with just the models
# extract permission ids to here
dest = {}
# prepare source dict with nsp namespaces
source = {
self.net.nsp_namespace_from_id(self.org.id, "*").strip(".*"): 0x01,
self.fac.nsp_namespace_from_id(self.org.id, "*").strip(".*"): 0x03,
self.ix.nsp_namespace_from_id(self.org.id, "*").strip(".*"): 0x01,
}
# extract ids
org_admin.extract_permission_id(source, dest, models.Network, self.org)
2019-12-05 16:57:52 +00:00
org_admin.extract_permission_id(source, dest, models.InternetExchange, self.org)
org_admin.extract_permission_id(source, dest, models.Facility, self.org)
2018-11-08 19:45:21 +00:00
self.assertEqual({"net": 0x01, "fac": 0x03, "ix": 0x01}, dest)
def test_uoar_approve(self):
"""
June updates (#751) * Add pointer from API docs to tutorial #650 * Sorting by clicking table headers should use local-compare #356 * Mark IXP peering LAN as bogon #352 * Add help text to "Add (Facility, Network, Exchange)" tab #669 * Add Looking Glass field to the IX object #672 * Add read-only Superuser #679 * Make spelling of traffic levels consistent #519 (#723) * Offer 2FA (#290) * Show "Last Updated" fields on fac, ix, org records (#526) * Enable sort and reverse sort of IP column in IX display (#72) * IRR validation not handling unexpected characters gracefully (#712) * Support alternative direction of writing, e.g. Arabic (#618) * Undeleting an ixlan with an emtpy IPv4 XOR IPv6 field throws a silly error (#644) * Changing org while adding net results in 500 #654 * missing delete button for organisations (#121) * When changing owner of an ix admin GUI borks because of "Ixlan for exchange already exists" #666 * Selection should only present undeleted objects (#664) * change default encoding of API calls to 'utf-8' #663 * Posting https://www.peeringdb.com onto social media doesn't select a good preview image #537 * Revert "Add Looking Glass field to the IX object #672" This reverts commit 4daf2520043c241fabe9a521757efa86a274e28a. Conflicts: peeringdb_server/migrations/0037_ix_looking_glass.py peeringdb_server/views.py * 500 Internal Error when creating IX where prefix already exists elsewhere #718 * Fix graceful restore of soft-deleted objects with translation active (#580) * Don't return any POC data with status=deleted #569 Hard delete soft-deleted pocs after grace period #566 * django-peeringdb from github@2.0.0.2-beta Co-authored-by: Stefan Pratter <stefan@20c.com>
2020-06-24 12:55:01 -05:00
Test approving of a user-org-affiliation-request
2018-11-08 19:45:21 +00:00
org_admin_views.uoar_approve
"""
# create a uoar for user c
uoar = models.UserOrgAffiliationRequest.objects.create(
2019-12-05 16:57:52 +00:00
user=self.user_c, asn=1, status="pending"
)
2018-11-08 19:45:21 +00:00
# test that org id was properly derived from network asn
self.assertEqual(uoar.org.id, self.org.id)
# test approval
with override_group_id():
request = self.factory.post(
"/org-admin/uoar/approve?org_id=%d" % self.org.id, data={"id": uoar.id}
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = json.loads(org_admin.uoar_approve(request).content)
2019-12-05 16:57:52 +00:00
self.assertEqual(
{
"status": "ok",
"full_name": self.user_c.full_name,
"id": self.user_c.id,
"email": self.user_c.email,
},
resp,
)
2018-11-08 19:45:21 +00:00
# check that user is now a member of the org
self.assertEqual(
2019-12-05 16:57:52 +00:00
self.org.usergroup.user_set.filter(id=self.user_c.id).exists(), True
)
2018-11-08 19:45:21 +00:00
# check that the UOAR is gone
self.assertEqual(
2019-12-05 16:57:52 +00:00
models.UserOrgAffiliationRequest.objects.filter(id=uoar.id).exists(), False
)
2018-11-08 19:45:21 +00:00
# test: we shouldnt be allowed to approve uoar's for the org we are not
# admins of
with override_group_id():
request = self.factory.post(
"/org-admin/uoar/approve?org_id=%d" % self.org_other.id,
data={"id": uoar.id},
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.uoar_approve(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
# test: trying to approve an uoar that doesn't belong to the org shouldn't
# be allowed
uoar_b = models.UserOrgAffiliationRequest.objects.create(
2019-12-05 16:57:52 +00:00
user=self.user_d, asn=22, status="pending"
)
2018-11-08 19:45:21 +00:00
with override_group_id():
request = self.factory.post(
"/org-admin/uoar/approve?org_id=%d" % self.org.id, data={"id": uoar_b.id}
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.uoar_approve(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
uoar_b.delete()
def test_uoar_deny(self):
"""
June updates (#751) * Add pointer from API docs to tutorial #650 * Sorting by clicking table headers should use local-compare #356 * Mark IXP peering LAN as bogon #352 * Add help text to "Add (Facility, Network, Exchange)" tab #669 * Add Looking Glass field to the IX object #672 * Add read-only Superuser #679 * Make spelling of traffic levels consistent #519 (#723) * Offer 2FA (#290) * Show "Last Updated" fields on fac, ix, org records (#526) * Enable sort and reverse sort of IP column in IX display (#72) * IRR validation not handling unexpected characters gracefully (#712) * Support alternative direction of writing, e.g. Arabic (#618) * Undeleting an ixlan with an emtpy IPv4 XOR IPv6 field throws a silly error (#644) * Changing org while adding net results in 500 #654 * missing delete button for organisations (#121) * When changing owner of an ix admin GUI borks because of "Ixlan for exchange already exists" #666 * Selection should only present undeleted objects (#664) * change default encoding of API calls to 'utf-8' #663 * Posting https://www.peeringdb.com onto social media doesn't select a good preview image #537 * Revert "Add Looking Glass field to the IX object #672" This reverts commit 4daf2520043c241fabe9a521757efa86a274e28a. Conflicts: peeringdb_server/migrations/0037_ix_looking_glass.py peeringdb_server/views.py * 500 Internal Error when creating IX where prefix already exists elsewhere #718 * Fix graceful restore of soft-deleted objects with translation active (#580) * Don't return any POC data with status=deleted #569 Hard delete soft-deleted pocs after grace period #566 * django-peeringdb from github@2.0.0.2-beta Co-authored-by: Stefan Pratter <stefan@20c.com>
2020-06-24 12:55:01 -05:00
Test denying of a user-org-affiliation-request
2018-11-08 19:45:21 +00:00
org_admin_views.uoar_deny
"""
# create a uoar for user d
uoar = models.UserOrgAffiliationRequest.objects.create(
2019-12-05 16:57:52 +00:00
user=self.user_d, asn=1, status="pending"
)
2018-11-08 19:45:21 +00:00
# test that org id was properly derived from network asn
self.assertEqual(uoar.org.id, self.org.id)
# test deny
request = self.factory.post(
2019-12-05 16:57:52 +00:00
"/org-admin/uoar/deny?org_id=%d" % self.org.id, data={"id": uoar.id}
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = json.loads(org_admin.uoar_deny(request).content)
self.assertEqual(
{
"status": "ok",
},
resp,
)
2018-11-08 19:45:21 +00:00
# check that user is not a member of the org
self.assertEqual(
2019-12-05 16:57:52 +00:00
self.org.usergroup.user_set.filter(id=self.user_d.id).exists(), False
)
2018-11-08 19:45:21 +00:00
# check that the UOAR is there, but status is denyed
uoar = models.UserOrgAffiliationRequest.objects.get(id=uoar.id)
self.assertEqual(uoar.status, "denied")
# test: we shouldnt be allowed to deny uoars for the org we are not
# admins of
request = self.factory.post(
2019-12-05 16:57:52 +00:00
"/org-admin/uoar/deny?org_id=%d" % self.org_other.id, data={"id": uoar.id}
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.uoar_approve(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
# test: trying to deny an uoar that doesn't belong to the org shouldn't
# be allowed
uoar_b = models.UserOrgAffiliationRequest.objects.create(
2019-12-05 16:57:52 +00:00
user=self.user_d, asn=22, status="pending"
)
2018-11-08 19:45:21 +00:00
request = self.factory.post(
2019-12-05 16:57:52 +00:00
"/org-admin/uoar/deny?org_id=%d" % self.org.id, data={"id": uoar_b.id}
)
2018-11-08 19:45:21 +00:00
request._dont_enforce_csrf_checks = True
request.user = self.org_admin
resp = org_admin.uoar_deny(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(json.loads(resp.content), {})
uoar_b.delete()
June updates (#751) * Add pointer from API docs to tutorial #650 * Sorting by clicking table headers should use local-compare #356 * Mark IXP peering LAN as bogon #352 * Add help text to "Add (Facility, Network, Exchange)" tab #669 * Add Looking Glass field to the IX object #672 * Add read-only Superuser #679 * Make spelling of traffic levels consistent #519 (#723) * Offer 2FA (#290) * Show "Last Updated" fields on fac, ix, org records (#526) * Enable sort and reverse sort of IP column in IX display (#72) * IRR validation not handling unexpected characters gracefully (#712) * Support alternative direction of writing, e.g. Arabic (#618) * Undeleting an ixlan with an emtpy IPv4 XOR IPv6 field throws a silly error (#644) * Changing org while adding net results in 500 #654 * missing delete button for organisations (#121) * When changing owner of an ix admin GUI borks because of "Ixlan for exchange already exists" #666 * Selection should only present undeleted objects (#664) * change default encoding of API calls to 'utf-8' #663 * Posting https://www.peeringdb.com onto social media doesn't select a good preview image #537 * Revert "Add Looking Glass field to the IX object #672" This reverts commit 4daf2520043c241fabe9a521757efa86a274e28a. Conflicts: peeringdb_server/migrations/0037_ix_looking_glass.py peeringdb_server/views.py * 500 Internal Error when creating IX where prefix already exists elsewhere #718 * Fix graceful restore of soft-deleted objects with translation active (#580) * Don't return any POC data with status=deleted #569 Hard delete soft-deleted pocs after grace period #566 * django-peeringdb from github@2.0.0.2-beta Co-authored-by: Stefan Pratter <stefan@20c.com>
2020-06-24 12:55:01 -05:00
def test_uoar_cancel_on_delete(self):
"""
Test that user affiliation requests get canceled if the
organization is deleted
"""
org = models.Organization.objects.create(name="TestCoD", status="ok")
uoar = models.UserOrgAffiliationRequest.objects.create(
user=self.user_c, org=org, status="pending"
)
assert uoar.status == "pending"
assert uoar.id
org.delete()
with pytest.raises(models.UserOrgAffiliationRequest.DoesNotExist):
uoar.refresh_from_db()
org.refresh_from_db()
assert org.status == "deleted"