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 { TourNgBootstrapModule } from 'ngx-ui-tour-ng-bootstrap'
import { UserEditDialogComponent } from './components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component' 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 { 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 { 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 { 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' 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, TasksComponent,
UserEditDialogComponent, UserEditDialogComponent,
GroupEditDialogComponent, GroupEditDialogComponent,
SsoGroupEditDialogComponent,
PermissionsSelectComponent, PermissionsSelectComponent,
MailAccountEditDialogComponent, MailAccountEditDialogComponent,
MailRuleEditDialogComponent, 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', 'view_consumptiontemplate',
'change_consumptiontemplate', 'change_consumptiontemplate',
'delete_consumptiontemplate', 'delete_consumptiontemplate',
'add_ssogroup',
'change_ssogroup',
'delete_ssogroup',
'view_ssogroup',
], ],
{ {
username: 'testuser', username: 'testuser',

View File

@ -26,6 +26,7 @@ export enum PermissionType {
Admin = '%s_logentry', Admin = '%s_logentry',
ShareLink = '%s_sharelink', ShareLink = '%s_sharelink',
ConsumptionTemplate = '%s_consumptiontemplate', ConsumptionTemplate = '%s_consumptiontemplate',
SsoGroup = '%s_ssogroup',
} }
@Injectable({ @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 django_filters.rest_framework import FilterSet
from documents.filters import CHAR_KWARGS from documents.filters import CHAR_KWARGS
from paperless.models import SSOGroup
class UserFilterSet(FilterSet): class UserFilterSet(FilterSet):
@ -15,3 +16,9 @@ class GroupFilterSet(FilterSet):
class Meta: class Meta:
model = Group model = Group
fields = {"name": CHAR_KWARGS} 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(), queryset=Permission.objects.all(),
slug_field="codename", slug_field="codename",
) )
sso_groups = serializers.PrimaryKeyRelatedField(
many=True,
queryset=SSOGroup.objects.all(),
required=False,
)
class Meta: class Meta:
model = Group model = Group
@ -103,7 +98,6 @@ class GroupSerializer(serializers.ModelSerializer):
"id", "id",
"name", "name",
"permissions", "permissions",
"sso_groups",
) )
@ -111,6 +105,7 @@ class SSOGroupSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = SSOGroup model = SSOGroup
fields = ( fields = (
"id",
"name", "name",
"group", "group",
) )

View File

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