Merge pull request #5359 from tsiegleauq/clean-projector-permissions

Add permission as lookup object
This commit is contained in:
Emanuel Schütze 2020-05-14 14:48:37 +02:00 committed by GitHub
commit b090e46b66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 268 additions and 174 deletions

View File

@ -2,6 +2,8 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Permission } from './core/core-services/operator.service';
/** /**
* Provides functionalities that will be used by most components * Provides functionalities that will be used by most components
* currently able to set the title with the suffix ' - OpenSlides' * currently able to set the title with the suffix ' - OpenSlides'
@ -10,6 +12,11 @@ import { TranslateService } from '@ngx-translate/core';
* Components in the 'Side'- or 'projector' Folder are BaseComponents * Components in the 'Side'- or 'projector' Folder are BaseComponents
*/ */
export abstract class BaseComponent { export abstract class BaseComponent {
/**
* To check permissions in templates using permission.[...]
*/
public permission = Permission;
/** /**
* To manipulate the browser title bar, adds the Suffix "OpenSlides" * To manipulate the browser title bar, adds the Suffix "OpenSlides"
* *

View File

@ -3,7 +3,7 @@ import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router } from '@
import { FallbackRoutesService } from './fallback-routes.service'; import { FallbackRoutesService } from './fallback-routes.service';
import { OpenSlidesService } from './openslides.service'; import { OpenSlidesService } from './openslides.service';
import { OperatorService } from './operator.service'; import { OperatorService, Permission } from './operator.service';
/** /**
* Classical Auth-Guard. Checks if the user has to correct permissions to enter a page, and forwards to login if not. * Classical Auth-Guard. Checks if the user has to correct permissions to enter a page, and forwards to login if not.
@ -36,7 +36,7 @@ export class AuthGuard implements CanActivate, CanActivateChild {
* @param route the route the user wants to navigate to * @param route the route the user wants to navigate to
*/ */
public canActivate(route: ActivatedRouteSnapshot): boolean { public canActivate(route: ActivatedRouteSnapshot): boolean {
const basePerm: string | string[] = route.data.basePerm; const basePerm: Permission | Permission[] = route.data.basePerm;
if (!basePerm) { if (!basePerm) {
return true; return true;

View File

@ -1,11 +1,11 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { OperatorService } from './operator.service'; import { OperatorService, Permission } from './operator.service';
export interface AuthGuardFallbackEntry { export interface AuthGuardFallbackEntry {
route: string; route: string;
weight: number; weight: number;
permission: string; permission: Permission;
} }
/** /**

View File

@ -2,6 +2,8 @@ import { Injectable } from '@angular/core';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { Permission } from './operator.service';
/** /**
* This represents one entry in the main menu * This represents one entry in the main menu
*/ */
@ -28,7 +30,7 @@ export interface MainMenuEntry {
/** /**
* The permission to see the entry. * The permission to see the entry.
*/ */
permission: string; permission: Permission;
} }
/** /**

View File

@ -21,7 +21,39 @@ import { UserRepositoryService } from '../repositories/users/user-repository.ser
* Permissions on the client are just strings. This makes clear, that * Permissions on the client are just strings. This makes clear, that
* permissions instead of arbitrary strings should be given. * permissions instead of arbitrary strings should be given.
*/ */
export type Permission = string; export enum Permission {
agendaCanManage = 'agenda.can_manage',
agendaCanSee = 'agenda.can_see',
agendaCanSeeInternalItems = 'agenda.can_see_internal_items',
agendaCanManageListOfSpeakers = 'agenda.can_manage_list_of_speakers',
agendaCanSeeListOfSpeakers = 'agenda.can_see_list_of_speakers',
agendaCanBeSpeaker = 'agenda.can_be_speaker',
assignmentsCanManage = 'assignments.can_manage',
assignmentsCanNominateOther = 'assignments.can_nominate_other',
assignmentsCanNominateSelf = 'assignments.can_nominate_self',
assignmentsCanSee = 'assignments.can_see',
coreCanManageConfig = 'core.can_manage_config',
coreCanManageLogosAndFonts = 'core.can_manage_logos_and_fonts',
coreCanSeeHistory = 'core.can_see_history',
coreCanManageProjector = 'core.can_manage_projector',
coreCanSeeFrontpage = 'core.can_see_frontpage',
coreCanSeeProjector = 'core.can_see_projector',
coreCanManageTags = 'core.can_manage_tags',
mediafilesCanManage = 'mediafiles.can_manage',
mediafilesCanSee = 'mediafiles.can_see',
motionsCanCreate = 'motions.can_create',
motionsCanCreateAmendments = 'motions.can_create_amendments',
motionsCanManage = 'motions.can_manage',
motionsCanManageMetadata = 'motions.can_manage_metadata',
motionsCanManagePolls = 'motions.can_manage_polls',
motionsCanSee = 'motions.can_see',
motionsCanSeeInternal = 'motions.can_see_internal',
motionsCanSupport = 'motions.can_support',
usersCanChangePassword = 'users.can_change_password',
usersCanManage = 'users.can_manage',
usersCanSeeExtraData = 'users.can_see_extra_data',
usersCanSeeName = 'users.can_see_name'
}
/** /**
* Response format of the WhoAmI request. * Response format of the WhoAmI request.
@ -394,12 +426,12 @@ export class OperatorService implements OnAfterAppsLoaded {
} else { } else {
// Anonymous or users in the default group. // Anonymous or users in the default group.
if (!this.user || this.user.groups_id.length === 0) { if (!this.user || this.user.groups_id.length === 0) {
const defaultGroup = this.DS.get<Group>('users/group', 1); const defaultGroup: Group = this.DS.get<Group>('users/group', 1);
if (defaultGroup && defaultGroup.permissions instanceof Array) { if (defaultGroup && defaultGroup.permissions instanceof Array) {
this.permissions = defaultGroup.permissions; this.permissions = defaultGroup.permissions;
} }
} else { } else {
const permissionSet = new Set<string>(); const permissionSet = new Set<Permission>();
this.DS.getMany(Group, this.user.groups_id).forEach(group => { this.DS.getMany(Group, this.user.groups_id).forEach(group => {
group.permissions.forEach(permission => { group.permissions.forEach(permission => {
permissionSet.add(permission); permissionSet.add(permission);

View File

@ -5,6 +5,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { HttpService } from 'app/core/core-services/http.service'; import { HttpService } from 'app/core/core-services/http.service';
import { Permission } from 'app/core/core-services/operator.service';
import { RelationManagerService } from 'app/core/core-services/relation-manager.service'; import { RelationManagerService } from 'app/core/core-services/relation-manager.service';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
import { Group } from 'app/shared/models/users/group'; import { Group } from 'app/shared/models/users/group';
@ -18,9 +19,9 @@ import { DataStoreService } from '../../core-services/data-store.service';
/** /**
* Shape of a permission * Shape of a permission
*/ */
interface Permission { interface PermDefinition {
display_name: string; display_name: string;
value: string; value: Permission;
} }
/** /**
@ -28,7 +29,7 @@ interface Permission {
*/ */
export interface AppPermissions { export interface AppPermissions {
name: string; name: string;
permissions: Permission[]; permissions: PermDefinition[];
} }
/** /**
@ -87,7 +88,7 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group, Gro
* @param group The group * @param group The group
* @param perm The permission to toggle * @param perm The permission to toggle
*/ */
public async togglePerm(group: ViewGroup, perm: string): Promise<void> { public async togglePerm(group: ViewGroup, perm: Permission): Promise<void> {
const set = !group.permissions.includes(perm); const set = !group.permissions.includes(perm);
return await this.http.post(`/rest/${group.collectionString}/${group.id}/set_permission/`, { return await this.http.post(`/rest/${group.collectionString}/${group.id}/set_permission/`, {
perm: perm, perm: perm,
@ -102,7 +103,7 @@ export class GroupRepositoryService extends BaseRepository<ViewGroup, Group, Gro
* @param perm certain permission as string * @param perm certain permission as string
* @param appName Indicates the header in the Permission Matrix * @param appName Indicates the header in the Permission Matrix
*/ */
private addAppPerm(appId: number, perm: Permission, appName: string): void { private addAppPerm(appId: number, perm: PermDefinition, appName: string): void {
if (!this.appPermissions[appId]) { if (!this.appPermissions[appId]) {
this.appPermissions[appId] = { this.appPermissions[appId] = {
name: appName, name: appName,

View File

@ -4,7 +4,7 @@ import { ActivatedRoute } from '@angular/router';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { AuthService } from 'app/core/core-services/auth.service'; import { AuthService } from 'app/core/core-services/auth.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service'; import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
import { ViewProjector } from 'app/site/projector/models/view-projector'; import { ViewProjector } from 'app/site/projector/models/view-projector';
import { Size } from 'app/site/projector/size'; import { Size } from 'app/site/projector/size';
@ -89,7 +89,7 @@ export class FullscreenProjectorComponent implements OnInit {
}); });
this.operator.getUserObservable().subscribe(() => { this.operator.getUserObservable().subscribe(() => {
this.canSeeProjector = this.operator.hasPerms('projector.can_see'); this.canSeeProjector = this.operator.hasPerms(Permission.coreCanSeeProjector);
}); });
} }

View File

@ -286,7 +286,7 @@ export class ListViewTableComponent<V extends BaseViewModel | BaseViewModelWithC
private subs: Subscription[] = []; private subs: Subscription[] = [];
private get projectorColumnWidth(): number { private get projectorColumnWidth(): number {
if (this.operator.hasPerms('core.can_manage_projector')) { if (this.operator.hasPerms(Permission.coreCanManageProjector)) {
return 60; return 60;
} else { } else {
return 24; return 24;
@ -367,7 +367,11 @@ export class ListViewTableComponent<V extends BaseViewModel | BaseViewModelWithC
} }
// hide the speakers in mobile // hide the speakers in mobile
if (this.isMobile || !this.operator.hasPerms('agenda.can_see_list_of_speakers') || !this.showListOfSpeakers) { if (
this.isMobile ||
!this.operator.hasPerms(Permission.agendaCanSeeListOfSpeakers) ||
!this.showListOfSpeakers
) {
hidden.push('speaker'); hidden.push('speaker');
} }

View File

@ -87,10 +87,10 @@ export class PermsDirective implements OnInit, OnDestroy {
* The value defines the requires permissions as an array or a single permission. * The value defines the requires permissions as an array or a single permission.
*/ */
@Input() @Input()
public set osPerms(value: string | string[]) { public set osPerms(value: Permission | Permission[]) {
if (!value) { if (!value) {
value = []; value = [];
} else if (typeof value === 'string') { } else if (!Array.isArray(value)) {
value = [value]; value = [value];
} }
this.permissions = value; this.permissions = value;

View File

@ -9,6 +9,16 @@ export enum MergeAmendment {
YES = 1 YES = 1
} }
/**
* Restrictions are usually processed in the motion workflow
*/
export enum Restriction {
motionsCanManage = 'motions.can_manage',
motionsCanSeeInternal = 'motions.can_see_internal',
motionsCanManageMetadata = 'motions.can_manage_metadata',
motionsIsSubmitter = 'is_submitter'
}
/** /**
* Representation of a workflow state * Representation of a workflow state
* *
@ -22,7 +32,7 @@ export class State extends BaseModel<State> {
public name: string; public name: string;
public recommendation_label: string; public recommendation_label: string;
public css_class: string; public css_class: string;
public restriction: string[]; public restriction: Restriction[];
public allow_support: boolean; public allow_support: boolean;
public allow_create_poll: boolean; public allow_create_poll: boolean;
public allow_submitter_edit: boolean; public allow_submitter_edit: boolean;

View File

@ -1,3 +1,4 @@
import { Permission } from 'app/core/core-services/operator.service';
import { BaseModel } from '../base/base-model'; import { BaseModel } from '../base/base-model';
/** /**
@ -9,7 +10,7 @@ export class Group extends BaseModel<Group> {
public id: number; public id: number;
public name: string; public name: string;
public permissions: string[]; public permissions: Permission[];
public constructor(input?: Partial<Group>) { public constructor(input?: Partial<Group>) {
super(Group.COLLECTIONSTRING, input); super(Group.COLLECTIONSTRING, input);

View File

@ -3,21 +3,26 @@ import { RouterModule, Routes } from '@angular/router';
import { AgendaListComponent } from './components/agenda-list/agenda-list.component'; import { AgendaListComponent } from './components/agenda-list/agenda-list.component';
import { AgendaSortComponent } from './components/agenda-sort/agenda-sort.component'; import { AgendaSortComponent } from './components/agenda-sort/agenda-sort.component';
import { Permission } from 'app/core/core-services/operator.service';
import { WatchForChangesGuard } from 'app/shared/utils/watch-for-changes.guard'; import { WatchForChangesGuard } from 'app/shared/utils/watch-for-changes.guard';
import { TopicImportListComponent } from 'app/site/topics/components/topic-import-list/topic-import-list.component'; import { TopicImportListComponent } from 'app/site/topics/components/topic-import-list/topic-import-list.component';
import { ListOfSpeakersComponent } from './components/list-of-speakers/list-of-speakers.component'; import { ListOfSpeakersComponent } from './components/list-of-speakers/list-of-speakers.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: AgendaListComponent, pathMatch: 'full' }, { path: '', component: AgendaListComponent, pathMatch: 'full' },
{ path: 'import', component: TopicImportListComponent, data: { basePerm: 'agenda.can_manage' } }, { path: 'import', component: TopicImportListComponent, data: { basePerm: Permission.agendaCanManage } },
{ {
path: 'sort-agenda', path: 'sort-agenda',
component: AgendaSortComponent, component: AgendaSortComponent,
canDeactivate: [WatchForChangesGuard], canDeactivate: [WatchForChangesGuard],
data: { basePerm: 'agenda.can_manage' } data: { basePerm: Permission.agendaCanManage }
}, },
{ path: 'speakers', component: ListOfSpeakersComponent, data: { basePerm: 'agenda.can_see_list_of_speakers' } }, { path: 'speakers', component: ListOfSpeakersComponent, data: { basePerm: Permission.agendaCanSeeListOfSpeakers } },
{ path: 'speakers/:id', component: ListOfSpeakersComponent, data: { basePerm: 'agenda.can_see_list_of_speakers' } } {
path: 'speakers/:id',
component: ListOfSpeakersComponent,
data: { basePerm: Permission.agendaCanSeeListOfSpeakers }
}
]; ];
@NgModule({ @NgModule({

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
import { ListOfSpeakersRepositoryService } from 'app/core/repositories/agenda/list-of-speakers-repository.service'; import { ListOfSpeakersRepositoryService } from 'app/core/repositories/agenda/list-of-speakers-repository.service';
import { ListOfSpeakers } from 'app/shared/models/agenda/list-of-speakers'; import { ListOfSpeakers } from 'app/shared/models/agenda/list-of-speakers';
@ -22,7 +23,7 @@ export const AgendaAppConfig: AppConfig = {
displayName: 'Agenda', displayName: 'Agenda',
icon: 'today', // 'calendar_today' aligns wrong! icon: 'today', // 'calendar_today' aligns wrong!
weight: 200, weight: 200,
permission: 'agenda.can_see' permission: Permission.agendaCanSee
} }
] ]
}; };

View File

@ -11,7 +11,7 @@ import { PblColumnDefinition } from '@pebula/ngrid';
import { AgendaCsvExportService } from '../../services/agenda-csv-export.service'; import { AgendaCsvExportService } from '../../services/agenda-csv-export.service';
import { AgendaFilterListService } from '../../services/agenda-filter-list.service'; import { AgendaFilterListService } from '../../services/agenda-filter-list.service';
import { AgendaPdfService } from '../../services/agenda-pdf.service'; import { AgendaPdfService } from '../../services/agenda-pdf.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { PdfDocumentService } from 'app/core/pdf-services/pdf-document.service'; import { PdfDocumentService } from 'app/core/pdf-services/pdf-document.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
@ -56,7 +56,7 @@ export class AgendaListComponent extends BaseListViewComponent<ViewItem> impleme
* @returns true if the operator can manage agenda items * @returns true if the operator can manage agenda items
*/ */
public get canManage(): boolean { public get canManage(): boolean {
return this.operator.hasPerms('agenda.can_manage'); return this.operator.hasPerms(Permission.agendaCanManage);
} }
public itemListSlide: ProjectorElementBuildDeskriptor = { public itemListSlide: ProjectorElementBuildDeskriptor = {
@ -92,7 +92,7 @@ export class AgendaListComponent extends BaseListViewComponent<ViewItem> impleme
public restrictedColumns: ColumnRestriction[] = [ public restrictedColumns: ColumnRestriction[] = [
{ {
columnName: 'menu', columnName: 'menu',
permission: 'agenda.can_manage' permission: Permission.agendaCanManage
} }
]; ];

View File

@ -8,7 +8,7 @@ import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, Subscription } from 'rxjs'; import { BehaviorSubject, Subscription } from 'rxjs';
import { CollectionStringMapperService } from 'app/core/core-services/collection-string-mapper.service'; import { CollectionStringMapperService } from 'app/core/core-services/collection-string-mapper.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ListOfSpeakersRepositoryService } from 'app/core/repositories/agenda/list-of-speakers-repository.service'; import { ListOfSpeakersRepositoryService } from 'app/core/repositories/agenda/list-of-speakers-repository.service';
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service'; import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
@ -229,7 +229,7 @@ export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit
} }
public opCanManage(): boolean { public opCanManage(): boolean {
return this.operator.hasPerms('agenda.can_manage_list_of_speakers'); return this.operator.hasPerms(Permission.agendaCanManageListOfSpeakers);
} }
/** /**

View File

@ -1,14 +1,15 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { Permission } from 'app/core/core-services/operator.service';
import { AssignmentDetailComponent } from './components/assignment-detail/assignment-detail.component'; import { AssignmentDetailComponent } from './components/assignment-detail/assignment-detail.component';
import { AssignmentListComponent } from './components/assignment-list/assignment-list.component'; import { AssignmentListComponent } from './components/assignment-list/assignment-list.component';
import { AssignmentPollDetailComponent } from './components/assignment-poll-detail/assignment-poll-detail.component'; import { AssignmentPollDetailComponent } from './components/assignment-poll-detail/assignment-poll-detail.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: AssignmentListComponent, pathMatch: 'full' }, { path: '', component: AssignmentListComponent, pathMatch: 'full' },
{ path: 'new', component: AssignmentDetailComponent, data: { basePerm: 'assignments.can_manage' } }, { path: 'new', component: AssignmentDetailComponent, data: { basePerm: Permission.assignmentsCanManage } },
{ path: ':id', component: AssignmentDetailComponent, data: { basePerm: 'assignments.can_see' } }, { path: ':id', component: AssignmentDetailComponent, data: { basePerm: Permission.assignmentsCanSee } },
{ path: 'polls', children: [{ path: ':id', component: AssignmentPollDetailComponent }] } { path: 'polls', children: [{ path: ':id', component: AssignmentPollDetailComponent }] }
]; ];

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
import { AssignmentOptionRepositoryService } from 'app/core/repositories/assignments/assignment-option-repository.service'; import { AssignmentOptionRepositoryService } from 'app/core/repositories/assignments/assignment-option-repository.service';
import { AssignmentPollRepositoryService } from 'app/core/repositories/assignments/assignment-poll-repository.service'; import { AssignmentPollRepositoryService } from 'app/core/repositories/assignments/assignment-poll-repository.service';
import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service'; import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service';
@ -43,7 +44,7 @@ export const AssignmentsAppConfig: AppConfig = {
displayName: 'Elections', displayName: 'Elections',
icon: 'how_to_vote', icon: 'how_to_vote',
weight: 400, weight: 400,
permission: 'assignments.can_see' permission: Permission.assignmentsCanSee
} }
] ]
}; };

View File

@ -7,7 +7,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service'; import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service';
import { MediafileRepositoryService } from 'app/core/repositories/mediafiles/mediafile-repository.service'; import { MediafileRepositoryService } from 'app/core/repositories/mediafiles/mediafile-repository.service';
@ -229,7 +229,7 @@ export class AssignmentDetailComponent extends BaseViewComponent implements OnIn
* @returns true if the user is able to perform the action * @returns true if the user is able to perform the action
*/ */
public hasPerms(operation: string): boolean { public hasPerms(operation: string): boolean {
const isManager = this.operator.hasPerms('assignments.can_manage'); const isManager = this.operator.hasPerms(Permission.assignmentsCanManage);
switch (operation) { switch (operation) {
case 'addSelf': case 'addSelf':
if (isManager && !this.assignment.isFinished) { if (isManager && !this.assignment.isFinished) {
@ -237,7 +237,7 @@ export class AssignmentDetailComponent extends BaseViewComponent implements OnIn
} else { } else {
return ( return (
this.assignment.isSearchingForCandidates && this.assignment.isSearchingForCandidates &&
this.operator.hasPerms('assignments.can_nominate_self') && this.operator.hasPerms(Permission.assignmentsCanNominateSelf) &&
!this.assignment.isFinished !this.assignment.isFinished
); );
} }
@ -247,7 +247,7 @@ export class AssignmentDetailComponent extends BaseViewComponent implements OnIn
} else { } else {
return ( return (
this.assignment.isSearchingForCandidates && this.assignment.isSearchingForCandidates &&
this.operator.hasPerms('assignments.can_nominate_other') && this.operator.hasPerms(Permission.assignmentsCanNominateOther) &&
!this.assignment.isFinished !this.assignment.isFinished
); );
} }

View File

@ -1,5 +1,5 @@
<os-head-bar <os-head-bar
[hasMainButton]="operator.hasPerms('assignments.can_manage')" [hasMainButton]="canManageAssignments"
(mainEvent)="onPlusButton()" (mainEvent)="onPlusButton()"
[multiSelectMode]="isMultiSelect" [multiSelectMode]="isMultiSelect"
> >

View File

@ -6,7 +6,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { PblColumnDefinition } from '@pebula/ngrid'; import { PblColumnDefinition } from '@pebula/ngrid';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service'; import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
@ -56,6 +56,10 @@ export class AssignmentListComponent extends BaseListViewComponent<ViewAssignmen
*/ */
public filterProps = ['title', 'candidates', 'assignment_related_users', 'tags', 'candidateAmount']; public filterProps = ['title', 'candidates', 'assignment_related_users', 'tags', 'candidateAmount'];
public get canManageAssignments(): boolean {
return this.operator.hasPerms(Permission.assignmentsCanManage);
}
/** /**
* Constructor. * Constructor.
* *
@ -83,7 +87,7 @@ export class AssignmentListComponent extends BaseListViewComponent<ViewAssignmen
private pdfService: AssignmentPdfExportService, private pdfService: AssignmentPdfExportService,
protected route: ActivatedRoute, protected route: ActivatedRoute,
private router: Router, private router: Router,
public operator: OperatorService, private operator: OperatorService,
public vp: ViewportService public vp: ViewportService
) { ) {
super(titleService, translate, matSnackBar, storage); super(titleService, translate, matSnackBar, storage);
@ -112,7 +116,7 @@ export class AssignmentListComponent extends BaseListViewComponent<ViewAssignmen
public getColumnsHiddenInMobile(): string[] { public getColumnsHiddenInMobile(): string[] {
const hiddenInMobile = ['phase', 'candidates']; const hiddenInMobile = ['phase', 'candidates'];
if (!this.operator.hasPerms('agenda.can_see_list_of_speakers', 'core.can_manage_projector')) { if (!this.operator.hasPerms(Permission.agendaCanSeeListOfSpeakers, Permission.coreCanManageProjector)) {
hiddenInMobile.push('menu'); hiddenInMobile.push('menu');
} }

View File

@ -6,7 +6,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { PblColumnDefinition } from '@pebula/ngrid'; import { PblColumnDefinition } from '@pebula/ngrid';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { AssignmentPollRepositoryService } from 'app/core/repositories/assignments/assignment-poll-repository.service'; import { AssignmentPollRepositoryService } from 'app/core/repositories/assignments/assignment-poll-repository.service';
import { AssignmentVoteRepositoryService } from 'app/core/repositories/assignments/assignment-vote-repository.service'; import { AssignmentVoteRepositoryService } from 'app/core/repositories/assignments/assignment-vote-repository.service';
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
@ -133,7 +133,7 @@ export class AssignmentPollDetailComponent extends BasePollDetailComponent<ViewA
} }
protected hasPerms(): boolean { protected hasPerms(): boolean {
return this.operator.hasPerms('assignments.can_manage'); return this.operator.hasPerms(Permission.assignmentsCanManage);
} }
protected onDeleted(): void { protected onDeleted(): void {

View File

@ -1,6 +1,7 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { Permission } from 'app/core/core-services/operator.service';
import { ErrorComponent } from './components/error/error.component'; import { ErrorComponent } from './components/error/error.component';
import { LegalNoticeComponent } from './components/legal-notice/legal-notice.component'; import { LegalNoticeComponent } from './components/legal-notice/legal-notice.component';
import { PrivacyPolicyComponent } from './components/privacy-policy/privacy-policy.component'; import { PrivacyPolicyComponent } from './components/privacy-policy/privacy-policy.component';
@ -11,7 +12,7 @@ const routes: Routes = [
path: '', path: '',
component: StartComponent, component: StartComponent,
pathMatch: 'full', pathMatch: 'full',
data: { basePerm: 'core.can_see_frontpage' } data: { basePerm: Permission.coreCanSeeFrontpage }
}, },
{ {
path: 'legalnotice', path: 'legalnotice',

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
export const CommonAppConfig: AppConfig = { export const CommonAppConfig: AppConfig = {
name: 'common', name: 'common',
@ -8,7 +9,7 @@ export const CommonAppConfig: AppConfig = {
displayName: 'Home', displayName: 'Home',
icon: 'home', icon: 'home',
weight: 100, weight: 100,
permission: 'core.can_see_frontpage' permission: Permission.coreCanSeeFrontpage
} }
] ]
}; };

View File

@ -5,7 +5,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { OpenSlidesService } from 'app/core/core-services/openslides.service'; import { OpenSlidesService } from 'app/core/core-services/openslides.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ConfigRepositoryService } from 'app/core/repositories/config/config-repository.service'; import { ConfigRepositoryService } from 'app/core/repositories/config/config-repository.service';
import { UpdateService } from 'app/core/ui-services/update.service'; import { UpdateService } from 'app/core/ui-services/update.service';
import { BaseViewComponent } from 'app/site/base/base-view'; import { BaseViewComponent } from 'app/site/base/base-view';
@ -65,6 +65,6 @@ export class LegalNoticeComponent extends BaseViewComponent implements OnInit {
* Returns, if the current user has the necessary permissions. * Returns, if the current user has the necessary permissions.
*/ */
public canManage(): boolean { public canManage(): boolean {
return this.operator.hasPerms('core.can_manage_config'); return this.operator.hasPerms(Permission.coreCanManageConfig);
} }
} }

View File

@ -4,7 +4,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ConfigRepositoryService } from 'app/core/repositories/config/config-repository.service'; import { ConfigRepositoryService } from 'app/core/repositories/config/config-repository.service';
import { BaseViewComponent } from 'app/site/base/base-view'; import { BaseViewComponent } from 'app/site/base/base-view';
@ -58,6 +58,6 @@ export class PrivacyPolicyComponent extends BaseViewComponent implements OnInit
* Returns, if the current user has the necessary permissions. * Returns, if the current user has the necessary permissions.
*/ */
public canManage(): boolean { public canManage(): boolean {
return this.operator.hasPerms('core.can_manage_config'); return this.operator.hasPerms(Permission.coreCanManageConfig);
} }
} }

View File

@ -5,7 +5,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; // showcase import { TranslateService } from '@ngx-translate/core'; // showcase
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ConfigRepositoryService } from 'app/core/repositories/config/config-repository.service'; import { ConfigRepositoryService } from 'app/core/repositories/config/config-repository.service';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { BaseViewComponent } from 'app/site/base/base-view'; import { BaseViewComponent } from 'app/site/base/base-view';
@ -115,6 +115,6 @@ export class StartComponent extends BaseViewComponent implements OnInit {
* Returns, if the current user has the necessary permissions. * Returns, if the current user has the necessary permissions.
*/ */
public canManage(): boolean { public canManage(): boolean {
return this.operator.hasPerms('core.can_manage_config'); return this.operator.hasPerms(Permission.coreCanManageConfig);
} }
} }

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
import { Config } from '../../shared/models/core/config'; import { Config } from '../../shared/models/core/config';
import { ConfigRepositoryService } from '../../core/repositories/config/config-repository.service'; import { ConfigRepositoryService } from '../../core/repositories/config/config-repository.service';
import { ViewConfig } from './models/view-config'; import { ViewConfig } from './models/view-config';
@ -12,7 +13,7 @@ export const ConfigAppConfig: AppConfig = {
displayName: 'Settings', displayName: 'Settings',
icon: 'settings', icon: 'settings',
weight: 1300, weight: 1300,
permission: 'core.can_manage_config' permission: Permission.coreCanManageConfig
} }
] ]
}; };

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
/** /**
* Config object for history. * Config object for history.
@ -12,7 +13,7 @@ export const HistoryAppConfig: AppConfig = {
displayName: 'History', displayName: 'History',
icon: 'history', icon: 'history',
weight: 1200, weight: 1200,
permission: 'core.can_see_history' permission: Permission.coreCanSeeHistory
} }
] ]
}; };

View File

@ -19,7 +19,7 @@ import { columnFactory, createDS, PblColumnDefinition } from '@pebula/ngrid';
import { PblNgridDataMatrixRow } from '@pebula/ngrid/target-events'; import { PblNgridDataMatrixRow } from '@pebula/ngrid/target-events';
import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { MediafileRepositoryService } from 'app/core/repositories/mediafiles/mediafile-repository.service'; import { MediafileRepositoryService } from 'app/core/repositories/mediafiles/mediafile-repository.service';
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
@ -71,7 +71,7 @@ export class MediafileListComponent extends BaseListViewComponent<ViewMediafile>
* @return true if the user can manage media files * @return true if the user can manage media files
*/ */
public get canEdit(): boolean { public get canEdit(): boolean {
return this.operator.hasPerms('mediafiles.can_manage'); return this.operator.hasPerms(Permission.mediafilesCanManage);
} }
/** /**
@ -79,9 +79,9 @@ export class MediafileListComponent extends BaseListViewComponent<ViewMediafile>
*/ */
public get canAccessFileMenu(): boolean { public get canAccessFileMenu(): boolean {
return ( return (
this.operator.hasPerms('core.can_manage_projector') || this.operator.hasPerms(Permission.coreCanManageProjector) ||
this.operator.hasPerms('agenda.can_see_list_of_speakers') || this.operator.hasPerms(Permission.agendaCanSeeListOfSpeakers) ||
this.operator.hasPerms('core.can_manage_logos_and_fonts') || this.operator.hasPerms(Permission.coreCanManageLogosAndFonts) ||
this.canEdit this.canEdit
); );
} }
@ -253,10 +253,10 @@ export class MediafileListComponent extends BaseListViewComponent<ViewMediafile>
*/ */
public showFileMenu(file: ViewMediafile): boolean { public showFileMenu(file: ViewMediafile): boolean {
return ( return (
this.operator.hasPerms('agenda.can_see_list_of_speakers') || this.operator.hasPerms(Permission.agendaCanSeeListOfSpeakers) ||
(file.isProjectable() && this.operator.hasPerms('core.can_manage_projector')) || (file.isProjectable() && this.operator.hasPerms(Permission.coreCanManageProjector)) ||
(file.isFont() && this.operator.hasPerms('core.can_manage_logos_and_fonts')) || (file.isFont() && this.operator.hasPerms(Permission.coreCanManageLogosAndFonts)) ||
(file.isImage() && this.operator.hasPerms('core.can_manage_logos_and_fonts')) || (file.isImage() && this.operator.hasPerms(Permission.coreCanManageLogosAndFonts)) ||
this.canEdit this.canEdit
); );
} }

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
import { MediafileRepositoryService } from 'app/core/repositories/mediafiles/mediafile-repository.service'; import { MediafileRepositoryService } from 'app/core/repositories/mediafiles/mediafile-repository.service';
import { Mediafile } from '../../shared/models/mediafiles/mediafile'; import { Mediafile } from '../../shared/models/mediafiles/mediafile';
import { ViewMediafile } from './models/view-mediafile'; import { ViewMediafile } from './models/view-mediafile';
@ -20,7 +21,7 @@ export const MediafileAppConfig: AppConfig = {
displayName: 'Files', displayName: 'Files',
icon: 'attach_file', icon: 'attach_file',
weight: 600, weight: 600,
permission: 'mediafiles.can_see' permission: Permission.mediafilesCanSee
} }
] ]
}; };

