浏览代码

HUE-5275 [libsentry] Add support for URI in privilege checker

Jenny Kim 9 年之前
父节点
当前提交
e18b270fce

+ 11 - 4
desktop/libs/libsentry/src/libsentry/privilege_checker.py

@@ -65,8 +65,8 @@ class PrivilegeChecker(object):
     Given a set of authorizable Sentry objects and a requested action, return a filtered set of objects that the user
     has privileges to perform the given action upon.
     :param authorizableSet: a list of Sentry authorizable objects which can consist of V1 or V2 objects:
-      V1 - {'column': 'total_emp', 'table': 'sample_08', 'db': 'default', 'server': 'server1'}
-      V2 - {'component': 'solr', 'serviceName': 'server1', 'type': 'COLLECTION', 'name': 'twitter_demo'}
+      V1 - {'column': 'total_emp', 'table': 'sample_08', 'db': 'default', 'server': 'server1', 'URI': None}
+      V2 - {'component': 'solr', 'serviceName': 'server1', 'type': 'COLLECTION', 'name': 'twitter_demo', 'URI': None}
     :param action: requested action-level that we should check privileges against (default: READ)
     """
     action = action.upper()
@@ -115,13 +115,16 @@ class PrivilegeChecker(object):
     hierarchy = tree()
 
     for privilege in privileges:
-      column, table, database, server = privilege['column'], privilege['table'], privilege['database'], privilege['server']
+      column, table, database, server, uri = \
+        privilege.get('column'), privilege.get('table'), privilege.get('database'), privilege.get('server'), privilege.get('URI')
       if column:
         hierarchy[server][database][table][column][SENTRY_PRIVILEGE_KEY] = privilege
       elif table:
         hierarchy[server][database][table][SENTRY_PRIVILEGE_KEY] = privilege
       elif database:
         hierarchy[server][database][SENTRY_PRIVILEGE_KEY] = privilege
+      elif uri:
+        hierarchy[server][uri][SENTRY_PRIVILEGE_KEY] = privilege
       else:
         hierarchy[server][SENTRY_PRIVILEGE_KEY] = privilege
 
@@ -152,12 +155,16 @@ class PrivilegeChecker(object):
     # Initialize all privileges for all object levels to non-authorized by default
     privileges_applied = dict((obj, -1) for obj in SENTRY_OBJECTS)
 
-    server, db, table, column = object['server'], object['db'], object['table'], object['column']
+    server, db, table, column, uri = \
+      object.get('server'), object.get('db'), object.get('table'), object.get('column'), object.get('URI')
 
     if server:  # Get server-level privilege
       if server in hierarchy:
         if SENTRY_PRIVILEGE_KEY in hierarchy[server]:
           privileges_applied['SERVER'] = PRIVILEGE_HIERARCHY[hierarchy[server][SENTRY_PRIVILEGE_KEY]['action']]
+        if uri and uri in hierarchy[server]:  # Get URI-level privilege
+          if SENTRY_PRIVILEGE_KEY in hierarchy[server][uri]:
+            privileges_applied['URI'] = PRIVILEGE_HIERARCHY[hierarchy[server][uri][SENTRY_PRIVILEGE_KEY]['action']]
         if db and db in hierarchy[server]: # Get db-level privilege
           if SENTRY_PRIVILEGE_KEY in hierarchy[server][db]:
             privileges_applied['DB'] = PRIVILEGE_HIERARCHY[hierarchy[server][db][SENTRY_PRIVILEGE_KEY]['action']]

+ 80 - 3
desktop/libs/libsentry/src/libsentry/test_privilege_checker.py

@@ -57,6 +57,8 @@ class TestDocumentConverter(object):
       {u'column': 'code', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
       {u'column': 'total_emp', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
       {u'column': 'total_emp', u'table': u'sample_07', u'db': u'default', u'server': u'server1'},
+      {u'column': None, u'table': None, u'db': None, u'server': u'server1', u'URI': u'hdfs://ha-nn-uri/data/landing-skid'},
+      {u'column': None, u'table': None, u'db': None, u'server': u'server1', u'URI': u'file:///path/to/nfs/local/to/nfs'},
       # V2 authorizables
       {u'component': u'solr', u'serviceName': u'server1', u'type': u'COLLECTION', u'name': u'logs_demo'},
       {u'component': u'solr', u'serviceName': u'server1', u'type': u'COLLECTION', u'name': u'test_demo'},
@@ -65,6 +67,8 @@ class TestDocumentConverter(object):
       {u'component': u'solr', u'serviceName': u'server1', u'type': u'CONFIG', u'name': u'twitter_demo'},
       {u'component': u'solr', u'serviceName': u'server1', u'type': u'CONFIG', u'name': u'managedTemplate'},
       {u'component': u'solr', u'serviceName': u'server1', u'type': u'CONFIG', u'name': u'yelp_demo'},
+      {u'component': u'hdfs', u'serviceName': u'server1', u'type': u'URI', u'name': u'hdfs://ha-nn-uri/data/landing-skid'},
+      {u'component': u'nfs', u'serviceName': u'server1', u'type': u'URI', u'name': u'file:///path/to/nfs/local/to/nfs'},
     ]
 
     self.api_v1.list_sentry_roles_by_group = Mock(return_value=[{'name': 'test', 'group': 'test'}])
@@ -73,7 +77,8 @@ class TestDocumentConverter(object):
       {'column': '', 'grantOption': False, 'timestamp': 1478810422058, 'database': 'default', 'action': 'SELECT', 'scope': 'TABLE', 'table': 'customers', 'URI': '', 'server': 'server1'},
       {'column': '', 'grantOption': False, 'timestamp': 1478810513849, 'database': 'default', 'action': 'SELECT', 'scope': 'TABLE', 'table': 'web_logs', 'URI': '', 'server': 'server1'},
       {'column': '', 'grantOption': False, 'timestamp': 1478810590335, 'database': 'default', 'action': 'SELECT', 'scope': 'TABLE', 'table': 'sample_08', 'URI': '', 'server': 'server1'},
-      {'column': 'salary', 'grantOption': False, 'timestamp': 1478810635396, 'database': 'default', 'action': 'ALL', 'scope': 'COLUMN', 'table': 'sample_08', 'URI': '', 'server': 'server1'}
+      {'column': 'salary', 'grantOption': False, 'timestamp': 1478810635396, 'database': 'default', 'action': 'ALL', 'scope': 'COLUMN', 'table': 'sample_08', 'URI': '', 'server': 'server1'},
+      {'column': '', 'grantOption': False, 'timestamp': 1478810513849, 'database': '', 'action': 'ALL', 'scope': 'URI', 'table': '', 'URI': 'hdfs://ha-nn-uri/data/landing-skid', 'server': 'server1'},
     ])
 
     self.api_v2.list_sentry_roles_by_group = Mock(return_value=[{'name': 'test', 'group': 'test'}])
@@ -81,17 +86,20 @@ class TestDocumentConverter(object):
       {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'ALL', 'authorizables': [{'type': 'CONFIG', 'name': 'managedTemplate'}]},
       {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'QUERY', 'authorizables': [{'type': 'COLLECTION', 'name': 'twitter_demo'}]},
       {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'UPDATE', 'authorizables': [{'type': 'COLLECTION', 'name': 'yelp_demo'}]},
-      {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'ALL', 'authorizables': [{'type': 'CONFIG', 'name': 'yelp_demo'}]}
+      {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'ALL', 'authorizables': [{'type': 'CONFIG', 'name': 'yelp_demo'}]},
+      {'grantOption': False, 'timestamp': None, 'component': 'hdfs', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'ALL', 'authorizables': [{'type': 'URI', 'name': 'hdfs://ha-nn-uri/data/landing-skid'}]},
     ])
 
     filtered_set = self.checker.filter_objects(authorizableSet=authorizableSet, action=action)
     expected_filtered_set = [
       # V2 authorizables
+      {u'type': u'URI', u'serviceName': u'server1', u'component': u'hdfs', u'name': u'hdfs://ha-nn-uri/data/landing-skid'},
       {u'type': u'COLLECTION', u'serviceName': u'server1', u'component': u'solr', u'name': u'twitter_demo'},
       {u'type': u'COLLECTION', u'serviceName': u'server1', u'component': u'solr', u'name': u'yelp_demo'},
       {u'type': u'CONFIG', u'serviceName': u'server1', u'component': u'solr', u'name': u'managedTemplate'},
       {u'type': u'CONFIG', u'serviceName': u'server1', u'component': u'solr', u'name': u'yelp_demo'},
       # V1 authorizables
+      {u'column': None, u'table': None, u'db': None, u'server': u'server1', u'URI': u'hdfs://ha-nn-uri/data/landing-skid'},
       {u'column': None, u'table': u'customers', u'db': u'default', u'server': u'server1'},
       {u'column': None, u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
       {u'column': 'code', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
@@ -99,4 +107,73 @@ class TestDocumentConverter(object):
       {u'column': 'total_emp', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
       {u'column': None, u'table': u'web_logs', u'db': u'default', u'server': u'server1'},
     ]
-    assert_equal(expected_filtered_set, sorted(filtered_set, key=lambda obj: (obj.get('table'), obj.get('column'), obj.get('component'), obj.get('type'), obj.get('name'))))
+
+    sort_keys = ['server', 'db', 'table', 'column', 'URI', 'serviceName', 'component', 'type', 'name']
+    assert_equal(expected_filtered_set, sorted(filtered_set, key=lambda obj: ([obj.get(key) for key in sort_keys])))
+
+
+  def test_write_privilege(self):
+    try:
+      from mock import Mock
+    except ImportError:
+      raise SkipTest("Skips until HUE-2947 is resolved")
+
+    action = 'WRITE'
+    authorizableSet = [
+      # V1 authorizables
+      {u'column': None, u'table': u'customers', u'db': u'default', u'server': u'server1'},
+      {u'column': None, u'table': u'sample_07', u'db': u'default', u'server': u'server1'},
+      {u'column': None, u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
+      {u'column': None, u'table': u'web_logs', u'db': u'default', u'server': u'server1'},
+      {u'column': 'salary', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
+      {u'column': 'code', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
+      {u'column': 'total_emp', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
+      {u'column': 'total_emp', u'table': u'sample_07', u'db': u'default', u'server': u'server1'},
+      {u'column': None, u'table': None, u'db': None, u'server': u'server1', u'URI': u'hdfs://ha-nn-uri/data/landing-skid'},
+      {u'column': None, u'table': None, u'db': None, u'server': u'server1', u'URI': u'file:///path/to/nfs/local/to/nfs'},
+      # V2 authorizables
+      {u'component': u'solr', u'serviceName': u'server1', u'type': u'COLLECTION', u'name': u'logs_demo'},
+      {u'component': u'solr', u'serviceName': u'server1', u'type': u'COLLECTION', u'name': u'test_demo'},
+      {u'component': u'solr', u'serviceName': u'server1', u'type': u'COLLECTION', u'name': u'twitter_demo'},
+      {u'component': u'solr', u'serviceName': u'server1', u'type': u'COLLECTION', u'name': u'yelp_demo'},
+      {u'component': u'solr', u'serviceName': u'server1', u'type': u'CONFIG', u'name': u'twitter_demo'},
+      {u'component': u'solr', u'serviceName': u'server1', u'type': u'CONFIG', u'name': u'managedTemplate'},
+      {u'component': u'solr', u'serviceName': u'server1', u'type': u'CONFIG', u'name': u'yelp_demo'},
+      {u'component': u'hdfs', u'serviceName': u'server1', u'type': u'URI', u'name': u'hdfs://ha-nn-uri/data/landing-skid'},
+      {u'component': u'nfs', u'serviceName': u'server1', u'type': u'URI', u'name': u'file:///path/to/nfs/local/to/nfs'},
+    ]
+
+    self.api_v1.list_sentry_roles_by_group = Mock(return_value=[{'name': 'test', 'group': 'test'}])
+    self.api_v1.list_sentry_privileges_by_role = Mock(return_value=[
+      {'column': 'total_emp', 'grantOption': False, 'timestamp': 1478810635378, 'database': 'default', 'action': 'INSERT', 'scope': 'COLUMN', 'table': 'sample_08', 'URI': '', 'server': 'server1'},
+      {'column': '', 'grantOption': False, 'timestamp': 1478810422058, 'database': 'default', 'action': 'SELECT', 'scope': 'TABLE', 'table': 'customers', 'URI': '', 'server': 'server1'},
+      {'column': '', 'grantOption': False, 'timestamp': 1478810513849, 'database': 'default', 'action': 'SELECT', 'scope': 'TABLE', 'table': 'web_logs', 'URI': '', 'server': 'server1'},
+      {'column': '', 'grantOption': False, 'timestamp': 1478810590335, 'database': 'default', 'action': 'SELECT', 'scope': 'TABLE', 'table': 'sample_08', 'URI': '', 'server': 'server1'},
+      {'column': 'salary', 'grantOption': False, 'timestamp': 1478810635396, 'database': 'default', 'action': 'ALL', 'scope': 'COLUMN', 'table': 'sample_08', 'URI': '', 'server': 'server1'},
+      {'column': '', 'grantOption': False, 'timestamp': 1478810513849, 'database': '', 'action': 'ALL', 'scope': 'URI', 'table': '', 'URI': 'hdfs://ha-nn-uri/data/landing-skid', 'server': 'server1'},
+    ])
+
+    self.api_v2.list_sentry_roles_by_group = Mock(return_value=[{'name': 'test', 'group': 'test'}])
+    self.api_v2.list_sentry_privileges_by_role = Mock(return_value=[
+      {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'ALL', 'authorizables': [{'type': 'CONFIG', 'name': 'managedTemplate'}]},
+      {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'QUERY', 'authorizables': [{'type': 'COLLECTION', 'name': 'twitter_demo'}]},
+      {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'UPDATE', 'authorizables': [{'type': 'COLLECTION', 'name': 'yelp_demo'}]},
+      {'grantOption': False, 'timestamp': None, 'component': 'solr', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'ALL', 'authorizables': [{'type': 'CONFIG', 'name': 'yelp_demo'}]},
+      {'grantOption': False, 'timestamp': None, 'component': 'hdfs', 'serviceName': 'server1', 'grantorPrincipal': None, 'action': 'ALL', 'authorizables': [{'type': 'URI', 'name': 'hdfs://ha-nn-uri/data/landing-skid'}]},
+    ])
+
+    filtered_set = self.checker.filter_objects(authorizableSet=authorizableSet, action=action)
+    expected_filtered_set = [
+      # V2 authorizables
+      {u'type': u'URI', u'serviceName': u'server1', u'component': u'hdfs', u'name': u'hdfs://ha-nn-uri/data/landing-skid'},
+      {u'type': u'COLLECTION', u'serviceName': u'server1', u'component': u'solr', u'name': u'yelp_demo'},
+      {u'type': u'CONFIG', u'serviceName': u'server1', u'component': u'solr', u'name': u'managedTemplate'},
+      {u'type': u'CONFIG', u'serviceName': u'server1', u'component': u'solr', u'name': u'yelp_demo'},
+      # V1 authorizables
+      {u'column': None, u'table': None, u'db': None, u'server': u'server1', u'URI': u'hdfs://ha-nn-uri/data/landing-skid'},
+      {u'column': 'salary', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
+      {u'column': 'total_emp', u'table': u'sample_08', u'db': u'default', u'server': u'server1'},
+    ]
+
+    sort_keys = ['server', 'db', 'table', 'column', 'URI', 'serviceName', 'component', 'type', 'name']
+    assert_equal(expected_filtered_set, sorted(filtered_set, key=lambda obj: ([obj.get(key) for key in sort_keys])), sorted(filtered_set, key=lambda obj: ([obj.get(key) for key in sort_keys])))