mirror of https://github.com/apache/archiva.git
Adding component for entity display
This commit is contained in:
parent
1e11eea36f
commit
0e2187bf0e
|
@ -41,8 +41,8 @@ import { ManageRolesComponent } from './modules/user/manage-roles/manage-roles.c
|
|||
import { SecurityConfigurationComponent } from './modules/user/security-configuration/security-configuration.component';
|
||||
import { ManageUsersListComponent } from './modules/user/users/manage-users-list/manage-users-list.component';
|
||||
import { ManageUsersAddComponent } from './modules/user/users/manage-users-add/manage-users-add.component';
|
||||
import { EnableTooltipDirective } from './directives/enable-tooltip.directive';
|
||||
import {NgbPagination, NgbPaginationModule} from "@ng-bootstrap/ng-bootstrap";
|
||||
import { NgbPaginationModule, NgbTooltipModule} from "@ng-bootstrap/ng-bootstrap";
|
||||
import { PaginatedEntitiesComponent } from './modules/general/paginated-entities/paginated-entities.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
|
@ -64,9 +64,7 @@ import {NgbPagination, NgbPaginationModule} from "@ng-bootstrap/ng-bootstrap";
|
|||
SecurityConfigurationComponent,
|
||||
ManageUsersListComponent,
|
||||
ManageUsersAddComponent,
|
||||
EnableTooltipDirective,
|
||||
|
||||
|
||||
PaginatedEntitiesComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -81,7 +79,8 @@ import {NgbPagination, NgbPaginationModule} from "@ng-bootstrap/ng-bootstrap";
|
|||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
NgbPaginationModule
|
||||
NgbPaginationModule,
|
||||
NgbTooltipModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
|
|
@ -16,18 +16,13 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import {AfterViewChecked, AfterViewInit, Directive, ElementRef, OnInit} from '@angular/core';
|
||||
import {PagedResult} from "./paged-result";
|
||||
import {Observable} from "rxjs";
|
||||
|
||||
declare var jQuery:any;
|
||||
@Directive({
|
||||
selector: '[appEnableTooltip]'
|
||||
})
|
||||
export class EnableTooltipDirective implements AfterViewInit {
|
||||
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
jQuery('[data-toggle="tooltip"]').tooltip({container: 'body', html: true});
|
||||
}
|
||||
/**
|
||||
* This is a functional interface that is used to retrieve entity data.
|
||||
* @typeparam T The type of the entity that is returned from the service
|
||||
*/
|
||||
export interface EntityService<T> {
|
||||
(searchTerm:string,offset:number,limit:number,orderBy:string,order:string):Observable<PagedResult<T>>
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<!--
|
||||
~ 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">
|
||||
<div class="form-row align-items-center">
|
||||
<div class="col-lg-4 col-md-2 col-sm-1">
|
||||
<label class="sr-only" for="searchQuery">{{'search.label' |translate}}</label>
|
||||
<input type="text" class="form-control" id="searchQuery" placeholder="Search" #searchTerm
|
||||
(keyup)="search(searchTerm.value)">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary">{{'search.button'|translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
<ng-content></ng-content>
|
||||
|
||||
<ngb-pagination [collectionSize]="total$|async" [pageSize]="pageSize" [maxSize]="pagination.maxSize" [rotate]="pagination.rotate"
|
||||
[boundaryLinks]="pagination.boundaryLinks" [ellipses]="pagination.ellipses"
|
||||
[(page)]="page" (pageChange)="changePage($event)" aria-label="Pagination"></ngb-pagination>
|
|
@ -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,11 +16,3 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { EnableTooltipDirective } from './enable-tooltip.directive';
|
||||
|
||||
describe('EnableTooltipDirective', () => {
|
||||
it('should create an instance', () => {
|
||||
const directive = new EnableTooltipDirective();
|
||||
expect(directive).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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 { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PaginatedEntitiesComponent } from './paginated-entities.component';
|
||||
|
||||
describe('PaginatedEntitiesComponent', () => {
|
||||
let component: PaginatedEntitiesComponent;
|
||||
let fixture: ComponentFixture<PaginatedEntitiesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ PaginatedEntitiesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PaginatedEntitiesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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 {Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
|
||||
import {merge, Observable, Subject} from "rxjs";
|
||||
import {UserInfo} from "../../../model/user-info";
|
||||
import {TranslateService} from "@ngx-translate/core";
|
||||
import {debounceTime, distinctUntilChanged, map, mergeMap, pluck, share, startWith} from "rxjs/operators";
|
||||
import {EntityService} from "../../../model/entity-service";
|
||||
|
||||
|
||||
/**
|
||||
* This component has a search field and pagination section. Entering data in the search field, or
|
||||
* a button click on the pagination triggers a call to a service method, that returns the entity data.
|
||||
* The service must implement the {@link EntityService} interface.
|
||||
*
|
||||
* The content is displayed between the search input and the pagination section. To use the data, you should
|
||||
* add an identifier and refer to the item$ variable:
|
||||
* ```
|
||||
* <app-paginated-entities #parent>
|
||||
* <table>
|
||||
* <tr ngFor="let entity in parent.item$ | async" >
|
||||
* <td>{{entity.id}}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* </app-paginated-entities>
|
||||
* ```
|
||||
*
|
||||
* @typeparam T The type of the retrieved entity elements.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-paginated-entities',
|
||||
templateUrl: './paginated-entities.component.html',
|
||||
styleUrls: ['./paginated-entities.component.scss']
|
||||
})
|
||||
export class PaginatedEntitiesComponent<T> implements OnInit {
|
||||
|
||||
/**
|
||||
* This must be set, if you use the component. This service retrieves the entity data.
|
||||
*/
|
||||
@Input() service : EntityService<T>;
|
||||
|
||||
/**
|
||||
* The number of elements per page retrieved
|
||||
*/
|
||||
@Input() pageSize = 10;
|
||||
|
||||
/**
|
||||
* Pagination controls
|
||||
*/
|
||||
@Input() pagination = {
|
||||
maxSize:5,
|
||||
rotate:true,
|
||||
boundaryLinks:true,
|
||||
ellipses:false
|
||||
}
|
||||
|
||||
/**
|
||||
* The current page that is selected
|
||||
*/
|
||||
page = 1;
|
||||
/**
|
||||
* The current search term entered in the search field
|
||||
*/
|
||||
searchTerm: string;
|
||||
|
||||
/**
|
||||
* Event thrown, if the page value changes
|
||||
*/
|
||||
@Output() pageEvent : EventEmitter<number> = new EventEmitter<number>();
|
||||
/**
|
||||
* Event thrown, if the search term changes
|
||||
*/
|
||||
@Output() searchTermEvent: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
/**
|
||||
* The total number of elements available for the given search term
|
||||
*/
|
||||
total$: Observable<number>;
|
||||
/**
|
||||
* The entity items retrieved from the service
|
||||
*/
|
||||
items$: Observable<T[]>;
|
||||
|
||||
private pageStream: Subject<number> = new Subject<number>();
|
||||
private searchTermStream: Subject<string> = new Subject<string>();
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
// We combine the sources for the page and the search input field to a observable 'source'
|
||||
const pageSource = this.pageStream.pipe(map(pageNumber => {
|
||||
return {search: this.searchTerm, page: pageNumber}
|
||||
}));
|
||||
const searchSource = this.searchTermStream.pipe(
|
||||
debounceTime(1000),
|
||||
distinctUntilChanged(),
|
||||
map(searchTerm => {
|
||||
this.searchTerm = searchTerm;
|
||||
return {search: searchTerm, page: 1}
|
||||
}));
|
||||
const source = merge(pageSource, searchSource).pipe(
|
||||
startWith({search: this.searchTerm, page: this.page}),
|
||||
mergeMap((params: { search: string, page: number }) => {
|
||||
return this.service(params.search, (params.page - 1) * this.pageSize, this.pageSize, "", "asc");
|
||||
}),share());
|
||||
this.total$ = source.pipe(pluck('pagination','totalCount'));
|
||||
this.items$ = source.pipe(pluck('data'));
|
||||
}
|
||||
|
||||
search(terms: string) {
|
||||
// console.log("Keystroke " + terms);
|
||||
this.searchTermEvent.emit(terms);
|
||||
this.searchTermStream.next(terms)
|
||||
}
|
||||
|
||||
changePage(pageNumber : number) {
|
||||
// console.log("Page change " +pageNumber);
|
||||
this.pageEvent.emit(pageNumber);
|
||||
this.pageStream.next(pageNumber);
|
||||
}
|
||||
|
||||
}
|
|
@ -17,35 +17,21 @@
|
|||
~ under the License.
|
||||
-->
|
||||
|
||||
<form class="mt-3 mb-3">
|
||||
<div class="form-row align-items-center">
|
||||
<div class="col-lg-4 col-md-2 col-sm-1">
|
||||
<label class="sr-only" for="searchQuery">{{'users.list.search' |translate}}</label>
|
||||
<input type="text" class="form-control" id="searchQuery" placeholder="Search" #searchTerm
|
||||
(keyup)="search(searchTerm.value)">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary">{{'search.button'|translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<app-paginated-entities [service]="service" pageSize="5"We #parent>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
<table class="table table-striped table-bordered" appEnableTooltip>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th scope="col">{{'users.list.table.head.id' | translate}}</th>
|
||||
<th scope="col">{{'users.list.table.head.user_id' | translate}}</th>
|
||||
<th scope="col">{{'users.list.table.head.fullName' | translate}}</th>
|
||||
<th scope="col">{{'users.list.table.head.email' | translate}}</th>
|
||||
<th scope="col"><span class="fas fa-check" data-toggle="tooltip" data-placement="top"
|
||||
[attr.data-original-title]="heads.validated" [attr.aria-label]="heads.validated"></span>
|
||||
<th scope="col"><span class="fas fa-check" placement="top"
|
||||
[ngbTooltip]="heads.validated" [attr.aria-label]="heads.validated"></span>
|
||||
</th>
|
||||
<th scope="col"><span class="fas fa-lock" data-toggle="tooltip" data-placement="top"
|
||||
[attr.data-original-title]="heads.locked" [attr.aria-label]="heads.locked"></span></th>
|
||||
<th scope="col"><span class="fa fa-chevron-circle-right" data-toggle="tooltip" data-placement="top"
|
||||
[attr.data-original-title]="heads.pwchange" [attr.aria-label]="heads.pwchange"></span>
|
||||
<th scope="col"><span class="fas fa-lock" placement="top"
|
||||
[ngbTooltip]="heads.locked" [attr.aria-label]="heads.locked"></span></th>
|
||||
<th scope="col"><span class="fa fa-chevron-circle-right" placement="top"
|
||||
[ngbTooltip]="heads.pwchange" [attr.aria-label]="heads.pwchange"></span>
|
||||
</th>
|
||||
<th scope="col">{{'users.list.table.head.lastLogin' | translate}}</th>
|
||||
<th scope="col">{{'users.list.table.head.created' | translate}}</th>
|
||||
|
@ -53,9 +39,8 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let user of items$ | async" [ngClass]="user.permanent?'table-secondary':''">
|
||||
<td>{{user.id}}</td>
|
||||
<td>{{user.user_id}}</td>
|
||||
<tr *ngFor="let user of parent.items$ | async" [ngClass]="(user.permanent||user.readOnly)?'table-secondary':''" >
|
||||
<td><span data-toggle="tooltip" placement="left" ngbTooltip="{{user.id}}">{{user.user_id}}</span></td>
|
||||
<td>{{user.fullName}}</td>
|
||||
<td>{{user.email}}</td>
|
||||
<td><span class="far" [attr.aria-valuetext]="user.validated" [ngClass]="user.validated?'fa-check-circle':'fa-circle'"></span></td>
|
||||
|
@ -68,4 +53,4 @@
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<ngb-pagination [collectionSize]="total$|async" maxSize="2" rotate="true" [(page)]="page" (pageChange)="changePage($event)" aria-label="Default pagination"></ngb-pagination>
|
||||
</app-paginated-entities>
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import {Component, OnInit, Input, OnDestroy} from '@angular/core';
|
||||
import {TranslateService} from "@ngx-translate/core";
|
||||
import {UserService} from "../../../../services/user.service";
|
||||
import {Observable, Subject, merge} from 'rxjs';
|
||||
import { map, pluck, debounceTime, distinctUntilChanged, startWith, mergeMap} from "rxjs/operators";
|
||||
import {UserInfo} from "../../../../model/user-info";
|
||||
import {EntityService} from "../../../../model/entity-service";
|
||||
import {Observable, of} from "rxjs";
|
||||
import {PagedResult} from "../../../../model/paged-result";
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -31,16 +32,17 @@ import {UserInfo} from "../../../../model/user-info";
|
|||
styleUrls: ['./manage-users-list.component.scss']
|
||||
})
|
||||
export class ManageUsersListComponent implements OnInit {
|
||||
@Input() heads: any;
|
||||
page = 1;
|
||||
pageSize = 10;
|
||||
total$: Observable<number>;
|
||||
items$: Observable<UserInfo[]>;
|
||||
searchTerm: string;
|
||||
private pageStream: Subject<number> = new Subject<number>();
|
||||
private searchTermStream: Subject<string> = new Subject<string>();
|
||||
|
||||
constructor(private translator: TranslateService, private userService : UserService) { }
|
||||
@Input() heads: any;
|
||||
service : EntityService<UserInfo>;
|
||||
|
||||
|
||||
constructor(private translator: TranslateService, private userService : UserService) {
|
||||
this.service = function (searchTerm: string, offset: number, limit: number, orderBy: string, order: string) : Observable<PagedResult<UserInfo>> {
|
||||
return userService.query(searchTerm, offset, limit, orderBy, order);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.heads = {};
|
||||
|
@ -51,42 +53,17 @@ export class ManageUsersListComponent implements OnInit {
|
|||
this.heads[suffix] = this.translator.instant('users.list.table.head.' + suffix);
|
||||
}
|
||||
});
|
||||
const pageSource = this.pageStream.pipe(map(pageNumber => {
|
||||
return {search: this.searchTerm, page: pageNumber}
|
||||
}));
|
||||
const searchSource = this.searchTermStream.pipe(
|
||||
debounceTime(1000),
|
||||
distinctUntilChanged(),
|
||||
map(searchTerm => {
|
||||
this.searchTerm = searchTerm;
|
||||
console.log("Search term " + searchTerm);
|
||||
return {search: searchTerm, page: 1}
|
||||
}));
|
||||
const source = merge(pageSource, searchSource).pipe(
|
||||
startWith({search: this.searchTerm, page: this.page}),
|
||||
mergeMap((params: { search: string, page: number }) => {
|
||||
console.log("Executing user list " + params.search);
|
||||
return this.userService.getUserList(params.search, params.page*this.pageSize, this.pageSize)
|
||||
}));
|
||||
|
||||
this.total$ = source.pipe(pluck('pagination.total'));
|
||||
this.items$ = source.pipe(pluck('data'));
|
||||
|
||||
|
||||
|
||||
// const pageSource = map(pageNumber => {
|
||||
// this.page = pageNumber
|
||||
// return {search: this.searchTerm, page: pageNumber}
|
||||
// })
|
||||
}
|
||||
search(terms: string) {
|
||||
console.log("Keystroke " + terms);
|
||||
this.searchTermStream.next(terms)
|
||||
}
|
||||
|
||||
changePage(pageNumber : number) {
|
||||
console.log("Page change " +typeof(pageNumber) +":" + JSON.stringify(pageNumber));
|
||||
this.pageStream.next(pageNumber);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -54,7 +54,11 @@ export class ArchivaRequestService {
|
|||
headers = {};
|
||||
}
|
||||
if (type == "get") {
|
||||
return this.http.get<R>(url, {"headers": headers});
|
||||
let params = {}
|
||||
if (input!=null) {
|
||||
params = input;
|
||||
}
|
||||
return this.http.get<R>(url, {"headers": headers,"params":params});
|
||||
} else if (type == "post") {
|
||||
return this.http.post<R>(url, input, {"headers": headers});
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import {ErrorResult} from "../model/error-result";
|
|||
import {Observable} from "rxjs";
|
||||
import {Permission} from '../model/permission';
|
||||
import {PagedResult} from "../model/paged-result";
|
||||
import {EntityService} from "../model/entity-service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -202,7 +203,6 @@ export class UserService implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
}
|
||||
console.log("New permissions: " + JSON.stringify(this.uiPermissions));
|
||||
}
|
||||
|
||||
private deepCopy(src: Object, dst: Object) {
|
||||
|
@ -258,8 +258,12 @@ export class UserService implements OnInit, OnDestroy {
|
|||
this.authenticated = false;
|
||||
}
|
||||
|
||||
public getUserList(searchTerm : string, offset : number = 0, limit : number = 10) : Observable<PagedResult<UserInfo>> {
|
||||
return this.rest.executeRestCall<PagedResult<UserInfo>>("get", "redback", "users", {'offset':offset,'limit':limit});
|
||||
public query(searchTerm : string, offset : number = 0, limit : number = 10, orderBy : string = 'user_id', order: string = 'asc') : Observable<PagedResult<UserInfo>> {
|
||||
console.log("getUserList " + searchTerm + "," + offset + "," + limit + "," + orderBy + "," + order);
|
||||
if (searchTerm==null) {
|
||||
searchTerm=""
|
||||
}
|
||||
return this.rest.executeRestCall<PagedResult<UserInfo>>("get", "redback", "users", {'q':searchTerm, 'offset':offset,'limit':limit});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
}
|
||||
},
|
||||
"search": {
|
||||
"button": "Search"
|
||||
"button": "Search",
|
||||
"label": "Enter your search term"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
# 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.
|
||||
#
|
||||
|
||||
# Just a simple script to generate users on the local archiva instance for interactive UI testing
|
||||
|
||||
BASE_URL="http://localhost:8080/archiva"
|
||||
USER_NAME="admin"
|
||||
PASSWD="admin456"
|
||||
USERS=25
|
||||
|
||||
#Authenticate
|
||||
TOKEN=$(curl -s -X POST "${BASE_URL}/api/v2/redback/auth/authenticate" -H "accept: application/json" -H "Content-Type: application/json" \
|
||||
-d "{\"grant_type\":\"authorization_code\",\"client_id\":\"test-bash\",\"client_secret\":\"string\",\"code\":\"string\",\"scope\":\"string\",\"state\":\"string\",\"user_id\":\"${USER_NAME}\",\
|
||||
\"password\":\"${PASSWD}\",\"redirect_uri\":\"string\"}"|sed -n -e '/access_token/s/.*"access_token":"\([^"]\+\)".*/\1/gp')
|
||||
if [ "${TOKEN}" == "" ]; then
|
||||
echo "Authentication failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
NUM=$USERS
|
||||
while [ $NUM -ge 0 ]; do
|
||||
SUFFIX=$(printf "%03d" $NUM)
|
||||
echo "User: test${SUFFIX}"
|
||||
curl -s -w ' - %{http_code}' -X POST "${BASE_URL}/api/v2/redback/users" -H "accept: application/json" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"user_id\":\"test${SUFFIX}\",\"fullName\":\"Test User ${SUFFIX}\",\"email\":\"test${SUFFIX}@test.org\",\"validated\":true,\"locked\":false,\"passwordChangeRequired\":false,\"password\":\"test123\"}"
|
||||
NUM=$((NUM-1))
|
||||
echo " "
|
||||
done
|
Loading…
Reference in New Issue