Преглед изворни кода

HUE-2361 [sentry] Grant privilege to a role the user does not belong too

Do not check the checkall checkbox when creating the firt role
Romain Rigaux пре 11 година
родитељ
комит
1bd4177

+ 20 - 1
apps/security/src/security/api/hive.py

@@ -119,7 +119,9 @@ def create_role(request):
     api = get_api(request.user)
 
     api.create_sentry_role(role['name'])
-    result['privileges'] = _hive_add_privileges(request.user, role, role['privileges'])
+
+    privileges = [privilege for privilege in role['privileges'] if privilege['status'] != 'deleted']
+    result['privileges'] = _hive_add_privileges(request.user, role, privileges)
     api.alter_sentry_role_add_groups(role['name'], role['groups'])
 
     result['role'] = {"name": role['name'], "groups": role['groups']}
@@ -184,6 +186,23 @@ def save_privileges(request):
   return HttpResponse(json.dumps(result), mimetype="application/json")
 
 
+def grant_privilege(request):
+  result = {'status': -1, 'message': 'Error'}
+
+  try:
+    roleName = json.loads(request.POST['roleName'])
+    privilege = json.loads(request.POST['privilege'])
+
+    result['privileges'] = _hive_add_privileges(request.user, {'name': roleName}, [privilege])
+
+    result['message'] = _('Privilege granted successfully to %s.') % roleName
+    result['status'] = 0
+  except Exception, e:
+    result['message'] = unicode(str(e), "utf8")
+
+  return HttpResponse(json.dumps(result), mimetype="application/json")
+
+
 def create_sentry_role(request):
   result = {'status': -1, 'message': 'Error'}
 

+ 38 - 4
apps/security/src/security/templates/hive.mako

@@ -48,6 +48,9 @@ ${ layout.menubar(section='hive') }
 
   <!-- ko if: editing() -->
     <div class="pull-right">
+      <a title="${ _('Grant this privilege') }" class="pointer" style="margin-right: 4px" data-bind="visible: grantOption() || $root.is_sentry_admin, click: function(){ $root.grantToPrivilege($data); $('#grantPrivilegeModal').modal('show'); }">
+        <i class="fa fa-send"></i>
+      </a>
       <a class="pointer" style="margin-right: 4px" data-bind="click: function() { if (editing()) { editing(false); }}"><i class="fa fa-eye"></i></a>
       <a class="pointer" style="margin-right: 4px" data-bind="click: remove"><i class="fa fa-times"></i></a>
     </div>
@@ -84,8 +87,11 @@ ${ layout.menubar(section='hive') }
   <!-- ko ifnot: editing() -->
     <!-- ko ifnot: $root.isApplyingBulk() -->
     <div class="pull-right">
-      <a class="pointer" style="margin-right: 4px" data-bind="click: function() { if (! editing()) { editing(true); }}"><i class="fa fa-pencil"></i></a>
-      <a class="pointer" style="margin-right: 4px" data-bind="click: remove"><i class="fa fa-times"></i></a>
+      <a title="${ _('Grant this privilege') }" class="pointer" style="margin-right: 4px" data-bind="visible: grantOption() || $root.is_sentry_admin, click: function(){ $root.grantToPrivilege($data); $('#grantPrivilegeModal').modal('show'); }">
+        <i class="fa fa-send"></i>
+      </a>
+      <a title="${ _('Edit this privilege') }" class="pointer" style="margin-right: 4px" data-bind="click: function() { if (! editing()) { editing(true); }}"><i class="fa fa-pencil"></i></a>
+      <a title="${ _('Delete this privilege') }" class="pointer" style="margin-right: 4px" data-bind="click: remove"><i class="fa fa-times"></i></a>
     </div>
     <!-- /ko -->
 
@@ -211,7 +217,7 @@ ${ layout.menubar(section='hive') }
                 <div data-bind="visible: $root.assist.privileges().length == 0 && $root.isLoadingPrivileges()"><i class="fa fa-spinner fa-spin" data-bind="visible: $root.isLoadingPrivileges()"></i> <em class="muted">${ _('Loading privileges...')}</em></div>
                 <h4 style="margin-top: 4px" data-bind="visible: $root.assist.privileges().length > 0 && ! $root.isLoadingPrivileges()">${ _('Privileges') } &nbsp;</h4>
                 <div data-bind="visible: $root.assist.privileges().length == 0 && ! $root.isLoadingPrivileges()">
-                  <div class="span10 offset1 center" style="cursor: pointer" data-bind="click: function(){ $root.showCreateRole(true); $('#createRoleModal').modal('show'); }">
+                  <div class="span10 offset1 center" style="cursor: pointer" data-bind="click: function(){ if ($root.is_sentry_admin) { $root.showCreateRole(true); $('#createRoleModal').modal('show'); } }">
                     <i class="fa fa-plus-circle waiting"></i>
                     <h1 class="emptyMessage">
                       ${ _('No privileges found for the selected item') }<br/>
@@ -234,7 +240,7 @@ ${ layout.menubar(section='hive') }
 
         <div class="card-body">
           <h1 class="muted" data-bind="visible: $root.isLoadingRoles()"><i class="fa fa-spinner fa-spin"></i></h1>
-          <div class="span10 offset1 center" style="cursor: pointer" data-bind="visible: $root.roles().length == 0 && ! $root.isLoadingRoles(), click: function(){ $root.showCreateRole(true); $('#createRoleModal').modal('show'); }">
+          <div class="span10 offset1 center" style="cursor: pointer" data-bind="visible: $root.roles().length == 0 && ! $root.isLoadingRoles(), click: function(){ if ($root.is_sentry_admin) { $root.showCreateRole(true); $('#createRoleModal').modal('show'); } }">
             <i class="fa fa-plus-circle waiting"></i>
             <h1 class="emptyMessage">
               ${ _('There are currently no roles defined') }<br/>
