From f876d1c1fad348c133dca1d182ebfec8f19b1c0d Mon Sep 17 00:00:00 2001 From: FinnStutzenstein Date: Tue, 30 Jul 2019 09:01:59 +0200 Subject: [PATCH] Added IsSuperAdmin directive --- .../core/core-services/operator.service.ts | 10 +-- .../is-super-admin.directive.spec.ts | 6 ++ .../directives/is-super-admin.directive.ts | 68 +++++++++++++++++++ client/src/app/shared/shared.module.ts | 3 + .../legal-notice/legal-notice.component.html | 2 +- .../history-list/history-list.component.html | 2 +- .../history-list/history-list.component.ts | 6 +- openslides/core/websocket.py | 2 +- 8 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 client/src/app/shared/directives/is-super-admin.directive.spec.ts create mode 100644 client/src/app/shared/directives/is-super-admin.directive.ts diff --git a/client/src/app/core/core-services/operator.service.ts b/client/src/app/core/core-services/operator.service.ts index 16bf9a6fc..bcef700cf 100644 --- a/client/src/app/core/core-services/operator.service.ts +++ b/client/src/app/core/core-services/operator.service.ts @@ -85,6 +85,10 @@ export class OperatorService implements OnAfterAppsLoaded { return !this.user || this.user.id === 0; } + public get isSuperAdmin(): boolean { + return this.isInGroupIdsNonAdminCheck(2); + } + /** * Save, if guests are enabled. */ @@ -358,10 +362,6 @@ export class OperatorService implements OnAfterAppsLoaded { return groupIds.some(id => this.user.groups_id.includes(id)); } - public isSuperAdmin(): boolean { - return this.isInGroupIdsNonAdminCheck(2); - } - /** * Update the operators permissions and publish the operator afterwards. * Saves the current WhoAmI to storage with the updated permissions @@ -383,7 +383,7 @@ export class OperatorService implements OnAfterAppsLoaded { this.permissions = defaultGroup.permissions; } } else { - const permissionSet = new Set(); + const permissionSet = new Set(); this.DS.getMany(Group, this.user.groups_id).forEach(group => { group.permissions.forEach(permission => { permissionSet.add(permission); diff --git a/client/src/app/shared/directives/is-super-admin.directive.spec.ts b/client/src/app/shared/directives/is-super-admin.directive.spec.ts new file mode 100644 index 000000000..b15d90a2c --- /dev/null +++ b/client/src/app/shared/directives/is-super-admin.directive.spec.ts @@ -0,0 +1,6 @@ +describe('IsSuperAdminDirective', () => { + it('should create an instance', () => { + // const directive = new IsSuperAdminDirective(); + // expect(directive).toBeTruthy(); + }); +}); diff --git a/client/src/app/shared/directives/is-super-admin.directive.ts b/client/src/app/shared/directives/is-super-admin.directive.ts new file mode 100644 index 000000000..f35840aa5 --- /dev/null +++ b/client/src/app/shared/directives/is-super-admin.directive.ts @@ -0,0 +1,68 @@ +import { Directive, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; + +import { Subscription } from 'rxjs'; + +import { OperatorService } from 'app/core/core-services/operator.service'; + +/** + * Directive to check if the operator is a superadmin + * + * @example
... < /div> + */ +@Directive({ + selector: '[osIsSuperAdmin]' +}) +export class IsSuperAdminDirective implements OnInit, OnDestroy { + /** + * Holds the value of the last is superadmin check. Therefore one can check, if the + * permission has changes, to save unnecessary view updates, if not. + */ + private lastIsSuperAdminCheckResult = false; + + private operatorSubscription: Subscription | null; + + /** + * Constructs the directive once. Observes the operator for it's groups so the + * directive can perform changes dynamically + * + * @param template inner part of the HTML container + * @param viewContainer outer part of the HTML container (for example a `
`) + * @param operator OperatorService + */ + public constructor( + private template: TemplateRef, + private viewContainer: ViewContainerRef, + private operator: OperatorService + ) {} + + public ngOnInit(): void { + // observe groups of operator, so the directive can actively react to changes + this.operatorSubscription = this.operator.getUserObservable().subscribe(() => { + this.updateView(); + }); + } + + public ngOnDestroy(): void { + if (this.operatorSubscription) { + this.operatorSubscription.unsubscribe(); + } + } + + /** + * Shows or hides certain content in the view. + */ + private updateView(): void { + const isSuperadmin = this.operator.isSuperAdmin; + const superADminChanged = isSuperadmin !== this.lastIsSuperAdminCheckResult; + + if (isSuperadmin && superADminChanged) { + // clean up and add the template + this.viewContainer.clear(); + this.viewContainer.createEmbeddedView(this.template); + } else if (!isSuperadmin) { + // will remove the content of the container + this.viewContainer.clear(); + } + this.lastIsSuperAdminCheckResult = isSuperadmin; + } +} diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index 6e7928cac..e80d6dad8 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts @@ -52,6 +52,7 @@ import { EditorModule } from '@tinymce/tinymce-angular'; // directives import { PermsDirective } from './directives/perms.directive'; +import { IsSuperAdminDirective } from './directives/is-super-admin.directive'; import { DomChangeDirective } from './directives/dom-change.directive'; import { AutofocusDirective } from './directives/autofocus.directive'; @@ -195,6 +196,7 @@ import { AttachmentControlComponent } from './components/attachment-control/atta TranslateModule, OpenSlidesTranslateModule, PermsDirective, + IsSuperAdminDirective, DomChangeDirective, AutofocusDirective, HeadBarComponent, @@ -235,6 +237,7 @@ import { AttachmentControlComponent } from './components/attachment-control/atta ], declarations: [ PermsDirective, + IsSuperAdminDirective, DomChangeDirective, AutofocusDirective, HeadBarComponent, diff --git a/client/src/app/site/common/components/legal-notice/legal-notice.component.html b/client/src/app/site/common/components/legal-notice/legal-notice.component.html index 75914712b..1b9d62f2c 100644 --- a/client/src/app/site/common/components/legal-notice/legal-notice.component.html +++ b/client/src/app/site/common/components/legal-notice/legal-notice.component.html @@ -19,7 +19,7 @@
-
+
diff --git a/client/src/app/site/history/components/history-list/history-list.component.ts b/client/src/app/site/history/components/history-list/history-list.component.ts index 5ad845d42..b37adba44 100644 --- a/client/src/app/site/history/components/history-list/history-list.component.ts +++ b/client/src/app/site/history/components/history-list/history-list.component.ts @@ -65,10 +65,6 @@ export class HistoryListComponent extends BaseViewComponent implements OnInit { return this.modelSelectForm.controls.model.value; } - public get isSuperAdmin(): boolean { - return this.operator.isSuperAdmin(); - } - /** * Constructor for the history list component * @@ -190,7 +186,7 @@ export class HistoryListComponent extends BaseViewComponent implements OnInit { * @param history Represents the selected element */ public async onClickRow(history: History): Promise { - if (!this.isSuperAdmin) { + if (!this.operator.isSuperAdmin) { return; } diff --git a/openslides/core/websocket.py b/openslides/core/websocket.py index a711f0430..8558c4792 100644 --- a/openslides/core/websocket.py +++ b/openslides/core/websocket.py @@ -50,7 +50,7 @@ class NotifyWebsocketClientMessage(BaseWebsocketClientMessage): } # Define a required permission for a notify message here. If the emitting user does not # have this permission, he will get an error message in response. - notify_permissions: Dict[str, str] = {"swCheckForUpdate": "users.can_manage"} + notify_permissions: Dict[str, str] = {"swCheckForUpdate": "superadmin"} async def receive_content( self, consumer: "ProtocollAsyncJsonWebsocketConsumer", content: Any, id: str