From 29679e81293d00f8bb8b7513021c66ea010e4e81 Mon Sep 17 00:00:00 2001 From: Martin Stockhammer Date: Sun, 10 Jan 2021 16:03:55 +0100 Subject: [PATCH] Adding ldap configuration --- .../src/app/model/bean-information.spec.ts | 18 ++++ .../src/app/model/bean-information.ts | 18 ++++ .../ldap-configuration.spec.ts} | 6 +- .../ldap-configuration.ts} | 22 +++-- .../base-security.component.html | 4 + .../base-security/base-security.component.ts | 20 +++-- .../ldap-security.component.html | 33 ++++++- .../ldap-security.component.spec.ts | 16 +++- .../ldap-security/ldap-security.component.ts | 89 ++++++++++++++++++- .../manage-users-roles.component.ts | 7 +- .../manage-users/manage-users.component.ts | 10 +-- .../paginated-entities.component.spec.ts | 43 --------- .../main/archiva-web/src/assets/i18n/en.json | 25 +++++- 13 files changed, 232 insertions(+), 79 deletions(-) rename archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/{modules/shared/model/page-query.spec.ts => model/ldap-configuration.spec.ts} (85%) rename archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/{directives/nav-subgroup.directive.spec.ts => model/ldap-configuration.ts} (62%) delete mode 100644 archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.spec.ts diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.spec.ts index 138cadce8..b39928ed3 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.spec.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.spec.ts @@ -1,3 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import { BeanInformation } from './bean-information'; describe('BeanInformation', () => { diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.ts index 379262ab4..9a561dba1 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.ts @@ -1,3 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + export class BeanInformation { id: string; display_name: string; diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/model/page-query.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/ldap-configuration.spec.ts similarity index 85% rename from archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/model/page-query.spec.ts rename to archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/ldap-configuration.spec.ts index 13b03a103..5c11c78c0 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/model/page-query.spec.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/ldap-configuration.spec.ts @@ -16,10 +16,10 @@ * under the License. */ -import { PageQuery } from './page-query'; +import { LdapConfiguration } from './ldap-configuration'; -describe('PageQuery', () => { +describe('LdapConfiguration', () => { it('should create an instance', () => { - expect(new PageQuery()).toBeTruthy(); + expect(new LdapConfiguration()).toBeTruthy(); }); }); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/directives/nav-subgroup.directive.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/ldap-configuration.ts similarity index 62% rename from archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/directives/nav-subgroup.directive.spec.ts rename to archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/ldap-configuration.ts index 295d6c076..94b64369c 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/directives/nav-subgroup.directive.spec.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/ldap-configuration.ts @@ -16,11 +16,17 @@ * under the License. */ -import { NavSubgroupDirective } from './nav-subgroup.directive'; - -describe('NavSubgroupDirective', () => { - it('should create an instance', () => { - const directive = new NavSubgroupDirective(); - expect(directive).toBeTruthy(); - }); -}); +export class LdapConfiguration { + host_name : string = ""; + port : number = -1; + ssl_enabled : boolean = false; + base_dn : string = ""; + groups_base_dn : string = ""; + bind_dn : string = ""; + bind_password : string = ""; + authentication_method : string = ""; + bind_authenticator_enabled : boolean = true; + use_role_name_as_group : boolean = false; + properties : Map = new Map() + writable : boolean = false; +} diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.html index fcf545f2a..79945d011 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.html +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.html @@ -17,6 +17,8 @@ -->
+

{{'security.config.base.head_managers'|translate}}

+

{{'security.config.base.explain_user_manager'|translate}}

@@ -38,6 +40,7 @@
+

{{'security.config.base.explain_rbac_manager'|translate}}

@@ -58,6 +61,7 @@
+

{{'security.config.base.head_flags'|translate}}

{{'security.config.base.flags'|translate}}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.ts index 4b3acf521..04134e9f9 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.ts @@ -48,6 +48,17 @@ export class BaseSecurityComponent extends EditBaseComponent = new Map(); userInfo: Map = new Map(); + constructor(private route: ActivatedRoute, + public fb: FormBuilder, private securityService: SecurityService, private toastService: ToastService) { + super(fb); + super.init(fb.group({ + user_cache_enabled:[''], + }, {})); + + + + } + drop(event: CdkDragDrop) { console.log("Drop " + event); if (event.previousContainer === event.container) { @@ -60,17 +71,8 @@ export class BaseSecurityComponent extends EditBaseComponent{ rbacInfo.forEach(info => this.rbacInfo.set(info.id, info)); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.html index 55895d827..e98239894 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.html +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.html @@ -16,4 +16,35 @@ ~ under the License. --> -

ldap-security works!

+ +

{{'security.config.ldap.explain'|translate}}

+
+ +
+ +
+
+
+ +
+ +
+
+
+
{{'security.config.ldap.flags'|translate}}
+
+
+ + +
+
+
+ + diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.spec.ts index 7de23ee3f..85bcf6b6a 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.spec.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.spec.ts @@ -18,7 +18,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { LdapSecurityComponent } from './ldap-security.component'; +import { LdapSecurityComponent, dnValidator } from './ldap-security.component'; +import {ValidatorFn} from "@angular/forms"; describe('LdapSecurityComponent', () => { let component: LdapSecurityComponent; @@ -40,4 +41,17 @@ describe('LdapSecurityComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('Test Custom DN Validator', () => { + it('check valid 1', () => { + const ctrl = component.userForm.controls['base_dn'] + ctrl.setValue('cn=abc'); + expect(ctrl.valid).toBeTruthy(); + }) + it('check invalid 1', () => { + const ctrl = component.userForm.controls['base_dn'] + ctrl.setValue('cn=abc,'); + expect(ctrl.invalid).toBeTruthy() + }) + }); }); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.ts index 3c3b09588..7cc829eeb 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.ts @@ -17,17 +17,102 @@ */ import { Component, OnInit } from '@angular/core'; +import {EditBaseComponent} from "@app/modules/shared/edit-base.component"; +import {LdapConfiguration} from "@app/model/ldap-configuration"; +import {ActivatedRoute} from "@angular/router"; +import {AbstractControl, FormBuilder, ValidatorFn, Validators} from "@angular/forms"; +import {SecurityService} from "@app/services/security.service"; +import {ToastService} from "@app/services/toast.service"; +import {propertyDescriptorPatch} from "zone.js/lib/browser/property-descriptor"; @Component({ selector: 'app-ldap-security', templateUrl: './ldap-security.component.html', styleUrls: ['./ldap-security.component.scss'] }) -export class LdapSecurityComponent implements OnInit { +export class LdapSecurityComponent extends EditBaseComponent implements OnInit { - constructor() { } + authenticationMethods=['none','simple','strong'] + + constructor(private route: ActivatedRoute, + public fb: FormBuilder, private securityService: SecurityService, private toastService: ToastService) { + super(fb); + super.init(fb.group({ + host_name:[''], + port:['', [Validators.min(1), Validators.max(65535)]], + ssl_enabled:[false], + base_dn:['',[dnValidator()]], + groups_base_dn:['',[dnValidator()]], + bind_dn:['',[dnValidator()]], + bind_password:[''], + authentication_method:['none'], + bind_authenticator_enabled:[false], + use_role_name_as_group:[true], + writable:[false] + }, {})); + } ngOnInit(): void { } + createEntity(): LdapConfiguration { + return new LdapConfiguration(); + } + + onSubmit() { + } + + getInputClasses(field: string) : string[] { + let csClasses = super.isValid(field); + if (csClasses.length==1 && csClasses[0]=='') { + csClasses = []; + } + csClasses.push('form-control'); + console.log("Classes "+field+" " + csClasses); + return csClasses; + } +} + +export function dnValidator(): ValidatorFn { + return (control: AbstractControl): {[key: string]: any} | null => { + let parts = [] + let value = control.value.toString() + let escape = false; + let partKey : string = '' + let partValue : string = '' + let key = true; + for (let i=0; i this.roleService.assignRole(role.id, this.userid)), + from(assignments).pipe(switchMap((role) => this.roleService.assignRole(role.id, this.userid)), catchError((err: ErrorResult, caught) => { this.success = false; this.errors.push(err); @@ -321,7 +320,7 @@ export class ManageUsersRolesComponent implements OnInit, AfterViewInit { this.saved=true; } ); - fromArray(unassignments).pipe(switchMap((role) => this.roleService.unAssignRole(role.id, this.userid)), + from(unassignments).pipe(switchMap((role) => this.roleService.unAssignRole(role.id, this.userid)), catchError((err: ErrorResult, caught) => { this.success = false; this.errors.push(err); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users/manage-users.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users/manage-users.component.ts index 8ad6c3ef7..16347d9d8 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users/manage-users.component.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/users/manage-users/manage-users.component.ts @@ -16,12 +16,10 @@ * under the License. */ -import {AfterViewInit, Component, OnInit} from '@angular/core'; -import {ActivatedRoute, Params} from "@angular/router"; -import {iif, Observable, of, pipe, merge, combineLatest} from "rxjs"; -import {combineAll, filter, map, mergeMap, share, switchMap, tap} from 'rxjs/operators'; -import {flatMap} from "rxjs/internal/operators"; -import {fromArray} from "rxjs/internal/observable/fromArray"; +import {Component, OnInit} from '@angular/core'; +import {ActivatedRoute} from "@angular/router"; +import {merge, Observable} from "rxjs"; +import {map} from 'rxjs/operators'; @Component({ selector: 'app-manage-users', diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.spec.ts deleted file mode 100644 index 0bd4fc801..000000000 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { PaginatedEntitiesComponent } from './paginated-entities.component'; - -describe('PaginatedEntitiesComponent', () => { - let component: PaginatedEntitiesComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ PaginatedEntitiesComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(PaginatedEntitiesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json index 834a1a21a..5bffc1412 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json @@ -176,6 +176,11 @@ "config": { "base": { "head": "Base Configuration", + "title": "Configure base security settings", + "head_managers": "Set the used User and RBAC managers", + "head_flags": "Additional flags", + "explain_user_manager": "User managers are binding your User IDs and authentication to a persistent storage or repository. You may combine them, but you have to ensure, that user IDs are unique over all repositories.", + "explain_rbac_manager": "RBAC managers handle roles and permissions and store them persistently. If you use LDAP, the roles are mapped to LDAP groups.", "flags": "Flags", "user_manager" : { "active_list" : "Active User Managers", @@ -189,12 +194,28 @@ "ldap_active": "LDAP Active", "user_cache_enabled": "User Cache Enabled" }, - "submit_success": "The Changes were submitted successfully", + "submit_success": "The Changes were submitted successfully. A restart may be required to activate the changes.", "submit_error": "There was an error during submit: {error}", "submit_active_empty": "There must be at least on active User and RBAC Manager defined" }, "ldap": { - "head": "LDAP Configuration" + "head": "LDAP Configuration", + "explain": "Settings for the LDAP connection. These settings are only used, if LDAP User Manager and/or LDAP RBAC Manager is activated.", + "attributes": { + "host_name": "Host Name", + "port": "Port", + "base_dn": "Base DN", + "groups_base_dn": "Base DN for Group Search", + "bind_dn": "Bind User DN", + "bind_password":"Bind Password", + "authentication_method": "Method used for Bind Authentication", + "bind_authenticator_enabled": "Use LDAP Bind during archiva authentication", + "use_role_name_as_group": "Archiva role names are LDAP group names", + "writable": "Bind User can write to LDAP Server", + "ssl_enabled": "Enable SSL" + + }, + "flags": "Flags" } } }, -- 2.39.5