@@ -370,6 +376,29 @@ ${ layout.menubar(section='hive') }
 </div>
 
 
+<div id="grantPrivilegeModal" class="modal hide fade in" role="dialog">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>${ _('Grant privilege') }</h3>
+  </div>
+  <div class="modal-body">
+
+    <!-- ko if: $root.grantToPrivilege() -->
+      <div data-bind="template: { name: 'privilege', data: $root.grantToPrivilege() }"></div>
+    <!-- /ko -->
+
+    <h4>${ _('To') }</h4>
+    <select data-bind="options: $root.selectableRoles(), value: $root.grantToPrivilegeRole, select2: { update: $root.grantToPrivilegeRole, placeholder: '${ _("Select a role") }' }" style="width: 360px"></select>
+    </br>
+
+  </div>
+  <div class="modal-footer">
+    <button class="btn" data-dismiss="modal" aria-hidden="true">${ _('Cancel') }</button>
+    <button data-loading-text="${ _('Saving...') }" class="btn btn-primary disable-enter" data-bind="click: $root.grant_privilege">${ _('Grant') }</button>
+  </div>
+</div>
+
+
 <div id="deleteRoleModal" class="modal hide fade in" role="dialog">
   <div class="modal-header">
     <a href="#" class="close" data-dismiss="modal">&times;</a>
@@ -543,6 +572,7 @@ ${ tree.import_templates(itemClick='$root.assist.setPath', iconClick='$root.assi
 
       $(document).on("created.role", function(){
         $("#createRoleModal").modal("hide");
+        $("#grantPrivilegeModal").modal("hide");
         window.setTimeout(function(){
           viewModel.refreshExpandedRoles();
         }, 500);
@@ -603,6 +633,10 @@ ${ tree.import_templates(itemClick='$root.assist.setPath', iconClick='$root.assi
         show: false
       });
 
+      $("#grantPrivilegeModal").modal({
+        show: false
+      });
+
       $("#createRoleModal").on("hidden", function () {
         $('#jHueHiveAutocomplete').hide();
         viewModel.resetCreateRole();

+ 3 - 2
apps/security/src/security/urls.py

@@ -47,6 +47,7 @@ urlpatterns += patterns('security.api.hive',
   url(r'^api/hive/save_privileges$', 'save_privileges', name='save_privileges'),
   url(r'^api/hive/bulk_delete_privileges', 'bulk_delete_privileges', name='bulk_delete_privileges'),
   url(r'^api/hive/bulk_add_privileges', 'bulk_add_privileges', name='bulk_add_privileges'),
-  
-  url(r'^api/hive/rename_sentry_privilege', 'rename_sentry_privilege', name='rename_sentry_privilege'),  
+  url(r'^api/hive/grant_privilege', 'grant_privilege', name='grant_privilege'),
+
+  url(r'^api/hive/rename_sentry_privilege', 'rename_sentry_privilege', name='rename_sentry_privilege'),
 )

+ 27 - 3
apps/security/static/js/hive.ko.js

@@ -246,7 +246,6 @@ var Role = function (vm, role) {
         role.showPrivileges(true);
         vm.originalRoles.unshift(role);
         vm.assist.refreshTree();
-        vm.refreshExpandedRoles();
         $(document).trigger("created.role");
       } else {
         $(document).trigger("error", data.message);
@@ -265,7 +264,6 @@ var Role = function (vm, role) {
         $(document).trigger("info", data.message);
         vm.showCreateRole(false);
         vm.assist.refreshTree();
-        vm.refreshExpandedRoles();
         $(document).trigger("created.role");
       } else {
         $(document).trigger("error", data.message);
@@ -786,6 +784,9 @@ var HiveViewModel = function (initial) {
   self.showCreateRole = ko.observable(false);
   self.role = ko.observable(new Role(self, {}));
 
+  self.grantToPrivilege = ko.observable();
+  self.grantToPrivilegeRole = ko.observable();
+
   self.resetCreateRole = function() {
     self.roles(self.originalRoles());
     self.role(new Role(self, {}));
@@ -816,7 +817,7 @@ var HiveViewModel = function (initial) {
   }, self);
 
   self.selectAllRoles = function () {
-    self.allRolesSelected(!self.allRolesSelected());
+    self.allRolesSelected(! self.allRolesSelected());
     ko.utils.arrayForEach(self.roles(), function (role) {
       role.selected(self.allRolesSelected());
     });
@@ -989,6 +990,29 @@ var HiveViewModel = function (initial) {
     }
   }
 
+  self.grant_privilege = function () {
+    $(".jHueNotify").hide();
+    $.ajax({
+      type: "POST",
+      url: "/security/api/hive/grant_privilege",
+      data: {
+        'privilege': ko.mapping.toJSON(self.grantToPrivilege()),
+        'roleName': ko.mapping.toJSON(self.grantToPrivilegeRole())
+      },
+      success: function (data) {
+        if (data.status == 0) {
+          $(document).trigger("info", data.message);
+          self.assist.refreshTree();
+          $(document).trigger("created.role");
+        } else {
+          $(document).trigger("error", data.message);
+        }
+      }
+    }).fail(function (xhr, textStatus, errorThrown) {
+      $(document).trigger("error", xhr.responseText);
+    });
+  }
+
   self.list_sentry_privileges_by_authorizable = function (optionalPath, skipList) {
     var _path = self.assist.path();
     if (optionalPath != null){