View File

@ -1,6 +1,7 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { Permission } from 'app/core/core-services/operator.service';
import { MediaUploadComponent } from './components/media-upload/media-upload.component'; import { MediaUploadComponent } from './components/media-upload/media-upload.component';
import { MediafileListComponent } from './components/mediafile-list/mediafile-list.component'; import { MediafileListComponent } from './components/mediafile-list/mediafile-list.component';
@ -17,7 +18,7 @@ const routes: Routes = [
}, },
{ {
path: 'upload', path: 'upload',
data: { basePerm: 'mediafiles.can_manage' }, data: { basePerm: Permission.mediafilesCanManage },
children: [{ path: '**', component: MediaUploadComponent }], children: [{ path: '**', component: MediaUploadComponent }],
pathMatch: 'prefix' pathMatch: 'prefix'
} }

View File

@ -8,7 +8,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service'; import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service';
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service'; import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
@ -59,7 +59,7 @@ export class CategoryDetailComponent extends BaseViewComponent implements OnInit
* @returns true if the user may alter motions * @returns true if the user may alter motions
*/ */
public get canEdit(): boolean { public get canEdit(): boolean {
return this.operator.hasPerms('motions.can_manage'); return this.operator.hasPerms(Permission.motionsCanManage);
} }
/** /**

View File

@ -7,7 +7,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { PblColumnDefinition } from '@pebula/ngrid'; import { PblColumnDefinition } from '@pebula/ngrid';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service'; import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service';
import { infoDialogSettings } from 'app/shared/utils/dialog-settings'; import { infoDialogSettings } from 'app/shared/utils/dialog-settings';
@ -56,7 +56,7 @@ export class CategoryListComponent extends BaseListViewComponent<ViewCategory> i
* @returns true if the user may alter motions or their metadata * @returns true if the user may alter motions or their metadata
*/ */
public get canEdit(): boolean { public get canEdit(): boolean {
return this.operator.hasPerms('motions.can_manage'); return this.operator.hasPerms(Permission.motionsCanManage);
} }
/** /**

View File

@ -8,6 +8,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { PblColumnDefinition } from '@pebula/ngrid'; import { PblColumnDefinition } from '@pebula/ngrid';
import { Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service'; import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
@ -74,7 +75,7 @@ export class MotionBlockDetailComponent extends BaseListViewComponent<ViewMotion
public restrictedColumns: ColumnRestriction[] = [ public restrictedColumns: ColumnRestriction[] = [
{ {
columnName: 'remove', columnName: 'remove',
permission: 'motions.can_manage' permission: Permission.motionsCanManage
} }
]; ];

View File

@ -8,7 +8,7 @@ import { TranslateService } from '@ngx-translate/core';
import { PblColumnDefinition } from '@pebula/ngrid'; import { PblColumnDefinition } from '@pebula/ngrid';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service'; import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
@ -57,7 +57,7 @@ export class MotionBlockListComponent extends BaseListViewComponent<ViewMotionBl
* @returns true if the user may alter motions or their metadata * @returns true if the user may alter motions or their metadata
*/ */
public get canEdit(): boolean { public get canEdit(): boolean {
return this.operator.hasPerms('motions.can_manage', 'motions.can_manage_metadata'); return this.operator.hasPerms(Permission.motionsCanManage, Permission.motionsCanManageMetadata);
} }
/** /**

View File

@ -11,7 +11,7 @@ import {
SimpleChanges SimpleChanges
} from '@angular/core'; } from '@angular/core';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { LineRange, ModificationType } from 'app/core/ui-services/diff.service'; import { LineRange, ModificationType } from 'app/core/ui-services/diff.service';
import { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-motion-change-recommendation'; import { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-motion-change-recommendation';
@ -110,7 +110,7 @@ export class MotionDetailOriginalChangeRecommendationsComponent implements OnIni
* The permissions of the user have changed -> activate / deactivate editing functionality * The permissions of the user have changed -> activate / deactivate editing functionality
*/ */
private onPermissionsChanged(): void { private onPermissionsChanged(): void {
if (this.operator.hasPerms('motions.can_manage')) { if (this.operator.hasPerms(Permission.motionsCanManage)) {
this.can_manage = true; this.can_manage = true;
if (this.selectedFrom === null) { if (this.selectedFrom === null) {
this.startCreating(); this.startCreating();

View File

@ -6,7 +6,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { PblColumnDefinition } from '@pebula/ngrid'; import { PblColumnDefinition } from '@pebula/ngrid';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { MotionPollRepositoryService } from 'app/core/repositories/motions/motion-poll-repository.service'; import { MotionPollRepositoryService } from 'app/core/repositories/motions/motion-poll-repository.service';
import { MotionVoteRepositoryService } from 'app/core/repositories/motions/motion-vote-repository.service'; import { MotionVoteRepositoryService } from 'app/core/repositories/motions/motion-vote-repository.service';
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
@ -78,6 +78,6 @@ export class MotionPollDetailComponent extends BasePollDetailComponent<ViewMotio
} }
protected hasPerms(): boolean { protected hasPerms(): boolean {
return this.operator.hasPerms('motions.can_manage_polls'); return this.operator.hasPerms(Permission.motionsCanManagePolls);
} }
} }

View File

@ -5,7 +5,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { MotionPollRepositoryService } from 'app/core/repositories/motions/motion-poll-repository.service'; import { MotionPollRepositoryService } from 'app/core/repositories/motions/motion-poll-repository.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
import { VotingPrivacyWarningComponent } from 'app/shared/components/voting-privacy-warning/voting-privacy-warning.component'; import { VotingPrivacyWarningComponent } from 'app/shared/components/voting-privacy-warning/voting-privacy-warning.component';
@ -54,7 +54,7 @@ export class MotionPollComponent extends BasePollComponent<ViewMotionPoll, Motio
public get showPoll(): boolean { public get showPoll(): boolean {
if (this.poll) { if (this.poll) {
if ( if (
this.operator.hasPerms('motions.can_manage_polls') || this.operator.hasPerms(Permission.motionsCanManagePolls) ||
this.poll.isPublished || this.poll.isPublished ||
(this.poll.isEVoting && !this.poll.isCreated) (this.poll.isEVoting && !this.poll.isCreated)
) { ) {

View File

@ -13,7 +13,7 @@ import { map } from 'rxjs/operators';
import { StateRepositoryService } from 'app/core/repositories/motions/state-repository.service'; import { StateRepositoryService } from 'app/core/repositories/motions/state-repository.service';
import { WorkflowRepositoryService } from 'app/core/repositories/motions/workflow-repository.service'; import { WorkflowRepositoryService } from 'app/core/repositories/motions/workflow-repository.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
import { MergeAmendment, State } from 'app/shared/models/motions/state'; import { MergeAmendment, Restriction, State } from 'app/shared/models/motions/state';
import { infoDialogSettings } from 'app/shared/utils/dialog-settings'; import { infoDialogSettings } from 'app/shared/utils/dialog-settings';
import { BaseViewComponent } from 'app/site/base/base-view'; import { BaseViewComponent } from 'app/site/base/base-view';
import { ViewState } from 'app/site/motions/models/view-state'; import { ViewState } from 'app/site/motions/models/view-state';
@ -59,8 +59,8 @@ interface AmendmentIntoFinal {
/** /**
* Defines the structure of restrictions * Defines the structure of restrictions
*/ */
interface Restriction { interface RestrictionShape {
key: string; key: Restriction;
label: string; label: string;
} }
@ -126,11 +126,11 @@ export class WorkflowDetailComponent extends BaseViewComponent implements OnInit
* Determines possible restrictions * Determines possible restrictions
*/ */
public restrictions = [ public restrictions = [
{ key: 'motions.can_manage', label: 'Can manage motions' }, { key: Restriction.motionsCanManage, label: 'Can manage motions' },
{ key: 'motions.can_see_internal', label: 'Can see motions in internal state' }, { key: Restriction.motionsCanSeeInternal, label: 'Can see motions in internal state' },
{ key: 'motions.can_manage_metadata', label: 'Can manage motion metadata' }, { key: Restriction.motionsCanManageMetadata, label: 'Can manage motion metadata' },
{ key: 'is_submitter', label: 'Submitters' } { key: Restriction.motionsIsSubmitter, label: 'Submitters' }
] as Restriction[]; ] as RestrictionShape[];
/** /**
* Determines possible "Merge amendments into final" * Determines possible "Merge amendments into final"
@ -313,7 +313,7 @@ export class WorkflowDetailComponent extends BaseViewComponent implements OnInit
* @param restrictions The new restrictions * @param restrictions The new restrictions
* @param state the state to change * @param state the state to change
*/ */
public onSetRestriction(restriction: string, state: ViewState): void { public onSetRestriction(restriction: Restriction, state: ViewState): void {
const restrictions = state.restriction.map(r => r); const restrictions = state.restriction.map(r => r);
const restrictionIndex = restrictions.findIndex(r => r === restriction); const restrictionIndex = restrictions.findIndex(r => r === restriction);

View File

@ -1,6 +1,8 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { Permission } from 'app/core/core-services/operator.service';
const routes: Routes = [ const routes: Routes = [
{ {
path: '', path: '',
@ -10,13 +12,13 @@ const routes: Routes = [
{ {
path: 'import', path: 'import',
loadChildren: () => import('./modules/motion-import/motion-import.module').then(m => m.MotionImportModule), loadChildren: () => import('./modules/motion-import/motion-import.module').then(m => m.MotionImportModule),
data: { basePerm: 'motions.can_manage' } data: { basePerm: Permission.motionsCanManage }
}, },
{ {
path: 'statute-paragraphs', path: 'statute-paragraphs',
loadChildren: () => loadChildren: () =>
import('./modules/statute-paragraph/statute-paragraph.module').then(m => m.StatuteParagraphModule), import('./modules/statute-paragraph/statute-paragraph.module').then(m => m.StatuteParagraphModule),
data: { basePerm: 'motions.can_manage' } data: { basePerm: Permission.motionsCanManage }
}, },
{ {
path: 'comment-section', path: 'comment-section',
@ -24,54 +26,54 @@ const routes: Routes = [
import('./modules/motion-comment-section/motion-comment-section.module').then( import('./modules/motion-comment-section/motion-comment-section.module').then(
m => m.MotionCommentSectionModule m => m.MotionCommentSectionModule
), ),
data: { basePerm: 'motions.can_manage' } data: { basePerm: Permission.motionsCanManage }
}, },
{ {
path: 'call-list', path: 'call-list',
loadChildren: () => import('./modules/call-list/call-list.module').then(m => m.CallListModule), loadChildren: () => import('./modules/call-list/call-list.module').then(m => m.CallListModule),
data: { basePerm: 'motions.can_manage' } data: { basePerm: Permission.motionsCanManage }
}, },
{ {
path: 'category', path: 'category',
loadChildren: () => import('./modules/category/category.module').then(m => m.CategoryModule), loadChildren: () => import('./modules/category/category.module').then(m => m.CategoryModule),
data: { basePerm: 'motions.can_see' } data: { basePerm: Permission.motionsCanSee }
}, },
{ {
path: 'blocks', path: 'blocks',
loadChildren: () => import('./modules/motion-block/motion-block.module').then(m => m.MotionBlockModule), loadChildren: () => import('./modules/motion-block/motion-block.module').then(m => m.MotionBlockModule),
data: { basePerm: 'motions.can_see' } data: { basePerm: Permission.motionsCanSee }
}, },
{ {
path: 'workflow', path: 'workflow',
loadChildren: () => loadChildren: () =>
import('./modules/motion-workflow/motion-workflow.module').then(m => m.MotionWorkflowModule), import('./modules/motion-workflow/motion-workflow.module').then(m => m.MotionWorkflowModule),
data: { basePerm: 'motions.can_manage' } data: { basePerm: Permission.motionsCanManage }
}, },
{ {
path: 'new', path: 'new',
loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule), loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule),
data: { basePerm: 'motions.can_create' } data: { basePerm: Permission.motionsCanCreate }
}, },
{ {
path: 'new-amendment', path: 'new-amendment',
loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule), loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule),
data: { basePerm: 'motions.can_create_amendments' } data: { basePerm: Permission.motionsCanCreateAmendments }
}, },
{ {
path: 'amendments', path: 'amendments',
loadChildren: () => import('./modules/amendment-list/amendment-list.module').then(m => m.AmendmentListModule), loadChildren: () => import('./modules/amendment-list/amendment-list.module').then(m => m.AmendmentListModule),
data: { basePerm: 'motions.can_see' } data: { basePerm: Permission.motionsCanSee }
}, },
{ {
path: 'polls', path: 'polls',
loadChildren: () => import('./modules/motion-poll/motion-poll.module').then(m => m.MotionPollModule), loadChildren: () => import('./modules/motion-poll/motion-poll.module').then(m => m.MotionPollModule),
data: { basePerm: 'motions.can_see' } data: { basePerm: Permission.motionsCanSee }
}, },
{ {
path: ':id', path: ':id',
loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule), loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule),
runGuardsAndResolvers: 'paramsChange', runGuardsAndResolvers: 'paramsChange',
data: { basePerm: 'motions.can_see' } data: { basePerm: Permission.motionsCanSee }
} }
]; ];

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service'; import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service';
import { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service'; import { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service';
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service'; import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
@ -90,7 +91,7 @@ export const MotionsAppConfig: AppConfig = {
displayName: 'Motions', displayName: 'Motions',
icon: 'assignment', icon: 'assignment',
weight: 300, weight: 300,
permission: 'motions.can_see' permission: Permission.motionsCanSee
} }
] ]
}; };

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { ViewMotion } from '../models/view-motion'; import { ViewMotion } from '../models/view-motion';
@ -30,7 +30,7 @@ export class LocalPermissionsService {
* in mobile mode * in mobile mode
*/ */
public canAccessMobileDotMenu(): boolean { public canAccessMobileDotMenu(): boolean {
return this.operator.hasPerms('agenda.can_see_list_of_speakers', 'core.can_manage_projector'); return this.operator.hasPerms(Permission.agendaCanSeeListOfSpeakers, Permission.coreCanManageProjector);
} }
/** /**
@ -57,14 +57,14 @@ export class LocalPermissionsService {
public isAllowed(action: string, motion?: ViewMotion): boolean { public isAllowed(action: string, motion?: ViewMotion): boolean {
switch (action) { switch (action) {
case 'create': { case 'create': {
return this.operator.hasPerms('motions.can_create'); return this.operator.hasPerms(Permission.motionsCanCreate);
} }
case 'support': { case 'support': {
if (!motion || !motion.state) { if (!motion || !motion.state) {
return false; return false;
} }
return ( return (
this.operator.hasPerms('motions.can_support') && this.operator.hasPerms(Permission.motionsCanSupport) &&
this.configMinSupporters > 0 && this.configMinSupporters > 0 &&
motion.state && motion.state &&
motion.state.allow_support && motion.state.allow_support &&
@ -90,8 +90,8 @@ export class LocalPermissionsService {
return false; return false;
} }
return ( return (
(this.operator.hasPerms('motions.can_manage') || (this.operator.hasPerms(Permission.motionsCanManage) ||
this.operator.hasPerms('motions.can_manage_metadata')) && this.operator.hasPerms(Permission.motionsCanManageMetadata)) &&
motion.state && motion.state &&
motion.state.allow_create_poll motion.state.allow_create_poll
); );
@ -103,7 +103,7 @@ export class LocalPermissionsService {
return false; return false;
} }
return ( return (
this.operator.hasPerms('motions.can_manage') || this.operator.hasPerms(Permission.motionsCanManage) ||
(motion.state && (motion.state &&
motion.state.allow_submitter_edit && motion.state.allow_submitter_edit &&
motion.submitters && motion.submitters &&
@ -113,14 +113,14 @@ export class LocalPermissionsService {
); );
} }
case 'update_submitters': { case 'update_submitters': {
return this.operator.hasPerms('motions.can_manage'); return this.operator.hasPerms(Permission.motionsCanManage);
} }
case 'delete': { case 'delete': {
if (!motion) { if (!motion) {
return false; return false;
} }
return ( return (
this.operator.hasPerms('motions.can_manage') && this.operator.hasPerms(Permission.motionsCanManage) &&
motion.state && motion.state &&
motion.state.allow_submitter_edit && motion.state.allow_submitter_edit &&
motion.submitters && motion.submitters &&
@ -135,8 +135,8 @@ export class LocalPermissionsService {
return false; return false;
} }
return ( return (
this.operator.hasPerms('motions.can_manage') || this.operator.hasPerms(Permission.motionsCanManage) ||
this.operator.hasPerms('motions.can_manage_metadata') || this.operator.hasPerms(Permission.motionsCanManageMetadata) ||
(motion.state && (motion.state &&
motion.state.allow_submitter_edit && motion.state.allow_submitter_edit &&
!this.operator.isAnonymous && !this.operator.isAnonymous &&
@ -146,8 +146,8 @@ export class LocalPermissionsService {
} }
case 'change_metadata': { case 'change_metadata': {
return ( return (
this.operator.hasPerms('motions.can_manage') || this.operator.hasPerms(Permission.motionsCanManage) ||
this.operator.hasPerms('motions.can_manage_metadata') this.operator.hasPerms(Permission.motionsCanManageMetadata)
); );
} }
case 'can_create_amendments': { case 'can_create_amendments': {
@ -155,19 +155,19 @@ export class LocalPermissionsService {
return false; return false;
} }
return ( return (
this.operator.hasPerms('motions.can_create_amendments') && this.operator.hasPerms(Permission.motionsCanCreateAmendments) &&
this.amendmentEnabled && this.amendmentEnabled &&
(!motion.parent_id || (motion.parent_id && this.amendmentOfAmendment)) (!motion.parent_id || (motion.parent_id && this.amendmentOfAmendment))
); );
} }
case 'can_manage_metadata': { case 'can_manage_metadata': {
return ( return (
this.operator.hasPerms('motions.can_manage') && this.operator.hasPerms(Permission.motionsCanManage) &&
this.operator.hasPerms('motions.can_manage_metadata') this.operator.hasPerms(Permission.motionsCanManageMetadata)
); );
} }
case 'manage': { case 'manage': {
return this.operator.hasPerms('motions.can_manage'); return this.operator.hasPerms(Permission.motionsCanManage);
} }
default: { default: {
return false; return false;

View File

@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { OpenSlidesStatusService } from 'app/core/core-services/openslides-status.service'; import { OpenSlidesStatusService } from 'app/core/core-services/openslides-status.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service'; import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service';
import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service'; import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service';
@ -17,6 +17,7 @@ import {
OsFilterOptions OsFilterOptions
} from 'app/core/ui-services/base-filter-list.service'; } from 'app/core/ui-services/base-filter-list.service';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { Restriction } from 'app/shared/models/motions/state';
import { AmendmentType } from '../motions.constants'; import { AmendmentType } from '../motions.constants';
import { ViewMotion } from '../models/view-motion'; import { ViewMotion } from '../models/view-motion';
@ -234,7 +235,7 @@ export class MotionFilterListService extends BaseFilterListService<ViewMotion> {
]; ];
// only add the filter if the user has the correct permission // only add the filter if the user has the correct permission
if (this.operator.hasPerms('agenda.can_see_list_of_speakers')) { if (this.operator.hasPerms(Permission.agendaCanSeeListOfSpeakers)) {
filterDefinitions.push(this.hasSpeakerOptions); filterDefinitions.push(this.hasSpeakerOptions);
} }
@ -276,7 +277,10 @@ export class MotionFilterListService extends BaseFilterListService<ViewMotion> {
for (const state of workflow.states) { for (const state of workflow.states) {
// get the restriction array, but remove the is_submitter condition, if present // get the restriction array, but remove the is_submitter condition, if present
const restrictions = state.restriction.filter(r => r !== 'is_submitter'); const restrictions = (state.restriction.filter(
r => r !== Restriction.motionsIsSubmitter
) as unknown) as Permission[];
if (!restrictions.length || this.operator.hasPerms(...restrictions)) { if (!restrictions.length || this.operator.hasPerms(...restrictions)) {
// sort final and non final states // sort final and non final states
state.isFinalState ? finalStates.push(state.id) : nonFinalStates.push(state.id); state.isFinalState ? finalStates.push(state.id) : nonFinalStates.push(state.id);

View File

@ -8,7 +8,7 @@ import { ActivatedRoute } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { timer } from 'rxjs'; import { timer } from 'rxjs';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ProjectorService } from 'app/core/core-services/projector.service'; import { ProjectorService } from 'app/core/core-services/projector.service';
import { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-repository.service'; import { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-repository.service';
import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service'; import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service';
@ -162,7 +162,7 @@ export class ProjectorDetailComponent extends BaseViewComponent implements OnIni
* @returns true if the operator can manage * @returns true if the operator can manage
*/ */
public canManage(): boolean { public canManage(): boolean {
return this.opertator.hasPerms('core.can_manage_projector'); return this.opertator.hasPerms(Permission.coreCanManageProjector);
} }
/** /**

View File

@ -5,7 +5,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service'; import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
import { largeDialogSettings } from 'app/shared/utils/dialog-settings'; import { largeDialogSettings } from 'app/shared/utils/dialog-settings';
@ -36,7 +36,7 @@ export class ProjectorListEntryComponent extends BaseViewComponent implements On
} }
public get projectionTarget(): '_blank' | '_self' { public get projectionTarget(): '_blank' | '_self' {
if (this.operator.hasPerms('core.can_manage_projector')) { if (this.operator.hasPerms(Permission.coreCanManageProjector)) {
return '_self'; return '_self';
} else { } else {
return '_blank'; return '_blank';
@ -94,7 +94,7 @@ export class ProjectorListEntryComponent extends BaseViewComponent implements On
* and not the detail view * and not the detail view
*/ */
public getDetailLink(): string { public getDetailLink(): string {
if (this.operator.hasPerms('core.can_can_manage_projector')) { if (this.operator.hasPerms(Permission.coreCanManageProjector)) {
return `/projectors/detail/${this.projector.id}`; return `/projectors/detail/${this.projector.id}`;
} else { } else {
return `/projector/${this.projector.id}`; return `/projector/${this.projector.id}`;

View File

@ -16,7 +16,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, timer } from 'rxjs'; import { BehaviorSubject, timer } from 'rxjs';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service'; import { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-repository.service';
import { Projector } from 'app/shared/models/core/projector'; import { Projector } from 'app/shared/models/core/projector';
import { infoDialogSettings } from 'app/shared/utils/dialog-settings'; import { infoDialogSettings } from 'app/shared/utils/dialog-settings';
@ -55,7 +55,7 @@ export class ProjectorListComponent extends BaseViewComponent implements OnInit,
* @returns true if the user can manage projectors * @returns true if the user can manage projectors
*/ */
public get canManage(): boolean { public get canManage(): boolean {
return this.operator.hasPerms('core.can_manage_projector'); return this.operator.hasPerms(Permission.coreCanManageProjector);
} }
/** /**

View File

@ -1,6 +1,7 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { Permission } from 'app/core/core-services/operator.service';
import { ProjectorDetailComponent } from './components/projector-detail/projector-detail.component'; import { ProjectorDetailComponent } from './components/projector-detail/projector-detail.component';
import { ProjectorListComponent } from './components/projector-list/projector-list.component'; import { ProjectorListComponent } from './components/projector-list/projector-list.component';
@ -13,7 +14,7 @@ const routes: Routes = [
{ {
path: 'detail/:id', path: 'detail/:id',
component: ProjectorDetailComponent, component: ProjectorDetailComponent,
data: { basePerm: 'core.can_can_manage_projector' } data: { basePerm: Permission.coreCanManageProjector }
} }
]; ];

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
import { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-repository.service'; import { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-repository.service';
import { ProjectionDefaultRepositoryService } from 'app/core/repositories/projector/projection-default-repository.service'; import { ProjectionDefaultRepositoryService } from 'app/core/repositories/projector/projection-default-repository.service';
import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service'; import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service';
@ -42,7 +43,7 @@ export const ProjectorAppConfig: AppConfig = {
displayName: 'Projector', displayName: 'Projector',
icon: 'videocam', icon: 'videocam',
weight: 700, weight: 700,
permission: 'core.can_see_projector' permission: Permission.coreCanSeeProjector
} }
] ]
}; };

View File

@ -1,6 +1,7 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { Permission } from 'app/core/core-services/operator.service';
import { AuthGuard } from '../core/core-services/auth-guard.service'; import { AuthGuard } from '../core/core-services/auth-guard.service';
import { SiteComponent } from './site.component'; import { SiteComponent } from './site.component';
@ -21,32 +22,32 @@ const routes: Routes = [
{ {
path: 'agenda', path: 'agenda',
loadChildren: () => import('./agenda/agenda.module').then(m => m.AgendaModule), loadChildren: () => import('./agenda/agenda.module').then(m => m.AgendaModule),
data: { basePerm: 'agenda.can_see' } data: { basePerm: Permission.agendaCanSee }
}, },
{ {
path: 'topics', path: 'topics',
loadChildren: () => import('./topics/topics.module').then(m => m.TopicsModule), loadChildren: () => import('./topics/topics.module').then(m => m.TopicsModule),
data: { basePerm: 'agenda.can_see' } data: { basePerm: Permission.agendaCanSee }
}, },
{ {
path: 'assignments', path: 'assignments',
loadChildren: () => import('./assignments/assignments.module').then(m => m.AssignmentsModule), loadChildren: () => import('./assignments/assignments.module').then(m => m.AssignmentsModule),
data: { basePerm: 'assignments.can_see' } data: { basePerm: Permission.assignmentsCanSee }
}, },
{ {
path: 'mediafiles', path: 'mediafiles',
loadChildren: () => import('./mediafiles/mediafiles.module').then(m => m.MediafilesModule), loadChildren: () => import('./mediafiles/mediafiles.module').then(m => m.MediafilesModule),
data: { basePerm: 'mediafiles.can_see' } data: { basePerm: Permission.mediafilesCanSee }
}, },
{ {
path: 'motions', path: 'motions',
loadChildren: () => import('./motions/motions.module').then(m => m.MotionsModule), loadChildren: () => import('./motions/motions.module').then(m => m.MotionsModule),
data: { basePerm: 'motions.can_see' } data: { basePerm: Permission.motionsCanSee }
}, },
{ {
path: 'settings', path: 'settings',
loadChildren: () => import('./config/config.module').then(m => m.ConfigModule), loadChildren: () => import('./config/config.module').then(m => m.ConfigModule),
data: { basePerm: 'core.can_manage_config' } data: { basePerm: Permission.coreCanManageConfig }
}, },
{ {
path: 'users', path: 'users',
@ -57,22 +58,23 @@ const routes: Routes = [
{ {
path: 'tags', path: 'tags',
loadChildren: () => import('./tags/tag.module').then(m => m.TagModule), loadChildren: () => import('./tags/tag.module').then(m => m.TagModule),
data: { basePerm: 'core.can_manage_tags' } data: { basePerm: Permission.coreCanManageTags }
}, },
{ {
path: 'history', path: 'history',
loadChildren: () => import('./history/history.module').then(m => m.HistoryModule), loadChildren: () => import('./history/history.module').then(m => m.HistoryModule),
data: { basePerm: 'core.can_see_history' } data: { basePerm: Permission.coreCanSeeHistory }
}, },
{ {
path: 'projectors', path: 'projectors',
loadChildren: () => import('./projector/projector.module').then(m => m.ProjectorModule), loadChildren: () => import('./projector/projector.module').then(m => m.ProjectorModule),
data: { basePerm: 'core.can_see_projector' } data: { basePerm: Permission.coreCanSeeProjector }
}, },
{ {
path: 'polls', path: 'polls',
loadChildren: () => import('./polls/polls.module').then(m => m.PollsModule), loadChildren: () => import('./polls/polls.module').then(m => m.PollsModule),
data: { basePerm: ['motions.can_see', 'assignments.can_see'] } // one of them is sufficient // one of them is sufficient
data: { basePerm: [Permission.motionsCanSee, Permission.assignmentsCanSee] }
} }
], ],
canActivateChild: [AuthGuard] canActivateChild: [AuthGuard]

View File

@ -7,7 +7,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service';
import { TopicRepositoryService } from 'app/core/repositories/topics/topic-repository.service'; import { TopicRepositoryService } from 'app/core/repositories/topics/topic-repository.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
@ -217,9 +217,9 @@ export class TopicDetailComponent extends BaseViewComponent {
public isAllowed(action: string): boolean { public isAllowed(action: string): boolean {
switch (action) { switch (action) {
case 'see': case 'see':
return this.operator.hasPerms('agenda.can_see'); return this.operator.hasPerms(Permission.agendaCanSee);
case 'edit': case 'edit':
return this.operator.hasPerms('agenda.can_manage'); return this.operator.hasPerms(Permission.agendaCanManage);
case 'default': case 'default':
return false; return false;
} }

View File

@ -1,11 +1,12 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { Permission } from 'app/core/core-services/operator.service';
import { TopicDetailComponent } from './components/topic-detail/topic-detail.component'; import { TopicDetailComponent } from './components/topic-detail/topic-detail.component';
const routes: Routes = [ const routes: Routes = [
{ path: 'new', component: TopicDetailComponent, data: { basePerm: 'agenda.can_manage' } }, { path: 'new', component: TopicDetailComponent, data: { basePerm: Permission.agendaCanManage } },
{ path: ':id', component: TopicDetailComponent, data: { basePerm: 'agenda.can_see' } } { path: ':id', component: TopicDetailComponent, data: { basePerm: Permission.agendaCanSee } }
]; ];
@NgModule({ @NgModule({

View File

@ -7,6 +7,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Permission } from 'app/core/core-services/operator.service';
import { AppPermissions, GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; import { AppPermissions, GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
import { PromptService } from 'app/core/ui-services/prompt.service'; import { PromptService } from 'app/core/ui-services/prompt.service';
import { Group } from 'app/shared/models/users/group'; import { Group } from 'app/shared/models/users/group';
@ -158,7 +159,7 @@ export class GroupListComponent extends BaseViewComponent implements OnInit {
* @param viewGroup * @param viewGroup
* @param perm * @param perm
*/ */
public togglePerm(viewGroup: ViewGroup, perm: string): void { public togglePerm(viewGroup: ViewGroup, perm: Permission): void {
this.repo.togglePerm(viewGroup, perm); this.repo.togglePerm(viewGroup, perm);
} }

View File

@ -6,7 +6,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
import { BaseViewComponent } from 'app/site/base/base-view'; import { BaseViewComponent } from 'app/site/base/base-view';
import { ViewUser } from '../../models/view-user'; import { ViewUser } from '../../models/view-user';
@ -120,7 +120,7 @@ export class PasswordComponent extends BaseViewComponent implements OnInit {
} else { } else {
this.user = this.repo.getViewModel(this.urlUserId); this.user = this.repo.getViewModel(this.urlUserId);
} }
this.canManage = this.operator.hasPerms('users.can_manage'); this.canManage = this.operator.hasPerms(Permission.usersCanManage);
} }
/** /**

View File

@ -4,7 +4,7 @@ import { FormBuilder, FormGroup } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { ViewUser } from '../../models/view-user'; import { ViewUser } from '../../models/view-user';
@ -51,7 +51,7 @@ export class PresenceDetailComponent implements OnInit {
* @returns true if the user is allowed to use this view * @returns true if the user is allowed to use this view
*/ */
public get permission(): boolean { public get permission(): boolean {
return this.operator.hasPerms('users.can_manage') && this._enabledInConfig; return this.operator.hasPerms(Permission.usersCanManage) && this._enabledInConfig;
} }
/** /**

View File

@ -8,7 +8,7 @@ import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { ConstantsService } from 'app/core/core-services/constants.service'; import { ConstantsService } from 'app/core/core-services/constants.service';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
@ -206,23 +206,25 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
public isAllowed(action: string): boolean { public isAllowed(action: string): boolean {
switch (action) { switch (action) {
case 'delete': case 'delete':
return this.operator.hasPerms('users.can_manage') && !this.ownPage; return this.operator.hasPerms(Permission.usersCanManage) && !this.ownPage;
case 'manage': case 'manage':
return this.operator.hasPerms('users.can_manage'); return this.operator.hasPerms(Permission.usersCanManage);
case 'seeName': case 'seeName':
return this.operator.hasPerms('users.can_see_name', 'users.can_manage') || this.ownPage; return this.operator.hasPerms(Permission.usersCanSeeName, Permission.usersCanManage) || this.ownPage;
case 'seeOtherUsers': case 'seeOtherUsers':
return this.operator.hasPerms('users.can_see_name', 'users.can_manage'); return this.operator.hasPerms(Permission.usersCanSeeName, Permission.usersCanManage);
case 'seeExtra': case 'seeExtra':
return this.operator.hasPerms('users.can_see_extra_data', 'users.can_manage'); return this.operator.hasPerms(Permission.usersCanSeeExtraData, Permission.usersCanManage);
case 'seePersonal': case 'seePersonal':
return this.operator.hasPerms('users.can_see_extra_data', 'users.can_manage') || this.ownPage; return (
this.operator.hasPerms(Permission.usersCanSeeExtraData, Permission.usersCanManage) || this.ownPage
);
case 'changePersonal': case 'changePersonal':
return this.operator.hasPerms('users.can_manage') || this.ownPage; return this.operator.hasPerms(Permission.usersCanManage) || this.ownPage;
case 'changePassword': case 'changePassword':
return ( return (
(this.ownPage && this.operator.hasPerms('users.can_change_password')) || (this.ownPage && this.operator.hasPerms(Permission.usersCanChangePassword)) ||
this.operator.hasPerms('users.can_manage') this.operator.hasPerms(Permission.usersCanManage)
); );
default: default:
return false; return false;

View File

@ -8,7 +8,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { PblColumnDefinition } from '@pebula/ngrid'; import { PblColumnDefinition } from '@pebula/ngrid';
import { OperatorService } from 'app/core/core-services/operator.service'; import { OperatorService, Permission } from 'app/core/core-services/operator.service';
import { StorageService } from 'app/core/core-services/storage.service'; import { StorageService } from 'app/core/core-services/storage.service';
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
@ -96,7 +96,7 @@ export class UserListComponent extends BaseListViewComponent<ViewUser> implement
* @returns true if the presence view is available to administrators * @returns true if the presence view is available to administrators
*/ */
public get presenceViewConfigured(): boolean { public get presenceViewConfigured(): boolean {
return this._presenceViewConfigured && this.operator.hasPerms('users.can_manage'); return this._presenceViewConfigured && this.operator.hasPerms(Permission.usersCanManage);
} }
private isVoteWeightActive: boolean; private isVoteWeightActive: boolean;
@ -107,7 +107,7 @@ export class UserListComponent extends BaseListViewComponent<ViewUser> implement
* @returns true if the user should be able to create users * @returns true if the user should be able to create users
*/ */
public get canAddUser(): boolean { public get canAddUser(): boolean {
return this.operator.hasPerms('users.can_manage'); return this.operator.hasPerms(Permission.usersCanManage);
} }
public get showVoteWeight(): boolean { public get showVoteWeight(): boolean {
@ -221,7 +221,7 @@ export class UserListComponent extends BaseListViewComponent<ViewUser> implement
} else if (this.allowSelfSetPresent && this.operator.viewUser === user) { } else if (this.allowSelfSetPresent && this.operator.viewUser === user) {
return false; return false;
} else { } else {
return !this.operator.hasPerms('users.can_manage'); return !this.operator.hasPerms(Permission.usersCanManage);
} }
} }
@ -233,7 +233,7 @@ export class UserListComponent extends BaseListViewComponent<ViewUser> implement
* @param user is an instance of ViewUser. This is the given user, who will be modified. * @param user is an instance of ViewUser. This is the given user, who will be modified.
*/ */
public openEditInfo(user: ViewUser, ev: MouseEvent): void { public openEditInfo(user: ViewUser, ev: MouseEvent): void {
if (this.isMultiSelect || !this.operator.hasPerms('users.can_manage')) { if (this.isMultiSelect || !this.operator.hasPerms(Permission.usersCanManage)) {
return; return;
} }
ev.stopPropagation(); ev.stopPropagation();
@ -437,7 +437,7 @@ export class UserListComponent extends BaseListViewComponent<ViewUser> implement
public setPresent(viewUser: ViewUser): void { public setPresent(viewUser: ViewUser): void {
viewUser.user.is_present = !viewUser.user.is_present; viewUser.user.is_present = !viewUser.user.is_present;
if (this.operator.hasPerms('users.can_manage')) { if (this.operator.hasPerms(Permission.usersCanManage)) {
this.repo.update(viewUser.user, viewUser).catch(this.raiseError); this.repo.update(viewUser.user, viewUser).catch(this.raiseError);
} else if (this.allowSelfSetPresent && this.operator.viewUser === viewUser) { } else if (this.allowSelfSetPresent && this.operator.viewUser === viewUser) {
this.operator.setPresence(viewUser.user.is_present).catch(this.raiseError); this.operator.setPresence(viewUser.user.is_present).catch(this.raiseError);

View File

@ -1,3 +1,4 @@
import { Permission } from 'app/core/core-services/operator.service';
import { Group } from 'app/shared/models/users/group'; import { Group } from 'app/shared/models/users/group';
import { BaseViewModel } from '../../base/base-view-model'; import { BaseViewModel } from '../../base/base-view-model';
@ -12,7 +13,7 @@ export class ViewGroup extends BaseViewModel<Group> implements GroupTitleInforma
return this._model; return this._model;
} }
public hasPermission(perm: string): boolean { public hasPermission(perm: Permission): boolean {
return this.permissions.includes(perm); return this.permissions.includes(perm);
} }
} }

View File

@ -1,6 +1,7 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { Permission } from 'app/core/core-services/operator.service';
import { GroupListComponent } from './components/group-list/group-list.component'; import { GroupListComponent } from './components/group-list/group-list.component';
import { PasswordComponent } from './components/password/password.component'; import { PasswordComponent } from './components/password/password.component';
import { PresenceDetailComponent } from './components/presence-detail/presence-detail.component'; import { PresenceDetailComponent } from './components/presence-detail/presence-detail.component';
@ -13,38 +14,38 @@ const routes: Routes = [
path: '', path: '',
component: UserListComponent, component: UserListComponent,
pathMatch: 'full', pathMatch: 'full',
data: { basePerm: 'users.can_see_name' } data: { basePerm: Permission.usersCanSeeName }
}, },
{ {
path: 'password', path: 'password',
component: PasswordComponent, component: PasswordComponent,
data: { basePerm: 'users.can_change_password' } data: { basePerm: Permission.usersCanChangePassword }
}, },
{ {
path: 'password/:id', path: 'password/:id',
component: PasswordComponent, component: PasswordComponent,
data: { basePerm: 'users.can_manage' } data: { basePerm: Permission.usersCanManage }
}, },
{ {
path: 'new', path: 'new',
component: UserDetailComponent, component: UserDetailComponent,
data: { basePerm: 'users.can_manage' } data: { basePerm: Permission.usersCanManage }
}, },
{ {
path: 'import', path: 'import',
component: UserImportListComponent, component: UserImportListComponent,
data: { basePerm: 'users.can_manage' } data: { basePerm: Permission.usersCanManage }
}, },
{ {
path: 'presence', path: 'presence',
component: PresenceDetailComponent, component: PresenceDetailComponent,
// TODO: 'users_enable_presence_view' missing in permissions // TODO: 'users_enable_presence_view' missing in permissions
data: { basePerm: 'users.can_manage' } data: { basePerm: Permission.usersCanManage }
}, },
{ {
path: 'groups', path: 'groups',
component: GroupListComponent, component: GroupListComponent,
data: { basePerm: 'users.can_manage' } data: { basePerm: Permission.usersCanManage }
}, },
{ {
path: ':id', path: ':id',

View File

@ -1,4 +1,5 @@
import { AppConfig } from '../../core/definitions/app-config'; import { AppConfig } from '../../core/definitions/app-config';
import { Permission } from 'app/core/core-services/operator.service';
import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service';
import { PersonalNoteRepositoryService } from 'app/core/repositories/users/personal-note-repository.service'; import { PersonalNoteRepositoryService } from 'app/core/repositories/users/personal-note-repository.service';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
@ -31,7 +32,7 @@ export const UsersAppConfig: AppConfig = {
displayName: 'Participants', displayName: 'Participants',
icon: 'people', icon: 'people',
weight: 500, weight: 500,
permission: 'users.can_see_name' permission: Permission.usersCanSeeName
} }
] ]
}; };