diff --git a/djangoldp/models.py b/djangoldp/models.py index 13a699ed1883a26ce0792de9f9c76a6a1f3430f2..5cc1c3eb7724abb797403826b0a0ae4b6f11ba76 100644 --- a/djangoldp/models.py +++ b/djangoldp/models.py @@ -2,7 +2,7 @@ import json import uuid from urllib.parse import urlparse from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.contrib.auth import get_user_model from django.db import models from django.db.models import BinaryField, DateField @@ -116,8 +116,18 @@ class Model(models.Model): @classonlymethod def resolve_id(cls, id): + ''' + Resolves the id of a given path (e.g. /container/1/) + Raises Resolver404 if the path cannot be found, ValidationError if the path is for a model base + and an ObjectDoesNotExist exception if the resource does not exist + ''' id = cls.__clean_path(id) - view, args, kwargs = get_resolver().resolve(id) + match = get_resolver().resolve(id) + kwargs = match.kwargs + view = match.func + + if match.url_name.endswith('-list') or len(match.kwargs.keys()) == 0: + raise ValidationError('resolve_id received a path for a container or nested container') return view.initkwargs['model'].objects.get(**kwargs) @classonlymethod @@ -128,12 +138,18 @@ class Model(models.Model): @classonlymethod def resolve_container(cls, path): + '''retruns the model container of passed URL path''' path = cls.__clean_path(path) view, args, kwargs = get_resolver().resolve(path) return view.initkwargs['model'] @classonlymethod def resolve(cls, path): + ''' + resolves the containing model and associated id in the path. If there is no id in the path returns None + :param path: a URL path to check + :return: the container model and resolved id in a tuple + ''' if settings.BASE_URL in path: path = path[len(settings.BASE_URL):] container = cls.resolve_container(path) diff --git a/djangoldp/tests/models.py b/djangoldp/tests/models.py index 30fe6d6d36b09eacdd5376b37e67873a6669506f..3de550a30355989838c5c4ab04461166ab23c2e2 100644 --- a/djangoldp/tests/models.py +++ b/djangoldp/tests/models.py @@ -188,7 +188,8 @@ class Post(Model): class Circle(Model): - description = models.CharField(max_length=255, null=True, blank=False) + name = models.CharField(max_length=255, blank=True) + description = models.CharField(max_length=255, blank=True) team = models.ManyToManyField(settings.AUTH_USER_MODEL, through="CircleMember", blank=True) owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="owned_circles", on_delete=models.DO_NOTHING, null=True, blank=True) diff --git a/djangoldp/tests/tests_guardian.py b/djangoldp/tests/tests_guardian.py index 2be9d4c99ff3b73e0ff16439573534c23eee5717..0b51fa351fe5d4ddbcd0253305169d108f3dc33a 100644 --- a/djangoldp/tests/tests_guardian.py +++ b/djangoldp/tests/tests_guardian.py @@ -38,13 +38,6 @@ class TestsGuardian(APITestCase): response = self.client.get('/permissionless-dummys/') self.assertEqual(response.status_code, 403) - # tests that dummy with permissions set enforces these permissions - def test_list_dummy_permission_granted(self): - self.setUpLoggedInUser() - self.setUpGuardianDummyWithPerms(['view']) - response = self.client.get('/permissionless-dummys/') - self.assertEqual(response.status_code, 200) - def test_get_dummy_permission_granted(self): self.setUpLoggedInUser() self.setUpGuardianDummyWithPerms(['view']) @@ -58,13 +51,6 @@ class TestsGuardian(APITestCase): response = self.client.get('/permissionless-dummys/{}/'.format(dummy_without.slug)) self.assertEqual(response.status_code, 403) - def test_post_dummy_permission_granted(self): - self.setUpLoggedInUser() - self.setUpGuardianDummyWithPerms(['add']) - post = {'some': "some_new", "slug": 'slug1'} - response = self.client.post('/permissionless-dummys/', data=json.dumps(post), content_type='application/ld+json') - self.assertEqual(response.status_code, 201) - def test_patch_dummy_permission_granted(self): self.setUpLoggedInUser() self.setUpGuardianDummyWithPerms(['change'])