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

commit cb3c2e2e041577df0de25f9c5b6c180cd58bc491
Author: Martin Stockhammer <[email protected]>
AuthorDate: Fri Jan 8 22:18:14 2021 +0100

    Adding base security config
---
 .../src/main/archiva-web/package-lock.json         |  17 +++
 .../src/main/archiva-web/package.json              |   1 +
 .../main/archiva-web/src/app/app-routing.module.ts |   8 +-
 .../src/main/archiva-web/src/app/app.module.ts     |   1 -
 .../src/app/model/bean-information.spec.ts         |   7 ++
 .../archiva-web/src/app/model/bean-information.ts  |   7 ++
 .../main/archiva-web/src/app/model/error-result.ts |  28 +++++
 ...or-result.ts => security-configuration.spec.ts} |  15 +--
 .../{error-result.ts => security-configuration.ts} |  13 +-
 .../app/modules/security/role-routing.module.ts    |   2 +-
 ...ts => security-configuration-routing.module.ts} |  29 ++---
 .../security/security-configuration.module.ts      |  47 +++++++
 .../base-security/base-security.component.html     |  83 +++++++++++++
 .../base-security/base-security.component.scss}    |  41 +++++--
 .../base-security/base-security.component.spec.ts} |  31 +++--
 .../base-security/base-security.component.ts       | 136 +++++++++++++++++++++
 .../ldap-security.component.html}                  |   2 +-
 .../ldap-security/ldap-security.component.scss}    |  12 +-
 .../ldap-security/ldap-security.component.spec.ts} |  31 +++--
 .../ldap-security/ldap-security.component.ts}      |  19 +--
 .../security-configuration.component.html          |  11 +-
 .../app/modules/security/user-routing.module.ts    |   2 +-
 .../src/app/modules/shared/shared.module.ts        |   5 +-
 .../shared/sidemenu/sidemenu.component.html        |  10 +-
 .../src/app/services/archiva-request.service.ts    |  12 ++
 .../security.service.spec.ts}                      |  22 ++--
 .../src/app/services/security.service.ts           |  69 +++++++++++
 .../archiva-web/src/app/services/user.service.ts   |  25 ++--
 .../src/main/archiva-web/src/assets/i18n/en.json   |  30 ++++-
 29 files changed, 604 insertions(+), 112 deletions(-)

diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package-lock.json
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package-lock.json
index d214b09..4c3d50e 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package-lock.json
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package-lock.json
@@ -177,6 +177,23 @@
         "tslib": "^2.0.0"
       }
     },
