Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change restrictor for Orgaadmin #4382

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/src/app/domain/models/meetings/meeting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export class Settings {

export class Meeting extends BaseModel<Meeting> {
public static COLLECTION = `meeting`;
public static ACCESSIBILITY_FIELD: keyof Meeting = `projector_countdown_default_time`;
public static ACCESSIBILITY_FIELD: keyof Meeting = `language`;

public imported_at!: number;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { ActivatedRoute } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable, Subject } from 'rxjs';
import { Collection, Fqid, Id } from 'src/app/domain/definitions/key-types';
import { OML } from 'src/app/domain/definitions/organization-permission';
import { Selectable } from 'src/app/domain/interfaces';
import { BaseModel } from 'src/app/domain/models/base/base-model';
import { HistoryPosition, HistoryPresenterService } from 'src/app/gateways/presenter/history-presenter.service';
Expand Down Expand Up @@ -93,10 +92,6 @@ export class HistoryListComponent extends BaseMeetingComponent implements OnInit
}
}

public get isSuperadmin(): boolean {
return this.operator.hasOrganizationPermissions(OML.superadmin);
}

public constructor(
protected override translate: TranslateService,
private viewModelStore: ViewModelStoreService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,6 @@ export class GroupListComponent extends BaseMeetingComponent implements OnInit,
* Function to allow to edit the external_id
*/
public get allowExternalId(): boolean {
return this.operator.isMeetingAdmin || this.operator.isSuperAdmin;
return this.operator.isMeetingAdmin || this.operator.canSkipPermissionCheck;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ export class ViewMeeting extends BaseHasMeetingUsersViewModel<Meeting> {
public canBeEnteredBy(user: ViewUser): boolean {
return !this.locked_from_inside || user.group_ids(this.id).length > 0;
}

public canEditMeetingSetting(user: ViewUser): boolean {
return user.getMeetingUser(this.id)?.group_ids.includes(this.meeting.admin_group_id);
}
}
interface IMeetingRelations {
motions_default_workflow: ViewMotionWorkflow;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export class AccountAddToMeetingsComponent extends BaseUiComponent implements On
.getViewModelListObservable()
.pipe(
map(meetings =>
this.operator.isSuperAdmin
this.operator.canSkipPermissionCheck
? meetings.filter(meeting => !meeting.locked_from_inside)
: meetings.filter(
meeting => this.operator.isInMeeting(meeting.id) && !meeting.locked_from_inside
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ export class AccountDetailComponent extends BaseComponent implements OnInit {
}

public get orgaManagementLevelChangeDisabled(): boolean {
return this.user?.id === this.operator.operatorId && this.operator.isSuperAdmin;
return (
this.user?.id === this.operator.operatorId &&
(this.operator.isSuperAdmin || this.operator.isOrgaManager || this.operator.isAccountAdmin)
);
}

@ViewChild(UserDetailViewComponent, { static: false })
Expand Down Expand Up @@ -253,7 +256,7 @@ export class AccountDetailComponent extends BaseComponent implements OnInit {
is_public: meeting.publicAccessPossible(),
is_accessible:
(meeting.canAccess() && this.operator.isInMeeting(meeting.id)) ||
(!meeting.locked_from_inside && this.operator.isSuperAdmin)
(!meeting.locked_from_inside && this.operator.canSkipPermissionCheck)
};
});
this._tableData = tableData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export class AccountListComponent extends BaseListViewComponent<ViewUser> {
const meetings = this.meetingRepo.getViewModelList();
const result = await this.choiceService.open<ViewMeeting>({
title,
choices: this.operator.isSuperAdmin
choices: this.operator.canSkipPermissionCheck
? meetings.filter(meeting => !meeting.locked_from_inside)
: meetings.filter(meeting => this.operator.isInMeeting(meeting.id) && !meeting.locked_from_inside),
multiSelect: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@if (meeting.isArchived) {
<mat-label class="archived-label">{{ 'Archived' | translate }}</mat-label>
}
<ng-container *osCmlPerms="CML.can_manage; committeeId: committee.id; nonAdminCheck: true">
<ng-container *osCmlPerms="CML.can_manage; committeeId: committee.id">
@if (isTemplateMeeting) {
<div class="template-indicator">
<mat-icon [matTooltip]="'Public template' | translate">star</mat-icon>
Expand Down Expand Up @@ -131,7 +131,7 @@

<mat-menu #meetingMenu="matMenu">
<ng-template matMenuContent>
@if (!meeting.isArchived && (meeting?.canBeEnteredBy(operator.user) || operator.isSuperAdmin)) {
@if (!meeting.isArchived && (meeting?.canBeEnteredBy(operator.user) || operator.canSkipPermissionCheck)) {
<a mat-menu-item [routerLink]="['meeting', 'edit', meeting.id]">
<mat-icon>edit</mat-icon>
<span>{{ 'Edit' | translate }}</span>
Expand All @@ -145,7 +145,7 @@
<span>{{ 'Public template' | translate }}</span>
</button>
}
@if (!isLockedFromInside) {
@if (canEditMeetingSetting) {
<button mat-menu-item (click)="onDuplicate()">
<mat-icon>file_copy</mat-icon>
<span>{{ 'Duplicate' | translate }}</span>
Expand All @@ -167,10 +167,12 @@
<span>{{ 'Export' | translate }}</span>
</button>
}
<mat-divider></mat-divider>
<button class="red-warning-text" mat-menu-item (click)="onDeleteMeeting()">
<mat-icon>delete</mat-icon>
<span>{{ 'Delete' | translate }}</span>
</button>
@if (canEditMeetingSetting) {
<mat-divider></mat-divider>
<button class="red-warning-text" mat-menu-item (click)="onDeleteMeeting()">
<mat-icon>delete</mat-icon>
<span>{{ 'Delete' | translate }}</span>
</button>
}
</ng-template>
</mat-menu>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Subscription } from 'rxjs';
import { CML, OML } from 'src/app/domain/definitions/organization-permission';
import { MeetingControllerService } from 'src/app/site/pages/meetings/services/meeting-controller.service';
import { ViewMeeting } from 'src/app/site/pages/meetings/view-models/view-meeting';
Expand All @@ -16,7 +17,7 @@ import { MeetingService } from '../services/meeting.service';
styleUrls: [`./committee-meeting-preview.component.scss`],
encapsulation: ViewEncapsulation.None
})
export class CommitteeMeetingPreviewComponent {
export class CommitteeMeetingPreviewComponent implements OnDestroy, OnInit {
@Input() public meeting!: ViewMeeting;
@Input() public committee!: ViewCommittee;
@Input() public isCMAndRequireDuplicateFrom!: boolean;
Expand Down Expand Up @@ -64,14 +65,46 @@ export class CommitteeMeetingPreviewComponent {
return this.meeting?.locked_from_inside;
}

public get canEditMeetingSetting(): boolean {
return this._canEditMeetingSetting;
}

private _canEditMeetingSetting = true;
private _canEditMeetingSubscription: Subscription;

public constructor(
private cd: ChangeDetectorRef,
private translate: TranslateService,
Elblinator marked this conversation as resolved.
Show resolved Hide resolved
private meetingRepo: MeetingControllerService,
private meetingService: MeetingService,
private promptService: PromptService,
public operator: OperatorService
) {}

/**
* Get the subject
*/
public ngOnInit(): void {
this._canEditMeetingSubscription = this.operator.operatorUpdated.subscribe(() => {
if (this.isLockedFromInside && !this.operator.isSuperAdmin) {
this._canEditMeetingSetting = this.meeting.canEditMeetingSetting(this.operator.user);
} else {
this._canEditMeetingSetting = true;
}
});
}

/**
* clear the Subscriptions
*/
public ngOnDestroy(): void {
if (this._canEditMeetingSubscription) {
this._canEditMeetingSubscription.unsubscribe();
this._canEditMeetingSubscription = null;
}
this.cd.detach();
}
Elblinator marked this conversation as resolved.
Show resolved Hide resolved

public async onArchive(): Promise<void> {
const title = this.translate.instant(`Are you sure you want to archive this meeting?`);
const content = this.translate.instant(`Attention: This action cannot be undone!`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export class MeetingEditComponent extends BaseComponent implements OnInit {

private onAfterCreateForm(): void {
this.enableFormControls();
if (!this.operator.isSuperAdmin && !this.isMeetingAdmin && !this.isCreateView) {
if (!this.operator.canSkipPermissionCheck && !this.isMeetingAdmin && !this.isCreateView) {
Object.keys(this.meetingForm.controls).forEach(controlName => {
if (!ORGA_ADMIN_ALLOWED_CONTROLNAMES.includes(controlName)) {
this.meetingForm.get(controlName)!.disable();
Expand Down Expand Up @@ -347,7 +347,7 @@ export class MeetingEditComponent extends BaseComponent implements OnInit {

private async doUpdateMeeting(): Promise<void> {
const options =
this.operator.isSuperAdmin && !this.isMeetingAdmin && this.editMeeting?.locked_from_inside
this.operator.canSkipPermissionCheck && !this.isMeetingAdmin && this.editMeeting?.locked_from_inside
? {}
: this.getUsersToUpdateForMeetingObject();
await this.meetingRepo.update(this.sanitizePayload(this.getPayload()), {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<os-head-bar
[customMenu]="true"
[hasMainButton]="canManageMeetingsInCommittee"
[hasMainButton]="canManageCommittee"
[mainActionTooltip]="'New meeting' | translate"
[nav]="false"
(mainEvent)="onCreateMeeting()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ export class CommitteeDetailViewComponent extends BaseUiComponent {
public forwardingExpanded = false;
public requireDuplicateFrom = false;

public get canManageMeetingsInCommittee(): boolean {
return this.operator.hasCommitteePermissionsNonAdminCheck(this.committeeId, CML.can_manage);
}

public get canManageCommittee(): boolean {
return this.operator.hasCommitteePermissions(this.committeeId, CML.can_manage);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class DashboardComponent extends BaseComponent {
const filteredMeetings = meetings.filter(
meeting =>
this.operator.isInMeeting(meeting.id) ||
this.operator.isSuperAdmin ||
this.operator.canSkipPermissionCheck ||
(meeting.publicAccessPossible() && this.operator.isAnonymous)
);
const currentDate = new Date();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,7 @@ <h2>{{ 'Meetings' | translate }}</h2>

<!-- Is Template -->
<span
*osCmlPerms="
CML.can_manage;
committeeId: meeting.committee_id;
nonAdminCheck: true;
and: meeting.isTemplate
"
*osCmlPerms="CML.can_manage; committeeId: meeting.committee_id; and: meeting.isTemplate"
class="icon-prefix"
>
<mat-icon [matTooltip]="'Public template' | translate">star</mat-icon>
Expand Down Expand Up @@ -181,7 +176,7 @@ <h2>{{ 'Meetings' | translate }}</h2>

<div *osScrollingTableCell="'menu'; row as meeting; config: { width: 40 }">
<button
*osCmlPerms="CML.can_manage; committeeId: meeting.committee?.id; nonAdminCheck: true"
*osCmlPerms="CML.can_manage; committeeId: meeting.committee?.id"
data-cy="meetingListSingleMenuTrigger"
mat-icon-button
[disabled]="isMultiSelect"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class MeetingListFilterService extends BaseFilterListService<ViewMeeting>
}

protected override preFilter(rawInputData: ViewMeeting[]): ViewMeeting[] {
return this.operator.isSuperAdmin
return this.operator.canSkipPermissionCheck
? rawInputData
: rawInputData.filter(meeting => this.operator.isInMeeting(meeting.id));
}
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/site/services/auth-check.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export class AuthCheckService {
await this.fetchMeetingIfNotExists(+meetingIdString);

await this.operator.ready;
return this.operator.isInMeeting(Number(meetingIdString)) || this.operator.isSuperAdmin;
return this.operator.isInMeeting(Number(meetingIdString)) || this.operator.canSkipPermissionCheck;
}

private async fetchMeetingIfNotExists(meetingId: Id): Promise<void> {
Expand Down
Loading
Loading