Kaynağa Gözat

HUE-5658 [libsentry] Perm checker returns a generator of results

Romain Rigaux 8 yıl önce
ebeveyn
işleme
004c39c

+ 4 - 5
desktop/libs/libsentry/src/libsentry/conf.py

@@ -46,8 +46,7 @@ SENTRY_CONF_DIR = Config(
 
 
 def is_enabled():
-  try:
-    from search.conf import SECURITY_ENABLED
-    return SECURITY_ENABLED.get()
-  except ImportError, e:
-    LOG.warn("Search app is not enabled")
+  from hadoop import cluster # Avoid dependencies conflicts
+  cluster = cluster.get_cluster_conf_for_job_submission()
+
+  return HOSTNAME.get() != 'localhost' and cluster.SECURITY_ENABLED.get()

+ 2 - 5
desktop/libs/libsentry/src/libsentry/privilege_checker.py

@@ -72,7 +72,6 @@ class PrivilegeChecker(object):
     :param key: a function that will be applied to each object in the objects iterable to convert it to a Sentry format
     """
     action = action.upper()
-    filtered_objects = []
 
     # Apply Sentry formatting key function
     object_authorizables = self._to_sentry_authorizables(objects=objects, key=key)
@@ -87,7 +86,7 @@ class PrivilegeChecker(object):
 
       for (object, authorizable) in v1_authorizables:
         if self._is_object_action_authorized_v1(hierarchy=privilege_hierarchy, object=authorizable, action=action):
-          filtered_objects.append(object)
+          yield object
 
     if v2_authorizables:
       privileges = self._get_privileges_for_user(self.api_v2)
@@ -95,9 +94,7 @@ class PrivilegeChecker(object):
 
       for (object, authorizable) in v2_authorizables:
         if self._is_object_action_authorized_v2(hierarchy=privilege_hierarchy, object=authorizable, action=action):
-          filtered_objects.append(object)
-
-    return filtered_objects
+          yield object
 
 
   def _to_sentry_authorizables(self, objects, key):

+ 1 - 1
desktop/libs/libsentry/src/libsentry/test_privilege_checker.py

@@ -144,7 +144,7 @@ class TestPrivilegeChecker(object):
           return None
 
       filtered_set = self.checker.filter_objects(objects=objectSet, action=action, key=test_key_fn)
-      assert_equal(expectedSet, filtered_set, filtered_set)
+      assert_equal(expectedSet, list(filtered_set), list(filtered_set))
 
 
   def test_columns_select(self):

+ 24 - 1
desktop/libs/metadata/src/metadata/conf.py

@@ -15,6 +15,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import logging
+
 from django.utils.translation import ugettext_lazy as _t
 
 from desktop.conf import AUTH_USERNAME as DEFAULT_AUTH_USERNAME, default_ssl_validate
@@ -24,6 +26,9 @@ from desktop.lib.paths import get_config_root
 from metadata.settings import DJANGO_APPS
 
 
+LOG = logging.getLogger(__name__)
+
+
 def get_auth_username():
   """Get from top level default from desktop"""
   return DEFAULT_AUTH_USERNAME.get()
@@ -131,6 +136,13 @@ def get_navigator_auth_password():
   '''Get default password from secured file'''
   return NAVIGATOR.AUTH_PASSWORD_SCRIPT.get()
 
+def get_security_default():
+  '''Get default security value from Hadoop'''
+  from hadoop import cluster # Avoid dependencies conflicts
+  cluster = cluster.get_cluster_conf_for_job_submission()
+
+  return cluster.SECURITY_ENABLED.get()
+
 
 NAVIGATOR = ConfigSection(
   key='navigator',
@@ -163,8 +175,19 @@ NAVIGATOR = ConfigSection(
     APPLY_SENTRY_PERMISSIONS = Config(
       key="apply_sentry_permissions",
       help=_t("Perform Sentry privilege filtering."),
-      default=False,
+      dynamic_default=get_security_default,
       type=coerce_bool
     ),
   )
 )
+
+
+def test_metadata_configurations(user):
+  from libsentry.conf import is_enabled
+
+  result = []
+
+  if not is_enabled() and NAVIGATOR.APPLY_SENTRY_PERMISSIONS.get():
+    result.append(("metadata", "Please enable Sentry when using metadata with Security."))
+
+  return result

+ 3 - 3
desktop/libs/metadata/src/metadata/navigator_api.py

@@ -80,7 +80,7 @@ def search_entities(request):
   query_s = smart_str(query_s)
 
   offset = request.POST.get('offset', 0)
-  limit = request.POST.get('limit', 100)
+  limit = int(request.POST.get('limit', 100))
   sources = json.loads(request.POST.get('sources')) or []
 
   query_s = query_s.strip() or '*'
@@ -111,7 +111,7 @@ def search_entities_interactive(request):
   query_s = json.loads(request.POST.get('query_s', ''))
   prefix = request.POST.get('prefix')
   offset = request.POST.get('offset', 0)
-  limit = request.POST.get('limit', 25)
+  limit = int(request.POST.get('limit', 25))
   field_facets = json.loads(request.POST.get('field_facets') or '[]')
   sources = json.loads(request.POST.get('sources') or '[]')
 
@@ -242,7 +242,7 @@ def _augment_highlighting(query_s, records):
         ts.append(term.strip('*'))
 
   for record in records:
-    name = record.get('originalName', '')
+    name = record.get('originalName', '') or ''
     record['hue_description'] = ''
     record['hue_name'] = record.get('parentPath', '') if record.get('parentPath') else ''
 

+ 10 - 5
desktop/libs/metadata/src/metadata/navigator_client.py

@@ -20,11 +20,14 @@ import json
 import logging
 import re
 
+from itertools import islice
+
 from desktop.lib.rest import resource
 from desktop.lib.rest.http_client import HttpClient, RestException
 
 from hadoop.conf import HDFS_CLUSTERS
 from libsentry.privilege_checker import PrivilegeChecker
+from libsentry.sentry_site import get_hive_sentry_provider
 
 from metadata.conf import NAVIGATOR
 
@@ -138,7 +141,7 @@ class NavigatorApi(object):
       LOG.info(params)
       response = self._root.get('entities', headers=self.__headers, params=params)
 
-      self._secure_results(response)
+      response = list(islice(self._secure_results(response), limit)) # Apply Sentry perms
 
       return response
     except RestException, e:
@@ -204,7 +207,7 @@ class NavigatorApi(object):
       LOG.info(data)
       response = self._root.post('interactive/entities?limit=%(limit)s&offset=%(offset)s' % pagination, data=data, contenttype=_JSON_CONTENT_TYPE, clear_cookies=True)
 
-      self._secure_results(response)
+      response['results'] = list(islice(self._secure_results(response['results']), limit)) # Apply Sentry perms
 
       return response
     except RestException:
@@ -213,18 +216,20 @@ class NavigatorApi(object):
       raise NavigatorApiException(msg)
 
 
-  def _secure_results(self, response):
+  def _secure_results(self, results):
     if NAVIGATOR.APPLY_SENTRY_PERMISSIONS.get():
       checker = PrivilegeChecker(user=self.user)
       action = 'SELECT'
 
       def getkey(result):
         if result['type'] == 'TABLE':
-          return {u'column': None, u'table': result['originalName'], u'db': result['parentPath'].strip('/')} #, 'server': 'server1'}
+          return {u'column': None, u'table': result.get('originalName', ''), u'db': result.get('parentPath', '') and result.get('parentPath', '').strip('/'), 'server': get_hive_sentry_provider()}
         else:
           return {u'column': None, u'table': None, u'db': None, u'server': None}
 
-      response['results'] = checker.filter_objects(response['results'], action, key=getkey)
+      return checker.filter_objects(results, action, key=getkey)
+    else:
+      return results
 
 
   def suggest(self, prefix=None):