Browse Source

HUE-7820 [metadata] Properly update entities properties or custom metadata

There was a mix between entity properties (e.g. name, description...) and its custom metadata (properties dict).
Add bunch of protection to not fail on json parse in API.
Delete custom metadata API not used anywhere.
Romain Rigaux 7 years ago
parent
commit
3110e9e

+ 17 - 16
desktop/libs/metadata/src/metadata/navigator_api.py

@@ -407,8 +407,8 @@ def add_tags(request):
   response = {'status': -1}
 
   api = NavigatorApi(request.user)
-  entity_id = json.loads(request.POST.get('id', ''))
-  tags = json.loads(request.POST.get('tags', []))
+  entity_id = json.loads(request.POST.get('id', '""'))
+  tags = json.loads(request.POST.get('tags', "[]"))
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
 
@@ -433,8 +433,8 @@ def delete_tags(request):
   response = {'status': -1}
 
   api = NavigatorApi(request.user)
-  entity_id = json.loads(request.POST.get('id', ''))
-  tags = json.loads(request.POST.get('tags', []))
+  entity_id = json.loads(request.POST.get('id', '""'))
+  tags = json.loads(request.POST.get('tags', '[]'))
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
 
@@ -459,21 +459,22 @@ def update_properties(request):
   response = {'status': -1}
 
   api = NavigatorApi(request.user)
-  entity_id = json.loads(request.POST.get('id', ''))
-  properties = json.loads(request.POST.get('properties', {}))
+  entity_id = json.loads(request.POST.get('id', '""'))
+  properties = json.loads(request.POST.get('properties', '{}')) # Entity properties
+  metadata = json.loads(request.POST.get('metadata', '{}')) # Aka "Custom Metadata"
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
 
   request.audit = {
     'allowed': is_allowed,
     'operation': 'NAVIGATOR_UPDATE_PROPERTIES',
-    'operationText': 'Updating property %s of entity %s' % (properties, entity_id)
+    'operationText': 'Updating metadata %s properties %s of entity %s' % (metadata, properties, entity_id)
   }
 
-  if not entity_id or not properties or not isinstance(properties, dict) or not is_allowed:
-    response['error'] = _("update_properties requires an 'id' parameter and 'properties' parameter that is a non-empty dict")
+  if not entity_id or (not properties and not metadata) or not is_allowed:
+    response['error'] = _("update_properties requires an 'id' parameter and 'properties' or 'metadata' parameters that are non-empty dicts")
   else:
-    response['entity'] = api.update_properties(entity_id, properties)
+    response['entity'] = api.update_properties(entity_id, properties, metadata)
     response['status'] = 0
 
   return JsonResponse(response)
@@ -481,25 +482,25 @@ def update_properties(request):
 
 @require_POST
 @error_handler
-def delete_properties(request):
+def delete_metadata_properties(request):
   response = {'status': -1}
 
   api = NavigatorApi(request.user)
-  entity_id = json.loads(request.POST.get('id', ''))
-  keys = json.loads(request.POST.get('keys', []))
+  entity_id = json.loads(request.POST.get('id', '""'))
+  keys = json.loads(request.POST.get('keys', '[]'))
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
 
   request.audit = {
     'allowed': is_allowed,
-    'operation': 'NAVIGATOR_DELETE_PROPERTIES',
-    'operationText': 'Deleting property %s of entity %s' % (keys, entity_id)
+    'operation': 'NAVIGATOR_DELETE_METADATA_PROPERTIES',
+    'operationText': 'Deleting metadata %s of entity %s' % (keys, entity_id)
   }
 
   if not entity_id or not keys or not isinstance(keys, list):
     response['error'] = _("update_properties requires an 'id' parameter and 'keys' parameter that is a non-empty list")
   else:
-    response['entity'] = api.delete_properties(entity_id, keys)
+    response['entity'] = api.delete_metadata_properties(entity_id, keys)
     response['status'] = 0
 
   return JsonResponse(response)

+ 7 - 6
desktop/libs/metadata/src/metadata/navigator_client.py

@@ -460,14 +460,15 @@ class NavigatorApi(object):
     return self.update_entity(entity_id, tags=new_tags)
 
 
-  def update_properties(self, entity_id, properties):
-    entity = self.get_entity(entity_id)
-    new_props = entity['properties'] or {}
-    new_props.update(properties)
-    return self.update_entity(entity_id, properties=new_props)
+  def update_properties(self, entity_id, properties, metadata=None):
+    if metadata:
+      entity = self.get_entity(entity_id)
+      properties['properties'] = entity['properties'] or {}
+      properties['properties'].update(metadata)
+    return self.update_entity(entity_id, **properties)
 
 
-  def delete_properties(self, entity_id, property_keys):
+  def delete_metadata_properties(self, entity_id, property_keys):
     entity = self.get_entity(entity_id)
     new_props = entity['properties'] or {}
     for key in property_keys:

+ 1 - 1
desktop/libs/metadata/src/metadata/navigator_tests.py

@@ -118,7 +118,7 @@ class TestNavigator(object):
     props.update({'hue': 'test'})
     assert_equal(props, json_resp['entity']['properties'])
 
-    resp = self.client.post(reverse('metadata:delete_properties'), self._format_json_body({'id': entity_id, 'keys': ['hue']}))
+    resp = self.client.post(reverse('metadata:delete_metadata_properties'), self._format_json_body({'id': entity_id, 'keys': ['hue']}))
     json_resp = json.loads(resp.content)
     assert_equal(0, json_resp['status'], json_resp)
     del props['hue']

+ 1 - 1
desktop/libs/metadata/src/metadata/urls.py

@@ -29,7 +29,7 @@ urlpatterns = patterns('metadata.navigator_api',
   url(r'^api/navigator/list_tags/?$', 'list_tags', name='list_tags'),
   url(r'^api/navigator/suggest/?$', 'suggest', name='suggest'),
   url(r'^api/navigator/update_properties/?$', 'update_properties', name='update_properties'),
-  url(r'^api/navigator/delete_properties/?$', 'delete_properties', name='delete_properties'),
+  url(r'^api/navigator/delete_metadata_properties/?$', 'delete_metadata_properties', name='delete_metadata_properties'),
   url(r'^api/navigator/lineage/?$', 'get_lineage', name='get_lineage'),
 )