♻️(contacts) switch API to get_abilities
Use the common way to define permissions on the API. Note: we keep here the notion of "public" contacts, even if the API does not really allows that. The use case is not clear for that, but we allow contact w/o owner to be displayed.
This commit is contained in:
@@ -136,7 +136,7 @@ class ContactViewSet(
|
||||
):
|
||||
"""Contact ViewSet"""
|
||||
|
||||
permission_classes = [permissions.IsOwnedOrPublic]
|
||||
permission_classes = [permissions.AccessPermission]
|
||||
queryset = models.Contact.objects.all()
|
||||
serializer_class = serializers.ContactSerializer
|
||||
throttle_classes = [BurstRateThrottle, SustainedRateThrottle]
|
||||
@@ -150,8 +150,10 @@ class ContactViewSet(
|
||||
|
||||
# List only contacts that:
|
||||
queryset = queryset.filter(
|
||||
# - is public (owner is None)
|
||||
Q(owner__isnull=True)
|
||||
# - are owned by the user
|
||||
Q(owner=user)
|
||||
| Q(owner=user)
|
||||
# - are profile contacts for a user from the same organization
|
||||
| Q(user__organization_id=user.organization_id),
|
||||
# - are not overriden by another contact
|
||||
|
||||
@@ -187,6 +187,27 @@ class Contact(BaseModel):
|
||||
error_message = f"Validation error in '{field_path:s}': {e.message}"
|
||||
raise exceptions.ValidationError({"data": [error_message]}) from e
|
||||
|
||||
def get_abilities(self, user):
|
||||
"""
|
||||
Compute and return abilities for a given user on the contact.
|
||||
|
||||
Beware that the model allows owner to be None, we are still not
|
||||
sure about the use case for this and the API does not allow this.
|
||||
For now, we still consider here, a contact without owner is "public"
|
||||
so we allow access to it.
|
||||
"""
|
||||
is_owner = user == self.owner
|
||||
is_profile_member_or_same_organization = bool(self.user) and (
|
||||
self.user.organization_id == user.organization_id
|
||||
)
|
||||
|
||||
return {
|
||||
"get": is_owner or is_profile_member_or_same_organization or not self.owner,
|
||||
"patch": is_owner,
|
||||
"put": is_owner,
|
||||
"delete": is_owner and not self.user, # Can't delete a profile contact
|
||||
}
|
||||
|
||||
|
||||
class ServiceProvider(BaseModel):
|
||||
"""
|
||||
|
||||
@@ -86,10 +86,10 @@ def test_api_contacts_delete_authenticated_owner():
|
||||
|
||||
def test_api_contacts_delete_authenticated_profile():
|
||||
"""
|
||||
Authenticated users should be allowed to delete their profile contact.
|
||||
Authenticated users should not be allowed to delete their profile contact.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
contact = factories.ContactFactory(owner=user, user=user)
|
||||
contact = factories.ProfileContactFactory(user=user)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -98,8 +98,8 @@ def test_api_contacts_delete_authenticated_profile():
|
||||
f"/api/v1.0/contacts/{contact.id!s}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
assert models.Contact.objects.exists() is False
|
||||
assert response.status_code == 403
|
||||
assert models.Contact.objects.exists() is True
|
||||
|
||||
|
||||
def test_api_contacts_delete_authenticated_other():
|
||||
|
||||
Reference in New Issue
Block a user