浏览代码

[sentry] Bulk edit privileges with columns

Fix infinite tree refresh spinner when clicking on a column
Romain Rigaux 10 年之前
父节点
当前提交
9e17926

+ 21 - 10
apps/security/src/security/api/hive.py

@@ -143,6 +143,20 @@ def _massage_uri(uri):
   return uri
 
 
+def _get_splitted_path(path):
+  parts = path.split('.')
+  db, table, column = '', '', ''
+
+  if len(parts) >= 1:
+    db = parts[0]
+  if len(parts) >= 2:
+    table = parts[1]
+  if len(parts) >= 3:
+    column = parts[2]
+
+  return db, table, column
+
+
 def _drop_sentry_privilege(user, role, authorizable):
   return get_api(user).alter_sentry_role_revoke_privilege(role['name'], _to_sentry_privilege(authorizable))
 
@@ -317,13 +331,11 @@ def bulk_delete_privileges(request):
     authorizableHierarchy = json.loads(request.POST['authorizableHierarchy'])
 
     for path in [path['path'] for path in checkedPaths]:
-      if '.' in path:
-        db, table = path.split('.')
-      else:
-        db, table = path, ''
+      db, table, column = _get_splitted_path(path)
       authorizableHierarchy.update({
         'db': db,
         'table': table,
+        'column': column,
       })
       get_api(request.user).drop_sentry_privileges(authorizableHierarchy)
     result['message'] = _('Privileges deleted.')
@@ -347,20 +359,19 @@ def bulk_add_privileges(request):
     privileges = [privilege for privilege in privileges if privilege['status'] == '']
 
     for path in [path['path'] for path in checkedPaths]:
-      # TODO: check how it goes with column
-      if '.' in path:
-        db, table = path.split('.')
-      else:
-        db, table = path, ''
-      privilegeScope = 'TABLE' if table else 'DATABASE' if db else 'SERVER'
+      db, table, column = _get_splitted_path(path)
+
+      privilegeScope = 'COLUMN' if column else 'TABLE' if table else 'DATABASE' if db else 'SERVER'
       authorizableHierarchy.update({
         'db': db,
         'table': table,
+        'column': column,
       })
 
       for privilege in privileges:
         privilege['dbName'] = db
         privilege['tableName'] = table
+        privilege['columnName'] = column
         privilege['privilegeScope'] = privilegeScope
         _hive_add_privileges(request.user, {'name': privilege['roleName']}, [privilege])
 

+ 8 - 1
apps/security/src/security/api/test_hive.py

@@ -30,7 +30,7 @@ from desktop.lib.django_test_util import make_logged_in_client
 from desktop.lib.test_utils import grant_access, add_to_group
 
 from libsentry import api
-from security.api.hive import _massage_uri
+from security.api.hive import _massage_uri, _get_splitted_path
 
 
 def mocked_get_api(user):
@@ -121,3 +121,10 @@ class TestUtils(object):
       assert_equal('file:///data', _massage_uri('file:///data'))
     finally:
       finish()
+
+  def test_get_splitted_path(self):
+    assert_equal(('', '', ''), _get_splitted_path(''))
+    assert_equal(('db', '', ''), _get_splitted_path('db'))
+    assert_equal(('db', 'table', ''), _get_splitted_path('db.table'))
+    assert_equal(('db', 'table', 'column'), _get_splitted_path('db.table.column'))
+    assert_equal(('db', 'table', 'column'), _get_splitted_path('db.table.column.blah'))

+ 8 - 5
apps/security/src/security/static/security/js/hive.ko.js

@@ -344,7 +344,7 @@ var Assist = function (vm, initial) {
   self.column = ko.computed(function () {
     var column = self.path().split(/[.]/)[2];
     return column ? column : null;
-  });  
+  });
   self.privileges = ko.observableArray();
   self.roles = ko.observableArray();
   self.isDiffMode = ko.observable(false);
@@ -701,11 +701,11 @@ var Assist = function (vm, initial) {
   }
 
   self.fetchHivePath = function (optionalPath, loadCallback) {
-    self.isLoadingTree(true);
-
     var _originalPath = typeof optionalPath != "undefined" ? optionalPath : self.path();
 
     if (_originalPath.split(".").length < 3) {
+      self.isLoadingTree(true);
+
       var _path = _originalPath.replace('.', '/');
       var request = {
         url: '/security/api/hive/fetch_hive_path',
@@ -734,6 +734,7 @@ var Assist = function (vm, initial) {
           else if (data.columns && data.columns.length > 0) {
             self.addColumns(_originalPath, data.columns, _hasCallback);
           }
+
           self.isLoadingTree(false);
 
           if (_hasCallback) {
@@ -1018,13 +1019,15 @@ var HiveViewModel = function (initial) {
       return {
         'server': self.assist.server(),
         'db': paths[0] ? paths[0] : null,
-        'table': paths[1] ? paths[1] : null
+        'table': paths[1] ? paths[1] : null,
+        'column': paths[2] ? paths[2] : null
       }
     } else {
       return {
         'server': self.assist.server(),
         'db': self.assist.db(),
-        'table': self.assist.table()
+        'table': self.assist.table(),
+        'column': self.assist.column(),
       }
     }
   }

+ 5 - 0
apps/security/src/security/templates/hive.mako

@@ -483,6 +483,11 @@ ${ layout.menubar(section='hive') }
             <i class="fa fa-long-arrow-right muted"></i>
             <i class="fa fa-table muted"></i>
             <span data-bind="text: path.split('.')[1]"></span>
+            <span data-bind="visible: path.split('.')[2]">
+              <i class="fa fa-long-arrow-right muted"></i>
+              <i class="fa fa-columns muted"></i>
+              <span data-bind="text: path.split('.')[2]"></span>
+            </span>
           </li>
           <li data-bind="visible: path.indexOf('.') == -1" class="force-word-break">
             <i class="fa fa-database muted"></i> <span data-bind="text: path.split('.')[0]"></span>

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

@@ -194,7 +194,7 @@ class SentryClient(object):
 
 
   def get_sentry_config_value(self, propertyName, defaultValue=None):
-    requestorUserName = self.username # Not available in Sentry API
+    # Note there is no requestorUserName in Sentry API
 
     request = TSentryConfigValueRequest(propertyName=propertyName, defaultValue=defaultValue)
     return self.client.get_sentry_config_value(request)