فهرست منبع

[sentry] Create a Hive privilege with API v2

Pass #1
Need to do another one when fixing can't get actionFactory in Sentry config.

Need to manage URI later too.
Romain Rigaux 10 سال پیش
والد
کامیت
7763b472f1

+ 5 - 7
apps/security/src/security/api/sentry.py

@@ -82,7 +82,7 @@ def list_sentry_roles_by_group(request):
 def list_sentry_privileges_by_role(request):
   result = {'status': -1, 'message': 'Error'}
 
-  try:    
+  try:
     serviceName = request.POST['server']
     component = request.POST['component']
     roleName = request.POST['roleName']
@@ -102,14 +102,12 @@ def list_sentry_privileges_by_role(request):
 
 def _to_sentry_privilege(privilege):
   return {
-      'privilegeScope': privilege['privilegeScope'],
-      'serverName': privilege['serverName'],
-      'dbName': privilege['dbName'],
-      'tableName': privilege['tableName'],
-      'columnName': privilege['columnName'],
-      'URI': _massage_uri(privilege['URI']),
+      'component': privilege['component'],
+      'serviceName': privilege['serverName'],
+      'authorizables': [{'type': auth['type'], 'name': auth['name_']} for auth in privilege['authorizables']], # TODO URI {'type': 'URI', 'name': _massage_uri('/path')}
       'action': privilege['action'],
       'createTime': privilege['timestamp'],
+      'grantorPrincipal': privilege['grantorPrincipal'],
       'grantOption': 1 if privilege['grantOption'] else 0,
   }
 

+ 82 - 29
apps/security/src/security/static/security/js/sentry.ko.js

@@ -25,6 +25,24 @@ function UUID() {
   return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
 }
 
+var Authorizable = function (vm, privilege, authorizable) {
+  var self = this;
+
+  self.type = ko.observable(typeof authorizable.type != "undefined" && authorizable.type != null ? authorizable.type : "");
+  self.type.subscribe(function () {
+    if (privilege.status() == '') {
+      privilege.status('modified');
+    }
+    privilege.privilegeScope(getPrivilegeScope());
+  });
+  self.name_ = ko.observable(typeof authorizable.name != "undefined" && authorizable.name != null ? authorizable.name : "");
+  self.name_.subscribe(function () {
+    if (privilege.status() == '') {
+      privilege.status('modified');
+    }
+    privilege.privilegeScope(getPrivilegeScope());
+  });
+}
 
 var Privilege = function (vm, privilege) {
   var self = this;
@@ -39,6 +57,22 @@ var Privilege = function (vm, privilege) {
       self.status('modified');
     }
   });
