mirror of
https://github.com/PostHog/posthog.git
synced 2024-12-01 04:12:23 +01:00
268 lines
12 KiB
Python
268 lines
12 KiB
Python
from rest_framework import status
|
|
|
|
from ee.api.test.base import APILicensedTest
|
|
from ee.models.dashboard_privilege import DashboardPrivilege
|
|
from posthog.models import Dashboard, OrganizationMembership, User
|
|
|
|
|
|
class TestDashboardCollaboratorsAPI(APILicensedTest):
|
|
test_dashboard: Dashboard
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.test_dashboard = Dashboard.objects.create(team=self.team, name="Test Insights 9001", created_by=self.user)
|
|
|
|
def test_list_collaborators_as_person_without_edit_access(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.ONLY_COLLABORATORS_CAN_EDIT
|
|
self.test_dashboard.created_by = None
|
|
self.test_dashboard.save()
|
|
other_user_a = User.objects.create_and_join(self.organization, "a@x.com", None)
|
|
other_user_b = User.objects.create_and_join(self.organization, "b@x.com", None)
|
|
DashboardPrivilege.objects.create(
|
|
user=other_user_a,
|
|
dashboard=self.test_dashboard,
|
|
level=Dashboard.PrivilegeLevel.CAN_VIEW,
|
|
)
|
|
DashboardPrivilege.objects.create(
|
|
user=other_user_b,
|
|
dashboard=self.test_dashboard,
|
|
level=Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
)
|
|
|
|
response = self.client.get(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/"
|
|
)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
|
|
response_data = response.json()
|
|
response_data = sorted(response_data, key=lambda entry: entry["user"]["email"])
|
|
|
|
self.assertEqual(len(response_data), 2)
|
|
self.assertEqual(response_data[0]["user"]["email"], other_user_a.email)
|
|
self.assertEqual(response_data[0]["level"], Dashboard.PrivilegeLevel.CAN_VIEW)
|
|
self.assertEqual(response_data[1]["user"]["email"], other_user_b.email)
|
|
self.assertEqual(response_data[1]["level"], Dashboard.PrivilegeLevel.CAN_EDIT)
|
|
|
|
def test_cannot_add_collaborator_to_unrestricted_dashboard_as_creator(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.EVERYONE_IN_PROJECT_CAN_EDIT
|
|
self.test_dashboard.save()
|
|
other_user = User.objects.create_and_join(self.organization, "a@x.com", None)
|
|
|
|
response = self.client.post(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/",
|
|
{
|
|
"user_uuid": str(other_user.uuid),
|
|
"level": Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
},
|
|
)
|
|
response_data = response.json()
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
self.assertEqual(
|
|
response_data,
|
|
self.validation_error_response("Cannot add collaborators to a dashboard on the lowest restriction level."),
|
|
)
|
|
|
|
def test_can_add_collaborator_to_edit_restricted_dashboard_as_creator(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.ONLY_COLLABORATORS_CAN_EDIT
|
|
self.test_dashboard.save()
|
|
other_user = User.objects.create_and_join(self.organization, "a@x.com", None)
|
|
|
|
response = self.client.post(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/",
|
|
{
|
|
"user_uuid": str(other_user.uuid),
|
|
"level": Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
},
|
|
)
|
|
response_data = response.json()
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
|
self.assertEqual(response_data["dashboard_id"], self.test_dashboard.id)
|
|
self.assertEqual(response_data["user"]["email"], other_user.email)
|
|
self.assertEqual(response_data["level"], Dashboard.PrivilegeLevel.CAN_EDIT)
|
|
|
|
def test_cannot_add_yourself_to_restricted_dashboard_as_creator(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.ONLY_COLLABORATORS_CAN_EDIT
|
|
self.test_dashboard.save()
|
|
|
|
response = self.client.post(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/",
|
|
{
|
|
"user_uuid": str(self.user.uuid),
|
|
"level": Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
},
|
|
)
|
|
response_data = response.json()
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
self.assertEqual(
|
|
response_data,
|
|
self.validation_error_response(
|
|
"Cannot add collaborators that already have inherent access (the dashboard owner or a project admins)."
|
|
),
|
|
)
|
|
|
|
def test_cannot_add_collaborator_to_edit_restricted_dashboard_as_other_user(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.ONLY_COLLABORATORS_CAN_EDIT
|
|
self.test_dashboard.created_by = None
|
|
self.test_dashboard.save()
|
|
other_user = User.objects.create_and_join(self.organization, "a@x.com", None)
|
|
|
|
response = self.client.post(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/",
|
|
{
|
|
"user_uuid": str(other_user.uuid),
|
|
"level": Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
},
|
|
)
|
|
response_data = response.json()
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
|
self.assertEqual(
|
|
response_data,
|
|
self.permission_denied_response("You don't have edit permissions for this dashboard."),
|
|
)
|
|
|
|
def test_cannot_add_collaborator_from_other_org_to_edit_restricted_dashboard_as_creator(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.ONLY_COLLABORATORS_CAN_EDIT
|
|
self.test_dashboard.save()
|
|
_, _, other_user = User.objects.bootstrap("Beta", "a@x.com", None)
|
|
|
|
response = self.client.post(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/",
|
|
{
|
|
"user_uuid": str(other_user.uuid),
|
|
"level": Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
},
|
|
)
|
|
response_data = response.json()
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
self.assertEqual(
|
|
response_data,
|
|
self.validation_error_response("Cannot add collaborators that have no access to the project."),
|
|
)
|
|
|
|
def test_cannot_add_collaborator_to_other_org_to_edit_restricted_dashboard_as_creator(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.ONLY_COLLABORATORS_CAN_EDIT
|
|
self.test_dashboard.save()
|
|
self.organization_membership.delete()
|
|
_, _, other_user = User.objects.bootstrap("Beta", "a@x.com", None)
|
|
|
|
response = self.client.post(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/",
|
|
{
|
|
"user_uuid": str(other_user.uuid),
|
|
"level": Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
},
|
|
)
|
|
response_data = response.json()
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
|
self.assertEqual(
|
|
response_data,
|
|
self.permission_denied_response("You don't have access to the project."),
|
|
)
|
|
|
|
def test_cannot_update_existing_collaborator(self):
|
|
# This will change once there are more levels, but with just two it doesn't make sense to PATCH privileges
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.EVERYONE_IN_PROJECT_CAN_EDIT
|
|
self.test_dashboard.save()
|
|
other_user = User.objects.create_and_join(self.organization, "a@x.com", None)
|
|
DashboardPrivilege.objects.create(
|
|
user=other_user,
|
|
dashboard=self.test_dashboard,
|
|
level=Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
)
|
|
|
|
response = self.client.patch(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/{other_user.uuid}",
|
|
{"level": Dashboard.PrivilegeLevel.CAN_VIEW},
|
|
)
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
|
|
|
|
def test_cannot_remove_collaborator_from_unrestricted_dashboard_as_creator(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.EVERYONE_IN_PROJECT_CAN_EDIT
|
|
self.test_dashboard.save()
|
|
other_user = User.objects.create_and_join(self.organization, "a@x.com", None)
|
|
DashboardPrivilege.objects.create(
|
|
user=other_user,
|
|
dashboard=self.test_dashboard,
|
|
level=Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
)
|
|
|
|
response = self.client.delete(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/{other_user.uuid}"
|
|
)
|
|
response_data = response.json()
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
|
self.assertEqual(
|
|
response_data,
|
|
self.validation_error_response(
|
|
"Cannot remove collaborators from a dashboard on the lowest restriction level."
|
|
),
|
|
)
|
|
|
|
def test_can_remove_collaborator_from_restricted_dashboard_as_creator(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.ONLY_COLLABORATORS_CAN_EDIT
|
|
self.test_dashboard.save()
|
|
other_user = User.objects.create_and_join(self.organization, "a@x.com", None)
|
|
DashboardPrivilege.objects.create(
|
|
user=other_user,
|
|
dashboard=self.test_dashboard,
|
|
level=Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
)
|
|
|
|
response = self.client.delete(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/{other_user.uuid}"
|
|
)
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
|
|
|
def test_cannot_remove_collaborator_from_restricted_dashboard_as_other_user(self):
|
|
self.organization_membership.level = OrganizationMembership.Level.MEMBER
|
|
self.organization_membership.save()
|
|
self.test_dashboard.restriction_level = Dashboard.RestrictionLevel.ONLY_COLLABORATORS_CAN_EDIT
|
|
self.test_dashboard.created_by = None
|
|
self.test_dashboard.save()
|
|
other_user = User.objects.create_and_join(self.organization, "a@x.com", None)
|
|
DashboardPrivilege.objects.create(
|
|
user=other_user,
|
|
dashboard=self.test_dashboard,
|
|
level=Dashboard.PrivilegeLevel.CAN_EDIT,
|
|
)
|
|
|
|
response = self.client.delete(
|
|
f"/api/projects/{self.test_dashboard.team_id}/dashboards/{self.test_dashboard.id}/collaborators/{other_user.uuid}"
|
|
)
|
|
response_data = response.json()
|
|
|
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
|
self.assertEqual(
|
|
response_data,
|
|
self.permission_denied_response("You don't have edit permissions for this dashboard."),
|
|
)
|