From fca4154bb50bd2f69ed3c68a99046e76c5419ab7 Mon Sep 17 00:00:00 2001 From: Sean Date: Thu, 14 May 2020 10:12:22 +0200 Subject: [PATCH] Add permission as lookup object Adds a lookup object for a more solid approach to handling permissions. Permissions are now an actual type rather than just a string. --- client/src/app/base.component.ts | 7 ++++ .../core/core-services/auth-guard.service.ts | 4 +- .../core-services/fallback-routes.service.ts | 4 +- .../core/core-services/main-menu.service.ts | 4 +- .../core/core-services/operator.service.ts | 38 +++++++++++++++++-- .../users/group-repository.service.ts | 11 +++--- .../fullscreen-projector.component.ts | 4 +- .../list-view-table.component.ts | 8 +++- .../app/shared/directives/perms.directive.ts | 4 +- client/src/app/shared/models/motions/state.ts | 12 +++++- client/src/app/shared/models/users/group.ts | 3 +- .../app/site/agenda/agenda-routing.module.ts | 13 +++++-- client/src/app/site/agenda/agenda.config.ts | 3 +- .../agenda-list/agenda-list.component.ts | 6 +-- .../list-of-speakers.component.ts | 4 +- .../assignments/assignments-routing.module.ts | 5 ++- .../site/assignments/assignments.config.ts | 3 +- .../assignment-detail.component.ts | 8 ++-- .../assignment-list.component.html | 2 +- .../assignment-list.component.ts | 10 +++-- .../assignment-poll-detail.component.ts | 4 +- .../app/site/common/common-routing.module.ts | 3 +- client/src/app/site/common/common.config.ts | 3 +- .../legal-notice/legal-notice.component.ts | 4 +- .../privacy-policy.component.ts | 4 +- .../components/start/start.component.ts | 4 +- client/src/app/site/config/config.config.ts | 3 +- client/src/app/site/history/history.config.ts | 3 +- .../mediafile-list.component.ts | 18 ++++----- .../app/site/mediafiles/mediafile.config.ts | 3 +- .../mediafiles/mediafiles-routing.module.ts | 3 +- .../category-detail.component.ts | 4 +- .../category-list/category-list.component.ts | 4 +- .../motion-block-detail.component.ts | 3 +- .../motion-block-list.component.ts | 4 +- ...iginal-change-recommendations.component.ts | 4 +- .../motion-poll-detail.component.ts | 4 +- .../motion-poll/motion-poll.component.ts | 4 +- .../workflow-detail.component.ts | 18 ++++----- .../site/motions/motions-routing.module.ts | 26 +++++++------ client/src/app/site/motions/motions.config.ts | 3 +- .../services/local-permissions.service.ts | 34 ++++++++--------- .../services/motion-filter-list.service.ts | 10 +++-- .../projector-detail.component.ts | 4 +- .../projector-list-entry.component.ts | 6 +-- .../projector-list.component.ts | 4 +- .../projector/projector-routing.module.ts | 3 +- .../app/site/projector/projector.config.ts | 3 +- client/src/app/site/site-routing.module.ts | 22 ++++++----- .../topic-detail/topic-detail.component.ts | 6 +-- .../app/site/topics/topics-routing.module.ts | 5 ++- .../group-list/group-list.component.ts | 3 +- .../components/password/password.component.ts | 4 +- .../presence-detail.component.ts | 4 +- .../user-detail/user-detail.component.ts | 22 ++++++----- .../user-list/user-list.component.ts | 12 +++--- .../src/app/site/users/models/view-group.ts | 3 +- .../app/site/users/users-routing.module.ts | 15 ++++---- client/src/app/site/users/users.config.ts | 3 +- 59 files changed, 268 insertions(+), 174 deletions(-) diff --git a/client/src/app/base.component.ts b/client/src/app/base.component.ts index 79a461602..e83b01003 100644 --- a/client/src/app/base.component.ts +++ b/client/src/app/base.component.ts @@ -2,6 +2,8 @@ import { Title } from '@angular/platform-browser'; import { TranslateService } from '@ngx-translate/core'; +import { Permission } from './core/core-services/operator.service'; + /** * Provides functionalities that will be used by most components * 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 */ export abstract class BaseComponent { + /** + * To check permissions in templates using permission.[...] + */ + public permission = Permission; + /** * To manipulate the browser title bar, adds the Suffix "OpenSlides" * diff --git a/client/src/app/core/core-services/auth-guard.service.ts b/client/src/app/core/core-services/auth-guard.service.ts index 770c4c43d..f94b71a25 100644 --- a/client/src/app/core/core-services/auth-guard.service.ts +++ b/client/src/app/core/core-services/auth-guard.service.ts @@ -3,7 +3,7 @@ import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router } from '@ import { FallbackRoutesService } from './fallback-routes.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. @@ -36,7 +36,7 @@ export class AuthGuard implements CanActivate, CanActivateChild { * @param route the route the user wants to navigate to */ public canActivate(route: ActivatedRouteSnapshot): boolean { - const basePerm: string | string[] = route.data.basePerm; + const basePerm: Permission | Permission[] = route.data.basePerm; if (!basePerm) { return true; diff --git a/client/src/app/core/core-services/fallback-routes.service.ts b/client/src/app/core/core-services/fallback-routes.service.ts index 93189e701..58b441ea4 100644 --- a/client/src/app/core/core-services/fallback-routes.service.ts +++ b/client/src/app/core/core-services/fallback-routes.service.ts @@ -1,11 +1,11 @@ import { Injectable } from '@angular/core'; -import { OperatorService } from './operator.service'; +import { OperatorService, Permission } from './operator.service'; export interface AuthGuardFallbackEntry { route: string; weight: number; - permission: string; + permission: Permission; } /** diff --git a/client/src/app/core/core-services/main-menu.service.ts b/client/src/app/core/core-services/main-menu.service.ts index 783055f20..fd2931d31 100644 --- a/client/src/app/core/core-services/main-menu.service.ts +++ b/client/src/app/core/core-services/main-menu.service.ts @@ -2,6 +2,8 @@ import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; +import { Permission } from './operator.service'; + /** * This represents one entry in the main menu */ @@ -28,7 +30,7 @@ export interface MainMenuEntry { /** * The permission to see the entry. */ - permission: string; + permission: Permission; } /** diff --git a/client/src/app/core/core-services/operator.service.ts b/client/src/app/core/core-services/operator.service.ts index 7d6b407aa..822a5f855 100644 --- a/client/src/app/core/core-services/operator.service.ts +++ b/client/src/app/core/core-services/operator.service.ts @@ -21,7 +21,39 @@ import { UserRepositoryService } from '../repositories/users/user-repository.ser * Permissions on the client are just strings. This makes clear, that * 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. @@ -394,12 +426,12 @@ export class OperatorService implements OnAfterAppsLoaded { } else { // Anonymous or users in the default group. if (!this.user || this.user.groups_id.length === 0) { - const defaultGroup = this.DS.get('users/group', 1); + const defaultGroup: Group = this.DS.get('users/group', 1); if (defaultGroup && defaultGroup.permissions instanceof Array) { this.permissions = defaultGroup.permissions; } } else { - const permissionSet = new Set(); + const permissionSet = new Set(); this.DS.getMany(Group, this.user.groups_id).forEach(group => { group.permissions.forEach(permission => { permissionSet.add(permission); diff --git a/client/src/app/core/repositories/users/group-repository.service.ts b/client/src/app/core/repositories/users/group-repository.service.ts index b7cc1cfde..a6ea8ce4d 100644 --- a/client/src/app/core/repositories/users/group-repository.service.ts +++ b/client/src/app/core/repositories/users/group-repository.service.ts @@ -5,6 +5,7 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; 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 { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { Group } from 'app/shared/models/users/group'; @@ -18,9 +19,9 @@ import { DataStoreService } from '../../core-services/data-store.service'; /** * Shape of a permission */ -interface Permission { +interface PermDefinition { display_name: string; - value: string; + value: Permission; } /** @@ -28,7 +29,7 @@ interface Permission { */ export interface AppPermissions { name: string; - permissions: Permission[]; + permissions: PermDefinition[]; } /** @@ -87,7 +88,7 @@ export class GroupRepositoryService extends BaseRepository { + public async togglePerm(group: ViewGroup, perm: Permission): Promise { const set = !group.permissions.includes(perm); return await this.http.post(`/rest/${group.collectionString}/${group.id}/set_permission/`, { perm: perm, @@ -102,7 +103,7 @@ export class GroupRepositoryService extends BaseRepository { - this.canSeeProjector = this.operator.hasPerms('projector.can_see'); + this.canSeeProjector = this.operator.hasPerms(Permission.coreCanSeeProjector); }); } diff --git a/client/src/app/shared/components/list-view-table/list-view-table.component.ts b/client/src/app/shared/components/list-view-table/list-view-table.component.ts index d2741ec68..bbe376d74 100644 --- a/client/src/app/shared/components/list-view-table/list-view-table.component.ts +++ b/client/src/app/shared/components/list-view-table/list-view-table.component.ts @@ -286,7 +286,7 @@ export class ListViewTableComponent { public name: string; public recommendation_label: string; public css_class: string; - public restriction: string[]; + public restriction: Restriction[]; public allow_support: boolean; public allow_create_poll: boolean; public allow_submitter_edit: boolean; diff --git a/client/src/app/shared/models/users/group.ts b/client/src/app/shared/models/users/group.ts index 14dbbddfc..894276b2f 100644 --- a/client/src/app/shared/models/users/group.ts +++ b/client/src/app/shared/models/users/group.ts @@ -1,3 +1,4 @@ +import { Permission } from 'app/core/core-services/operator.service'; import { BaseModel } from '../base/base-model'; /** @@ -9,7 +10,7 @@ export class Group extends BaseModel { public id: number; public name: string; - public permissions: string[]; + public permissions: Permission[]; public constructor(input?: Partial) { super(Group.COLLECTIONSTRING, input); diff --git a/client/src/app/site/agenda/agenda-routing.module.ts b/client/src/app/site/agenda/agenda-routing.module.ts index b2ad36c3a..fde7b8533 100644 --- a/client/src/app/site/agenda/agenda-routing.module.ts +++ b/client/src/app/site/agenda/agenda-routing.module.ts @@ -3,21 +3,26 @@ import { RouterModule, Routes } from '@angular/router'; import { AgendaListComponent } from './components/agenda-list/agenda-list.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 { TopicImportListComponent } from 'app/site/topics/components/topic-import-list/topic-import-list.component'; import { ListOfSpeakersComponent } from './components/list-of-speakers/list-of-speakers.component'; const routes: Routes = [ { 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', component: AgendaSortComponent, 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/:id', 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: Permission.agendaCanSeeListOfSpeakers } + } ]; @NgModule({ diff --git a/client/src/app/site/agenda/agenda.config.ts b/client/src/app/site/agenda/agenda.config.ts index 4d212b251..1d68844dd 100644 --- a/client/src/app/site/agenda/agenda.config.ts +++ b/client/src/app/site/agenda/agenda.config.ts @@ -1,4 +1,5 @@ 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 { ListOfSpeakersRepositoryService } from 'app/core/repositories/agenda/list-of-speakers-repository.service'; import { ListOfSpeakers } from 'app/shared/models/agenda/list-of-speakers'; @@ -22,7 +23,7 @@ export const AgendaAppConfig: AppConfig = { displayName: 'Agenda', icon: 'today', // 'calendar_today' aligns wrong! weight: 200, - permission: 'agenda.can_see' + permission: Permission.agendaCanSee } ] }; diff --git a/client/src/app/site/agenda/components/agenda-list/agenda-list.component.ts b/client/src/app/site/agenda/components/agenda-list/agenda-list.component.ts index 57c462c93..bf0547a04 100644 --- a/client/src/app/site/agenda/components/agenda-list/agenda-list.component.ts +++ b/client/src/app/site/agenda/components/agenda-list/agenda-list.component.ts @@ -11,7 +11,7 @@ import { PblColumnDefinition } from '@pebula/ngrid'; import { AgendaCsvExportService } from '../../services/agenda-csv-export.service'; import { AgendaFilterListService } from '../../services/agenda-filter-list.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 { PdfDocumentService } from 'app/core/pdf-services/pdf-document.service'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; @@ -56,7 +56,7 @@ export class AgendaListComponent extends BaseListViewComponent impleme * @returns true if the operator can manage agenda items */ public get canManage(): boolean { - return this.operator.hasPerms('agenda.can_manage'); + return this.operator.hasPerms(Permission.agendaCanManage); } public itemListSlide: ProjectorElementBuildDeskriptor = { @@ -92,7 +92,7 @@ export class AgendaListComponent extends BaseListViewComponent impleme public restrictedColumns: ColumnRestriction[] = [ { columnName: 'menu', - permission: 'agenda.can_manage' + permission: Permission.agendaCanManage } ]; diff --git a/client/src/app/site/agenda/components/list-of-speakers/list-of-speakers.component.ts b/client/src/app/site/agenda/components/list-of-speakers/list-of-speakers.component.ts index 33d30d5c7..86dff33df 100644 --- a/client/src/app/site/agenda/components/list-of-speakers/list-of-speakers.component.ts +++ b/client/src/app/site/agenda/components/list-of-speakers/list-of-speakers.component.ts @@ -8,7 +8,7 @@ import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, Subscription } from 'rxjs'; 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 { ProjectorRepositoryService } from 'app/core/repositories/projector/projector-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 { - return this.operator.hasPerms('agenda.can_manage_list_of_speakers'); + return this.operator.hasPerms(Permission.agendaCanManageListOfSpeakers); } /** diff --git a/client/src/app/site/assignments/assignments-routing.module.ts b/client/src/app/site/assignments/assignments-routing.module.ts index ef4dffdf9..df9dcfbcd 100644 --- a/client/src/app/site/assignments/assignments-routing.module.ts +++ b/client/src/app/site/assignments/assignments-routing.module.ts @@ -1,14 +1,15 @@ import { NgModule } from '@angular/core'; 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 { AssignmentListComponent } from './components/assignment-list/assignment-list.component'; import { AssignmentPollDetailComponent } from './components/assignment-poll-detail/assignment-poll-detail.component'; const routes: Routes = [ { path: '', component: AssignmentListComponent, pathMatch: 'full' }, - { path: 'new', component: AssignmentDetailComponent, data: { basePerm: 'assignments.can_manage' } }, - { path: ':id', component: AssignmentDetailComponent, data: { basePerm: 'assignments.can_see' } }, + { path: 'new', component: AssignmentDetailComponent, data: { basePerm: Permission.assignmentsCanManage } }, + { path: ':id', component: AssignmentDetailComponent, data: { basePerm: Permission.assignmentsCanSee } }, { path: 'polls', children: [{ path: ':id', component: AssignmentPollDetailComponent }] } ]; diff --git a/client/src/app/site/assignments/assignments.config.ts b/client/src/app/site/assignments/assignments.config.ts index 78aa5bf01..586141d9b 100644 --- a/client/src/app/site/assignments/assignments.config.ts +++ b/client/src/app/site/assignments/assignments.config.ts @@ -1,4 +1,5 @@ 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 { AssignmentPollRepositoryService } from 'app/core/repositories/assignments/assignment-poll-repository.service'; import { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service'; @@ -43,7 +44,7 @@ export const AssignmentsAppConfig: AppConfig = { displayName: 'Elections', icon: 'how_to_vote', weight: 400, - permission: 'assignments.can_see' + permission: Permission.assignmentsCanSee } ] }; diff --git a/client/src/app/site/assignments/components/assignment-detail/assignment-detail.component.ts b/client/src/app/site/assignments/components/assignment-detail/assignment-detail.component.ts index 4ed9f1a10..199757ebb 100644 --- a/client/src/app/site/assignments/components/assignment-detail/assignment-detail.component.ts +++ b/client/src/app/site/assignments/components/assignment-detail/assignment-detail.component.ts @@ -7,7 +7,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; 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 { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-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 */ public hasPerms(operation: string): boolean { - const isManager = this.operator.hasPerms('assignments.can_manage'); + const isManager = this.operator.hasPerms(Permission.assignmentsCanManage); switch (operation) { case 'addSelf': if (isManager && !this.assignment.isFinished) { @@ -237,7 +237,7 @@ export class AssignmentDetailComponent extends BaseViewComponent implements OnIn } else { return ( this.assignment.isSearchingForCandidates && - this.operator.hasPerms('assignments.can_nominate_self') && + this.operator.hasPerms(Permission.assignmentsCanNominateSelf) && !this.assignment.isFinished ); } @@ -247,7 +247,7 @@ export class AssignmentDetailComponent extends BaseViewComponent implements OnIn } else { return ( this.assignment.isSearchingForCandidates && - this.operator.hasPerms('assignments.can_nominate_other') && + this.operator.hasPerms(Permission.assignmentsCanNominateOther) && !this.assignment.isFinished ); } diff --git a/client/src/app/site/assignments/components/assignment-list/assignment-list.component.html b/client/src/app/site/assignments/components/assignment-list/assignment-list.component.html index 60466bd7d..08191b5fc 100644 --- a/client/src/app/site/assignments/components/assignment-list/assignment-list.component.html +++ b/client/src/app/site/assignments/components/assignment-list/assignment-list.component.html @@ -1,5 +1,5 @@ diff --git a/client/src/app/site/assignments/components/assignment-list/assignment-list.component.ts b/client/src/app/site/assignments/components/assignment-list/assignment-list.component.ts index 5af62dfad..aa60076f3 100644 --- a/client/src/app/site/assignments/components/assignment-list/assignment-list.component.ts +++ b/client/src/app/site/assignments/components/assignment-list/assignment-list.component.ts @@ -6,7 +6,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; 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 { AssignmentRepositoryService } from 'app/core/repositories/assignments/assignment-repository.service'; import { PromptService } from 'app/core/ui-services/prompt.service'; @@ -56,6 +56,10 @@ export class AssignmentListComponent extends BaseListViewComponent * @return true if the user can manage media files */ 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 */ public get canAccessFileMenu(): boolean { return ( - this.operator.hasPerms('core.can_manage_projector') || - this.operator.hasPerms('agenda.can_see_list_of_speakers') || - this.operator.hasPerms('core.can_manage_logos_and_fonts') || + this.operator.hasPerms(Permission.coreCanManageProjector) || + this.operator.hasPerms(Permission.agendaCanSeeListOfSpeakers) || + this.operator.hasPerms(Permission.coreCanManageLogosAndFonts) || this.canEdit ); } @@ -253,10 +253,10 @@ export class MediafileListComponent extends BaseListViewComponent */ public showFileMenu(file: ViewMediafile): boolean { return ( - this.operator.hasPerms('agenda.can_see_list_of_speakers') || - (file.isProjectable() && this.operator.hasPerms('core.can_manage_projector')) || - (file.isFont() && this.operator.hasPerms('core.can_manage_logos_and_fonts')) || - (file.isImage() && this.operator.hasPerms('core.can_manage_logos_and_fonts')) || + this.operator.hasPerms(Permission.agendaCanSeeListOfSpeakers) || + (file.isProjectable() && this.operator.hasPerms(Permission.coreCanManageProjector)) || + (file.isFont() && this.operator.hasPerms(Permission.coreCanManageLogosAndFonts)) || + (file.isImage() && this.operator.hasPerms(Permission.coreCanManageLogosAndFonts)) || this.canEdit ); } diff --git a/client/src/app/site/mediafiles/mediafile.config.ts b/client/src/app/site/mediafiles/mediafile.config.ts index 732eec303..aab402676 100644 --- a/client/src/app/site/mediafiles/mediafile.config.ts +++ b/client/src/app/site/mediafiles/mediafile.config.ts @@ -1,4 +1,5 @@ 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 { Mediafile } from '../../shared/models/mediafiles/mediafile'; import { ViewMediafile } from './models/view-mediafile'; @@ -20,7 +21,7 @@ export const MediafileAppConfig: AppConfig = { displayName: 'Files', icon: 'attach_file', weight: 600, - permission: 'mediafiles.can_see' + permission: Permission.mediafilesCanSee } ] }; diff --git a/client/src/app/site/mediafiles/mediafiles-routing.module.ts b/client/src/app/site/mediafiles/mediafiles-routing.module.ts index 1d75a342b..b8e12354a 100644 --- a/client/src/app/site/mediafiles/mediafiles-routing.module.ts +++ b/client/src/app/site/mediafiles/mediafiles-routing.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core'; 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 { MediafileListComponent } from './components/mediafile-list/mediafile-list.component'; @@ -17,7 +18,7 @@ const routes: Routes = [ }, { path: 'upload', - data: { basePerm: 'mediafiles.can_manage' }, + data: { basePerm: Permission.mediafilesCanManage }, children: [{ path: '**', component: MediaUploadComponent }], pathMatch: 'prefix' } diff --git a/client/src/app/site/motions/modules/category/components/category-detail/category-detail.component.ts b/client/src/app/site/motions/modules/category/components/category-detail/category-detail.component.ts index 2e65218ef..ac86f9209 100644 --- a/client/src/app/site/motions/modules/category/components/category-detail/category-detail.component.ts +++ b/client/src/app/site/motions/modules/category/components/category-detail/category-detail.component.ts @@ -8,7 +8,7 @@ import { ActivatedRoute, Router } from '@angular/router'; 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 { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.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 */ public get canEdit(): boolean { - return this.operator.hasPerms('motions.can_manage'); + return this.operator.hasPerms(Permission.motionsCanManage); } /** diff --git a/client/src/app/site/motions/modules/category/components/category-list/category-list.component.ts b/client/src/app/site/motions/modules/category/components/category-list/category-list.component.ts index b7b81ee2d..eace73246 100644 --- a/client/src/app/site/motions/modules/category/components/category-list/category-list.component.ts +++ b/client/src/app/site/motions/modules/category/components/category-list/category-list.component.ts @@ -7,7 +7,7 @@ import { Title } from '@angular/platform-browser'; import { TranslateService } from '@ngx-translate/core'; 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 { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service'; import { infoDialogSettings } from 'app/shared/utils/dialog-settings'; @@ -56,7 +56,7 @@ export class CategoryListComponent extends BaseListViewComponent i * @returns true if the user may alter motions or their metadata */ public get canEdit(): boolean { - return this.operator.hasPerms('motions.can_manage'); + return this.operator.hasPerms(Permission.motionsCanManage); } /** diff --git a/client/src/app/site/motions/modules/motion-block/components/motion-block-detail/motion-block-detail.component.ts b/client/src/app/site/motions/modules/motion-block/components/motion-block-detail/motion-block-detail.component.ts index ed54bffa4..bf0d5ccaa 100644 --- a/client/src/app/site/motions/modules/motion-block/components/motion-block-detail/motion-block-detail.component.ts +++ b/client/src/app/site/motions/modules/motion-block/components/motion-block-detail/motion-block-detail.component.ts @@ -8,6 +8,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { PblColumnDefinition } from '@pebula/ngrid'; +import { Permission } from 'app/core/core-services/operator.service'; import { StorageService } from 'app/core/core-services/storage.service'; import { ItemRepositoryService } from 'app/core/repositories/agenda/item-repository.service'; import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service'; @@ -74,7 +75,7 @@ export class MotionBlockDetailComponent extends BaseListViewComponent activate / deactivate editing functionality */ private onPermissionsChanged(): void { - if (this.operator.hasPerms('motions.can_manage')) { + if (this.operator.hasPerms(Permission.motionsCanManage)) { this.can_manage = true; if (this.selectedFrom === null) { this.startCreating(); diff --git a/client/src/app/site/motions/modules/motion-poll/motion-poll-detail/motion-poll-detail.component.ts b/client/src/app/site/motions/modules/motion-poll/motion-poll-detail/motion-poll-detail.component.ts index cdd6072d8..a4c6c6887 100644 --- a/client/src/app/site/motions/modules/motion-poll/motion-poll-detail/motion-poll-detail.component.ts +++ b/client/src/app/site/motions/modules/motion-poll/motion-poll-detail/motion-poll-detail.component.ts @@ -6,7 +6,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; 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 { MotionVoteRepositoryService } from 'app/core/repositories/motions/motion-vote-repository.service'; import { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; @@ -78,6 +78,6 @@ export class MotionPollDetailComponent extends BasePollDetailComponent r); const restrictionIndex = restrictions.findIndex(r => r === restriction); diff --git a/client/src/app/site/motions/motions-routing.module.ts b/client/src/app/site/motions/motions-routing.module.ts index ba62335c2..0159b5784 100644 --- a/client/src/app/site/motions/motions-routing.module.ts +++ b/client/src/app/site/motions/motions-routing.module.ts @@ -1,6 +1,8 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { Permission } from 'app/core/core-services/operator.service'; + const routes: Routes = [ { path: '', @@ -10,13 +12,13 @@ const routes: Routes = [ { path: 'import', loadChildren: () => import('./modules/motion-import/motion-import.module').then(m => m.MotionImportModule), - data: { basePerm: 'motions.can_manage' } + data: { basePerm: Permission.motionsCanManage } }, { path: 'statute-paragraphs', loadChildren: () => import('./modules/statute-paragraph/statute-paragraph.module').then(m => m.StatuteParagraphModule), - data: { basePerm: 'motions.can_manage' } + data: { basePerm: Permission.motionsCanManage } }, { path: 'comment-section', @@ -24,54 +26,54 @@ const routes: Routes = [ import('./modules/motion-comment-section/motion-comment-section.module').then( m => m.MotionCommentSectionModule ), - data: { basePerm: 'motions.can_manage' } + data: { basePerm: Permission.motionsCanManage } }, { path: 'call-list', loadChildren: () => import('./modules/call-list/call-list.module').then(m => m.CallListModule), - data: { basePerm: 'motions.can_manage' } + data: { basePerm: Permission.motionsCanManage } }, { path: 'category', loadChildren: () => import('./modules/category/category.module').then(m => m.CategoryModule), - data: { basePerm: 'motions.can_see' } + data: { basePerm: Permission.motionsCanSee } }, { path: 'blocks', loadChildren: () => import('./modules/motion-block/motion-block.module').then(m => m.MotionBlockModule), - data: { basePerm: 'motions.can_see' } + data: { basePerm: Permission.motionsCanSee } }, { path: 'workflow', loadChildren: () => import('./modules/motion-workflow/motion-workflow.module').then(m => m.MotionWorkflowModule), - data: { basePerm: 'motions.can_manage' } + data: { basePerm: Permission.motionsCanManage } }, { path: 'new', loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule), - data: { basePerm: 'motions.can_create' } + data: { basePerm: Permission.motionsCanCreate } }, { path: 'new-amendment', loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule), - data: { basePerm: 'motions.can_create_amendments' } + data: { basePerm: Permission.motionsCanCreateAmendments } }, { path: 'amendments', loadChildren: () => import('./modules/amendment-list/amendment-list.module').then(m => m.AmendmentListModule), - data: { basePerm: 'motions.can_see' } + data: { basePerm: Permission.motionsCanSee } }, { path: 'polls', loadChildren: () => import('./modules/motion-poll/motion-poll.module').then(m => m.MotionPollModule), - data: { basePerm: 'motions.can_see' } + data: { basePerm: Permission.motionsCanSee } }, { path: ':id', loadChildren: () => import('./modules/motion-detail/motion-detail.module').then(m => m.MotionDetailModule), runGuardsAndResolvers: 'paramsChange', - data: { basePerm: 'motions.can_see' } + data: { basePerm: Permission.motionsCanSee } } ]; diff --git a/client/src/app/site/motions/motions.config.ts b/client/src/app/site/motions/motions.config.ts index e2cad9b83..13474377a 100644 --- a/client/src/app/site/motions/motions.config.ts +++ b/client/src/app/site/motions/motions.config.ts @@ -1,4 +1,5 @@ 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 { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service'; import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service'; @@ -90,7 +91,7 @@ export const MotionsAppConfig: AppConfig = { displayName: 'Motions', icon: 'assignment', weight: 300, - permission: 'motions.can_see' + permission: Permission.motionsCanSee } ] }; diff --git a/client/src/app/site/motions/services/local-permissions.service.ts b/client/src/app/site/motions/services/local-permissions.service.ts index 95d893e2c..64c277929 100644 --- a/client/src/app/site/motions/services/local-permissions.service.ts +++ b/client/src/app/site/motions/services/local-permissions.service.ts @@ -1,6 +1,6 @@ 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 { ViewMotion } from '../models/view-motion'; @@ -30,7 +30,7 @@ export class LocalPermissionsService { * in mobile mode */ 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 { switch (action) { case 'create': { - return this.operator.hasPerms('motions.can_create'); + return this.operator.hasPerms(Permission.motionsCanCreate); } case 'support': { if (!motion || !motion.state) { return false; } return ( - this.operator.hasPerms('motions.can_support') && + this.operator.hasPerms(Permission.motionsCanSupport) && this.configMinSupporters > 0 && motion.state && motion.state.allow_support && @@ -90,8 +90,8 @@ export class LocalPermissionsService { return false; } return ( - (this.operator.hasPerms('motions.can_manage') || - this.operator.hasPerms('motions.can_manage_metadata')) && + (this.operator.hasPerms(Permission.motionsCanManage) || + this.operator.hasPerms(Permission.motionsCanManageMetadata)) && motion.state && motion.state.allow_create_poll ); @@ -103,7 +103,7 @@ export class LocalPermissionsService { return false; } return ( - this.operator.hasPerms('motions.can_manage') || + this.operator.hasPerms(Permission.motionsCanManage) || (motion.state && motion.state.allow_submitter_edit && motion.submitters && @@ -113,14 +113,14 @@ export class LocalPermissionsService { ); } case 'update_submitters': { - return this.operator.hasPerms('motions.can_manage'); + return this.operator.hasPerms(Permission.motionsCanManage); } case 'delete': { if (!motion) { return false; } return ( - this.operator.hasPerms('motions.can_manage') && + this.operator.hasPerms(Permission.motionsCanManage) && motion.state && motion.state.allow_submitter_edit && motion.submitters && @@ -135,8 +135,8 @@ export class LocalPermissionsService { return false; } return ( - this.operator.hasPerms('motions.can_manage') || - this.operator.hasPerms('motions.can_manage_metadata') || + this.operator.hasPerms(Permission.motionsCanManage) || + this.operator.hasPerms(Permission.motionsCanManageMetadata) || (motion.state && motion.state.allow_submitter_edit && !this.operator.isAnonymous && @@ -146,8 +146,8 @@ export class LocalPermissionsService { } case 'change_metadata': { return ( - this.operator.hasPerms('motions.can_manage') || - this.operator.hasPerms('motions.can_manage_metadata') + this.operator.hasPerms(Permission.motionsCanManage) || + this.operator.hasPerms(Permission.motionsCanManageMetadata) ); } case 'can_create_amendments': { @@ -155,19 +155,19 @@ export class LocalPermissionsService { return false; } return ( - this.operator.hasPerms('motions.can_create_amendments') && + this.operator.hasPerms(Permission.motionsCanCreateAmendments) && this.amendmentEnabled && (!motion.parent_id || (motion.parent_id && this.amendmentOfAmendment)) ); } case 'can_manage_metadata': { return ( - this.operator.hasPerms('motions.can_manage') && - this.operator.hasPerms('motions.can_manage_metadata') + this.operator.hasPerms(Permission.motionsCanManage) && + this.operator.hasPerms(Permission.motionsCanManageMetadata) ); } case 'manage': { - return this.operator.hasPerms('motions.can_manage'); + return this.operator.hasPerms(Permission.motionsCanManage); } default: { return false; diff --git a/client/src/app/site/motions/services/motion-filter-list.service.ts b/client/src/app/site/motions/services/motion-filter-list.service.ts index 0c432ac0c..c1c0e980f 100644 --- a/client/src/app/site/motions/services/motion-filter-list.service.ts +++ b/client/src/app/site/motions/services/motion-filter-list.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; 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 { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service'; import { MotionBlockRepositoryService } from 'app/core/repositories/motions/motion-block-repository.service'; @@ -17,6 +17,7 @@ import { OsFilterOptions } from 'app/core/ui-services/base-filter-list.service'; import { ConfigService } from 'app/core/ui-services/config.service'; +import { Restriction } from 'app/shared/models/motions/state'; import { AmendmentType } from '../motions.constants'; import { ViewMotion } from '../models/view-motion'; @@ -234,7 +235,7 @@ export class MotionFilterListService extends BaseFilterListService { ]; // 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); } @@ -276,7 +277,10 @@ export class MotionFilterListService extends BaseFilterListService { for (const state of workflow.states) { // 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)) { // sort final and non final states state.isFinalState ? finalStates.push(state.id) : nonFinalStates.push(state.id); diff --git a/client/src/app/site/projector/components/projector-detail/projector-detail.component.ts b/client/src/app/site/projector/components/projector-detail/projector-detail.component.ts index cb5a4a2db..bc2c796f7 100644 --- a/client/src/app/site/projector/components/projector-detail/projector-detail.component.ts +++ b/client/src/app/site/projector/components/projector-detail/projector-detail.component.ts @@ -8,7 +8,7 @@ import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; 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 { CountdownRepositoryService } from 'app/core/repositories/projector/countdown-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 */ public canManage(): boolean { - return this.opertator.hasPerms('core.can_manage_projector'); + return this.opertator.hasPerms(Permission.coreCanManageProjector); } /** diff --git a/client/src/app/site/projector/components/projector-list-entry/projector-list-entry.component.ts b/client/src/app/site/projector/components/projector-list-entry/projector-list-entry.component.ts index 49305e5df..bc02a1037 100644 --- a/client/src/app/site/projector/components/projector-list-entry/projector-list-entry.component.ts +++ b/client/src/app/site/projector/components/projector-list-entry/projector-list-entry.component.ts @@ -5,7 +5,7 @@ import { Title } from '@angular/platform-browser'; 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 { PromptService } from 'app/core/ui-services/prompt.service'; import { largeDialogSettings } from 'app/shared/utils/dialog-settings'; @@ -36,7 +36,7 @@ export class ProjectorListEntryComponent extends BaseViewComponent implements On } public get projectionTarget(): '_blank' | '_self' { - if (this.operator.hasPerms('core.can_manage_projector')) { + if (this.operator.hasPerms(Permission.coreCanManageProjector)) { return '_self'; } else { return '_blank'; @@ -94,7 +94,7 @@ export class ProjectorListEntryComponent extends BaseViewComponent implements On * and not the detail view */ public getDetailLink(): string { - if (this.operator.hasPerms('core.can_can_manage_projector')) { + if (this.operator.hasPerms(Permission.coreCanManageProjector)) { return `/projectors/detail/${this.projector.id}`; } else { return `/projector/${this.projector.id}`; diff --git a/client/src/app/site/projector/components/projector-list/projector-list.component.ts b/client/src/app/site/projector/components/projector-list/projector-list.component.ts index 2f8e5e179..0f0003ccb 100644 --- a/client/src/app/site/projector/components/projector-list/projector-list.component.ts +++ b/client/src/app/site/projector/components/projector-list/projector-list.component.ts @@ -16,7 +16,7 @@ import { Title } from '@angular/platform-browser'; import { TranslateService } from '@ngx-translate/core'; 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 { Projector } from 'app/shared/models/core/projector'; 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 */ public get canManage(): boolean { - return this.operator.hasPerms('core.can_manage_projector'); + return this.operator.hasPerms(Permission.coreCanManageProjector); } /** diff --git a/client/src/app/site/projector/projector-routing.module.ts b/client/src/app/site/projector/projector-routing.module.ts index ff6f28d1e..d3f5a372a 100644 --- a/client/src/app/site/projector/projector-routing.module.ts +++ b/client/src/app/site/projector/projector-routing.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core'; 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 { ProjectorListComponent } from './components/projector-list/projector-list.component'; @@ -13,7 +14,7 @@ const routes: Routes = [ { path: 'detail/:id', component: ProjectorDetailComponent, - data: { basePerm: 'core.can_can_manage_projector' } + data: { basePerm: Permission.coreCanManageProjector } } ]; diff --git a/client/src/app/site/projector/projector.config.ts b/client/src/app/site/projector/projector.config.ts index 8f5110e34..8eb8f05e3 100644 --- a/client/src/app/site/projector/projector.config.ts +++ b/client/src/app/site/projector/projector.config.ts @@ -1,4 +1,5 @@ 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 { ProjectionDefaultRepositoryService } from 'app/core/repositories/projector/projection-default-repository.service'; import { ProjectorMessageRepositoryService } from 'app/core/repositories/projector/projector-message-repository.service'; @@ -42,7 +43,7 @@ export const ProjectorAppConfig: AppConfig = { displayName: 'Projector', icon: 'videocam', weight: 700, - permission: 'core.can_see_projector' + permission: Permission.coreCanSeeProjector } ] }; diff --git a/client/src/app/site/site-routing.module.ts b/client/src/app/site/site-routing.module.ts index 9b33d7d2e..78592596e 100644 --- a/client/src/app/site/site-routing.module.ts +++ b/client/src/app/site/site-routing.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core'; 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 { SiteComponent } from './site.component'; @@ -21,32 +22,32 @@ const routes: Routes = [ { path: 'agenda', loadChildren: () => import('./agenda/agenda.module').then(m => m.AgendaModule), - data: { basePerm: 'agenda.can_see' } + data: { basePerm: Permission.agendaCanSee } }, { path: 'topics', loadChildren: () => import('./topics/topics.module').then(m => m.TopicsModule), - data: { basePerm: 'agenda.can_see' } + data: { basePerm: Permission.agendaCanSee } }, { path: 'assignments', loadChildren: () => import('./assignments/assignments.module').then(m => m.AssignmentsModule), - data: { basePerm: 'assignments.can_see' } + data: { basePerm: Permission.assignmentsCanSee } }, { path: 'mediafiles', loadChildren: () => import('./mediafiles/mediafiles.module').then(m => m.MediafilesModule), - data: { basePerm: 'mediafiles.can_see' } + data: { basePerm: Permission.mediafilesCanSee } }, { path: 'motions', loadChildren: () => import('./motions/motions.module').then(m => m.MotionsModule), - data: { basePerm: 'motions.can_see' } + data: { basePerm: Permission.motionsCanSee } }, { path: 'settings', loadChildren: () => import('./config/config.module').then(m => m.ConfigModule), - data: { basePerm: 'core.can_manage_config' } + data: { basePerm: Permission.coreCanManageConfig } }, { path: 'users', @@ -57,22 +58,23 @@ const routes: Routes = [ { path: 'tags', loadChildren: () => import('./tags/tag.module').then(m => m.TagModule), - data: { basePerm: 'core.can_manage_tags' } + data: { basePerm: Permission.coreCanManageTags } }, { path: 'history', loadChildren: () => import('./history/history.module').then(m => m.HistoryModule), - data: { basePerm: 'core.can_see_history' } + data: { basePerm: Permission.coreCanSeeHistory } }, { path: 'projectors', loadChildren: () => import('./projector/projector.module').then(m => m.ProjectorModule), - data: { basePerm: 'core.can_see_projector' } + data: { basePerm: Permission.coreCanSeeProjector } }, { path: 'polls', 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] diff --git a/client/src/app/site/topics/components/topic-detail/topic-detail.component.ts b/client/src/app/site/topics/components/topic-detail/topic-detail.component.ts index 0249e7c07..a731e72ac 100644 --- a/client/src/app/site/topics/components/topic-detail/topic-detail.component.ts +++ b/client/src/app/site/topics/components/topic-detail/topic-detail.component.ts @@ -7,7 +7,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; 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 { TopicRepositoryService } from 'app/core/repositories/topics/topic-repository.service'; import { PromptService } from 'app/core/ui-services/prompt.service'; @@ -217,9 +217,9 @@ export class TopicDetailComponent extends BaseViewComponent { public isAllowed(action: string): boolean { switch (action) { case 'see': - return this.operator.hasPerms('agenda.can_see'); + return this.operator.hasPerms(Permission.agendaCanSee); case 'edit': - return this.operator.hasPerms('agenda.can_manage'); + return this.operator.hasPerms(Permission.agendaCanManage); case 'default': return false; } diff --git a/client/src/app/site/topics/topics-routing.module.ts b/client/src/app/site/topics/topics-routing.module.ts index ab64d8cdc..5806d1394 100644 --- a/client/src/app/site/topics/topics-routing.module.ts +++ b/client/src/app/site/topics/topics-routing.module.ts @@ -1,11 +1,12 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { Permission } from 'app/core/core-services/operator.service'; import { TopicDetailComponent } from './components/topic-detail/topic-detail.component'; const routes: Routes = [ - { path: 'new', component: TopicDetailComponent, data: { basePerm: 'agenda.can_manage' } }, - { path: ':id', component: TopicDetailComponent, data: { basePerm: 'agenda.can_see' } } + { path: 'new', component: TopicDetailComponent, data: { basePerm: Permission.agendaCanManage } }, + { path: ':id', component: TopicDetailComponent, data: { basePerm: Permission.agendaCanSee } } ]; @NgModule({ diff --git a/client/src/app/site/users/components/group-list/group-list.component.ts b/client/src/app/site/users/components/group-list/group-list.component.ts index 19f074ab4..0ade87020 100644 --- a/client/src/app/site/users/components/group-list/group-list.component.ts +++ b/client/src/app/site/users/components/group-list/group-list.component.ts @@ -7,6 +7,7 @@ import { Title } from '@angular/platform-browser'; 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 { PromptService } from 'app/core/ui-services/prompt.service'; import { Group } from 'app/shared/models/users/group'; @@ -158,7 +159,7 @@ export class GroupListComponent extends BaseViewComponent implements OnInit { * @param viewGroup * @param perm */ - public togglePerm(viewGroup: ViewGroup, perm: string): void { + public togglePerm(viewGroup: ViewGroup, perm: Permission): void { this.repo.togglePerm(viewGroup, perm); } diff --git a/client/src/app/site/users/components/password/password.component.ts b/client/src/app/site/users/components/password/password.component.ts index b640d1b4a..935415ece 100644 --- a/client/src/app/site/users/components/password/password.component.ts +++ b/client/src/app/site/users/components/password/password.component.ts @@ -6,7 +6,7 @@ import { ActivatedRoute, Router } from '@angular/router'; 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 { BaseViewComponent } from 'app/site/base/base-view'; import { ViewUser } from '../../models/view-user'; @@ -120,7 +120,7 @@ export class PasswordComponent extends BaseViewComponent implements OnInit { } else { this.user = this.repo.getViewModel(this.urlUserId); } - this.canManage = this.operator.hasPerms('users.can_manage'); + this.canManage = this.operator.hasPerms(Permission.usersCanManage); } /** diff --git a/client/src/app/site/users/components/presence-detail/presence-detail.component.ts b/client/src/app/site/users/components/presence-detail/presence-detail.component.ts index 7a48e437a..7aac99ba4 100644 --- a/client/src/app/site/users/components/presence-detail/presence-detail.component.ts +++ b/client/src/app/site/users/components/presence-detail/presence-detail.component.ts @@ -4,7 +4,7 @@ import { FormBuilder, FormGroup } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; 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 { ConfigService } from 'app/core/ui-services/config.service'; 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 */ public get permission(): boolean { - return this.operator.hasPerms('users.can_manage') && this._enabledInConfig; + return this.operator.hasPerms(Permission.usersCanManage) && this._enabledInConfig; } /** diff --git a/client/src/app/site/users/components/user-detail/user-detail.component.ts b/client/src/app/site/users/components/user-detail/user-detail.component.ts index 89dcbff92..12c497b4f 100644 --- a/client/src/app/site/users/components/user-detail/user-detail.component.ts +++ b/client/src/app/site/users/components/user-detail/user-detail.component.ts @@ -8,7 +8,7 @@ import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject } from 'rxjs'; 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 { UserRepositoryService } from 'app/core/repositories/users/user-repository.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 { switch (action) { case 'delete': - return this.operator.hasPerms('users.can_manage') && !this.ownPage; + return this.operator.hasPerms(Permission.usersCanManage) && !this.ownPage; case 'manage': - return this.operator.hasPerms('users.can_manage'); + return this.operator.hasPerms(Permission.usersCanManage); 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': - return this.operator.hasPerms('users.can_see_name', 'users.can_manage'); + return this.operator.hasPerms(Permission.usersCanSeeName, Permission.usersCanManage); case 'seeExtra': - return this.operator.hasPerms('users.can_see_extra_data', 'users.can_manage'); + return this.operator.hasPerms(Permission.usersCanSeeExtraData, Permission.usersCanManage); 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': - return this.operator.hasPerms('users.can_manage') || this.ownPage; + return this.operator.hasPerms(Permission.usersCanManage) || this.ownPage; case 'changePassword': return ( - (this.ownPage && this.operator.hasPerms('users.can_change_password')) || - this.operator.hasPerms('users.can_manage') + (this.ownPage && this.operator.hasPerms(Permission.usersCanChangePassword)) || + this.operator.hasPerms(Permission.usersCanManage) ); default: return false; diff --git a/client/src/app/site/users/components/user-list/user-list.component.ts b/client/src/app/site/users/components/user-list/user-list.component.ts index 7350fb726..948a000d8 100644 --- a/client/src/app/site/users/components/user-list/user-list.component.ts +++ b/client/src/app/site/users/components/user-list/user-list.component.ts @@ -8,7 +8,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { TranslateService } from '@ngx-translate/core'; 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 { GroupRepositoryService } from 'app/core/repositories/users/group-repository.service'; import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; @@ -96,7 +96,7 @@ export class UserListComponent extends BaseListViewComponent implement * @returns true if the presence view is available to administrators */ public get presenceViewConfigured(): boolean { - return this._presenceViewConfigured && this.operator.hasPerms('users.can_manage'); + return this._presenceViewConfigured && this.operator.hasPerms(Permission.usersCanManage); } private isVoteWeightActive: boolean; @@ -107,7 +107,7 @@ export class UserListComponent extends BaseListViewComponent implement * @returns true if the user should be able to create users */ public get canAddUser(): boolean { - return this.operator.hasPerms('users.can_manage'); + return this.operator.hasPerms(Permission.usersCanManage); } public get showVoteWeight(): boolean { @@ -221,7 +221,7 @@ export class UserListComponent extends BaseListViewComponent implement } else if (this.allowSelfSetPresent && this.operator.viewUser === user) { return false; } else { - return !this.operator.hasPerms('users.can_manage'); + return !this.operator.hasPerms(Permission.usersCanManage); } } @@ -233,7 +233,7 @@ export class UserListComponent extends BaseListViewComponent implement * @param user is an instance of ViewUser. This is the given user, who will be modified. */ 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; } ev.stopPropagation(); @@ -437,7 +437,7 @@ export class UserListComponent extends BaseListViewComponent implement public setPresent(viewUser: ViewUser): void { 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); } else if (this.allowSelfSetPresent && this.operator.viewUser === viewUser) { this.operator.setPresence(viewUser.user.is_present).catch(this.raiseError); diff --git a/client/src/app/site/users/models/view-group.ts b/client/src/app/site/users/models/view-group.ts index 8d301c993..f2739f5b0 100644 --- a/client/src/app/site/users/models/view-group.ts +++ b/client/src/app/site/users/models/view-group.ts @@ -1,3 +1,4 @@ +import { Permission } from 'app/core/core-services/operator.service'; import { Group } from 'app/shared/models/users/group'; import { BaseViewModel } from '../../base/base-view-model'; @@ -12,7 +13,7 @@ export class ViewGroup extends BaseViewModel implements GroupTitleInforma return this._model; } - public hasPermission(perm: string): boolean { + public hasPermission(perm: Permission): boolean { return this.permissions.includes(perm); } } diff --git a/client/src/app/site/users/users-routing.module.ts b/client/src/app/site/users/users-routing.module.ts index f1a1411c1..85890fbda 100644 --- a/client/src/app/site/users/users-routing.module.ts +++ b/client/src/app/site/users/users-routing.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core'; 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 { PasswordComponent } from './components/password/password.component'; import { PresenceDetailComponent } from './components/presence-detail/presence-detail.component'; @@ -13,38 +14,38 @@ const routes: Routes = [ path: '', component: UserListComponent, pathMatch: 'full', - data: { basePerm: 'users.can_see_name' } + data: { basePerm: Permission.usersCanSeeName } }, { path: 'password', component: PasswordComponent, - data: { basePerm: 'users.can_change_password' } + data: { basePerm: Permission.usersCanChangePassword } }, { path: 'password/:id', component: PasswordComponent, - data: { basePerm: 'users.can_manage' } + data: { basePerm: Permission.usersCanManage } }, { path: 'new', component: UserDetailComponent, - data: { basePerm: 'users.can_manage' } + data: { basePerm: Permission.usersCanManage } }, { path: 'import', component: UserImportListComponent, - data: { basePerm: 'users.can_manage' } + data: { basePerm: Permission.usersCanManage } }, { path: 'presence', component: PresenceDetailComponent, // TODO: 'users_enable_presence_view' missing in permissions - data: { basePerm: 'users.can_manage' } + data: { basePerm: Permission.usersCanManage } }, { path: 'groups', component: GroupListComponent, - data: { basePerm: 'users.can_manage' } + data: { basePerm: Permission.usersCanManage } }, { path: ':id', diff --git a/client/src/app/site/users/users.config.ts b/client/src/app/site/users/users.config.ts index 3f7ce1ab0..ed385db4d 100644 --- a/client/src/app/site/users/users.config.ts +++ b/client/src/app/site/users/users.config.ts @@ -1,4 +1,5 @@ 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 { PersonalNoteRepositoryService } from 'app/core/repositories/users/personal-note-repository.service'; import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service'; @@ -31,7 +32,7 @@ export const UsersAppConfig: AppConfig = { displayName: 'Participants', icon: 'people', weight: 500, - permission: 'users.can_see_name' + permission: Permission.usersCanSeeName } ] };