diff options
author | Martin Stockhammer <martin_s@apache.org> | 2021-01-11 00:32:09 +0100 |
---|---|---|
committer | Martin Stockhammer <martin_s@apache.org> | 2021-01-11 00:32:09 +0100 |
commit | 76985db7ffa4ecce1557444eb490f9bceb06fb1a (patch) | |
tree | ff9d0038ba52073d4b1ce273182719200c8d2657 /archiva-modules/archiva-web | |
parent | c7308557f9882909a59f48cad853c4cd81a7c87d (diff) | |
download | archiva-76985db7ffa4ecce1557444eb490f9bceb06fb1a.tar.gz archiva-76985db7ffa4ecce1557444eb490f9bceb06fb1a.zip |
Adding additional message and checks for ldap
Diffstat (limited to 'archiva-modules/archiva-web')
5 files changed, 173 insertions, 125 deletions
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts index 4dd034822..64130fb2d 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts @@ -22,8 +22,13 @@ export class ErrorResult { error_messages: Array<ErrorMessage> status: number; - constructor(errorMessages: Array<ErrorMessage>) { - this.error_messages = errorMessages; + constructor(json:any) { + if (Array.isArray(json)) { + this.error_messages = json; + } else { + this.error_messages = json.error_messages; + this.status = json.status; + } } hasMessages() :boolean { 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 c6850e330..5f2705861 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 @@ -18,16 +18,29 @@ <form class="mt-3 mb-3" [formGroup]="userForm" (ngSubmit)="onSubmit()"> <p class="row col-md-10">{{'security.config.ldap.explain'|translate}}</p> - <div class="form-group row col-md-10" *ngFor="let attName of ['host_name','port','base_dn','groups_base_dn','bind_dn','bind_password','context_factory']"> - <label class="col-md-3 col-form-label" for="{{attName}}">{{'security.config.ldap.attributes.'+attName |translate}}</label> + <div class="form-group row col-md-10" + *ngFor="let attName of ['host_name','port','base_dn','groups_base_dn','bind_dn','bind_password']"> + <label class="col-md-3 col-form-label" + for="{{attName}}">{{'security.config.ldap.attributes.' + attName |translate}}</label> <div [attr.class]="attName=='port'?'col-md-3':'col-md-7'"> - <input [attr.type]="attName=='bind_password'?'password':'text'" formControlName="{{attName}}" id="{{attName}}" + <input [attr.type]="attName=='bind_password'?'password':'text'" formControlName="{{attName}}" + id="{{attName}}" [ngClass]="getInputClasses(attName)" > </div> </div> - <div class="form-group row col-md-10" > - <label class="col-md-3 col-form-label" for="authentication_method">{{'security.config.ldap.attributes.authentication_method' |translate}}</label> + <div class="form-group row col-md-10"> + <label class="col-md-3 col-form-label" + for="context_factory">{{'security.config.ldap.attributes.context_factory' |translate}}</label> + <div class="col-md-7"> + <input type="text" formControlName="context_factory" id="context_factory" + [ngClass]="getInputClasses('context_factory')" [ngbTypeahead]="searchContextFactory" + > + </div> + </div> + <div class="form-group row col-md-10"> + <label class="col-md-3 col-form-label" + for="authentication_method">{{'security.config.ldap.attributes.authentication_method' |translate}}</label> <div class="col-md-2"> <select formControlName="authentication_method" id="authentication_method" class="form-control"> <option *ngFor="let method of authenticationMethods">{{method}}</option> @@ -37,22 +50,29 @@ <div class="form-group row col-md-10"> <div class="col-md-3">{{'security.config.ldap.flags'|translate}}</div> <div class="col-md-7"> - <div class="form-check pt-1 pb-1" *ngFor="let flagName of ['writable','ssl_enabled','bind_authenticator_enabled','use_role_name_as_group']"> + <div class="form-check pt-1 pb-1" + *ngFor="let flagName of ['writable','ssl_enabled','bind_authenticator_enabled','use_role_name_as_group']"> <input class="form-check-input" type="checkbox" formControlName="{{flagName}}" - id="{{flagName}}" > + id="{{flagName}}"> <label class="form-check-label " for="{{flagName}}"> - {{'security.config.ldap.attributes.'+flagName|translate}} + {{'security.config.ldap.attributes.' + flagName|translate}} </label> </div> </div> </div> - <div class="row col-md-10 mt-4" > + <div class="row col-md-10 mt-4"> <button class="btn btn-primary col-md-2" type="submit" [disabled]="userForm.invalid || !userForm.dirty">{{'form.button.save'|translate}}</button> <button class="btn btn-primary col-md-2 offset-1" type="button" (click)="checkLdapConnection()" [disabled]="userForm.invalid || !userForm.dirty">{{'form.button.check'|translate}}</button> </div> + <div class="row col-md-10 mt-2"> + <div class="alert col-md-6 ml-1 alert-success" role="alert" + *ngIf="checkResult=='success'">{{'security.config.ldap.check_success'|translate}}</div> + <div class="alert col-md-6 ml-1 alert-warning" role="alert" + *ngIf="checkResult=='error'">{{'security.config.ldap.check_failed'|translate}}</div> + </div> </form> 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 bc00ad873..f0c4eeb31 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 @@ -24,141 +24,159 @@ import {AbstractControl, FormBuilder, ValidatorFn, Validators} from "@angular/fo import {SecurityService} from "@app/services/security.service"; import {ToastService} from "@app/services/toast.service"; import {ErrorResult} from "@app/model/error-result"; +import {Observable} from 'rxjs'; +import {debounceTime, distinctUntilChanged, map} from 'rxjs/operators'; @Component({ - selector: 'app-ldap-security', - templateUrl: './ldap-security.component.html', - styleUrls: ['./ldap-security.component.scss'] + selector: 'app-ldap-security', + templateUrl: './ldap-security.component.html', + styleUrls: ['./ldap-security.component.scss'] }) export class LdapSecurityComponent extends EditBaseComponent<LdapConfiguration> implements OnInit { - authenticationMethods=['none','simple','strong'] - formFields = ['host_name', 'port', 'ssl_enabled', 'context_factory', - 'base_dn', 'groups_base_dn', 'bind_dn', 'bind_password', 'authentication_method', 'bind_authenticator_enabled', - 'use_role_name_as_group', 'writable']; + authenticationMethods = ['none', 'simple', 'strong'] + formFields = ['host_name', 'port', 'ssl_enabled', 'context_factory', + 'base_dn', 'groups_base_dn', 'bind_dn', 'bind_password', 'authentication_method', 'bind_authenticator_enabled', + 'use_role_name_as_group', 'writable']; + availableContextFactories = []; + checkResult = null; - 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], - context_factory:[''], - base_dn:['',[dnValidator()]], - groups_base_dn:['',[dnValidator()]], - bind_dn:[''], - bind_password:[''], - authentication_method:['none'], - bind_authenticator_enabled:[false], - use_role_name_as_group:[true], - writable:[false] - }, {})); - } - - ngOnInit(): void { - this.securityService.getLdapConfiguration().subscribe( ldapConfiguration => { - this.copyToForm(this.formFields, ldapConfiguration); - if ((ldapConfiguration.context_factory==null || ldapConfiguration.context_factory=='') && ldapConfiguration.available_context_factories.length==1) { - this.userForm.controls['context_factory'].setValue(ldapConfiguration.available_context_factories[0]); - } - if (ldapConfiguration.authentication_method=='') { - this.userForm.controls['authentication_method'].setValue('none'); - } - } - ) - this.userForm.controls['bind_dn'].valueChanges.subscribe(selectedValue => { - if (selectedValue!='' && this.userForm.controls['authentication_method'].value=='none') { - this.userForm.controls['authentication_method'].setValue('simple',{emitEvent: false}) - } else if (selectedValue=='' && this.userForm.controls['authentication_method'].value!='none') { - this.userForm.controls['authentication_method'].setValue('none',{emitEvent: false}) - } - }) - } + 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], + context_factory: [''], + base_dn: ['', [dnValidator()]], + groups_base_dn: ['', [dnValidator()]], + bind_dn: [''], + bind_password: [''], + authentication_method: ['none'], + bind_authenticator_enabled: [false], + use_role_name_as_group: [true], + writable: [false] + }, {})); + } - createEntity(): LdapConfiguration { - return new LdapConfiguration(); - } + ngOnInit(): void { + this.securityService.getLdapConfiguration().subscribe(ldapConfiguration => { + this.copyToForm(this.formFields, ldapConfiguration); + if ((ldapConfiguration.context_factory == null || ldapConfiguration.context_factory == '') && ldapConfiguration.available_context_factories.length == 1) { + this.userForm.controls['context_factory'].setValue(ldapConfiguration.available_context_factories[0]); + } + if (ldapConfiguration.authentication_method == '') { + this.userForm.controls['authentication_method'].setValue('none'); + } + this.availableContextFactories = ldapConfiguration.available_context_factories + } + ) + this.userForm.controls['bind_dn'].valueChanges.subscribe(selectedValue => { + if (selectedValue != '' && this.userForm.controls['authentication_method'].value == 'none') { + this.userForm.controls['authentication_method'].setValue('simple', {emitEvent: false}) + } else if (selectedValue == '' && this.userForm.controls['authentication_method'].value != 'none') { + this.userForm.controls['authentication_method'].setValue('none', {emitEvent: false}) + } + }) + this.userForm.valueChanges.subscribe(val => { + this.checkResult = null; + }) - onSubmit() { - console.log("Saving configuration"); - let config = this.copyFromForm(this.formFields) + } + createEntity(): LdapConfiguration { + return new LdapConfiguration(); + } + onSubmit() { + console.log("Saving configuration"); + let config = this.copyFromForm(this.formFields) - } - getInputClasses(field: string) : string[] { - let csClasses = super.isValid(field); - if (csClasses.length==1 && csClasses[0]=='') { - csClasses = []; } - csClasses.push('form-control'); - return csClasses; - } - checkLdapConnection() { - console.log("Checking LDAP connection"); - let config = this.copyFromForm(this.formFields) - this.securityService.verifyLdapConfiguration(config).subscribe(()=>{ - this.toastService.showSuccessByKey('ldap-security', 'security.config.ldap.check_success'); - }, - (error:ErrorResult) =>{ - this.toastService.showErrorByKey('ldap-security', error.firstMessageString()); + searchContextFactory = (text$: Observable<string>) => + text$.pipe( + debounceTime(200), + distinctUntilChanged(), + map(term => term.length < 2 ? [] + : this.availableContextFactories.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)) + ) + + getInputClasses(field: string): string[] { + let csClasses = super.isValid(field); + if (csClasses.length == 1 && csClasses[0] == '') { + csClasses = []; } + csClasses.push('form-control'); + return csClasses; + } + + checkLdapConnection() { + console.log("Checking LDAP connection"); + let config = this.copyFromForm(this.formFields) + this.securityService.verifyLdapConfiguration(config).subscribe(() => { + this.toastService.showSuccessByKey('ldap-security', 'security.config.ldap.check_success'); + this.checkResult = 'success'; + }, + (error: ErrorResult) => { + this.toastService.showErrorByKey('ldap-security', error.firstMessageString()); + this.checkResult = 'error'; + } ); - } + } } /** * This validator checks the DN names for valid RDN segments */ export function dnValidator(): ValidatorFn { - return (control: AbstractControl): {[key: string]: any} | null => { - let parts = [] - let value = control.value.toString() - if (value=='') { - return null; - } - let escape = false; - let partKey : string = '' - let partValue : string = '' - let key = true; - for (let i=0; i<value.length; i+=1) { - let c = value.charAt(i); - if (c=='\\' && !escape) { - escape = true; - } else if (c==',' && !escape) { - parts.push( [partKey,partValue]); - if (partKey.length==0) { - return {'invalidDnBadKey':{value:value,index:i}} + return (control: AbstractControl): { [key: string]: any } | null => { + let parts = [] + let value = control.value.toString() + if (value == '') { + return null; } - if (partValue.length==0) { - return {'invalidDnBadValue':{value:value, index: i}} + let escape = false; + let partKey: string = '' + let partValue: string = '' + let key = true; + for (let i = 0; i < value.length; i += 1) { + let c = value.charAt(i); + if (c == '\\' && !escape) { + escape = true; + } else if (c == ',' && !escape) { + parts.push([partKey, partValue]); + if (partKey.length == 0) { + return {'invalidDnBadKey': {value: value, index: i}} + } + if (partValue.length == 0) { + return {'invalidDnBadValue': {value: value, index: i}} + } + partKey = ''; + partValue = ''; + key = true; + continue; + } else if (c == '=' && !escape) { + if (!key) { + return {'invalidDnBadEquals': {value: value, index: i}} + } + key = false; + continue; + } else if (escape) { + escape = false; + } + if (key) { + partKey = partKey + c; + } else { + partValue = partValue + c; + } + } - partKey=''; - partValue=''; - key=true; - continue; - } else if (c=='=' && !escape) { - if (!key) { - return {'invalidDnBadEquals':{value: value, index:i}} + if (partKey == '' || partValue == '') { + return {'invalidDnBadRdn': {value: value, index: value.length - 1}} } - key=false; - continue; - } else if (escape) { - escape = false; - } - if (key) { - partKey = partKey + c; - } else { - partValue = partValue + c; - } - - } - if (partKey=='' || partValue=='') { - return {'invalidDnBadRdn':{value:value,index:value.length-1}} - } - return null; - }; + return null; + }; } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/archiva-request.service.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/archiva-request.service.ts index 727032d91..d5a02f07a 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/archiva-request.service.ts +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/archiva-request.service.ts @@ -145,8 +145,11 @@ export class ArchivaRequestService { if (httpError == null) { return new ErrorResult([]); } - let errorResult = httpError.error as ErrorResult; - if (errorResult==null) { + + let errorResult + if (httpError.error) { + errorResult = new ErrorResult(httpError.error); + } else { if (httpError.statusText!=null) { errorResult = new ErrorResult([ErrorMessage.of(httpError.statusText)]); } else { 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 4f0b01996..a10c2cf66 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 @@ -208,6 +208,8 @@ "ldap": { "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.", + "check_success": "The LDAP settings have been verified successfully", + "check_failed": "Could not connect to the LDAP server successfully", "attributes": { "host_name": "Host Name", "port": "Port", |