]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Add permission validation to the "Purge Trash" button 24370/head
authorTiago Melo <tspmelo@gmail.com>
Tue, 2 Oct 2018 14:27:13 +0000 (15:27 +0100)
committerTiago Melo <tspmelo@gmail.com>
Tue, 2 Oct 2018 14:39:35 +0000 (15:39 +0100)
Added missing permission validations in the RBD Trash endpoints.

Fixes: http://tracker.ceph.com/issues/36272
Signed-off-by: Tiago Melo <tmelo@suse.com>
src/pybind/mgr/dashboard/controllers/rbd.py
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.spec.ts

index a8f4d452a45ecacb7f07c1ceef2e4e7b796798d1..2e18b37f22f7a2ea9c062766d4c8bcfb08b82915 100644 (file)
@@ -12,7 +12,7 @@ import six
 
 import rbd
 
-from . import ApiController, RESTController, Task, UpdatePermission
+from . import ApiController, RESTController, Task, UpdatePermission, DeletePermission
 from .. import mgr
 from ..security import Scope
 from ..services.ceph_service import CephService
@@ -466,7 +466,7 @@ class RbdSnapshot(RESTController):
         return _rbd_call(pool_name, _parent_clone)
 
 
-@ApiController('/block/image/trash')
+@ApiController('/block/image/trash', Scope.RBD_IMAGE)
 class RbdTrash(RESTController):
     RESOURCE_ID = "pool_name/image_id"
     rbd_inst = rbd.RBD()
@@ -506,6 +506,7 @@ class RbdTrash(RESTController):
     @handle_rados_error('pool')
     @RbdTask('trash/purge', ['{pool_name}'], 2.0)
     @RESTController.Collection('POST', query_params=['pool_name'])
+    @DeletePermission
     def purge(self, pool_name=None):
         """Remove all expired images from trash."""
         now = "{}Z".format(datetime.now().isoformat())
@@ -518,6 +519,7 @@ class RbdTrash(RESTController):
 
     @RbdTask('trash/restore', ['{pool_name}', '{image_id}', '{new_image_name}'], 2.0)
     @RESTController.Resource('POST')
+    @UpdatePermission
     def restore(self, pool_name, image_id, new_image_name):
         """Restore an image from trash."""
         return _rbd_call(pool_name, self.rbd_inst.trash_restore, image_id, new_image_name)
index a16ece60f8bcd33ae624a0f9f4e41b6e1bd5cc29..2902ed23903bb3f57061a99e7a73ae7323cc20e2 100644 (file)
@@ -18,7 +18,8 @@
 
     <button class="btn btn-sm btn-default btn-label"
             type="button"
-            (click)="purgeModal()">
+            (click)="purgeModal()"
+            *ngIf="permission.delete">
       <i class="fa fa-fw fa-times"
          aria-hidden="true"></i>
       <ng-container i18n>Purge Trash</ng-container>
index 26dbdb66d594f7e6cc1aa1d1b1bc57ad967f5545..766d2eed278f804a767f6d4cd51db9d4d79feeca 100644 (file)
@@ -5,6 +5,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { ToastModule } from 'ng2-toastr';
 import { of } from 'rxjs';
 
+import { By } from '@angular/platform-browser';
 import { configureTestBed } from '../../../../testing/unit-test-helper';
 import { RbdService } from '../../../shared/api/rbd.service';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
@@ -102,4 +103,34 @@ describe('RbdTrashListComponent', () => {
       expectImageTasks(component.images[1], 'Restoring');
     });
   });
+
+  describe('display purge button', () => {
+    beforeEach(() => {});
+
+    it('should show button with delete permission', () => {
+      component.permission = {
+        read: true,
+        create: true,
+        delete: true,
+        update: true
+      };
+      fixture.detectChanges();
+
+      const purge = fixture.debugElement.query(By.css('.table-actions button .fa-times'));
+      expect(purge).not.toBeNull();
+    });
+
+    it('should remove button without delete permission', () => {
+      component.permission = {
+        read: true,
+        create: true,
+        delete: false,
+        update: true
+      };
+      fixture.detectChanges();
+
+      const purge = fixture.debugElement.query(By.css('.table-actions button .fa-times'));
+      expect(purge).toBeNull();
+    });
+  });
 });