aboutsummaryrefslogtreecommitdiffstats
path: root/archiva-modules/archiva-web
diff options
context:
space:
mode:
authorMartin Stockhammer <martin_s@apache.org>2021-01-11 00:32:09 +0100
committerMartin Stockhammer <martin_s@apache.org>2021-01-11 00:32:09 +0100
commit76985db7ffa4ecce1557444eb490f9bceb06fb1a (patch)
treeff9d0038ba52073d4b1ce273182719200c8d2657 /archiva-modules/archiva-web
parentc7308557f9882909a59f48cad853c4cd81a7c87d (diff)
downloadarchiva-76985db7ffa4ecce1557444eb490f9bceb06fb1a.tar.gz
archiva-76985db7ffa4ecce1557444eb490f9bceb06fb1a.zip
Adding additional message and checks for ldap
Diffstat (limited to 'archiva-modules/archiva-web')
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts9
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.html38
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.ts242
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/archiva-request.service.ts7
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json2
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",