aboutsummaryrefslogtreecommitdiffstats
path: root/archiva-modules
diff options
context:
space:
mode:
authorMartin Stockhammer <martin_s@apache.org>2021-01-17 16:37:57 +0100
committerMartin Stockhammer <martin_s@apache.org>2021-01-17 16:37:57 +0100
commitebd46ab1cec4d76e9b40b49a41ac7886417b029f (patch)
tree0dfb1039dbb21dc54d856a82eaadb2c0ee4abe09 /archiva-modules
parented06b9d673a72ab9bb52297243a629dbb4f900a3 (diff)
downloadarchiva-ebd46ab1cec4d76e9b40b49a41ac7886417b029f.tar.gz
archiva-ebd46ab1cec4d76e9b40b49a41ac7886417b029f.zip
Adding role group mapping
Diffstat (limited to 'archiva-modules')
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group-mapping.spec.ts25
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group-mapping.ts23
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group.spec.ts25
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group.ts24
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html71
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts93
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html1
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts6
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/group.service.spec.ts34
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/group.service.ts71
-rw-r--r--archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json11
11 files changed, 352 insertions, 32 deletions
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group-mapping.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group-mapping.spec.ts
new file mode 100644
index 000000000..1f0b81cdc
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group-mapping.spec.ts
@@ -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 { GroupMapping } from './group-mapping';
+
+describe('GroupMapping', () => {
+ it('should create an instance', () => {
+ expect(new GroupMapping()).toBeTruthy();
+ });
+});
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group-mapping.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group-mapping.ts
new file mode 100644
index 000000000..4643fe5ef
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group-mapping.ts
@@ -0,0 +1,23 @@
+/*
+ * 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 GroupMapping {
+ group_name:string;
+ unique_group_name:string;
+ roles:string[];
+}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group.spec.ts
new file mode 100644
index 000000000..4d702030d
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group.spec.ts
@@ -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 { Group } from './group';
+
+describe('Group', () => {
+ it('should create an instance', () => {
+ expect(new Group()).toBeTruthy();
+ });
+});
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group.ts
new file mode 100644
index 000000000..d5f6fc87b
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/group.ts
@@ -0,0 +1,24 @@
+/*
+ * 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 Group {
+ name:string;
+ unique_name:string;
+ description:string;
+ member_list:string[];
+}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html
index bdbf7da47..47ac7c0e8 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.html
@@ -86,9 +86,9 @@
<ng-template ngbPanelHeader let-opened="opened">
<div class="d-flex align-items-center justify-content-between">
<button ngbPanelToggle class="btn btn-link text-left shadow-none">
- <h3>{{'roles.edit.parents'|translate}}</h3></button>
- <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container>
- <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container>
+ <h4>{{'roles.edit.parents'|translate}}</h4></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="opened"><i class="fa fa-eye-slash"></i></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="!opened"><i class="fa fa-eye"></i></button>
</div>
</ng-template>
<ng-template ngbPanelContent>
@@ -103,9 +103,9 @@
<ng-template ngbPanelHeader let-opened="opened">
<div class="d-flex align-items-center justify-content-between">
<button ngbPanelToggle class="btn btn-link text-left shadow-none">
- <h3>{{'roles.edit.children'|translate}}</h3></button>
- <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container>
- <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container>
+ <h4>{{'roles.edit.children'|translate}}</h4></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="opened"><i class="fa fa-eye-slash"></i></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="!opened"><i class="fa fa-eye"></i></button>
</div>
</ng-template>
<ng-template ngbPanelContent>
@@ -122,9 +122,9 @@
<div class="d-flex align-items-center justify-content-between">
<button ngbPanelToggle class="btn btn-link text-left shadow-none">
- <h3>{{'roles.edit.permissions'|translate}}</h3></button>
- <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container>
- <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container>
+ <h4>{{'roles.edit.permissions'|translate}}</h4></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="opened"><i class="fa fa-eye-slash"></i></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="!opened"><i class="fa fa-eye"></i></button>
</div>
</ng-template>
<ng-template ngbPanelContent>
@@ -154,9 +154,9 @@
<ng-template ngbPanelHeader let-opened="opened">
<div class="d-flex align-items-center justify-content-between">
<button ngbPanelToggle class="btn btn-link text-left shadow-none">
- <h3>{{'roles.edit.users'|translate}}</h3></button>
- <ng-container *ngIf="!opened"><i class="fa fa-eye-slash"></i></ng-container>
- <ng-container *ngIf="opened"><i class="fa fa-eye"></i></ng-container>
+ <h4>{{'roles.edit.users'|translate}}</h4></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="opened"><i class="fa fa-eye-slash"></i></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="!opened"><i class="fa fa-eye"></i></button>
</div>
</ng-template>
<ng-template ngbPanelContent>
@@ -244,8 +244,8 @@
<ngb-highlight [result]="r.user_id + ' - ' + r.full_name" [term]="t"></ngb-highlight>
</ng-template>
<div class="form-group">
- <label for="typeahead-http">{{'roles.edit.assignUserSearch'|translate}}</label>
- <input id="typeahead-http" type="text" class="form-control col-md-2"
+ <label for="userSearchField">{{'roles.edit.assignUserSearch'|translate}}</label>
+ <input id="userSearchField" type="text" class="form-control col-md-2"
name="userSearchField"
[class.is-invalid]="userSearchFailed" [resultTemplate]="userResultTemplate"
[inputFormatter]="getUserId"
@@ -260,12 +260,43 @@
</form>
</ng-template>
- <div *ngIf="success">
- Success
- </div>
- <div *ngIf="error">
- <div>Error {{errorResult.error_messages}}</div>
- </div>
</ngb-panel>
+ <ngb-panel id="groupMapping">
+ <ng-template ngbPanelHeader let-opened="opened">
+ <div class="d-flex align-items-center justify-content-between">
+ <button ngbPanelToggle class="btn btn-link text-left shadow-none">
+ <h4>{{'roles.edit.groupMapping'|translate}}</h4></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="opened"><i class="fa fa-eye-slash"></i></button>
+ <button class="btn btn-link shadow-none" ngbPanelToggle *ngIf="!opened"><i class="fa fa-eye"></i></button>
+ </div>
+ </ng-template>
+ <ng-template ngbPanelContent>
+ <ul class="list-group" >
+ <li class="list-group-item" *ngFor="let group of roleMappings$ |async">{{group}}</li>
+ </ul>
+ <form class="mt-2">
+ <ng-template #groupResultTemplate let-r="result" let-t="term">
+ <ngb-highlight [result]="r.name" [term]="t"></ngb-highlight>
+ </ng-template>
+
+ <div class="form-group">
+ <label for="groupSearchField">{{'roles.edit.assignGroupSearch'|translate}}</label>
+ <input id="groupSearchField" type="text" class="form-control col-md-2"
+ name="groupSearchField"
+ [class.is-invalid]="groupSearchFailed" [resultTemplate]="groupResultTemplate"
+ [inputFormatter]="getGroupName"
+ [placement]="'top'"
+ [(ngModel)]="groupSearchModel" [ngbTypeahead]="searchGroup" placeholder="Group Search"/>
+ <small *ngIf="groupSearching"
+ class="form-text text-muted">{{'form.searching' |translate}}</small>
+ <div class="invalid-feedback"
+ *ngIf="groupSearchFailed">{{'roles.edit.groupSearchFailed'|translate}}</div>
+ </div>
+ <button class="btn btn-primary" (click)="assignGroupRole()">{{'roles.edit.assignButton'|translate}}</button>
+ </form>
+ </ng-template>
+ </ngb-panel>
+
+
</ngb-accordion>
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts
index 49ab9f334..59f8feae2 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-edit/manage-roles-edit.component.ts
@@ -20,11 +20,11 @@ import {AfterContentInit, Component, EventEmitter, OnInit, Output, ViewChild} fr
import {ActivatedRoute} from "@angular/router";
import {FormBuilder, Validators} from "@angular/forms";
import {RoleService} from "@app/services/role.service";
-import {catchError, debounceTime, distinctUntilChanged, filter, map, switchMap, tap} from "rxjs/operators";
+import {catchError, concatAll, debounceTime, distinctUntilChanged, filter, map, switchMap, tap} from "rxjs/operators";
import {Role} from '@app/model/role';
import {ErrorResult} from "@app/model/error-result";
import {EditBaseComponent} from "@app/modules/shared/edit-base.component";
-import {forkJoin, Observable, of, zip} from 'rxjs';
+import {EMPTY, forkJoin, Observable, of, zip} from 'rxjs';
import {RoleUpdate} from "@app/model/role-update";
import {EntityService} from "@app/model/entity-service";
import {User} from '@app/model/user';
@@ -34,6 +34,9 @@ import {UserInfo} from '@app/model/user-info';
import {HttpResponse} from "@angular/common/http";
import {PaginatedEntitiesComponent} from "@app/modules/shared/paginated-entities/paginated-entities.component";
import {ToastService} from "@app/services/toast.service";
+import {GroupService} from "@app/services/group.service";
+import {GroupMapping} from "@app/model/group-mapping";
+import { Group } from '@app/model/group';
@Component({
selector: 'app-manage-roles-edit',
@@ -55,16 +58,22 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
userSearching:boolean=false;
userSearchFailed:boolean=false;
-
public userSearchModel:any;
+ groupSearching:boolean=false;
+ groupSearchFailed:boolean=false;
+ public groupSearchModel:any;
+
@ViewChild('userSection') roleUserComponent: PaginatedEntitiesComponent<UserInfo>;
@ViewChild('userParentSection') roleUserParentComponent: PaginatedEntitiesComponent<UserInfo>;
@Output()
roleIdEvent: EventEmitter<string> = new EventEmitter<string>(true);
+ private roleMappings$;
+
constructor(private route: ActivatedRoute, public roleService: RoleService, private userService: UserService,
+ private groupService: GroupService,
public fb: FormBuilder, private toastService: ToastService) {
super(fb);
super.init(fb.group({
@@ -119,6 +128,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
if (this.roleUserParentComponent) {
this.roleUserParentComponent.changeService(this.roleUserParentService);
}
+ this.roleMappings$ = this.getMappedGroups(role.id);
}, error => {
this.editRole = new Role();
});
@@ -232,10 +242,33 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
tap(() => this.userSearching = false)
)
+
getUserId(item:UserInfo) : string {
return item.user_id;
}
+ searchGroup = (text$: Observable<string>) =>
+ text$.pipe(
+ debounceTime(300),
+ distinctUntilChanged(),
+ tap(() => this.groupSearching = true),
+ switchMap(term =>
+ this.groupService.query( term, 0, 10).pipe(
+ tap(() => this.groupSearchFailed = false),
+ map(pagedResult=>
+ pagedResult.data),
+ catchError(() => {
+ this.groupSearchFailed = true;
+ return of([]);
+ }))
+ ),
+ tap(() => this.groupSearching = false)
+ )
+
+ getGroupName(item:Group) : string {
+ return item.name;
+ }
+
showError(err: ErrorResult, errorKey:string, params:any={}) : void {
let message = err.error_messages.length>0?err.error_messages[0]:''
params['message']=message
@@ -243,7 +276,6 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
}
showSuccess(successKey:string, params:any={}) : void {
- console.log("Success " + successKey + " - " + JSON.stringify(params));
this.toastService.showSuccessByKey('manage-roles-edit',successKey,params)
}
@@ -262,7 +294,7 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
this.error = true;
this.success = false;
this.errorResult = err;
- this.showError(err, 'roles.edit.errors.assignFailed', {'role_id':this.editRole.id,'user_id':userId})
+ this.showError(err, 'roles.edit.errors.userAssignFailed', {'role_id':this.editRole.id,'user_id':userId})
return [];
})
).subscribe((response : HttpResponse<Role>) => {
@@ -301,5 +333,56 @@ export class ManageRolesEditComponent extends EditBaseComponent<Role> implements
}
}
+ assignGroupRole() {
+ let groupName;
+ if (typeof(this.groupSearchModel)=='string') {
+ groupName=this.groupSearchModel;
+ } else {
+ if (this.groupSearchModel.name) {
+ groupName = this.groupSearchModel.name;
+ }
+ }
+ if (this.editRole.id!=null && groupName!=null && groupName.length>0) {
+ this.groupService.assignGroup(groupName, this.editRole.id).pipe(
+ catchError((err: ErrorResult) => {
+ this.error = true;
+ this.success = false;
+ this.errorResult = err;
+ this.showError(err, 'roles.edit.errors.groupAssignFailed', {'role_id':this.editRole.id,'group_name':groupName})
+ return [];
+ })
+ ).subscribe((response : HttpResponse<any>) => {
+ this.error = false;
+ this.success = true;
+ this.errorResult = null;
+ this.result = response.body;
+ this.showSuccess('roles.edit.success.assignGroup',{'role_id':this.editRole.id,'group_name':groupName})
+ this.groupSearchModel=''
+ });
+ }
+ }
+
+
+ getMappedGroups(roleId:string) : Observable<string[]> {
+ console.log("Get mapped groups "+roleId);
+ if (roleId!=null && roleId.length>0) {
+ return this.groupService.getGroupMappings().pipe(
+ map((gMapArray: GroupMapping[]) => {
+ console.log("Array " + gMapArray + " - " + gMapArray.length);
+ let result = [];
+ for (let gMap of gMapArray) {
+ if (gMap.roles.includes(roleId)) {
+ result.push(gMap.group_name);
+ }
+ }
+ return result;
+ })
+ );
+ } else {
+ console.log("No role id found");
+ return EMPTY;
+ }
+ }
+
}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html
index 01654af3e..94cbbd748 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/security/roles/manage-roles-list/manage-roles-list.component.html
@@ -17,6 +17,7 @@
-->
<app-paginated-entities [service]="service" pageSize="10" [(sortField)]="sortField" [(sortOrder)]="sortOrder"
+ [id]="'rolesList'"
#parent>
<ng-container *ngIf="parent.items$ |async as roleItemLoader" >
<ng-template [ngIf]="roleItemLoader.loading" #spinner let-modal>
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts
index 8c1605255..ff54a5a24 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/shared/paginated-entities/paginated-entities.component.ts
@@ -24,18 +24,16 @@ import {
filter,
map,
multicast,
- pluck,
refCount,
- share,
startWith,
- switchMap, tap
+ switchMap,
+ tap
} from "rxjs/operators";
import {EntityService} from "@app/model/entity-service";
import {FieldToggle} from "@app/model/field-toggle";
import {PageQuery} from "../model/page-query";
import {LoadingValue} from '../model/loading-value';
import {PagedResult} from "@app/model/paged-result";
-import {Multipage} from "@app/model/multipage";
import {PaginationInfo} from "@app/model/pagination-info";
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/group.service.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/group.service.spec.ts
new file mode 100644
index 000000000..d86080289
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/group.service.spec.ts
@@ -0,0 +1,34 @@
+/*
+ * 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 { TestBed } from '@angular/core/testing';
+
+import { GroupService } from './group.service';
+
+describe('GroupService', () => {
+ let service: GroupService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(GroupService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/group.service.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/group.service.ts
new file mode 100644
index 000000000..d0f91a73d
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/group.service.ts
@@ -0,0 +1,71 @@
+/*
+ * 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 {GroupMapping} from "@app/model/group-mapping";
+import {catchError} from "rxjs/operators";
+import {HttpErrorResponse, HttpResponse} from "@angular/common/http";
+import {Observable, throwError} from 'rxjs';
+import {PagedResult} from "@app/model/paged-result";
+import {Group} from '@app/model/group';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class GroupService {
+
+ constructor(private rest: ArchivaRequestService) {
+
+ }
+
+ getGroupMappings(): Observable<GroupMapping[]> {
+ return this.rest.executeRestCall<GroupMapping[]>("get", "redback", "groups/mappings", null).pipe(
+ catchError((error: HttpErrorResponse) => {
+ return throwError(this.rest.getTranslatedErrorResult(error));
+ })
+ )
+ }
+
+ assignGroup(groupName: string, roleId: string): Observable<HttpResponse<any>> {
+ return this.rest.executeResponseCall<any>("put", "redback", "groups/mappings/" + encodeURI(groupName) + "/roles/" + encodeURI(roleId), null)
+ .pipe(catchError((error: HttpErrorResponse) => {
+ return throwError(this.rest.getTranslatedErrorResult(error));
+ }));
+ }
+
+ public query(searchTerm: string, offset: number = 0, limit: number = 10, orderBy: string[] = ['name'], order: string = 'asc'): Observable<PagedResult<Group>> {
+ if (searchTerm == null) {
+ searchTerm = ""
+ }
+ if (orderBy == null || orderBy.length == 0) {
+ orderBy = ['id'];
+ }
+ return this.rest.executeRestCall<PagedResult<Group>>("get", "redback", "groups", {
+ 'q': searchTerm,
+ 'offset': offset,
+ 'limit': limit,
+ 'orderBy': orderBy,
+ 'order': order
+ }).pipe(
+ catchError((error: HttpErrorResponse) => {
+ return throwError(this.rest.getTranslatedErrorResult(error));
+ }));
+ }
+
+}
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 744f015d5..cf87a2ac5 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
@@ -153,21 +153,26 @@
"children": "Children",
"permissions": "Permissions",
"users": "Users",
+ "groupMapping": "Groups",
"usersInstance": "Users Assigned to this Role",
"usersParents": "Users Assigned to Parent Roles",
"noUsersAssigned": "There are no users assigned to this role",
"assignUserSearch": "Search and assign users to this role",
+ "assignGroupSearch": "Search and assign a group to this role",
"userSearchFailed": "Sorry, could not load users",
+ "groupSearchFailed": "Sorry, could not get any groups",
"assignButton": "Assign",
"errors": {
"updateFailed": "Could not update role {role_id}: {message}",
- "assignFailed": "Could not assign role {role_id} to user {user_id}: {message}",
- "retrieveFailed": "Could not retrieve role information: {message}"
+ "userAssignFailed": "Could not assign role {role_id} to user {user_id}: {message}",
+ "retrieveFailed": "Could not retrieve role information: {message}",
+ "groupAssignFailed": "Could not assign role {role_id} to group {group_name}: {message}"
},
"success": {
"updated": "Role {role_id} was updated",
"assign": "Role {role_id} was assigned to user {user_id}",
- "unassign": "Removed assignment of {role_id} to {user_id}"
+ "unassign": "Removed assignment of {role_id} to {user_id}",
+ "assignGroup": "Role {role_id} was assigned to group {group_name}"
}
},
"attributes": {