Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions kpi/tests/test_api_assets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-

import copy
from hashlib import md5
import json
import requests
import StringIO
Expand Down Expand Up @@ -81,6 +82,29 @@ def test_asset_list_matches_detail(self):
self.assertIsNotNone(list_result_detail)
self.assertDictEqual(expected_list_data, dict(list_result_detail))

def test_assets_hash(self):
another_user = User.objects.get(username="anotheruser")
user_asset = Asset.objects.first()
user_asset.save()
user_asset.assign_perm(another_user, "view_asset")

self.client.logout()
self.client.login(username="anotheruser", password="anotheruser")
creation_response = self.test_create_asset()

another_user_asset = another_user.assets.last()
another_user_asset.save()

versions_ids = [
user_asset.version_id,
another_user_asset.version_id
]
versions_ids.sort()
expected_hash = md5("".join(versions_ids)).hexdigest()
hash_url = reverse("asset-hash-list")
hash_response = self.client.get(hash_url)
self.assertEqual(hash_response.data.get("hash"), expected_hash)


class AssetVersionApiTests(APITestCase):
fixtures = ['test_data']
Expand Down
44 changes: 43 additions & 1 deletion kpi/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from distutils.util import strtobool
from itertools import chain
import copy
from hashlib import md5
import json
import base64
import datetime
Expand Down Expand Up @@ -30,7 +31,7 @@
)
from rest_framework.decorators import api_view
from rest_framework.decorators import renderer_classes
from rest_framework.decorators import detail_route
from rest_framework.decorators import detail_route, list_route
from rest_framework.decorators import authentication_classes
from rest_framework.parsers import MultiPartParser
from rest_framework.response import Response
Expand Down Expand Up @@ -755,6 +756,17 @@ class AssetViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
>
> curl -X GET https://[kpi-url]/assets/

Get an hash of all `version_id`s of assets.
Useful to detect any changes in assets with only one call to `API`

<pre class="prettyprint">
<b>GET</b> /assets/hash/
</pre>

> Example
>
> curl -X GET https://[kpi-url]/assets/hash/

## CRUD

* `uid` - is the unique identifier of a specific asset
Expand Down Expand Up @@ -1000,6 +1012,36 @@ def create(self, request, *args, **kwargs):
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)

@list_route(methods=["GET"], renderer_classes=[renderers.JSONRenderer])
def hash(self, request):
"""
Creates an hash of `version_id` of all accessible assets by the user.
Useful to detect changes between each request.

:param request:
:return: JSON
"""
user = self.request.user
if user.is_anonymous():
raise exceptions.NotAuthenticated()
else:
accessible_assets = get_objects_for_user(
user, "view_asset", Asset).filter(asset_type=ASSET_TYPE_SURVEY)\
.order_by("uid")

assets_version_ids = [asset.version_id for asset in accessible_assets if asset.version_id is not None]
# Sort alphabetically
assets_version_ids.sort()

if len(assets_version_ids) > 0:
hash = md5("".join(assets_version_ids)).hexdigest()
else:
hash = ""

return Response({
"hash": hash
})

@detail_route(renderer_classes=[renderers.JSONRenderer])
def content(self, request, uid):
asset = self.get_object()
Expand Down