+  self.component = ko.observable(typeof privilege.component != "undefined" && privilege.component != null ? privilege.component : vm.component());
+  self.authorizables = ko.observableArray();
+  if (typeof privilege.authorizables != "undefined" && privilege.authorizables != null) {
+    self.authorizables(
+      $.map(privilege.authorizables, function(authorizable) {
+        return new Authorizable(vm, privilege, authorizable);
+      })
+    )
+  };
+  self.authorizables.subscribe(function () {
+    if (self.status() == '') {
+      self.status('modified');
+    }
+    self.privilegeScope(getPrivilegeScope());
+  });
+  /**
   self.dbName = ko.observable(typeof privilege.dbName != "undefined" && privilege.dbName != null ? privilege.dbName : "");
   self.dbName.subscribe(function () {
     if (self.status() == '') {
@@ -62,7 +96,7 @@ var Privilege = function (vm, privilege) {
     if (self.status() == '') {
       self.status('modified');
     }
-  });
+  });*/
   self.action = ko.observable(typeof privilege.action != "undefined" && privilege.action != null ? privilege.action : 'SELECT');
   self.action.subscribe(function () {
     if (self.status() == '') {
@@ -70,6 +104,7 @@ var Privilege = function (vm, privilege) {
     }
   });
   self.timestamp = ko.observable(typeof privilege.timestamp != "undefined" && privilege.timestamp != null ? privilege.timestamp : 0);
+  self.grantorPrincipal = ko.observable(typeof privilege.grantorPrincipal != "undefined" && privilege.grantorPrincipal != null ? privilege.grantorPrincipal : vm.user());
   self.grantOption = ko.observable(typeof privilege.grantOption != "undefined" && privilege.grantOption != null ? privilege.grantOption : false);
   self.grantOption.subscribe(function () {
     if (self.status() == '') {
@@ -82,43 +117,50 @@ var Privilege = function (vm, privilege) {
   self.showAdvanced = ko.observable(false);
   self.path = ko.computed({
     read: function () {
-      if (self.columnName().length > 0) {
-        return self.dbName() + "." + self.tableName() + "." + self.columnName();
-      } else if (self.tableName().length > 0) {
-        return self.dbName() + "." + self.tableName();
-      } else {
-        return self.dbName();
-      }
+      return $.map(self.authorizables(), function(authorizable) {
+        return authorizable.name_();
+      }).join(".");
     },
     write: function (value) {
       var _parts = value.split(".");
-      this.dbName(_parts[0]);
-      this.tableName(_parts.length > 1 ? _parts[1] : "");
-      this.columnName(_parts.length > 2 ? _parts[2] : "");
+
+      self.authorizables.removeAll();
+      self.authorizables.push(new Authorizable(vm, self, {type: 'DATABASE', name: _parts[0]}))
+      if (_parts.length > 1) {
+        self.authorizables.push(new Authorizable(vm, self, {type: 'TABLE', name: _parts[1]}))
+      }
+      if (_parts.length > 2) {
+        self.authorizables.push(new Authorizable(vm, self, {type: 'COLUMN', name: _parts[2]}))
+      }
     },
     owner: self
   });
 
-  self.metastorePath = ko.computed(function(){
-    if (self.columnName().length > 0) {
-      return '/metastore/table/' + self.dbName() + "/" + self.tableName() + "#col=" + self.columnName();
-    } else if (self.tableName().length > 0) {
-      return '/metastore/table/' + self.dbName() + "/" + self.tableName();
-    } else if (self.dbName().length > 0) {
-      return '/metastore/tables/' + self.dbName();
-    } else {
-      return '';
+  self.metastorePath = ko.computed(function() {
+    var path = '';
+
+    if (self.authorizables()[0] && self.authorizables()[0]['type'] == 'DATABASE') {
+      path = '/metastore/tables/' + self.authorizables()[0];
     }
+    if (self.authorizables()[1] && self.authorizables()[1]['type'] == 'TABLE') {
+      path +=  "/" + self.authorizables()[1];
+    }
+    if (self.authorizables()[2] && self.authorizables()[2]['type'] == 'COLUMN') {
+      path +=  "#col=" + self.authorizables()[2];
+    }
+
+    return path;
   });
 
+  // TODO remove
   function getPrivilegeScope() {
     if (self.privilegeType() == 'uri') {
       return 'URI';
-    } else if (self.columnName().length > 0) {
+    } else if (self.authorizables()[2] == 'COLUMN') {
       return 'COLUMN';
-    } else if (self.tableName().length > 0) {
+    } else if (self.authorizables()[1] == 'TABLE') {
       return 'TABLE';
-    } else if (self.dbName().length > 0) {
+    } else if (self.authorizables()[0] == 'DATABASE') {
       return 'DATABASE';
     } else {
       return 'SERVER';
@@ -126,7 +168,7 @@ var Privilege = function (vm, privilege) {
   }
 
   self.privilegeScope = ko.observable(typeof privilege.privilegeScope != "undefined" ? privilege.privilegeScope : getPrivilegeScope());
-
+/**
   self.privilegeType.subscribe(function(newVal){
     self.privilegeScope(getPrivilegeScope());
   });
@@ -142,7 +184,7 @@ var Privilege = function (vm, privilege) {
   self.dbName.subscribe(function(newVal){
     self.privilegeScope(getPrivilegeScope());
   });
-
+*/
   self.remove = function (privilege) {
     if (privilege.status() == 'new') {
       privilege.status('alreadydeleted');
@@ -240,8 +282,18 @@ var Role = function (vm, role) {
   }
 
   self.addPrivilege = function () {
-    if (vm.getSectionHash() == 'edit') {
-      self.privileges.push(new Privilege(vm, {'serverName': vm.assist.server(), 'status': 'new', 'editing': true, 'dbName': vm.assist.db(), 'tableName': vm.assist.table(), 'columnName': vm.assist.column()}));
+    if (vm.getSectionHash() == 'edit') { // used?
+      self.privileges.push(new Privilege(vm, {
+          'serverName': vm.assist.server(),
+          'status': 'new',
+          'component': vm.component(),
+          'editing': true,
+          'authorizables': [
+              {'type': 'DATABASE', 'name': vm.assist.db()},
+              {'type': 'TABLE', 'name': vm.assist.table()},
+              {'type': 'COLUMN', 'name': vm.assist.column()}
+           ]
+      }));
     } else {
       self.privileges.push(new Privilege(vm, {'serverName': vm.assist.server(), 'status': 'new', 'editing': true}));
     }
@@ -821,6 +873,7 @@ var HiveViewModel = function (initial) {
 
   // Models
   self.component = ko.observable(initial.component);
+  self.user = ko.observable(initial.user);
   self.server = ko.observable(initial.sentry_provider);
   self.roles = ko.observableArray();
   self.tempRoles = ko.observableArray();
@@ -1021,7 +1074,7 @@ var HiveViewModel = function (initial) {
     $.ajax({
       type: "POST",
       url: "/security/api/sentry/list_sentry_privileges_by_role",
-      data: {        
+      data: {
         'server': self.server(),
         'component': self.component(),
         'roleName': role.name
@@ -1070,7 +1123,7 @@ var HiveViewModel = function (initial) {
 
     if (optionalPath != null) {
       var paths = optionalPath.split(/[.]/);
-      
+
       if (paths[0]) { authorizables.push({'type': 'db', 'name': paths[0]}); }
       if (paths[1]) { authorizables.push({'type': 'table', 'name': paths[1]}); }
       if (paths[2]) { authorizables.push({'type': 'column', 'name': paths[2]}); }

+ 3 - 1
apps/security/src/security/templates/sentry.mako

@@ -65,7 +65,9 @@ ${ layout.menubar(section='hive2') }
         <i class="fa fa-fw fa-1halfx muted" data-bind="css: {'fa-circle-o': privilegeType() != 'uri' , 'fa-check-circle-o': privilegeType() == 'uri'}"></i>
       </a>
     </div>
-    <input type="text" data-bind="filechooser: $data.URI, enable: privilegeType() == 'uri'" placeholder="URI">
+    <!-- ko if: editing() -->
+    <input type="text" data-bind="filechooser: 'URI TODO', enable: privilegeType() == 'uri'" placeholder="URI">
+    <!-- /ko -->
 
     <select data-bind="options: $root.availableActions, value: $data.action, enable: (privilegeType() == 'db')" style="width: 100px; margin-bottom: 0"></select>
 

+ 2 - 2
desktop/libs/libsentry/src/libsentry/api2.py

@@ -93,8 +93,8 @@ class SentryApi(object):
       raise SentryException(response)
 
   @ha_error_handler
-  def alter_sentry_role_grant_privilege(self, roleName, tSentryPrivilege=None, tSentryPrivileges=None):
-    response = self.client.alter_sentry_role_grant_privilege(roleName, tSentryPrivilege, tSentryPrivileges)
+  def alter_sentry_role_grant_privilege(self, roleName, tSentryPrivilege=None):
+    response = self.client.alter_sentry_role_grant_privilege(roleName, tSentryPrivilege)
 
     if response.status.value == 0:
       return response

+ 6 - 9
desktop/libs/libsentry/src/libsentry/client2.py

@@ -102,14 +102,11 @@ class SentryClient(object):
     return self.client.drop_sentry_role(request)
 
 
-  def alter_sentry_role_grant_privilege(self, roleName, tSentryPrivilege, tSentryPrivileges):
-    if tSentryPrivilege is not None:
-      tSentryPrivilege = TSentryPrivilege(**tSentryPrivilege)
-
-    if tSentryPrivileges is not None:
-      tSentryPrivileges = [TSentryPrivilege(**tSentryPrivilege) for tSentryPrivilege in tSentryPrivileges]
+  def alter_sentry_role_grant_privilege(self, roleName, tSentryPrivilege):
+    tSentryPrivilege['authorizables'] = [TAuthorizable(type=_auth['type'], name=_auth['name']) for _auth in tSentryPrivilege['authorizables']]
+    tSentryPrivilege = TSentryPrivilege(**tSentryPrivilege)
 
-    request = TAlterSentryRoleGrantPrivilegeRequest(requestorUserName=self.username, component=self.component, roleName=roleName, privilege=tSentryPrivilege, privileges=tSentryPrivileges)
+    request = TAlterSentryRoleGrantPrivilegeRequest(requestorUserName=self.username, component=self.component, roleName=roleName, privilege=tSentryPrivilege)
     return self.client.alter_sentry_role_grant_privilege(request)
 
 
@@ -183,10 +180,10 @@ class SentryClient(object):
 #     authorizableSet = [TAuthorizable(**authorizable) for authorizable in authorizableSet]
 #     if roleSet is not None:
 #       roleSet = TSentryActiveRoleSet(**roleSet)
-#  
+#
 #     request = TListSentryPrivilegesByAuthRequest(requestorUserName=self.username, component=self.component, authorizableSet=authorizableSet, groups=groups, roleSet=roleSet)
 #     return self.client.list_sentry_privileges_by_authorizable(request)
     return type('Response', (object,), {
         'status': type('Status', (object,), {'value': 0}),
-        'privilegesMapByAuth': {}          
+        'privilegesMapByAuth': {}
     })