+    "@angular/cdk": {
+      "version": "11.0.3",
+      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-11.0.3.tgz";,
+      "integrity": 
"sha512-hgbJXvZURKBnZawwxUrsZE/3a+HCJh2UhoLIng3cn5Q+WIW/4a37knDl8B9DYKBWrCqeINXNcUHVSKkWc/gjCA==",
+      "requires": {
+        "parse5": "^5.0.0",
+        "tslib": "^2.0.0"
+      },
+      "dependencies": {
+        "parse5": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz";,
+          "integrity": 
"sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+          "optional": true
+        }
+      }
+    },
     "@angular/cli": {
       "version": "11.0.2",
       "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.0.2.tgz";,
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package.json 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package.json
index 3f686c4..06b6666 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package.json
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package.json
@@ -12,6 +12,7 @@
   "private": true,
   "dependencies": {
     "@angular/animations": "~11.0.2",
+    "@angular/cdk": "^11.0.3",
     "@angular/common": "~11.0.2",
     "@angular/compiler": "~11.0.2",
     "@angular/core": "~11.0.2",
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app-routing.module.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app-routing.module.ts
index aa5083d..e3d9e88 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app-routing.module.ts
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app-routing.module.ts
@@ -48,11 +48,11 @@ const routes: Routes = [
     },
 
     {
-        path: 'security', component: 
HomeComponent,canActivate:[Guard],data:{perm: 'menu.user.section'},
+        path: 'security', component: 
HomeComponent,canActivate:[Guard],data:{perm: 'menu.security.section'},
         children: [
-            {path: 'users', loadChildren: () => 
import('./modules/security/user.module').then(m => m.UserModule)},
-            {path: 'roles', loadChildren: () => 
import('./modules/security/role.module').then(m => m.RoleModule)},
-            {path: 'config', component: SecurityConfigurationComponent},
+            {path: 'users', loadChildren: () => 
import('@app/modules/security/user.module').then(m => m.UserModule)},
+            {path: 'roles', loadChildren: () => 
import('@app/modules/security/role.module').then(m => m.RoleModule)},
+            {path: 'config', loadChildren: () => 
import('@app/modules/security/security-configuration.module').then(m => 
m.SecurityConfigurationModule)},
         ]
     },
     {path: 'contact', component: ContactComponent},
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app.module.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app.module.ts
index d312023..9cc81b6 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app.module.ts
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app.module.ts
@@ -55,7 +55,6 @@ import {TranslateCompiler, TranslateLoader, TranslateModule} 
from "@ngx-translat
     SearchComponent,
     BrowseComponent,
     UploadComponent,
-    SecurityConfigurationComponent,
   ],
   imports: [
     TranslateModule.forRoot({
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
new file mode 100644
index 0000000..138cadc
--- /dev/null
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.spec.ts
@@ -0,0 +1,7 @@
+import { BeanInformation } from './bean-information';
+
+describe('BeanInformation', () => {
+  it('should create an instance', () => {
+    expect(new BeanInformation()).toBeTruthy();
+  });
+});
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
new file mode 100644
index 0000000..379262a
--- /dev/null
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/bean-information.ts
@@ -0,0 +1,7 @@
+export class BeanInformation {
+    id: string;
+    display_name: string;
+    description_key: string;
+    default_description: string;
+    readonly: boolean;
+}
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 b54fa84..4dd0348 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
@@ -25,4 +25,32 @@ export class ErrorResult {
     constructor(errorMessages: Array<ErrorMessage>) {
         this.error_messages = errorMessages;
     }
+
+    hasMessages() :boolean {
+        return this.error_messages != null && this.error_messages.length > 0;
+    }
+
+    public firstMessage() : ErrorMessage {
+        if (this.error_messages!=null && this.error_messages.length>0) {
+            return this.error_messages[0];
+        } else {
+            return new ErrorMessage();
+        }
+    }
+
+    public firstMessageString() : string {
+        if (this.error_messages!=null && this.error_messages.length>0) {
+            return this.error_messages[0].message;
+        } else {
+            return '';
+        }
+    }
+
+    public toString() : string {
+        if (this.error_messages!=null && this.error_messages.length>0) {
+            return this.error_messages.join(',');
+        } else {
+            return 'status=' + this.status;
+        }
+    }
 }
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/security-configuration.spec.ts
similarity index 76%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/security-configuration.spec.ts
index b54fa84..a02ee7a 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/security-configuration.spec.ts
@@ -16,13 +16,10 @@
  * under the License.
  */
 
-import {ErrorMessage} from "./error-message";
+import { SecurityConfiguration } from './security-configuration';
 
-export class ErrorResult {
-    error_messages: Array<ErrorMessage>
-    status: number;
-
-    constructor(errorMessages: Array<ErrorMessage>) {
-        this.error_messages = errorMessages;
-    }
-}
+describe('SecurityConfiguration', () => {
+  it('should create an instance', () => {
+    expect(new SecurityConfiguration()).toBeTruthy();
+  });
+});
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/security-configuration.ts
similarity index 77%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/security-configuration.ts
index b54fa84..5d9dc8e 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/security-configuration.ts
@@ -16,13 +16,10 @@
  * under the License.
  */
 
-import {ErrorMessage} from "./error-message";
+export class SecurityConfiguration {
 
-export class ErrorResult {
-    error_messages: Array<ErrorMessage>
-    status: number;
-
-    constructor(errorMessages: Array<ErrorMessage>) {
-        this.error_messages = errorMessages;
-    }
+    active_user_managers: string[];
+    active_rbac_managers: string[];
+    ldap_active: boolean;
+    user_cache_enabled: boolean;
 }
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts
index 1be49d7..05d9265 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts
@@ -31,7 +31,7 @@ import {ManageRolesEditComponent} from 
"@app/modules/security/roles/manage-roles
 const routes: Routes = [
     {
         path: '', component: ManageRolesComponent, canActivate: [Guard],
-        data: {perm: 'menu.user.roles'},
+        data: {perm: 'menu.security.roles'},
         children: [
             {path: 'list', component: ManageRolesListComponent},
             {path: 'edit/:roleid', component: ManageRolesEditComponent},
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration-routing.module.ts
similarity index 59%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration-routing.module.ts
index 1be49d7..4b40ce4 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/role-routing.module.ts
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration-routing.module.ts
@@ -18,9 +18,9 @@
 import {NgModule} from '@angular/core';
 import {RouterModule, Routes} from '@angular/router';
 import {RoutingGuardService as Guard} from 
"@app/services/routing-guard.service";
-import {ManageRolesComponent} from 
"@app/modules/security/roles/manage-roles/manage-roles.component";
-import {ManageRolesListComponent} from 
"@app/modules/security/roles/manage-roles-list/manage-roles-list.component";
-import {ManageRolesEditComponent} from 
"@app/modules/security/roles/manage-roles-edit/manage-roles-edit.component";
+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";
 
 
 /**
@@ -29,23 +29,20 @@ import {ManageRolesEditComponent} from 
"@app/modules/security/roles/manage-roles
  */
 
 const routes: Routes = [
-    {
-        path: '', component: ManageRolesComponent, canActivate: [Guard],
-        data: {perm: 'menu.user.roles'},
+      { path: '', component: 
SecurityConfigurationComponent,canActivate:[Guard],
+        data: { perm: 'menu.security.config' },
         children: [
-            {path: 'list', component: ManageRolesListComponent},
-            {path: 'edit/:roleid', component: ManageRolesEditComponent},
-            {path: 'edit', component: ManageRolesEditComponent},
-            {path: '', redirectTo: 'list', pathMatch: 'full'}
+          {path: 'base', component: BaseSecurityComponent},
+            {path: 'ldap', component: LdapSecurityComponent},
+          {path: '', redirectTo:'base',pathMatch:'full'}
         ]
-    }
+      }
 ];
 
 @NgModule({
-    imports: [RouterModule.forChild(routes)],
-    exports: [],
-    declarations: []
+  imports: [RouterModule.forChild(routes)],
+  exports: [],
+  declarations: []
 })
-export class RoleRoutingModule {
-}
+export class SecurityConfigurationRoutingModule { }
 
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration.module.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration.module.ts
new file mode 100644
index 0000000..e5ee115
--- /dev/null
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration.module.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {SharedModule} from "@app/modules/shared/shared.module";
+import {FormsModule, ReactiveFormsModule} from "@angular/forms";
+import {SecurityConfigurationComponent} from 
"./security-configuration/security-configuration.component";
+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';
+
+
+@NgModule({
+    declarations: [
+        SecurityConfigurationComponent,
+        BaseSecurityComponent,
+        LdapSecurityComponent
+    ],
+    exports: [
+        SecurityConfigurationComponent
+    ],
+    imports: [
+        CommonModule,
+        SharedModule,
+        FormsModule,
+        ReactiveFormsModule,
+        SecurityConfigurationRoutingModule
+    ]
+})
+export class SecurityConfigurationModule {
+}
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
new file mode 100644
index 0000000..fcf545f
--- /dev/null
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.html
@@ -0,0 +1,83 @@
+<!--
+  ~ 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.
+  -->
+
+<form class="mt-3 mb-3" [formGroup]="userForm" (ngSubmit)="onSubmit()">
+    <div class="row">
+        <div class="col-md-4">
+            <div class="drag-container">
+                <div class="section-heading 
mb-2">{{'security.config.base.user_manager.active_list'|translate}}</div>
+                <div cdkDropList #activeUserManagersList="cdkDropList" 
[cdkDropListData]="activeUserManagers" 
[cdkDropListConnectedTo]="[availableUserManagersList]"
+                     class="drop-list-group" 
(cdkDropListDropped)="drop($event)">
+                    <div class="list-group-item" *ngFor="let item of 
activeUserManagers" cdkDrag>{{item.id}} - {{item.display_name}}</div>
+                </div>
+            </div>
+        </div>
+        <div class="col-md-4">
+            <div class="drag-container">
+                <div class="section-heading 
mb-2">{{'security.config.base.user_manager.available_list' |translate}}</div>
+                <div cdkDropList #availableUserManagersList="cdkDropList" 
[cdkDropListData]="availableUserManagers" 
[cdkDropListConnectedTo]="[activeUserManagersList]"
+                     class="drop-list-group" 
(cdkDropListDropped)="drop($event)">
+                    <div class="list-group-item" *ngFor="let item of 
availableUserManagers" cdkDrag>{{item.id}} - {{item.display_name}}</div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="row">
+        <div class="col-md-4">
+            <div class="drag-container">
+                <div class="section-heading 
mb-2">{{'security.config.base.rbac_manager.active_list'|translate}}</div>
+                <div cdkDropList #activeRbacManagersList="cdkDropList" 
[cdkDropListData]="activeRbacManagers" 
[cdkDropListConnectedTo]="[availableRbacManagersList]"
+                     class="drop-list-group" 
(cdkDropListDropped)="drop($event)">
+                    <div class="list-group-item" *ngFor="let item of 
activeRbacManagers" cdkDrag>{{item.id}} - {{item.display_name}}</div>
+                </div>
+            </div>
+        </div>
+        <div class="col-md-4">
+            <div class="drag-container">
+                <div class="section-heading 
mb-2">{{'security.config.base.rbac_manager.available_list' |translate}}</div>
+                <div cdkDropList #availableRbacManagersList="cdkDropList" 
[cdkDropListData]="availableRbacManagers" 
[cdkDropListConnectedTo]="[activeRbacManagersList]"
+                     class="drop-list-group" 
(cdkDropListDropped)="drop($event)">
+                    <div class="list-group-item" *ngFor="let item of 
availableRbacManagers" cdkDrag>{{item.id}} - {{item.display_name}}</div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="form-group row col-md-8">
+        <div class="col-md-2">{{'security.config.base.flags'|translate}}</div>
+        <div class="col-md-4">
+            <div class="form-check">
+                <input class="form-check-input" type="checkbox" 
formControlName="user_cache_enabled"
+                       id="user_cache_enabled" >
+                <label class="user_cache_enabled " for="user_cache_enabled">
+                    
{{'security.config.base.attributes.user_cache_enabled'|translate}}
+                </label>
+            </div>
+        </div>
+
+
+    </div>
+
+    <div class="form-group row" >
+        <div class="col-md-4">
+            <button class="btn btn-primary" 
[class.disabled]="enableSubmit()?null:'true'"
+                    type="submit">{{'users.edit.submit'|translate}}</button>
+        </div>
+    </div>
+
+</form>
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/modules/security/security-configuration/base-security/base-security.component.scss
similarity index 55%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.scss
index b54fa84..1517b39 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/modules/security/security-configuration/base-security/base-security.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * 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
@@ -16,13 +16,38 @@
  * under the License.
  */
 
-import {ErrorMessage} from "./error-message";
+.drag-container {
+  width: 400px;
+  max-width: 100%;
+  margin: 0 25px 25px 0;
+  display: inline-block;
+  vertical-align: top;
+  background-color: #E9ECEF;
+  padding: 15px;
+  border-radius: 5px;
+}
 
-export class ErrorResult {
-    error_messages: Array<ErrorMessage>
-    status: number;
+.drop-list-group  {
+  @extend .list-group;
+  background: white;
+  min-height: 50px;
+}
 
-    constructor(errorMessages: Array<ErrorMessage>) {
-        this.error_messages = errorMessages;
-    }
+.cdk-drag-preview  {
+  @extend .list-group-item;
 }
+
+.cdk-drag-placeholder {
+  opacity: 0;
+}
+
+.cdk-drag-animating {
+  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
+}
+
+.cdk-drop-list-receiving extends list-group-item {
+}
+
+.list-group.cdk-drop-list-dragging .list-group-item:not(.cdk-drag-placeholder) 
{
+  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
+}
\ No newline at end of file
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/modules/security/security-configuration/base-security/base-security.component.spec.ts
similarity index 54%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.spec.ts
index b54fa84..2487b32 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/modules/security/security-configuration/base-security/base-security.component.spec.ts
@@ -16,13 +16,28 @@
  * under the License.
  */
 
-import {ErrorMessage} from "./error-message";
+import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-export class ErrorResult {
-    error_messages: Array<ErrorMessage>
-    status: number;
+import { BaseSecurityComponent } from './base-security.component';
 
-    constructor(errorMessages: Array<ErrorMessage>) {
-        this.error_messages = errorMessages;
-    }
-}
+describe('BaseSecurityComponent', () => {
+  let component: BaseSecurityComponent;
+  let fixture: ComponentFixture<BaseSecurityComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ BaseSecurityComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(BaseSecurityComponent);
+    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/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
new file mode 100644
index 0000000..4b3acf5
--- /dev/null
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/base-security/base-security.component.ts
@@ -0,0 +1,136 @@
+/*
+ * 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 {AfterContentInit, Component, OnInit} from '@angular/core';
+import {ActivatedRoute} from "@angular/router";
+import {RoleService} from "@app/services/role.service";
+import {UserService} from "@app/services/user.service";
+import {FormBuilder} from "@angular/forms";
+import {ToastService} from "@app/services/toast.service";
+import {EditBaseComponent} from "@app/modules/shared/edit-base.component";
+import {SecurityConfiguration} from "@app/model/security-configuration";
+import { CdkDragDrop, moveItemInArray, transferArrayItem } from 
'@angular/cdk/drag-drop';
+import {SecurityService} from "@app/services/security.service";
+import {switchMap, tap, withLatestFrom} from 'rxjs/operators';
+import {BeanInformation} from "@app/model/bean-information";
+import {zip} from "rxjs";
+import {ErrorResult} from "@app/model/error-result";
+
+@Component({
+  selector: 'app-base-security',
+  templateUrl: './base-security.component.html',
+  styleUrls: ['./base-security.component.scss']
+})
+export class BaseSecurityComponent extends 
EditBaseComponent<SecurityConfiguration> implements OnInit, AfterContentInit  {
+
+  activeUserManagers : BeanInformation[] = [];
+  availableUserManagers: BeanInformation[] = [];
+  activeRbacManagers: BeanInformation[] = [];
+  availableRbacManagers: BeanInformation[] = [];
+
+  submitting: boolean = false;
+
+  rbacInfo: Map<string,BeanInformation> = new Map<string, BeanInformation>();
+  userInfo: Map<string,BeanInformation> = new Map<string, BeanInformation>();
+
+  drop(event: CdkDragDrop<string[]>) {
+    console.log("Drop " + event);
+    if (event.previousContainer === event.container) {
+      moveItemInArray(event.container.data, event.previousIndex, 
event.currentIndex);
+    } else {
+      transferArrayItem(event.previousContainer.data,
+          event.container.data,
+          event.previousIndex,
+          event.currentIndex);
+    }
+  }
+
+  constructor(private route: ActivatedRoute,
+              public fb: FormBuilder, private securityService: 
SecurityService, private toastService: ToastService) {
+    super(fb);
+    super.init(fb.group({
+      user_cache_enabled:[''],
+    }, {}));
+
+
+
+  }
+
+  ngOnInit(): void {
+    
zip(this.securityService.getRbacManagers(),this.securityService.getUserManagers()).pipe(tap(([rbacInfo,userInfo])=>{
+      rbacInfo.forEach(info => this.rbacInfo.set(info.id, info));
+      userInfo.forEach(info => this.userInfo.set(info.id, info));
+      console.log("Rbac info " + JSON.stringify(this.rbacInfo));
+      console.log("User info " + JSON.stringify(this.userInfo));
+    
}),switchMap(()=>this.securityService.getConfiguration())).subscribe(userConfig=>{
+      this.activeRbacManagers=[];
+      this.activeUserManagers=[];
+      this.availableRbacManagers=[];
+      this.availableUserManagers=[];
+      
this.userForm.get('user_cache_enabled').setValue(userConfig.user_cache_enabled);
+      let availableRbacManagers : string[] = Array.from(this.rbacInfo.keys())
+      let availableUserManagers : string[] = Array.from(this.userInfo.keys());
+      userConfig.active_rbac_managers.forEach(rbacId=>{
+        this.activeRbacManagers.push(this.rbacInfo.get(rbacId));
+        availableRbacManagers = availableRbacManagers.filter(item => item != 
rbacId);
+      });
+      userConfig.active_user_managers.forEach(userId=>{
+        this.activeUserManagers.push(this.userInfo.get(userId));
+        availableUserManagers = availableUserManagers.filter(item => item != 
userId);
+      });
+      availableRbacManagers.forEach(rbacId => 
this.availableRbacManagers.push(this.rbacInfo.get(rbacId)));
+      availableUserManagers.forEach(userId => 
this.availableUserManagers.push(this.userInfo.get(userId)));
+    })
+  }
+
+  createEntity(): SecurityConfiguration {
+    return undefined;
+  }
+
+  onSubmit() {
+    if (this.activeUserManagers.length>0 && this.activeRbacManagers.length>0) {
+      this.submitting=true;
+      let sConfig = new SecurityConfiguration()
+      sConfig.active_user_managers = [];
+      sConfig.active_user_managers = this.activeUserManagers.map(uInfo => 
uInfo.id);
+      sConfig.active_rbac_managers = this.activeRbacManagers.map(rInfo => 
rInfo.id);
+      sConfig.user_cache_enabled = 
this.userForm.get('user_cache_enabled').value;
+      this.securityService.updateConfiguration(sConfig).subscribe(()=>
+          {
+            
this.toastService.showSuccessByKey('base-security','security.config.base.submit_success')
+            this.submitting = false;
+          }, ( error :ErrorResult) => {
+            
this.toastService.showErrorByKey('base-security','security.config.base.submit_error',
+                {'error':error.toString()})
+            this.submitting = false;
+          }
+      );
+    } else {
+      
this.toastService.showErrorByKey('base-security','security.config.base.submit_active_empty')
+    }
+
+  }
+
+  ngAfterContentInit(): void {
+  }
+
+  enableSubmit() : boolean {
+    return !this.submitting && this.activeUserManagers.length>0 && 
this.activeRbacManagers.length>0 && this.userForm.valid;
+  }
+
+}
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-configuration.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
similarity index 95%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-configuration.component.html
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.html
index ec4f0f9..55895d8 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-configuration.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,4 @@
   ~ under the License.
   -->
 
-<p>security-configuration works!</p>
+<p>ldap-security works!</p>
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/modules/security/security-configuration/ldap-security/ldap-security.component.scss
similarity index 76%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.scss
index b54fa84..343c3b1 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/modules/security/security-configuration/ldap-security/ldap-security.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * 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
@@ -16,13 +16,3 @@
  * under the License.
  */
 
-import {ErrorMessage} from "./error-message";
-
-export class ErrorResult {
-    error_messages: Array<ErrorMessage>
-    status: number;
-
-    constructor(errorMessages: Array<ErrorMessage>) {
-        this.error_messages = errorMessages;
-    }
-}
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/modules/security/security-configuration/ldap-security/ldap-security.component.spec.ts
similarity index 54%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.spec.ts
index b54fa84..7de23ee 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/modules/security/security-configuration/ldap-security/ldap-security.component.spec.ts
@@ -16,13 +16,28 @@
  * under the License.
  */
 
-import {ErrorMessage} from "./error-message";
+import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-export class ErrorResult {
-    error_messages: Array<ErrorMessage>
-    status: number;
+import { LdapSecurityComponent } from './ldap-security.component';
 
-    constructor(errorMessages: Array<ErrorMessage>) {
-        this.error_messages = errorMessages;
-    }
-}
+describe('LdapSecurityComponent', () => {
+  let component: LdapSecurityComponent;
+  let fixture: ComponentFixture<LdapSecurityComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ LdapSecurityComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(LdapSecurityComponent);
+    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/model/error-result.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.ts
similarity index 72%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/ldap-security/ldap-security.component.ts
index b54fa84..3c3b095 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/modules/security/security-configuration/ldap-security/ldap-security.component.ts
@@ -16,13 +16,18 @@
  * under the License.
  */
 
-import {ErrorMessage} from "./error-message";
+import { Component, OnInit } from '@angular/core';
 
-export class ErrorResult {
-    error_messages: Array<ErrorMessage>
-    status: number;
+@Component({
+  selector: 'app-ldap-security',
+  templateUrl: './ldap-security.component.html',
+  styleUrls: ['./ldap-security.component.scss']
+})
+export class LdapSecurityComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit(): void {
+  }
 
-    constructor(errorMessages: Array<ErrorMessage>) {
-        this.error_messages = errorMessages;
-    }
 }
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-configuration.component.html
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-configuration.component.html
index ec4f0f9..340af07 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-configuration.component.html
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/security-configuration/security-configuration.component.html
@@ -16,4 +16,13 @@
   ~ under the License.
   -->
 
-<p>security-configuration works!</p>
+<ul class="nav nav-tabs">
+    <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/ldap" 
routerLinkActive="active" href="#">{{'security.config.ldap.head' |translate 
}}</a>
+    </li>
+</ul>
+
+<router-outlet></router-outlet>
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/user-routing.module.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/user-routing.module.ts
index c1cae57..6f5f13a 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/user-routing.module.ts
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/user-routing.module.ts
@@ -33,7 +33,7 @@ import {RoutingGuardService as Guard} from 
"@app/services/routing-guard.service"
 
 const routes: Routes = [
       { path: '', component: ManageUsersComponent,canActivate:[Guard],
-        data: { perm: 'menu.user.manage' },
+        data: { perm: 'menu.security.users' },
         children: [
           {path: 'list', component: ManageUsersListComponent},
           {path: 'add', component: ManageUsersAddComponent},
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/shared.module.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/shared.module.ts
index 38fc25d..ce7f454 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/shared.module.ts
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/shared.module.ts
@@ -39,6 +39,7 @@ import { StripLoadingPipe } from './strip-loading.pipe';
 import { ToastComponent } from './toast/toast.component';
 import { UserInfoComponent } from './user-info/user-info.component';
 import {FormsModule} from "@angular/forms";
+import {DragDropModule} from "@angular/cdk/drag-drop";
 
 export { LoadingValue } from './model/loading-value';
 export { PageQuery } from './model/page-query';
@@ -68,9 +69,11 @@ export { PageQuery } from './model/page-query';
         SortedTableHeaderRowComponent,
         WithLoadingPipe,
         StripLoadingPipe,
-        ToastComponent
+        ToastComponent,
+        DragDropModule
     ],
     imports: [
+        DragDropModule,
         CommonModule,
         RouterModule,
         NgbPaginationModule,
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/sidemenu/sidemenu.component.html
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/sidemenu/sidemenu.component.html
index cbded1e..670074e 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/sidemenu/sidemenu.component.html
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/sidemenu/sidemenu.component.html
@@ -52,15 +52,15 @@
         <a class="nav-link my-0 py-0" id="admin-reports" 
routerLink="/admin/reports" routerLinkActive="active" data-toggle="pill"
            [appViewPermission]="perms.menu.admin.reports" role="tab" 
aria-controls="v-pills-browse" 
aria-selected="false">{{'sidemenu.admin.reports'|translate}}</a>
     </div>
-    <div class="nav flex-column nav-pills" 
[appViewPermission]="perms.menu.user.section">
+    <div class="nav flex-column nav-pills" 
[appViewPermission]="perms.menu.security.section">
         <a class="nav-link disabled" href="#" tabindex="-1" 
aria-disabled="true" data-toggle="pill"
-           role="tab" aria-controls="v-pills-home" 
aria-selected="false">{{'sidemenu.user.section'|translate}}</a>
+           role="tab" aria-controls="v-pills-home" 
aria-selected="false">{{'sidemenu.security.section'|translate}}</a>
         <a class="nav-link my-0 py-0" id="users-manage" 
routerLink="/security/users" routerLinkActive="active" data-toggle="pill"
-           role="tab" aria-controls="v-pills-browse" 
aria-selected="false">{{'sidemenu.user.users'|translate}}</a>
+           role="tab" aria-controls="v-pills-browse" 
aria-selected="false">{{'sidemenu.security.users'|translate}}</a>
         <a class="nav-link my-0 py-0" id="users-roles" 
routerLink="/security/roles" routerLinkActive="active" data-toggle="pill"
-           role="tab" aria-controls="v-pills-browse" 
aria-selected="false">{{'sidemenu.user.roles'|translate}}</a>
+           role="tab" aria-controls="v-pills-browse" 
aria-selected="false">{{'sidemenu.security.roles'|translate}}</a>
         <a class="nav-link my-0 py-0" id="users-configuration" 
routerLink="/security/config" routerLinkActive="active" data-toggle="pill"
-           role="tab" aria-controls="v-pills-browse" 
aria-selected="false">{{'sidemenu.user.config'|translate}}</a>
+           role="tab" aria-controls="v-pills-browse" 
aria-selected="false">{{'sidemenu.security.config'|translate}}</a>
     </div>
     <div class="nav flex-column nav-pills" >
         <a class="nav-link disabled" href="#" tabindex="-1" 
aria-disabled="true" data-toggle="pill"
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 4e8ca0c..727032d 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
@@ -141,7 +141,19 @@ export class ArchivaRequestService {
     }
 
     public getTranslatedErrorResult(httpError : HttpErrorResponse) : 
ErrorResult {
+        console.log("Error " + httpError);
+        if (httpError == null) {
+            return new ErrorResult([]);
+        }
         let errorResult = httpError.error as ErrorResult;
+        if (errorResult==null) {
+            if (httpError.statusText!=null) {
+                errorResult = new 
ErrorResult([ErrorMessage.of(httpError.statusText)]);
+            } else {
+                errorResult = new ErrorResult([]);
+            }
+        }
+        console.log("Returning error " + errorResult);
         errorResult.status = httpError.status;
         if (errorResult.error_messages!=null) {
             for (let message of errorResult.error_messages) {
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/services/security.service.spec.ts
similarity index 68%
copy from 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/error-result.ts
copy to 
archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/security.service.spec.ts
index b54fa84..e73fd63 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/services/security.service.spec.ts
@@ -16,13 +16,19 @@
  * under the License.
  */
 
-import {ErrorMessage} from "./error-message";
+import { TestBed } from '@angular/core/testing';
 
-export class ErrorResult {
-    error_messages: Array<ErrorMessage>
-    status: number;
+import { SecurityService } from './security.service';
 
-    constructor(errorMessages: Array<ErrorMessage>) {
-        this.error_messages = errorMessages;
-    }
-}
+describe('SecurityService', () => {
+  let service: SecurityService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(SecurityService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/security.service.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/security.service.ts
new file mode 100644
index 0000000..954d448
--- /dev/null
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/security.service.ts
@@ -0,0 +1,69 @@
+/*
+ * 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 { Injectable } from '@angular/core';
+import {ArchivaRequestService} from "@app/services/archiva-request.service";
+import {SecurityConfiguration} from "@app/model/security-configuration";
+import {Observable, throwError} from "rxjs";
+import {catchError} from "rxjs/operators";
+import {HttpErrorResponse, HttpResponse} from "@angular/common/http";
+import {BeanInformation} from "@app/model/bean-information";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class SecurityService {
+
+  constructor(private rest:ArchivaRequestService) {
+
+  }
+
+  getConfiguration() : Observable<SecurityConfiguration> {
+    return this.rest.executeRestCall<SecurityConfiguration>("get", "archiva", 
"security/config", null).pipe(
+        catchError((error: HttpErrorResponse) => {
+          return throwError(this.rest.getTranslatedErrorResult(error));
+        })
+    );
+  }
+
+    updateConfiguration(securityConfiguration : SecurityConfiguration) : 
Observable<HttpResponse<any>> {
+        return this.rest.executeResponseCall<any>("put", "archiva", 
"security/config", securityConfiguration).pipe(
+            catchError((error: HttpErrorResponse) => {
+                console.log("Error thrown " + typeof (error));
+                return throwError(this.rest.getTranslatedErrorResult(error));
+            })
+        );
+    }
+
+    getRbacManagers() : Observable<BeanInformation[]> {
+        return this.rest.executeRestCall<BeanInformation[]>("get", "archiva", 
"security/rbac_managers", null).pipe(
+            catchError((error: HttpErrorResponse) => {
+                return throwError(this.rest.getTranslatedErrorResult(error));
+            })
+        );
+    }
+
+    getUserManagers() : Observable<BeanInformation[]> {
+        return this.rest.executeRestCall<BeanInformation[]>("get", "archiva", 
"security/user_managers", null).pipe(
+            catchError((error: HttpErrorResponse) => {
+                return throwError(this.rest.getTranslatedErrorResult(error));
+            })
+        );
+    }
+
+}
diff --git 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/user.service.ts
 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/user.service.ts
index fa89b40..12eea21 100644
--- 
a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/user.service.ts
+++ 
b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/user.service.ts
@@ -45,18 +45,18 @@ export class UserService implements OnInit, OnDestroy {
                 'search': true,
                 'upload': false
             },
+            'security':{
+                'section': false,
+                'roles': false,
+                'users': false,
+                'config': false
+            },
             'admin': {
                 'section': false,
                 'config': false,
                 'status': false,
                 'reports': false
             },
-            'user': {
-                'section': false,
-                'manage': false,
-                'roles': false,
-                'config': false
-            }
         }
     };
     uiPermissions;
@@ -181,21 +181,22 @@ export class UserService implements OnInit, OnDestroy {
                         this.uiPermissions.menu.admin.config = true;
                         this.uiPermissions.menu.admin.reports = true;
                         this.uiPermissions.menu.admin.status = true;
+                        this.uiPermissions.menu.security.section = true;
+                        this.uiPermissions.menu.security.config = true;
                     }
 
                 }
                 case "archiva-manage-users": {
                     if (perm.resource.identifier == '*') {
-                        this.uiPermissions.menu.user.section = true;
-                        this.uiPermissions.menu.user.config = true;
-                        this.uiPermissions.menu.user.manage = true;
-                        this.uiPermissions.menu.user.roles = true;
+                        this.uiPermissions.menu.security.section = true;
+                        this.uiPermissions.menu.security.users = true;
+                        this.uiPermissions.menu.security.roles = true;
                     }
                 }
                 case "redback-configuration-edit": {
                     if (perm.resource.identifier == '*') {
-                        this.uiPermissions.menu.user.section = true;
-                        this.uiPermissions.menu.user.config = true;
+                        this.uiPermissions.menu.security.section = true;
+                        this.uiPermissions.menu.security.config = true;
                     }
                 }
                 case "archiva-upload-file": {
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 645701e..834a1a2 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
@@ -44,8 +44,8 @@
       "status": "System Status",
       "reports": "Reports"
     },
-    "user": {
-      "section": "User",
+    "security": {
+      "section": "Security",
       "users": "Manage Users",
       "roles": "Manage Roles",
       "config": "Security Configuration"
@@ -172,6 +172,32 @@
       "assignable": "Assignable"
     }
   },
+  "security": {
+    "config": {
+      "base": {
+        "head": "Base Configuration",
+        "flags": "Flags",
+        "user_manager" : {
+          "active_list" : "Active User Managers",
+          "available_list" : "Available User Managers"
+        },
+        "rbac_manager" : {
+          "active_list": "Active RBAC Managers",
+          "available_list" : "Available RBAC Managers"
+        },
+        "attributes": {
+          "ldap_active": "LDAP Active",
+          "user_cache_enabled": "User Cache Enabled"
+        },
+        "submit_success": "The Changes were submitted successfully",
+        "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"
+      }
+    }
+  },
   "permissions": {
     "attributes": {
       "permission": "Permission",

Reply via email to