Fakultas Ilmu Komputer UI

Commit 1c9a5205 authored by Jonathan Christopher Jakub's avatar Jonathan Christopher Jakub
Browse files

[RED] Include missing common files

parent 6457ab9a
......@@ -13,21 +13,3 @@ class SoftDeleteManager(models.Manager):
def deleted(self):
queryset = self.get_queryset(with_deleted=True)
return queryset.filter(deleted_at__isnull=False)
class SoftObjectManager(SoftDeleteManager):
def get_queryset(self, with_deleted=False):
if with_deleted:
return super().get_queryset()
return super().get_queryset().filter(deleted_at__isnull=True)
def all(self, with_deleted=False):
return self.get_queryset(with_deleted=with_deleted)
def deleted(self):
queryset = self.get_queryset(with_deleted=True)
return queryset.filter(deleted_at__isnull=False)
def active_revisions(self):
queryset = self.get_queryset()
return queryset.filter(is_active=True)
......@@ -8,7 +8,8 @@ from apps.constants import (
TIMEZONE,
ACTIVITY_TYPE_CREATE,
ACTIVITY_TYPE_EDIT,
ACTIVITY_TYPE_DELETE
ACTIVITY_TYPE_DELETE,
ACTIVITY_TYPE_CHOICES,
)
......@@ -29,22 +30,32 @@ class SoftDeleteModel(BaseModel):
def delete(self):
if self.deleted_at is None:
self.deleted_at = datetime.now(tz=pytz.timezone(TIMEZONE))
self.save()
super(SoftDeleteModel, self).save()
return self
class HistoryModel(models.Model):
revision_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
object_id = models.UUIDField(default=uuid.uuid4, editable=False)
action_type = models.CharField(choices=ACTIVITY_TYPE_CHOICES, max_length=64)
recorded_at = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
class Meta:
abstract = True
class HistoryEnabledModel(SoftDeleteModel):
class Meta:
abstract = True
def save(self, *args, **kwargs):
instance = super(HistoryEnabledModel, self).save(*args, **kwargs)
def _assign_history(self, action, author):
instance_dict = model_to_dict(self)
if instance_dict.get("id") is not None:
instance_dict.pop("id")
if instance_dict.get("created_at") is not None:
instance_dict.pop("created_at")
instance_dict.pop("deleted_at")
non_related_fields = ["id", "created_at", "deleted_at", "author"]
for field in non_related_fields:
if field in instance_dict.keys():
instance_dict.pop(field)
if hasattr(self, "relation_fields"):
for field in self.relation_fields:
......@@ -52,24 +63,33 @@ class HistoryEnabledModel(SoftDeleteModel):
instance_dict["{}_id".format(field)] = str(value) if value != None else value
instance_dict.pop(field)
action = ACTIVITY_TYPE_CREATE if self._state.adding else ACTIVITY_TYPE_EDIT
instance_dict["object_id"] = self.id
instance_dict["action_type"] = action
self.history_class.objects.create(**instance_dict)
def delete(self):
instance = super(HistoryEnabledModel, self).delete()
instance_dict = model_to_dict(self)
if hasattr(self, "author"):
self.history_class.objects.create(**instance_dict, author=author)
else:
self.history_class.objects.create(**instance_dict)
if instance_dict.get("id") is not None:
instance_dict.pop("id")
if instance_dict.get("created_at") is not None:
instance_dict.pop("created_at")
instance_dict.pop("deleted_at")
instance_dict["object_id"] = self.id
instance_dict["action_type"] = ACTIVITY_TYPE_DELETE
def save(self, *args, **kwargs):
if hasattr(self, "author"):
author = self.author
else:
author = None
if self.deleted_at is None:
self.history_class.objects.create(**instance_dict)
action = ACTIVITY_TYPE_CREATE if self._state.adding else ACTIVITY_TYPE_EDIT
super(HistoryEnabledModel, self).save(*args, **kwargs)
self._assign_history(action, author)
return self
def delete(self, *args, **kwargs):
if "author" in kwargs.keys():
author = kwargs.pop("author")
else:
author = None
action = ACTIVITY_TYPE_DELETE
super(HistoryEnabledModel, self).delete()
self._assign_history(action, author)
return self
......@@ -16,26 +16,3 @@ class IsAuthenticated(BasePermission):
class CreateOnly(BasePermission):
def has_permission(self, request, view):
return request.method == "POST"
class IsSelfOrAdministrator(IsAuthenticated):
def has_permission(self, request, view):
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
account = request.user.account
return obj.user == request.user or account.is_admin
class IsAuthorOrAdministrator(IsAuthenticated):
def has_permission(self, request, view):
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
account = request.user.account
user_is_author = False
if hasattr(obj, "author"):
user_is_author = (obj.author is not None) and (obj.author == account)
return user_is_author or account.is_admin
return account.is_admin
......@@ -88,121 +88,3 @@ class CreateOnlyPermissionTest(APITestCase):
request = self.client.delete("/").wsgi_request
self.assertFalse(self.permission.has_permission(request, None))
class DummyObjectWithUser:
def __init__(self, user=None):
self.user = user
class IsSelfOrAdministratorPermissionTest(APITestCase):
@classmethod
def setUpTestData(self):
self.permission = IsSelfOrAdministrator()
self.user_1 = UserFactory(username="user_1", password="justpass")
self.user_2 = UserFactory(username="user_2", password="justpass")
self.account_1 = AccountFactory(admin=True, user=self.user_1)
self.account_2 = AccountFactory(admin=False, user=self.user_2, is_active=False)
self.token_1, _ = Token.objects.get_or_create(user=self.user_1)
self.token_2, _ = Token.objects.get_or_create(user=self.user_2)
self.object = DummyObjectWithUser(user=self.user_2)
def test_has_permission_true_for_authenticated_user(self):
self.client = APIClient(HTTP_AUTHORIZATION=HEADER_PREFIX + self.token_1.key)
request = self.client.get("/").wsgi_request
request.user = self.user_1
self.assertTrue(self.permission.has_permission(request, None))
def test_has_permission_false_for_unauthenticated_user(self):
self.client = APIClient()
request = self.client.get("/").wsgi_request
request.user = self.user_2
self.assertFalse(self.permission.has_permission(request, None))
self.client = APIClient(HTTP_AUTHORIZATION=HEADER_PREFIX + self.token_2.key)
request = self.client.get("/").wsgi_request
request.user = self.user_2
self.assertFalse(self.permission.has_permission(request, None))
def test_has_object_permission_true_for_admin(self):
self.client = APIClient(HTTP_AUTHORIZATION=HEADER_PREFIX + self.token_1.key)
request = self.client.get("/").wsgi_request
request.user = self.user_1
self.assertTrue(
self.permission.has_object_permission(request, None, self.object)
)
def test_has_object_permission_true_for_self(self):
self.client = APIClient(HTTP_AUTHORIZATION=HEADER_PREFIX + self.token_2.key)
request = self.client.get("/").wsgi_request
request.user = self.user_2
self.assertTrue(
self.permission.has_object_permission(request, None, self.object)
)
class DummyObjectWithAuthor:
def __init__(self, author=None):
self.author = author
class IsAuthorOrAdministratorPermissionTest(APITestCase):
@classmethod
def setUpTestData(self):
self.permission = IsAuthorOrAdministrator()
self.user_1 = UserFactory(username="user_1", password="justpass")
self.user_2 = UserFactory(username="user_2", password="justpass")
self.account_1 = AccountFactory(admin=True, user=self.user_1)
self.account_2 = AccountFactory(admin=False, user=self.user_2, is_active=False)
self.token_1, _ = Token.objects.get_or_create(user=self.user_1)
self.token_2, _ = Token.objects.get_or_create(user=self.user_2)
self.object = DummyObjectWithAuthor(author=self.account_2)
self.wrong_object = DummyObjectWithUser(user=self.user_2)
def test_has_permission_true_for_authenticated_user(self):
self.client = APIClient(HTTP_AUTHORIZATION=HEADER_PREFIX + self.token_1.key)
request = self.client.get("/").wsgi_request
request.user = self.user_1
self.assertTrue(self.permission.has_permission(request, None))
def test_has_permission_false_for_unauthenticated_user(self):
self.client = APIClient()
request = self.client.get("/").wsgi_request
request.user = self.user_2
self.assertFalse(self.permission.has_permission(request, None))
self.client = APIClient(HTTP_AUTHORIZATION=HEADER_PREFIX + self.token_2.key)
request = self.client.get("/").wsgi_request
request.user = self.user_2
self.assertFalse(self.permission.has_permission(request, None))
def test_has_object_permission_true_for_admin(self):
self.client = APIClient(HTTP_AUTHORIZATION=HEADER_PREFIX + self.token_1.key)
request = self.client.get("/").wsgi_request
request.user = self.user_1
self.assertTrue(
self.permission.has_object_permission(request, None, self.object)
)
self.assertTrue(
self.permission.has_object_permission(request, None, self.wrong_object)
)
def test_has_object_permission_true_for_self(self):
self.client = APIClient(HTTP_AUTHORIZATION=HEADER_PREFIX + self.token_2.key)
request = self.client.get("/").wsgi_request
request.user = self.user_2
self.assertTrue(
self.permission.has_object_permission(request, None, self.object)
)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment