Setting page to manage SSO Groups.

Add section in "User&Group" tab to manage SSO groups.
Only display this section if user have the rights to edit it.
This commit is contained in:
Louis Chauvet 2023-07-10 21:52:46 +02:00 committed by shamoon
parent 853ff30bf4
commit 92928a0311
13 changed files with 170 additions and 6 deletions

View File

View File

@ -81,6 +81,7 @@ import { TasksComponent } from './components/admin/tasks/tasks.component'
import { TourNgBootstrapModule } from 'ngx-ui-tour-ng-bootstrap'
import { UserEditDialogComponent } from './components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component'
import { GroupEditDialogComponent } from './components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component'
import { SsoGroupEditDialogComponent } from './components/common/edit-dialog/sso-group-edit-dialog/sso-group-edit-dialog.component'
import { PermissionsSelectComponent } from './components/common/permissions-select/permissions-select.component'
import { MailAccountEditDialogComponent } from './components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component'
import { MailRuleEditDialogComponent } from './components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component'
@ -225,6 +226,7 @@ function initializeApp(settings: SettingsService) {
TasksComponent,
UserEditDialogComponent,
GroupEditDialogComponent,
SsoGroupEditDialogComponent,
PermissionsSelectComponent,
MailAccountEditDialogComponent,
MailRuleEditDialogComponent,

View File

@ -0,0 +1,19 @@
<form [formGroup]="objectForm" (ngSubmit)="save()">
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">{{getTitle()}}</h4>
<button type="button" [disabled]="!closeEnabled" class="btn-close" aria-label="Close" (click)="cancel()">
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
<app-input-select i18n-title title="Group" [items]="groups" formControlName="group"></app-input-select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" (click)="cancel()" i18n [disabled]="networkActive">Cancel</button>
<button type="submit" class="btn btn-primary" i18n [disabled]="networkActive">Save</button>
</div>
</form>

View File

@ -0,0 +1,57 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { NgbActiveModal, NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { EditDialogMode } from '../edit-dialog.component'
import { IfOwnerDirective } from 'src/app/directives/if-owner.directive'
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
import { SelectComponent } from '../../input/select/select.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { TextComponent } from '../../input/text/text.component'
import { NgSelectModule } from '@ng-select/ng-select'
import { PermissionsFormComponent } from '../../input/permissions/permissions-form/permissions-form.component'
import { SsoGroupEditDialogComponent } from './sso-group-edit-dialog.component'
import { PermissionsSelectComponent } from '../../permissions-select/permissions-select.component'
describe('GroupEditDialogComponent', () => {
let component: SsoGroupEditDialogComponent
let fixture: ComponentFixture<SsoGroupEditDialogComponent>
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [
SsoGroupEditDialogComponent,
IfPermissionsDirective,
IfOwnerDirective,
SelectComponent,
TextComponent,
PermissionsFormComponent,
PermissionsSelectComponent,
],
providers: [NgbActiveModal],
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
NgSelectModule,
NgbModule,
],
}).compileComponents()
fixture = TestBed.createComponent(SsoGroupEditDialogComponent)
component = fixture.componentInstance
fixture.detectChanges()
})
it('should support create and edit modes', () => {
component.dialogMode = EditDialogMode.CREATE
const createTitleSpy = jest.spyOn(component, 'getCreateTitle')
const editTitleSpy = jest.spyOn(component, 'getEditTitle')
fixture.detectChanges()
expect(createTitleSpy).toHaveBeenCalled()
expect(editTitleSpy).not.toHaveBeenCalled()
component.dialogMode = EditDialogMode.EDIT
fixture.detectChanges()
expect(editTitleSpy).toHaveBeenCalled()
})
})

View File

@ -0,0 +1,52 @@
import { Component } from '@angular/core'
import { FormControl, FormGroup } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
import { PaperlessGroup } from 'src/app/data/paperless-group'
import { GroupService } from 'src/app/services/rest/group.service'
import { UserService } from 'src/app/services/rest/user.service'
import { SettingsService } from 'src/app/services/settings.service'
import { PaperlessSSOGroup } from '../../../../data/paperless-sso-group'
import { SsoGroupService } from '../../../../services/rest/sso-group.service'
import { first } from 'rxjs'
@Component({
selector: 'app-sso-group-edit-dialog',
templateUrl: './sso-group-edit-dialog.component.html',
styleUrls: ['./sso-group-edit-dialog.component.scss'],
})
export class SsoGroupEditDialogComponent extends EditDialogComponent<PaperlessSSOGroup> {
groups: PaperlessGroup[]
constructor(
service: SsoGroupService,
activeModal: NgbActiveModal,
userService: UserService,
settingsService: SettingsService,
groupsService: GroupService
) {
super(service, activeModal, userService, settingsService)
groupsService
.listAll()
.pipe(first())
.subscribe((result) => {
this.groups = result.results
})
}
getCreateTitle() {
return $localize`Create new sso group`
}
getEditTitle() {
return $localize`Edit sso group`
}
getForm(): FormGroup {
return new FormGroup({
name: new FormControl(''),
group: new FormControl(null),
})
}
}

View File

@ -0,0 +1,6 @@
import { ObjectWithId } from './object-with-id'
export interface PaperlessSSOGroup extends ObjectWithId {
name?: string
group?: number
}

View File

@ -256,6 +256,10 @@ describe('PermissionsService', () => {
'view_consumptiontemplate',
'change_consumptiontemplate',
'delete_consumptiontemplate',
'add_ssogroup',
'change_ssogroup',
'delete_ssogroup',
'view_ssogroup',
],
{
username: 'testuser',

View File

@ -26,6 +26,7 @@ export enum PermissionType {
Admin = '%s_logentry',
ShareLink = '%s_sharelink',
ConsumptionTemplate = '%s_consumptiontemplate',
SsoGroup = '%s_ssogroup',
}
@Injectable({

View File

@ -0,0 +1,13 @@
import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { AbstractNameFilterService } from './abstract-name-filter-service'
import { PaperlessSSOGroup } from '../../data/paperless-sso-group'
@Injectable({
providedIn: 'root',
})
export class SsoGroupService extends AbstractNameFilterService<PaperlessSSOGroup> {
constructor(http: HttpClient) {
super(http, 'sso_groups')
}
}

View File

@ -3,6 +3,7 @@ from django.contrib.auth.models import User
from django_filters.rest_framework import FilterSet
from documents.filters import CHAR_KWARGS
from paperless.models import SSOGroup
class UserFilterSet(FilterSet):
@ -15,3 +16,9 @@ class GroupFilterSet(FilterSet):
class Meta:
model = Group
fields = {"name": CHAR_KWARGS}
class SSOGroupFilterSet(FilterSet):
class Meta:
model = SSOGroup
fields = {"name": CHAR_KWARGS}

View File

@ -91,11 +91,6 @@ class GroupSerializer(serializers.ModelSerializer):
queryset=Permission.objects.all(),
slug_field="codename",
)
sso_groups = serializers.PrimaryKeyRelatedField(
many=True,
queryset=SSOGroup.objects.all(),
required=False,
)
class Meta:
model = Group
@ -103,7 +98,6 @@ class GroupSerializer(serializers.ModelSerializer):
"id",
"name",
"permissions",
"sso_groups",
)
@ -111,6 +105,7 @@ class SSOGroupSerializer(serializers.ModelSerializer):
class Meta:
model = SSOGroup
fields = (
"id",
"name",
"group",
)

View File

@ -15,6 +15,7 @@ from rest_framework.viewsets import ModelViewSet
from documents.permissions import PaperlessObjectPermissions
from paperless.filters import GroupFilterSet
from paperless.filters import SSOGroupFilterSet
from paperless.filters import UserFilterSet
from paperless.models import SSOGroup
from paperless.serialisers import GroupSerializer
@ -112,5 +113,12 @@ class GroupViewSet(ModelViewSet):
class SSOGroupViewSet(ModelViewSet):
model = SSOGroup
queryset = SSOGroup.objects
serializer_class = SSOGroupSerializer
pagination_class = StandardPagination
permission_classes = (IsAuthenticated, PaperlessObjectPermissions)
filter_backends = (DjangoFilterBackend, OrderingFilter)
filterset_class = SSOGroupFilterSet
ordering_fields = ("name",)