refs #2078 and #2079 Implement role-based command filtering and UI adjustments for user permissions
testing/ogGui-multibranch/pipeline/head There was a failure building this commit Details

pull/24/head
Lucas Lara García 2025-05-27 14:14:01 +02:00
parent a26f2481fa
commit 84fd9d0335
6 changed files with 56 additions and 22 deletions

View File

@ -3,9 +3,10 @@ import { HttpClient } from '@angular/common/http';
import { Router } from "@angular/router";
import { ToastrService } from "ngx-toastr";
import { ConfigService } from '@services/config.service';
import {BootSoPartitionComponent} from "./boot-so-partition/boot-so-partition.component";
import {MatDialog} from "@angular/material/dialog";
import {RemoveCacheImageComponent} from "./remove-cache-image/remove-cache-image.component";
import { BootSoPartitionComponent } from "./boot-so-partition/boot-so-partition.component";
import { MatDialog } from "@angular/material/dialog";
import { RemoveCacheImageComponent } from "./remove-cache-image/remove-cache-image.component";
import { AuthService } from '@services/auth.service';
@Component({
selector: 'app-execute-command',
@ -44,6 +45,7 @@ export class ExecuteCommandComponent implements OnInit {
private router: Router,
private configService: ConfigService,
private toastService: ToastrService,
public auth: AuthService,
private dialog: MatDialog,
) {
this.baseUrl = this.configService.apiUrl;
@ -51,6 +53,9 @@ export class ExecuteCommandComponent implements OnInit {
ngOnInit(): void {
this.clientData = this.clientData || [];
const allowed = this.getAllowedCommandsByRole();
this.arrayCommands = this.arrayCommands.filter(c => allowed.includes(c.slug));
this.updateCommandStates();
}
@ -58,6 +63,34 @@ export class ExecuteCommandComponent implements OnInit {
this.updateCommandStates();
}
private getAllowedCommandsByRole(): string[] {
const role = this.auth.userCategory;
const permissions: Record<string, string[]> = {
'super-admin': ['*'],
'ou-admin': ['*'],
'ou-operator': [
'power-on',
'power-off',
'reboot',
'login',
'deploy-image',
'software-inventory',
'hardware-inventory',
'remove-cache-image',
'partition'
],
'ou-minimal': [
'power-on',
'power-off'
]
};
const allowed = permissions[role] || [];
return allowed.includes('*') ? this.arrayCommands.map(c => c.slug) : allowed;
}
private updateCommandStates(): void {
let states: string[] = [];

View File

@ -11,11 +11,12 @@
</div>
<div class="groups-button-row">
<div joyrideStep="addStep" text="{{ 'groupsAddStepText' | translate }}" style="display: flex; gap: 15px;">
<button class="action-button" (click)="addOU($event)"
<button class="action-button" (click)="addOU($event)" *ngIf="auth.userCategory !== 'ou-minimal'"
matTooltip="{{ 'newOrganizationalUnitTooltip' | translate }}" matTooltipShowDelay="1000">
{{ 'newOrganizationalUnitButton' | translate }}
</button>
<button class="action-button" [matMenuTriggerFor]="menuClients">{{ 'newClientButton' | translate }}</button>
<button class="action-button" [matMenuTriggerFor]="menuClients" *ngIf="auth.userCategory !== 'ou-minimal'">{{
'newClientButton' | translate }}</button>
<mat-menu #menuClients="matMenu">
<button mat-menu-item (click)="addClient($event)">{{ 'newSingleClientButton' | translate }}</button>
<button mat-menu-item (click)="addMultipleClients($event)">{{ 'newMultipleClientButton' | translate

View File

@ -115,7 +115,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
private joyrideService: JoyrideService,
private breakpointObserver: BreakpointObserver,
private toastr: ToastrService,
private auth: AuthService,
public auth: AuthService,
private configService: ConfigService,
private cd: ChangeDetectorRef,
) {
@ -871,7 +871,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
this.dialog.open(ClientTaskLogsComponent, {
width: '1200px',
data: {client}
data: { client }
})
}
}

View File

@ -23,7 +23,7 @@
{{ 'Administration' | translate }}
</button>
<button class="ordinary-button" *ngIf="auth.userCategory === 'super-admin'" (click)="editUser()"
<button class="ordinary-button" (click)="editUser()"
matTooltip="Editar tu información de usuario" matTooltipShowDelay="1000">
{{ 'changePassword' | translate }}
</button>

View File

@ -1,9 +1,9 @@
<mat-nav-list class="sidebar-content">
<div disabled class="user-info">
<div class="user-info-wrapper" matTooltipShowDelay="1000">
<img ngSrc="assets/images/logo.png" alt="Logo" class="user-logo" height="500" width="500"/>
<img ngSrc="assets/images/logo.png" alt="Logo" class="user-logo" height="500" width="500" />
<span class="user-logged">
{{ 'welcomeUser' | translate:{username: username} }}
{{ 'welcomeUser' | translate:{username: username} }}
</span>
</div>
</div>
@ -18,7 +18,7 @@
</mat-list-item>
<mat-list-item (click)="toggleCommandSub()" matTooltip="{{ 'TOOLTIP_ACTIONS' | translate }}"
matTooltipShowDelay="1000">
matTooltipShowDelay="1000" *ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">playlist_play</mat-icon>
<span>{{ 'actions' | translate }}</span>
@ -28,7 +28,7 @@
<!-- Submenu items for commands -->
<mat-nav-list *ngIf="showCommandSub" style="padding-left: 20px;">
<mat-list-item routerLink="/commands" (click)="onItemClick()" matTooltip="{{ 'TOOLTIP_COMMANDS' | translate }}"
matTooltipShowDelay="1000">
matTooltipShowDelay="1000" *ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">chevron_right</mat-icon>
<span>{{ 'commands' | translate }}</span>
@ -44,7 +44,7 @@
</mat-list-item>
-->
<mat-list-item routerLink="/commands-task" (click)="onItemClick()" matTooltip="{{ 'TOOLTIP_TASKS' | translate }}"
matTooltipShowDelay="1000">
matTooltipShowDelay="1000" *ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">chevron_right</mat-icon>
<span>{{ 'tasks' | translate }}</span>
@ -53,15 +53,15 @@
</mat-nav-list>
<mat-list-item routerLink="/subnets" (click)="onItemClick()" matTooltip="{{ 'TOOLTIP_SUBNETS' | translate }}"
matTooltipShowDelay="1000">
matTooltipShowDelay="1000" *ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">lan</mat-icon>
<span> {{ 'subnets' | translate }}</span>
</span>
</mat-list-item>
<mat-list-item (click)="toggleOgBootSub()" matTooltip="{{ 'TOOLTIP_BOOT' | translate }}"
matTooltipShowDelay="1000">
<mat-list-item (click)="toggleOgBootSub()" matTooltip="{{ 'TOOLTIP_BOOT' | translate }}" matTooltipShowDelay="1000"
*ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">desktop_windows</mat-icon>
<span>{{ 'boot' | translate }}</span>
@ -94,7 +94,7 @@
</mat-nav-list>
<mat-list-item routerLink="/calendars" (click)="onItemClick()" matTooltip="{{ 'TOOLTIP_CALENDARS' | translate }}"
matTooltipShowDelay="1000">
matTooltipShowDelay="1000" *ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">calendar_month</mat-icon>
<span>{{ 'calendars' | translate }}</span>
@ -102,7 +102,7 @@
</mat-list-item>
<mat-list-item (click)="toggleSoftwareSub()" matTooltip="{{ 'TOOLTIP_SOFTWARE' | translate }}"
matTooltipShowDelay="1000">
matTooltipShowDelay="1000" *ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">terminal</mat-icon>
<span>{{ 'software' | translate }}</span>
@ -135,7 +135,8 @@
</mat-nav-list>
<mat-list-item routerLink="/repositories" (click)="onItemClick()"
matTooltip="{{ 'TOOLTIP_REPOSITORIES' | translate }}" matTooltipShowDelay="1000">
matTooltip="{{ 'TOOLTIP_REPOSITORIES' | translate }}" matTooltipShowDelay="1000"
*ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">warehouse</mat-icon>
<span>{{ 'repositories' | translate }}</span>
@ -143,10 +144,10 @@
</mat-list-item>
<mat-list-item routerLink="/menus" (click)="onItemClick()" matTooltip="{{ 'TOOLTIP_MENUS' | translate }}"
matTooltipShowDelay="1000">
matTooltipShowDelay="1000" *ngIf="auth.userCategory !== 'ou-operator' && auth.userCategory !== 'ou-minimal'">
<span class="entry">
<mat-icon class="icon">list</mat-icon>
<span>{{ 'menus' | translate }}</span>
</span>
</mat-list-item>
</mat-nav-list>
</mat-nav-list>

View File

@ -1,5 +1,4 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { jwtDecode } from 'jwt-decode';
import { MatDialog } from '@angular/material/dialog';
import { AuthService } from '@services/auth.service';