Prechádzať zdrojové kódy

HUE-3891 [sentry] Disallow to create a URI privilege that has an empty path

Enrico Berti 9 rokov pred
rodič
commit
500db74

+ 47 - 38
apps/security/src/security/static/security/js/hive.ko.js

@@ -206,6 +206,11 @@ var Role = function (vm, role) {
   self.showEditGroups = ko.observable(false);
   self.isEditing = ko.observable(false);
   self.isLoading = ko.observable(false);
+  self.isValid = ko.computed(function () {
+    return $.grep(self.privileges(), function (privilege) {
+      return privilege.privilegeType() === 'uri' && privilege.URI() === '';
+    }).length === 0;
+  });
 
   self.privilegesChanged = ko.computed(function () {
     return $.grep(self.privileges(), function (privilege) {
@@ -279,48 +284,52 @@ var Role = function (vm, role) {
 
   self.create = function () {
     $(".jHueNotify").hide();
-    self.isLoading(true);
-    $.post("/security/api/hive/create_role", {
-      role: ko.mapping.toJSON(self)
-    }, function (data) {
-      if (data.status == 0) {
-        $(document).trigger("info", data.message);
-        vm.showCreateRole(false);
-        self.reset();
-        var role = new Role(vm, data.role);
-        role.showPrivileges(true);
-        vm.originalRoles.unshift(role);
-        vm.list_sentry_privileges_by_authorizable();
-        $(document).trigger("created.role");
-      } else {
-        $(document).trigger("error", data.message);
-      }
-    }).fail(function (xhr, textStatus, errorThrown) {
-      $(document).trigger("error", xhr.responseText);
-    }).always(function() {
-      self.isLoading(false);
-    });
+    if (self.isValid()) {
+      self.isLoading(true);
+      $.post("/security/api/hive/create_role", {
+        role: ko.mapping.toJSON(self)
+      }, function (data) {
+        if (data.status == 0) {
+          $(document).trigger("info", data.message);
+          vm.showCreateRole(false);
+          self.reset();
+          var role = new Role(vm, data.role);
+          role.showPrivileges(true);
+          vm.originalRoles.unshift(role);
+          vm.list_sentry_privileges_by_authorizable();
+          $(document).trigger("created.role");
+        } else {
+          $(document).trigger("error", data.message);
+        }
+      }).fail(function (xhr, textStatus, errorThrown) {
+        $(document).trigger("error", xhr.responseText);
+      }).always(function () {
+        self.isLoading(false);
+      });
+    }
   }
 
   self.update = function () {
     $(".jHueNotify").hide();
-    self.isLoading(true);
-    $.post("/security/api/hive/save_privileges", {
-      role: ko.mapping.toJSON(self)
-    }, function (data) {
-      if (data.status == 0) {
-        $(document).trigger("info", data.message);
-        vm.showCreateRole(false);
-        vm.list_sentry_privileges_by_authorizable();
-        $(document).trigger("created.role");
-      } else {
-        $(document).trigger("error", data.message);
-      }
-    }).fail(function (xhr, textStatus, errorThrown) {
-      $(document).trigger("error", xhr.responseText);
-    }).always(function() {
-      self.isLoading(false);
-    });
+    if (self.isValid()) {
+      self.isLoading(true);
+      $.post("/security/api/hive/save_privileges", {
+        role: ko.mapping.toJSON(self)
+      }, function (data) {
+        if (data.status == 0) {
+          $(document).trigger("info", data.message);
+          vm.showCreateRole(false);
+          vm.list_sentry_privileges_by_authorizable();
+          $(document).trigger("created.role");
+        } else {
+          $(document).trigger("error", data.message);
+        }
+      }).fail(function (xhr, textStatus, errorThrown) {
+        $(document).trigger("error", xhr.responseText);
+      }).always(function () {
+        self.isLoading(false);
+      });
+    }
   }
 
   self.remove = function (role) {

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

@@ -65,7 +65,7 @@ ${ layout.menubar(section='hive1') }
         <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">
+    <input type="text" data-bind="filechooser: $data.URI, enable: privilegeType() == 'uri', valueUpdate: 'afterkeydown'" placeholder="URI">
 
     <select data-bind="options: $root.availableActions, value: $data.action, enable: (privilegeType() == 'db')" style="width: 100px; margin-bottom: 0"></select>
 
@@ -347,7 +347,7 @@ ${ layout.menubar(section='hive1') }
                   <div class="acl-block acl-actions" data-bind="click: privilegesChanged().length == 0 ? addPrivilege : void(0), visible: $root.is_sentry_admin">
                     <span class="pointer" data-bind="click: addPrivilege, visible: $data.showPrivileges" title="${ _('Add privilege') }"><i class="fa fa-plus"></i></span>
                     <span class="pointer" data-bind="click: $root.list_sentry_privileges_by_role, visible: privilegesChanged().length > 0" title="${ _('Undo') }"> &nbsp; <i class="fa fa-undo"></i></span>
-                    <span class="pointer" data-bind="click: function() { deletePrivilegeModal($data) }, visible: privilegesChanged().length > 0" title="${ _('Save') }"> &nbsp; <i class="fa fa-save"></i></span>
+                    <span class="pointer" data-bind="click: function() { deletePrivilegeModal($data) }, visible: privilegesChanged().length > 0 && isValid()" title="${ _('Save') }"> &nbsp; <i class="fa fa-save"></i></span>
                   </div>
                 </td>
               </tr>
@@ -389,8 +389,8 @@ ${ layout.menubar(section='hive1') }
   </div>
   <div class="modal-footer">
     <button class="btn" data-dismiss="modal" aria-hidden="true">${ _('Cancel') }</button>
-    <button class="btn btn-primary disable-enter disable-feedback" data-bind="click: $root.role().create, visible: ! $root.role().isEditing(), css: {'disabled': $root.role().isLoading()}">${ _('Save') }</button>
-    <button class="btn btn-primary disable-enter disable-feedback" data-bind="click: $root.role().update, visible: $root.role().isEditing(), css: {'disabled': $root.role().isLoading()}"">${ _('Update') }</button>
+    <button class="btn btn-primary disable-enter disable-feedback" data-bind="click: $root.role().create, visible: ! $root.role().isEditing(), css: {'disabled': $root.role().isLoading() || !$root.role().isValid()}">${ _('Save') }</button>
+    <button class="btn btn-primary disable-enter disable-feedback" data-bind="click: $root.role().update, visible: $root.role().isEditing(), css: {'disabled': $root.role().isLoading() || !$root.role().isValid()}"">${ _('Update') }</button>
   </div>
 </div>
 

+ 17 - 0
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -2278,6 +2278,7 @@
   ko.bindingHandlers.filechooser = {
     init: function (element, valueAccessor, allBindingsAccessor, vm) {
       var self = $(element);
+      var options = ko.unwrap(allBindingsAccessor());
       self.attr("autocomplete", "off");
       if (typeof valueAccessor() == "function" || typeof valueAccessor().value == "function") {
         self.val(valueAccessor().value ? valueAccessor().value(): valueAccessor()());
@@ -2304,12 +2305,28 @@
           }
           self.attr("data-original-title", self.data("fullPath"));
         });
+
+        if (options.valueUpdate && options.valueUpdate === 'afterkeydown') {
+          self.on('keyup', function () {
+            if (valueAccessor().value){
+              valueAccessor().value(self.val());
+            }
+            else {
+              valueAccessor()(self.val());
+            }
+          });
+        }
       }
       else {
         self.val(valueAccessor());
         self.on("blur", function () {
           valueAccessor(self.val());
         });
+        if (options.valueUpdate && options.valueUpdate === 'afterkeydown') {
+          self.on('keyup', function () {
+            valueAccessor(self.val());
+          });
+        }
       }
 
       self.after(getFileBrowseButton(self, true, valueAccessor, true, allBindingsAccessor, valueAccessor().isAddon, valueAccessor().isNestedModal));