Merge pull request #4884 from FinnStutzenstein/superadminDirective

Added IsSuperAdmin directive
This commit is contained in:
Finn Stutzenstein 2019-07-30 13:27:05 +02:00 committed by GitHub
commit 29e06bf7ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 86 additions and 13 deletions

View File

@ -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<string>();
this.DS.getMany(Group, this.user.groups_id).forEach(group => {
group.permissions.forEach(permission => {
permissionSet.add(permission);

View File

@ -0,0 +1,6 @@
describe('IsSuperAdminDirective', () => {
it('should create an instance', () => {
// const directive = new IsSuperAdminDirective();
// expect(directive).toBeTruthy();
});
});

View File

@ -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 *osIsSuperadmin ..> ... < /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 `<div>`)
* @param operator OperatorService
*/
public constructor(
private template: TemplateRef<any>,
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;
}
}

View File

@ -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';
@ -196,6 +197,7 @@ import { RoundedInputComponent } from './components/rounded-input/rounded-input.
TranslateModule,
OpenSlidesTranslateModule,
PermsDirective,
IsSuperAdminDirective,
DomChangeDirective,
AutofocusDirective,
HeadBarComponent,
@ -237,6 +239,7 @@ import { RoundedInputComponent } from './components/rounded-input/rounded-input.
],
declarations: [
PermsDirective,
IsSuperAdminDirective,
DomChangeDirective,
AutofocusDirective,
HeadBarComponent,

View File

@ -19,7 +19,7 @@
</button>
</div>
<div *osPerms="'users.can_manage'">
<div *osIsSuperAdmin>
<button
type="button"
mat-button

View File

@ -5,7 +5,7 @@
<!-- Menu -->
<div class="menu-slot">
<!-- Hidden for everyone but the superadmin -->
<button *ngIf="isSuperAdmin" type="button" mat-icon-button [matMenuTriggerFor]="historyMenu">
<button *osIsSuperAdmin type="button" mat-icon-button [matMenuTriggerFor]="historyMenu">
<mat-icon>more_vert</mat-icon>
</button>
</div>

View File

@ -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<void> {
if (!this.isSuperAdmin) {
if (!this.operator.isSuperAdmin) {
return;
}

View File

@ -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