This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git


The following commit(s) were added to refs/heads/master by this push:
     new 76985db  Adding additional message and checks for ldap
76985db is described below

commit 76985db7ffa4ecce1557444eb490f9bceb06fb1a
Author: Martin Stockhammer <[email protected]>
AuthorDate: Mon Jan 11 00:32:09 2021 +0100

    Adding additional message and checks for ldap
---
 .../main/archiva-web/src/app/model/error-result.ts |   9 +-
 .../ldap-security/ldap-security.component.html     |  38 +++-
 .../ldap-security/ldap-security.component.ts       | 242 +++++++++++----------
 .../src/app/services/archiva-request.service.ts    |   7 +-
 .../src/main/archiva-web/src/assets/i18n/en.json   |   2 +
 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 4dd0348..64130fb 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 c6850e3..5f27058 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 bc00ad8..f0c4eeb 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 727032d..d5a02f0 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 4f0b019..a10c2cf 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",

Reply via email to