]> source.dussan.org Git - archiva.git/commitdiff
Adding tooltips and properties
authorMartin Stockhammer <martin_s@apache.org>
Mon, 11 Jan 2021 18:16:47 +0000 (19:16 +0100)
committerMartin Stockhammer <martin_s@apache.org>
Mon, 11 Jan 2021 18:16:47 +0000 (19:16 +0100)
12 files changed:
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/property-entry.spec.ts [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/property-entry.ts [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration-routing.module.ts
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration.module.ts
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.html
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-configuration.component.html
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.html [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.scss [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.spec.ts [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.ts [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/security.service.ts
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json

diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/property-entry.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/property-entry.spec.ts
new file mode 100644 (file)
index 0000000..1c7555c
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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 { PropertyEntry } from './property-entry';
+
+describe('PropertyEntry', () => {
+  it('should create an instance', () => {
+    expect(new PropertyEntry()).toBeTruthy();
+  });
+});
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/property-entry.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/property-entry.ts
new file mode 100644 (file)
index 0000000..3390dcf
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * 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 PropertyEntry {
+    key: string;
+    value: string;
+}
index 4b40ce41e6cb45fcaa81798f82a6a29867b075cb..edb681d6115304bf7baabecf8327936f889a7721 100644 (file)
@@ -21,6 +21,7 @@ import {RoutingGuardService as Guard} from "@app/services/routing-guard.service"
 import {SecurityConfigurationComponent} from "./security-configuration/security-configuration.component";
 import {BaseSecurityComponent} from "./security-configuration/base-security/base-security.component";
 import {LdapSecurityComponent} from "./security-configuration/ldap-security/ldap-security.component";
+import {SecurityPropertiesComponent} from "@app/modules/security/security-configuration/security-properties/security-properties.component";
 
 
 /**
@@ -29,20 +30,23 @@ import {LdapSecurityComponent} from "./security-configuration/ldap-security/ldap
  */
 
 const routes: Routes = [
-      { path: '', component: SecurityConfigurationComponent,canActivate:[Guard],
-        data: { perm: 'menu.security.config' },
+    {
+        path: '', component: SecurityConfigurationComponent, canActivate: [Guard],
+        data: {perm: 'menu.security.config'},
         children: [
-          {path: 'base', component: BaseSecurityComponent},
+            {path: 'base', component: BaseSecurityComponent},
+            {path: 'properties', component: SecurityPropertiesComponent},
             {path: 'ldap', component: LdapSecurityComponent},
-          {path: '', redirectTo:'base',pathMatch:'full'}
+            {path: '', redirectTo: 'base', pathMatch: 'full'}
         ]
-      }
+    }
 ];
 
 @NgModule({
-  imports: [RouterModule.forChild(routes)],
-  exports: [],
-  declarations: []
+    imports: [RouterModule.forChild(routes)],
+    exports: [],
+    declarations: []
 })
-export class SecurityConfigurationRoutingModule { }
+export class SecurityConfigurationRoutingModule {
+}
 
index e5ee115049bd769e6b36f56f6ffdc1fbbb68b9d1..a36d79693394e3a229b40af20a0cab4cdd20b3fb 100644 (file)
@@ -24,13 +24,15 @@ import {SecurityConfigurationComponent} from "./security-configuration/security-
 import {SecurityConfigurationRoutingModule} from "@app/modules/security/security-configuration-routing.module";
 import { BaseSecurityComponent } from './security-configuration/base-security/base-security.component';
 import { LdapSecurityComponent } from './security-configuration/ldap-security/ldap-security.component';
+import { SecurityPropertiesComponent } from './security-configuration/security-properties/security-properties.component';
 
 
 @NgModule({
     declarations: [
         SecurityConfigurationComponent,
         BaseSecurityComponent,
-        LdapSecurityComponent
+        LdapSecurityComponent,
+        SecurityPropertiesComponent
     ],
     exports: [
         SecurityConfigurationComponent
index f7940741f6eeda9d97fb755d8f56c1d2cdcfeb91..aa2d70615e999871db03e24b5029a6e00972d076 100644 (file)
     <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>
+               for="{{attName}}"
+               [openDelay]="500"
+               [ngbTooltip]="'security.config.ldap.attdesc.'+attName|translate" placement="top"
+        >{{'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}}"
     </div>
     <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>
+               for="context_factory"
+               [openDelay]="500" [ngbTooltip]="'security.config.ldap.attdesc.context_factory'|translate" placement="top"
+        >{{'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"
-                   [placement]="top"
+                   [placement]="'top'"
             >
         </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>
+               for="authentication_method"
+               [openDelay]="500" [ngbTooltip]="'security.config.ldap.attdesc.authentication_method'|translate" placement="top"
+        >{{'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>
                  *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}}">
-                <label class="form-check-label " for="{{flagName}}">
+                <label class="form-check-label " for="{{flagName}}"
+                       [openDelay]="500" [ngbTooltip]="'security.config.ldap.attdesc.'+flagName|translate" placement="top"
+                >
                     {{'security.config.ldap.attributes.' + flagName|translate}}
                 </label>
             </div>
         </div>
     </div>
     <div class="form-group row col-md-10" >
-        <div class="col-md-3">{{'security.config.ldap.attributes.properties'|translate}}</div>
+        <div class="col-md-3"
+             [openDelay]="500" [ngbTooltip]="'security.config.ldap.attdesc.properties'|translate" placement="top"
+        >{{'security.config.ldap.attributes.properties'|translate}}</div>
         <div class="col-md-7 form-row">
             <input type="text" id="prop_key" formControlName="prop_key" class="form-control col" placeholder="{{'form.button.key'|translate}}"
 
index 340af07341d6d4851e4bc0bc424a7d5647800c0d..bcbe2c9b9c19837f6ad809b148fad10d3c14c710 100644 (file)
@@ -20,6 +20,9 @@
     <li class="nav-item">
         <a class="nav-link" routerLink="/security/config/base" routerLinkActive="active" href="#">{{'security.config.base.head' | translate}}</a>
     </li>
+    <li class="nav-item">
+        <a class="nav-link" routerLink="/security/config/properties" routerLinkActive="active" href="#">{{'security.config.properties.head' |translate }}</a>
+    </li>
     <li class="nav-item">
         <a class="nav-link" routerLink="/security/config/ldap" routerLinkActive="active" href="#">{{'security.config.ldap.head' |translate }}</a>
     </li>
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.html
new file mode 100644 (file)
index 0000000..59bcdef
--- /dev/null
@@ -0,0 +1,39 @@
+<app-paginated-entities [service]="service" pageSize="10" [(sortField)]="sortField" [(sortOrder)]="sortOrder"
+                        #parent>
+    <ng-container *ngIf="parent.items$ |async as roleItemLoader" >
+        <ng-template [ngIf]="roleItemLoader.loading" #spinner let-modal>
+            <div class="fixed-top d-flex justify-content-center mt-5 pt-5">
+                <div class="spinner-border text-info mt-5" role="status">
+                    <span class="sr-only">Loading...</span>
+                </div>
+            </div>
+        </ng-template>
+    </ng-container>
+    <ng-container *ngIf="parent.items$ |stripLoading|async as propertyItem" >
+        <table class="table table-striped table-bordered">
+            <thead class="thead-light">
+            <tr sorted [sortFieldEmitter]="parent.sortFieldChange" [sortOrderEmitter]="parent.sortOrderChange"
+                [toggleObserver]="parent">
+                <app-th-sorted [fieldArray]="['key']" contentText="security.config.properties.attributes.key"></app-th-sorted>
+                <app-th-sorted [fieldArray]="['value']" contentText="security.config.properties.attributes.value"></app-th-sorted>
+                <th>{{'headers.action' |translate}}</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr *ngFor="let propertyEntry  of propertyItem.data" >
+                <td>{{propertyEntry.key}}</td>
+                <td>{{propertyEntry.value}}</td>
+                <td>
+                    <a [routerLink]="['..','edit', propertyEntry.key]"
+                       [attr.title]="'security.config.properties.edit' |translate"><span class="fas fa-edit"></span></a>
+                    <a class="ml-2" [routerLink]="['..','delete', propertyEntry.key]"
+                       [attr.title]="'security.config.properties.delete' |translate"><span class="fas fa-trash-alt"></span></a>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </ng-container>
+
+</app-paginated-entities>
+
+
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.scss b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.scss
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.spec.ts
new file mode 100644 (file)
index 0000000..d122830
--- /dev/null
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SecurityPropertiesComponent } from './security-properties.component';
+
+describe('SecurityPropertiesComponent', () => {
+  let component: SecurityPropertiesComponent;
+  let fixture: ComponentFixture<SecurityPropertiesComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ SecurityPropertiesComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SecurityPropertiesComponent);
+    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/app/modules/security/security-configuration/security-properties/security-properties.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-properties/security-properties.component.ts
new file mode 100644 (file)
index 0000000..961866a
--- /dev/null
@@ -0,0 +1,27 @@
+import {Component, OnInit} from '@angular/core';
+import {SortedTableComponent} from "@app/modules/shared/sorted-table-component";
+import {PropertyEntry} from '@app/model/property-entry';
+import {TranslateService} from "@ngx-translate/core";
+import {Observable} from "rxjs";
+import {PagedResult} from "@app/model/paged-result";
+import {SecurityService} from "@app/services/security.service";
+
+@Component({
+    selector: 'app-security-properties',
+    templateUrl: './security-properties.component.html',
+    styleUrls: ['./security-properties.component.scss']
+})
+export class SecurityPropertiesComponent extends SortedTableComponent<PropertyEntry> implements OnInit {
+
+    constructor(translator: TranslateService, securityService: SecurityService) {
+        super(translator, function (searchTerm: string, offset: number, limit: number, orderBy: string[], order: string): Observable<PagedResult<PropertyEntry>> {
+            // console.log("Retrieving data " + searchTerm + "," + offset + "," + limit + "," + orderBy + "," + order);
+            return securityService.queryProperties(searchTerm, offset, limit, orderBy, order);
+        });
+        super.sortField=['key']
+    }
+
+    ngOnInit(): void {
+    }
+
+}
index 244257ab14491de299d73ceaa84eae9fa197d6c2..8902341b13a5f4898fd152900bb1e264a32480d6 100644 (file)
@@ -24,6 +24,9 @@ import {catchError, map} from "rxjs/operators";
 import {HttpErrorResponse, HttpResponse} from "@angular/common/http";
 import {BeanInformation} from "@app/model/bean-information";
 import {LdapConfiguration} from "@app/model/ldap-configuration";
+import {PagedResult} from "@app/model/paged-result";
+import {Role} from "@app/model/role";
+import {PropertyEntry} from "@app/model/property-entry";
 
 @Injectable({
   providedIn: 'root'
@@ -94,5 +97,23 @@ export class SecurityService {
         );
     }
 
+    queryProperties(searchTerm: string, offset: number = 0, limit: number = 10, orderBy: string[] = ['key'], order: string = 'asc'): Observable<PagedResult<PropertyEntry>> {
+        if (searchTerm == null) {
+            searchTerm = ""
+        }
+        if (orderBy == null || orderBy.length == 0) {
+            orderBy = ['key'];
+        }
+        return this.rest.executeRestCall<PagedResult<PropertyEntry>>("get", "archiva", "security/config/properties", {
+            'q': searchTerm,
+            'offset': offset,
+            'limit': limit,
+            'orderBy': orderBy,
+            'order': order
+        }).pipe(
+            catchError((error: HttpErrorResponse) => {
+                return throwError(this.rest.getTranslatedErrorResult(error));
+            }));
+    }
 
 }
index dff49c78e38438dd9e9530f64141a220e83f17c0..18074b7d47919d0d9ca495ae66ceff4779bc21ce 100644 (file)
           "ssl_enabled": "Enable SSL",
           "context_factory": "Context Factory",
           "properties": "Properties"
-
+        },
+        "attdesc": {
+          "host_name": "Fully qualified LDAP Server Name",
+          "port": "Port, on which the LDAP server is listening (389, 636, ...)",
+          "base_dn": "The Base DN used during bind and ldap queries",
+          "groups_base_dn": "The full DN used as base for searching groups",
+          "bind_dn": "The name or DN of the bind user, which is used to query the LDAP server",
+          "bind_password": "The password to use for binding to the LDAP server",
+          "authentication_method": "The method used to bind to the LDAP server. If strong is used, you may have to set additional properties.",
+          "bind_authenticator_enabled": "If true, LDAP query and bind is used for Archiva Login.",
+          "use_role_name_as_group": "If true, each role as a LDAP group with the same name",
+          "writable": "If true, attributes in the LDAP server can be modified",
+          "ssl_enabled": "If true, SSL/TLS is used for connecting to the LDAP server. You may have to add certificates to the keystore.",
+          "context_factory": "The LDAP JNDI Context Factory to use",
+          "properties": "Add additional environment properties for creating the initial directory context"
         },
         "flags": "Flags"
+      },
+      "properties": {
+        "head": "Properties",
+        "attributes": {
+          "key": "Key",
+          "value": "Value"
+        }
       }
     }
   },