diff --git a/kpi/tests/test_api_assets.py b/kpi/tests/test_api_assets.py index a0c0f051b7..2d8f240ac1 100644 --- a/kpi/tests/test_api_assets.py +++ b/kpi/tests/test_api_assets.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import copy +from hashlib import md5 import json import requests import StringIO @@ -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'] diff --git a/kpi/views.py b/kpi/views.py index 362517bbc1..63532a14ef 100644 --- a/kpi/views.py +++ b/kpi/views.py @@ -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 @@ -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 @@ -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` + +
+ GET /assets/hash/ ++ + > Example + > + > curl -X GET https://[kpi-url]/assets/hash/ + ## CRUD * `uid` - is the unique identifier of a specific asset @@ -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()