Skip to content

Commit

Permalink
Merge pull request #301 from nexB/disallow-put-requests-on-watch-endp…
Browse files Browse the repository at this point in the history
…oint

Disallow PUT requests on /api/watch endpoint
  • Loading branch information
JonoYang authored Mar 22, 2024
2 parents 61fa396 + 02e579d commit 578e037
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packagedb/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,11 +564,12 @@ class PackageWatchViewSet(CreateListRetrieveUpdateViewSetMixin):
serializer_class = PackageWatchAPISerializer
lookup_field = 'package_url'
lookup_value_regex = r'pkg:[a-zA-Z0-9_]+\/[a-zA-Z0-9_.-]+(?:\/[a-zA-Z0-9_.-]+)*'
http_method_names = ['get', 'post', 'patch']

def get_serializer_class(self):
if self.action == 'create':
return PackageWatchCreateSerializer
elif self.action == 'update':
elif self.request.method == 'PATCH':
return PackageWatchUpdateSerializer
return super().get_serializer_class()

Expand Down
99 changes: 99 additions & 0 deletions packagedb/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from packagedb.models import Package
from packagedb.models import PackageContentType
from packagedb.models import PackageSet
from packagedb.models import PackageWatch
from packagedb.models import Resource


Expand Down Expand Up @@ -1182,6 +1183,104 @@ def test_api_purl_validation_empty_request(self):
self.assertAlmostEquals(expected, response1.data)


class PackageWatchTestCase(TestCase):

@mock.patch("packagedb.models.PackageWatch.create_new_job")
def setUp(self, mock_create_new_job):
mock_create_new_job.return_value = None

self.watch = PackageWatch.objects.create(package_url="pkg:npm/foobar")

def test_api_package_watch_get(self):
response1 = self.client.get("/api/watch/pkg:npm/foobar/")
expected = {
"url": "http://testserver/api/watch/pkg:npm/foobar/",
"package_url": "pkg:npm/foobar",
"is_active": True,
"depth": 3,
"watch_interval": 7,
"creation_date": None,
"last_watch_date": None,
"watch_error": None,
"schedule_work_id": None,
}
result = response1.json()
result["creation_date"] = None

self.assertDictEqual(expected, result)

@mock.patch("packagedb.models.PackageWatch.create_new_job")
def test_api_package_watch_post(self, mock_create_new_job):
mock_create_new_job.return_value = None
data = {"package_url": "pkg:npm/foobar2"}

response1 = self.client.post(
"/api/watch/", data=data, content_type="application/json"
)
expected = {
"package_url": "pkg:npm/foobar2",
"depth": 3,
"watch_interval": 7,
"is_active": True,
}
result = response1.json()

self.assertDictEqual(expected, result)

@mock.patch("packagedb.models.PackageWatch.create_new_job")
def test_api_package_watch_post_with_duplicate_purl(self, mock_create_new_job):
mock_create_new_job.return_value = None
data = {"package_url": "pkg:npm/foobar"}

response1 = self.client.post(
"/api/watch/", data=data, content_type="application/json"
)
expected = {
"package_url": ["package watch with this package url already exists."]
}

result = response1.json()

self.assertEqual(status.HTTP_400_BAD_REQUEST, response1.status_code)
self.assertDictEqual(expected, result)

@mock.patch("packagedb.models.PackageWatch.create_new_job")
def test_api_package_watch_patch(self, mock_create_new_job):
mock_create_new_job.return_value = None
data = {"depth": 3, "watch_interval": 1, "is_active": False}

response1 = self.client.patch(
"/api/watch/pkg:npm/foobar/", data=data, content_type="application/json"
)
self.assertEqual(status.HTTP_200_OK, response1.status_code)

response2 = self.client.get("/api/watch/pkg:npm/foobar/")
expected = {
"url": "http://testserver/api/watch/pkg:npm/foobar/",
"package_url": "pkg:npm/foobar",
"is_active": False,
"depth": 3,
"watch_interval": 1,
"creation_date": None,
"last_watch_date": None,
"watch_error": None,
"schedule_work_id": None,
}
result = response2.json()
result["creation_date"] = None

self.assertDictEqual(expected, result)

def test_api_package_watch_put_not_allowed(self):
data = {"depth": 3, "watch_interval": 1, "is_active": False}

response1 = self.client.put(
"/api/watch/pkg:npm/foobar/", data=data, content_type="application/json"
)

self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, response1.status_code)


class ToGolangPurlTestCase(TestCase):

def test_to_golang_purl(self):
Expand Down

0 comments on commit 578e037

Please sign in to comment.