From cf3e5bb8641a77f7dde27abf690143b79bf390c9 Mon Sep 17 00:00:00 2001 From: Tiago Melo Date: Thu, 18 Apr 2019 09:31:38 +0000 Subject: [PATCH] mgr/dashboard: Fix iSCSI Discovery user permissions Fixes: http://tracker.ceph.com/issues/39328 Signed-off-by: Tiago Melo --- src/pybind/mgr/dashboard/controllers/iscsi.py | 2 +- ...scsi-target-discovery-modal.component.html | 1 + ...i-target-discovery-modal.component.spec.ts | 107 +++++++++++------- .../iscsi-target-discovery-modal.component.ts | 31 +++-- .../iscsi-target-list.component.html | 2 +- .../frontend/src/locale/messages.xlf | 8 +- 6 files changed, 97 insertions(+), 54 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/iscsi.py b/src/pybind/mgr/dashboard/controllers/iscsi.py index f8b0e3063b5..744e4c8d8f3 100644 --- a/src/pybind/mgr/dashboard/controllers/iscsi.py +++ b/src/pybind/mgr/dashboard/controllers/iscsi.py @@ -144,7 +144,7 @@ class IscsiUi(BaseController): class Iscsi(BaseController): @Endpoint('GET', 'discoveryauth') - @UpdatePermission + @ReadPermission def get_discoveryauth(self): return self._get_discoveryauth() diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html index fbd603f4754..9fe64e83171 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html @@ -130,6 +130,7 @@
Submit { let httpTesting: HttpTestingController; let req: TestRequest; + const elem = (css) => fixture.debugElement.query(By.css(css)); + const elemDisabled = (css) => elem(css).nativeElement.disabled; + configureTestBed({ declarations: [IscsiTargetDiscoveryModalComponent], imports: [ @@ -36,54 +41,80 @@ describe('IscsiTargetDiscoveryModalComponent', () => { fixture = TestBed.createComponent(IscsiTargetDiscoveryModalComponent); component = fixture.componentInstance; httpTesting = TestBed.get(HttpTestingController); - fixture.detectChanges(); - req = httpTesting.expectOne('api/iscsi/discoveryauth'); }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + describe('with update permissions', () => { + beforeEach(() => { + component.permission = new Permission(['update']); + fixture.detectChanges(); + req = httpTesting.expectOne('api/iscsi/discoveryauth'); + }); - it('should create form', () => { - expect(component.discoveryForm.value).toEqual({ - user: '', - password: '', - mutual_user: '', - mutual_password: '' + it('should create', () => { + expect(component).toBeTruthy(); }); - }); - it('should patch form', () => { - req.flush({ - user: 'foo', - password: 'bar', - mutual_user: 'mutual_foo', - mutual_password: 'mutual_bar' + it('should create form', () => { + expect(component.discoveryForm.value).toEqual({ + user: '', + password: '', + mutual_user: '', + mutual_password: '' + }); }); - expect(component.discoveryForm.value).toEqual({ - user: 'foo', - password: 'bar', - mutual_user: 'mutual_foo', - mutual_password: 'mutual_bar' + + it('should patch form', () => { + req.flush({ + user: 'foo', + password: 'bar', + mutual_user: 'mutual_foo', + mutual_password: 'mutual_bar' + }); + expect(component.discoveryForm.value).toEqual({ + user: 'foo', + password: 'bar', + mutual_user: 'mutual_foo', + mutual_password: 'mutual_bar' + }); }); - }); - it('should submit new values', () => { - component.discoveryForm.patchValue({ - user: 'new_user', - password: 'new_pass', - mutual_user: 'mutual_new_user', - mutual_password: 'mutual_new_pass' + it('should submit new values', () => { + component.discoveryForm.patchValue({ + user: 'new_user', + password: 'new_pass', + mutual_user: 'mutual_new_user', + mutual_password: 'mutual_new_pass' + }); + component.submitAction(); + + const submit_req = httpTesting.expectOne('api/iscsi/discoveryauth'); + expect(submit_req.request.method).toBe('PUT'); + expect(submit_req.request.body).toEqual({ + user: 'new_user', + password: 'new_pass', + mutual_user: 'mutual_new_user', + mutual_password: 'mutual_new_pass' + }); }); - component.submitAction(); - const submit_req = httpTesting.expectOne('api/iscsi/discoveryauth'); - expect(submit_req.request.method).toBe('PUT'); - expect(submit_req.request.body).toEqual({ - user: 'new_user', - password: 'new_pass', - mutual_user: 'mutual_new_user', - mutual_password: 'mutual_new_pass' + it('should enable form if user has update permission', () => { + expect(elemDisabled('input#user')).toBeFalsy(); + expect(elemDisabled('input#password')).toBeFalsy(); + expect(elemDisabled('input#mutual_user')).toBeFalsy(); + expect(elemDisabled('input#mutual_password')).toBeFalsy(); + expect(elem('cd-submit-button')).toBeDefined(); }); }); + + it('should disabled form if user does not have update permission', () => { + component.permission = new Permission(['read', 'create', 'delete']); + fixture.detectChanges(); + req = httpTesting.expectOne('api/iscsi/discoveryauth'); + + expect(elemDisabled('input#user')).toBeTruthy(); + expect(elemDisabled('input#password')).toBeTruthy(); + expect(elemDisabled('input#mutual_user')).toBeTruthy(); + expect(elemDisabled('input#mutual_password')).toBeTruthy(); + expect(elem('cd-submit-button')).toBeNull(); + }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts index 4b8c1809ab1..2060b81b867 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts @@ -8,6 +8,8 @@ import { IscsiService } from '../../../shared/api/iscsi.service'; import { NotificationType } from '../../../shared/enum/notification-type.enum'; import { CdFormGroup } from '../../../shared/forms/cd-form-group'; import { CdValidators } from '../../../shared/forms/cd-validators'; +import { Permission } from '../../../shared/models/permissions'; +import { AuthStorageService } from '../../../shared/services/auth-storage.service'; import { NotificationService } from '../../../shared/services/notification.service'; @Component({ @@ -17,21 +19,36 @@ import { NotificationService } from '../../../shared/services/notification.servi }) export class IscsiTargetDiscoveryModalComponent implements OnInit { discoveryForm: CdFormGroup; + permission: Permission; + hasPermission: boolean; USER_REGEX = /[\w\.:@_-]{8,64}/; PASSWORD_REGEX = /[\w@\-_\/]{12,16}/; constructor( + private authStorageService: AuthStorageService, public bsModalRef: BsModalRef, private iscsiService: IscsiService, private notificationService: NotificationService, private i18n: I18n ) { + this.permission = this.authStorageService.getPermissions().iscsi; + } + + ngOnInit() { + this.hasPermission = this.permission.update; + this.createForm(); + this.iscsiService.getDiscovery().subscribe((auth) => { + this.discoveryForm.patchValue(auth); + }); + } + + createForm() { this.discoveryForm = new CdFormGroup({ - user: new FormControl(''), - password: new FormControl(''), - mutual_user: new FormControl(''), - mutual_password: new FormControl('') + user: new FormControl({ value: '', disabled: !this.hasPermission }), + password: new FormControl({ value: '', disabled: !this.hasPermission }), + mutual_user: new FormControl({ value: '', disabled: !this.hasPermission }), + mutual_password: new FormControl({ value: '', disabled: !this.hasPermission }) }); CdValidators.validateIf( @@ -89,12 +106,6 @@ export class IscsiTargetDiscoveryModalComponent implements OnInit { ); } - ngOnInit() { - this.iscsiService.getDiscovery().subscribe((auth) => { - this.discoveryForm.patchValue(auth); - }); - } - submitAction() { this.iscsiService.updateDiscovery(this.discoveryForm.value).subscribe( () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html index aef54596c5f..084182df963 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html @@ -36,7 +36,7 @@ - Set discovery authentication + Discovery authentication
diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf index 8a1f6be6909..90434a0993a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf @@ -881,7 +881,7 @@ app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html - 135 + 136 app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html @@ -945,7 +945,7 @@ app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html - 133 + 134 app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html @@ -2423,8 +2423,8 @@ app/ceph/block/iscsi-target-list/iscsi-target-list.component.html 4 - - Set discovery authentication + + Discovery authentication app/ceph/block/iscsi-target-list/iscsi-target-list.component.html 39 -- 2.39.5