Add user group when http auth mode

add the pages  in project and system

Signed-off-by: Yogi_Wang <yawang@vmware.com>
This commit is contained in:
Yogi_Wang 2019-07-04 15:36:05 +08:00
parent 66e85f8318
commit 8e5b4dcaf4
24 changed files with 374 additions and 47 deletions

View File

@ -25,4 +25,5 @@ export * from './gridview/index';
export * from './repository-gridview/index';
export * from './operation/index';
export * from './_animations/index';
export * from "./shared/shared.const";

View File

@ -407,3 +407,8 @@ export class OriginCron {
cron: string;
}
export interface ProjectRootInterface {
NAME: string;
VALUE: number;
LABEL: string;
}

View File

@ -109,3 +109,34 @@ export enum ResourceType {
CHART_VERSION = 2,
REPOSITORY_TAG = 3,
}
export const CONFIG_AUTH_MODE = {
HTTP_AUTH: "http_auth",
LDAP_AUTH: "ldap_auth"
};
export const PROJECT_ROOTS = [
{
NAME: "admin",
VALUE: 1,
LABEL: "GROUP.PROJECT_ADMIN"
},
{
NAME: "master",
VALUE: 4,
LABEL: "GROUP.PROJECT_MASTER"
},
{
NAME: "developer",
VALUE: 2,
LABEL: "GROUP.DEVELOPER"
},
{
NAME: "guest",
VALUE: 3,
LABEL: "GROUP.GUEST"
}
];
export enum GroupType {
LDAP_TYPE = 1,
HTTP_TYPE = 2
}

View File

@ -19,6 +19,7 @@ import { CookieService } from 'ngx-cookie';
import { AppConfig } from './app-config';
import { CookieKeyOfAdmiral, HarborQueryParamKey } from './shared/shared.const';
import { maintainUrlQueryParmas, HTTP_GET_OPTIONS} from './shared/shared.utils';
import { CONFIG_AUTH_MODE} from "@harbor/ui";
import { map, catchError } from "rxjs/operators";
import { Observable, throwError as observableThrowError } from "rxjs";
export const systemInfoEndpoint = "/api/systeminfo";
@ -66,7 +67,10 @@ export class AppConfigService {
}
public isLdapMode(): boolean {
return this.configurations && this.configurations.auth_mode === 'ldap_auth';
return this.configurations && this.configurations.auth_mode === CONFIG_AUTH_MODE.LDAP_AUTH;
}
public isHttpAuthMode(): boolean {
return this.configurations && this.configurations.auth_mode === CONFIG_AUTH_MODE.HTTP_AUTH;
}
// Return the reconstructed admiral url

View File

@ -28,7 +28,7 @@
<clr-icon shape="users" clrVerticalNavIcon></clr-icon>
{{'SIDE_NAV.SYSTEM_MGMT.USER' | translate}}
</a>
<a *ngIf='isLdapMode' clrVerticalNavLink routerLink="/harbor/groups" routerLinkActive="active">
<a *ngIf='isLdapMode || isHttpAuthMode' clrVerticalNavLink routerLink="/harbor/groups" routerLinkActive="active">
<clr-icon shape="users" clrVerticalNavIcon></clr-icon>
{{'SIDE_NAV.SYSTEM_MGMT.GROUP' | translate}}
</a>

View File

@ -54,6 +54,8 @@ export class HarborShellComponent implements OnInit, OnDestroy {
searchSub: Subscription;
searchCloseSub: Subscription;
isLdapMode: boolean;
isHttpAuthMode: boolean;
constructor(
private route: ActivatedRoute,
@ -63,6 +65,11 @@ export class HarborShellComponent implements OnInit, OnDestroy {
private appConfigService: AppConfigService) { }
ngOnInit() {
if (this.appConfigService.isLdapMode()) {
this.isLdapMode = true;
} else if (this.appConfigService.isHttpAuthMode()) {
this.isHttpAuthMode = true;
}
this.searchSub = this.searchTrigger.searchTriggerChan$.subscribe(searchEvt => {
if (searchEvt && searchEvt.trim() !== "") {
this.isSearchResultsOpened = true;
@ -70,7 +77,7 @@ export class HarborShellComponent implements OnInit, OnDestroy {
});
this.searchCloseSub = this.searchTrigger.searchCloseChan$.subscribe(close => {
this.isSearchResultsOpened = false;
this.isSearchResultsOpened = false;
});
}
@ -97,11 +104,6 @@ export class HarborShellComponent implements OnInit, OnDestroy {
return account != null && account.has_admin_role;
}
public get isLdapMode(): boolean {
let appConfig = this.appConfigService.getConfig();
return appConfig.auth_mode === 'ldap_auth';
}
public get isUserExisting(): boolean {
let account = this.session.getCurrentUser();
return account != null;

View File

@ -1,11 +1,12 @@
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
<h3 class="modal-title" *ngIf="mode === 'create'">{{'GROUP.IMPORT_LDAP_GROUP' | translate}}</h3>
<h3 class="modal-title" *ngIf="mode === 'create' && isLdapMode">{{'GROUP.IMPORT_LDAP_GROUP' | translate}}</h3>
<h3 class="modal-title" *ngIf="mode === 'create' && isHttpAuthMode">{{'GROUP.IMPORT_HTTP_GROUP' | translate}}</h3>
<h3 class="modal-title" *ngIf="mode !== 'create'">{{'GROUP.EDIT' | translate}}</h3>
<div class="modal-body">
<form class="form" #groupForm="ngForm">
<section class="form-block">
<div class="form-group">
<div class="form-group" *ngIf="isLdapMode">
<label for="ldap_group_dn" class="required">{{ 'GROUP.GROUP_DN' | translate}}</label>
<label for="ldap_group_dn"
aria-haspopup="true"
@ -22,7 +23,7 @@
</span>
</label>
</div>
<div class="form-group">
<div class="form-group" *ngIf="isLdapMode">
<label for="type">{{'GROUP.TYPE' | translate}}</label>
<label id="type">LDAP</label>
</div>

View File

@ -1,13 +1,15 @@
import {finalize} from 'rxjs/operators';
import { finalize } from 'rxjs/operators';
import { Subscription } from "rxjs";
import { Component, OnInit, EventEmitter, Output, ChangeDetectorRef, OnDestroy, ViewChild } from "@angular/core";
import { NgForm } from "@angular/forms";
import { GroupType } from "@harbor/ui";
import { GroupService } from "../group.service";
import { MessageHandlerService } from "./../../shared/message-handler/message-handler.service";
import { SessionService } from "./../../shared/session.service";
import { UserGroup } from "./../group";
import { AppConfigService } from "../../app-config.service";
@Component({
selector: "hbr-add-group-modal",
@ -19,7 +21,7 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
mode = "create";
dnTooltip = 'TOOLTIP.ITEM_REQUIRED';
group: UserGroup = new UserGroup();
group: UserGroup;
formChangeSubscription: Subscription;
@ -30,25 +32,36 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
@Output() dataChange = new EventEmitter();
isLdapMode: boolean;
isHttpAuthMode: boolean;
constructor(
private session: SessionService,
private msgHandler: MessageHandlerService,
private appConfigService: AppConfigService,
private groupService: GroupService,
private cdr: ChangeDetectorRef
) {}
) { }
ngOnInit() { }
ngOnInit() {
if (this.appConfigService.isLdapMode()) {
this.isLdapMode = true;
}
if (this.appConfigService.isHttpAuthMode()) {
this.isHttpAuthMode = true;
}
this.group = new UserGroup(this.isLdapMode ? GroupType.LDAP_TYPE : GroupType.HTTP_TYPE);
}
ngOnDestroy() { }
public get isDNInvalid(): boolean {
let dnControl = this.groupForm.controls['ldap_group_dn'];
return dnControl && dnControl.invalid && (dnControl.dirty || dnControl.touched);
return dnControl && dnControl.invalid && (dnControl.dirty || dnControl.touched);
}
public get isNameInvalid(): boolean {
let dnControl = this.groupForm.controls['group_name'];
return dnControl && dnControl.invalid && (dnControl.dirty || dnControl.touched);
return dnControl && dnControl.invalid && (dnControl.dirty || dnControl.touched);
}
public get isFormValid(): boolean {
@ -83,7 +96,7 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
let groupCopy = Object.assign({}, this.group);
this.groupService
.createGroup(groupCopy).pipe(
finalize(() => this.close()))
finalize(() => this.close()))
.subscribe(
res => {
this.msgHandler.showSuccess("GROUP.ADD_GROUP_SUCCESS");
@ -97,7 +110,7 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
let groupCopy = Object.assign({}, this.group);
this.groupService
.editGroup(groupCopy).pipe(
finalize(() => this.close()))
finalize(() => this.close()))
.subscribe(
res => {
this.msgHandler.showSuccess("GROUP.EDIT_GROUP_SUCCESS");
@ -108,7 +121,7 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
}
resetGroup() {
this.group = new UserGroup();
this.group = new UserGroup(this.isLdapMode ? GroupType.LDAP_TYPE : GroupType.HTTP_TYPE);
this.groupForm.reset();
}
}

View File

@ -15,18 +15,18 @@
<clr-icon shape="plus" size="15"></clr-icon>&nbsp;{{'GROUP.ADD' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" (click)="editGroup()" [disabled]="!canEditGroup">
<clr-icon shape="pencil" size="15"></clr-icon>&nbsp;{{'GROUP.EDIT' | translate}}</button>
<button type="button" class="btn btn-sm btn-secondary" (click)="openDeleteConfirmationDialog()" [disabled]="!canEditGroup">
<button type="button" class="btn btn-sm btn-secondary" (click)="openDeleteConfirmationDialog()" [disabled]="!canDeleteGroup">
<clr-icon shape="times" size="15"></clr-icon>&nbsp;{{'GROUP.DELETE' | translate}}</button>
</clr-dg-action-bar>
<clr-dg-column>{{'GROUP.NAME' | translate}}</clr-dg-column>
<clr-dg-column>{{'GROUP.TYPE' | translate}}</clr-dg-column>
<clr-dg-column>{{'GROUP.DN' | translate}}</clr-dg-column>
<clr-dg-column *ngIf="isLdapMode">{{'GROUP.DN' | translate}}</clr-dg-column>
<clr-dg-row *clrDgItems="let group of groups" [clrDgItem]="group">
<clr-dg-cell>{{group.group_name}}</clr-dg-cell>
<clr-dg-cell>{{groupToSring(group.group_type) | translate}}</clr-dg-cell>
<clr-dg-cell>{{group.ldap_group_dn}}</clr-dg-cell>
<clr-dg-cell *ngIf="isLdapMode">{{group.ldap_group_dn}}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<clr-dg-pagination #pagination [clrDgPageSize]="15">

View File

@ -4,7 +4,7 @@ import { flatMap, catchError } from "rxjs/operators";
import { SessionService } from "./../shared/session.service";
import { TranslateService } from "@ngx-translate/core";
import { Component, OnInit, ViewChild, OnDestroy } from "@angular/core";
import { operateChanges, OperateInfo, OperationService, OperationState } from "@harbor/ui";
import { operateChanges, OperateInfo, OperationService, OperationState, GroupType } from "@harbor/ui";
import {
ConfirmationTargets,
@ -18,7 +18,9 @@ import { UserGroup } from "./group";
import { GroupService } from "./group.service";
import { MessageHandlerService } from "../shared/message-handler/message-handler.service";
import { errorHandler as errorHandFn } from "../shared/shared.utils";
import { Observable, throwError as observableThrowError } from "rxjs";
import { throwError as observableThrowError } from "rxjs";
import { AppConfigService } from '../app-config.service';
@Component({
selector: "app-group",
templateUrl: "./group.component.html",
@ -35,6 +37,7 @@ export class GroupComponent implements OnInit, OnDestroy {
delSub: Subscription;
batchOps = 'idle';
batchInfos = new Map();
isLdapMode: boolean;
@ViewChild(AddGroupModalComponent) newGroupModal: AddGroupModalComponent;
@ -46,10 +49,14 @@ export class GroupComponent implements OnInit, OnDestroy {
private msgHandler: MessageHandlerService,
private session: SessionService,
private translateService: TranslateService,
private appConfigService: AppConfigService
) { }
ngOnInit() {
this.loadData();
if (this.appConfigService.isLdapMode()) {
this.isLdapMode = true;
}
this.delSub = this.operateDialogService.confirmationConfirm$.subscribe(
message => {
if (
@ -150,7 +157,13 @@ export class GroupComponent implements OnInit, OnDestroy {
}
groupToSring(type: number) {
if (type === 1) { return 'GROUP.LDAP_TYPE'; } else { return 'UNKNOWN'; }
if (type === GroupType.LDAP_TYPE) {
return 'GROUP.LDAP_TYPE';
} else if (type === GroupType.HTTP_TYPE) {
return 'GROUP.HTTP_TYPE';
} else {
return 'UNKNOWN';
}
}
doFilter(groupName: string): void {
@ -162,6 +175,12 @@ export class GroupComponent implements OnInit, OnDestroy {
}
get canEditGroup(): boolean {
return (
this.selectedGroups.length === 1 &&
this.session.currentUser.has_admin_role && this.isLdapMode
);
}
get canDeleteGroup(): boolean {
return (
this.selectedGroups.length === 1 &&
this.session.currentUser.has_admin_role

View File

@ -4,9 +4,9 @@ export class UserGroup {
group_type: number;
ldap_group_dn?: string;
constructor() {
constructor(groupType) {
{
this.group_type = 1;
this.group_type = groupType;
}
}
}

View File

@ -31,7 +31,7 @@ export class AddGroupComponent implements OnInit {
currentTerm = '';
selectedRole = 1;
group = new UserGroup();
group = new UserGroup(1);
selectedGroups: UserGroup[] = [];
groups: UserGroup[] = [];
totalCount = 0;
@ -90,7 +90,7 @@ export class AddGroupComponent implements OnInit {
resetModaldata() {
this.createGroupMode = false;
this.group = new UserGroup();
this.group = new UserGroup(1);
this.selectedRole = 1;
this.selectedGroups = [];
this.groups = [];

View File

@ -0,0 +1,36 @@
<clr-modal [(clrModalOpen)]="addHttpAuthOpened" [clrModalStaticBackdrop]="staticBackdrop" [clrModalClosable]="closable">
<h3 class="modal-title">{{'GROUP.NEW_MEMBER' | translate}}</h3>
<inline-alert class="modal-title padding-0"></inline-alert>
<div class="modal-body">
<label>{{ 'GROUP.NEW_USER_INFO' | translate}}</label>
<form #memberForm="ngForm">
<section class="form-block">
<div class="form-group">
<label for="member_name" class="col-md-4 form-group-label-override required">{{'GROUP.GROUP' | translate}} {{'GROUP.NAME' | translate}}</label>
<label for="member_name" aria-haspopup="true" role="tooltip"
class="tooltip tooltip-validation tooltip-sm tooltip-bottom-left">
<input type="text" id="member_name" [(ngModel)]="member_group.group_name"
name="member_name"
size="20"
minlength="3"
#memberName="ngModel"
required autocomplete="off">
</label>
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>
</div>
<div class="form-group">
<label class="col-md-4 form-group-label-override">{{'GROUP.ROLE' | translate}}</label>
<div class="radio" *ngFor="let projectRoot of projectRoots">
<input type="radio" name="member_role" id="{{'check_root_project_' + projectRoot.NAME}}" [value]="projectRoot.VALUE" [(ngModel)]="role_id">
<label for="{{'check_root_project_' + projectRoot.NAME}}">{{ projectRoot.LABEL | translate}}</label>
</div>
</div>
</section>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
<button type="button" class="btn btn-primary" [disabled]="!isValid" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
</div>
</clr-modal>

View File

@ -0,0 +1,8 @@
.form-group-label-override {
font-size: 14px;
font-weight: 400;
}
.padding-0 {
padding: 0;
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AddHttpAuthGroupComponent } from './add-http-auth-group.component';
describe('AddHttpAuthGroupComponent', () => {
let component: AddHttpAuthGroupComponent;
let fixture: ComponentFixture<AddHttpAuthGroupComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddHttpAuthGroupComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AddHttpAuthGroupComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,120 @@
import { finalize } from 'rxjs/operators';
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
//
// Licensed 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,
Input,
EventEmitter,
Output,
ViewChild,
OnInit
} from '@angular/core';
import { NgForm } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { InlineAlertComponent } from '../../../shared/inline-alert/inline-alert.component';
import { UserService } from '../../../user/user.service';
import { PROJECT_ROOTS, ProjectRootInterface } from "@harbor/ui";
import { MemberService } from '../member.service';
import { errorHandler as errorHandFn, } from '../../../shared/shared.utils';
import { UserGroup } from "./../../../group/group";
@Component({
selector: 'add-http-auth-group',
templateUrl: './add-http-auth-group.component.html',
styleUrls: ['./add-http-auth-group.component.scss'],
providers: [UserService]
})
export class AddHttpAuthGroupComponent implements OnInit {
projectRoots: ProjectRootInterface[];
member_group: UserGroup = { group_name: '', group_type: 2 };
role_id: number;
addHttpAuthOpened: boolean;
memberForm: NgForm;
staticBackdrop: boolean = true;
closable: boolean = false;
@ViewChild('memberForm')
currentForm: NgForm;
@ViewChild(InlineAlertComponent)
inlineAlert: InlineAlertComponent;
@Input() projectId: number;
@Output() added = new EventEmitter<boolean>();
checkOnGoing: boolean = false;
constructor(private memberService: MemberService,
private translateService: TranslateService) { }
ngOnInit(): void {
this.projectRoots = PROJECT_ROOTS;
}
createGroupAsMember() {
this.checkOnGoing = true;
this.memberService.addGroupMember(this.projectId, this.member_group, this.role_id)
.pipe(
finalize(() => {
this.checkOnGoing = false;
}
))
.subscribe(
res => {
this.role_id = null;
this.addHttpAuthOpened = false;
this.added.emit(true);
},
err => {
let errorMessageKey: string = errorHandFn(err);
this.translateService
.get(errorMessageKey)
.subscribe(errorMessage => this.inlineAlert.showInlineError(errorMessage));
this.added.emit(false);
}
);
}
onSubmit(): void {
this.createGroupAsMember();
}
onCancel() {
this.role_id = null;
this.addHttpAuthOpened = false;
}
openAddMemberModal(): void {
this.currentForm.reset();
this.addHttpAuthOpened = true;
this.role_id = 1;
this.inlineAlert.close();
}
public get isValid(): boolean {
return this.currentForm &&
this.currentForm.valid &&
!this.checkOnGoing;
}
}

View File

@ -16,7 +16,7 @@
<button class="btn btn-sm btn-secondary" (click)="openAddMemberModal()" [disabled]="!hasCreateMemberPermission">
<span><clr-icon shape="plus" size="16"></clr-icon>&nbsp;{{'MEMBER.USER' | translate }}</span>
</button>
<button class="btn btn-sm btn-secondary" (click)="openAddGroupModal()" [disabled]="!hasCreateMemberPermission || !isLdapMode">
<button class="btn btn-sm btn-secondary" (click)="openAddGroupModal()" [disabled]="!hasCreateMemberPermission || !(isLdapMode || isHttpAuthMode)">
<span><clr-icon shape="plus" size="16"></clr-icon>&nbsp;{{'MEMBER.LDAP_GROUP' | translate}}</span>
</button>
<clr-dropdown id='member-action' [clrCloseMenuOnItemClick]="false" class="btn btn-sm btn-link" clrDropdownTrigger>
@ -53,4 +53,5 @@
</div>
<add-member [projectId]="projectId" [memberList]="members" (added)="addedMember($event)"></add-member>
<add-group [projectId]="projectId" [memberList]="members" (added)="addedGroup($event)"></add-group>
<add-http-auth-group [projectId]="projectId" (added)="addedGroup($event)"></add-http-auth-group>
</div>

View File

@ -29,6 +29,7 @@ import { Project } from "../../project/project";
import { Member } from "./member";
import { SessionUser } from "../../shared/session-user";
import { AddGroupComponent } from './add-group/add-group.component';
import { AddHttpAuthGroupComponent } from './add-http-auth-group/add-http-auth-group.component';
import { MemberService } from "./member.service";
import { AddMemberComponent } from "./add-member/add-member.component";
import { AppConfigService } from "../../app-config.service";
@ -57,16 +58,18 @@ export class MemberComponent implements OnInit, OnDestroy {
isDelete = false;
isChangeRole = false;
loading = false;
isLdapMode: boolean = false;
isChangingRole = false;
batchChangeRoleInfos = {};
isLdapMode: boolean;
isHttpAuthMode: boolean;
@ViewChild(AddMemberComponent)
addMemberComponent: AddMemberComponent;
@ViewChild(AddGroupComponent)
addGroupComponent: AddGroupComponent;
@ViewChild(AddHttpAuthGroupComponent)
addHttpAuthGroupComponent: AddHttpAuthGroupComponent;
hasCreateMemberPermission: boolean;
hasUpdateMemberPermission: boolean;
hasDeleteMemberPermission: boolean;
@ -109,13 +112,15 @@ export class MemberComponent implements OnInit, OnDestroy {
// Get current user from registered resolver.
this.currentUser = this.session.getCurrentUser();
this.retrieve(this.projectId, "");
// get member permission rule
this.getMemberPermissionRule(this.projectId);
if (this.appConfigService.isLdapMode()) {
this.isLdapMode = true;
}
// get member permission rule
this.getMemberPermissionRule(this.projectId);
if (this.appConfigService.isHttpAuthMode()) {
this.isHttpAuthMode = true;
}
}
doSearch(searchMember: string) {
this.searchMember = searchMember;
this.retrieve(this.projectId, this.searchMember);
@ -172,7 +177,11 @@ export class MemberComponent implements OnInit, OnDestroy {
// Add group
openAddGroupModal() {
this.addGroupComponent.open();
if (this.isLdapMode) {
this.addGroupComponent.open();
} else {
this.addHttpAuthGroupComponent.openAddMemberModal();
}
}
addedGroup(result: boolean) {
this.searchMember = "";
@ -188,10 +197,10 @@ export class MemberComponent implements OnInit, OnDestroy {
return this.memberService
.changeMemberRole(projectId, member.id, roleId)
.pipe(map(() => this.batchChangeRoleInfos[member.id] = 'done')
, catchError(error => {
this.messageHandlerService.handleError(error + ": " + member.entity_name);
return observableThrowError(error);
}));
, catchError(error => {
this.messageHandlerService.handleError(error + ": " + member.entity_name);
return observableThrowError(error);
}));
};
// Preparation for members role change

View File

@ -38,6 +38,7 @@ import { ProjectLabelComponent } from "../project/project-label/project-label.co
import { HelmChartModule } from './helm-chart/helm-chart.module';
import { RobotAccountComponent } from './robot-account/robot-account.component';
import { AddRobotComponent } from './robot-account/add-robot/add-robot.component';
import { AddHttpAuthGroupComponent } from './member/add-http-auth-group/add-http-auth-group.component';
@NgModule({
imports: [
@ -59,7 +60,8 @@ import { AddRobotComponent } from './robot-account/add-robot/add-robot.component
ProjectLabelComponent,
AddGroupComponent,
RobotAccountComponent,
AddRobotComponent
AddRobotComponent,
AddHttpAuthGroupComponent
],
exports: [ProjectComponent, ListProjectComponent],
providers: [ProjectRoutingResolver, ProjectService, MemberService, RobotService]

View File

@ -324,6 +324,7 @@
"GROUP": "Group",
"GROUPS": "Groups",
"IMPORT_LDAP_GROUP": "Import LDAP Group",
"IMPORT_HTTP_GROUP": "New HTTP Group",
"ADD": "New Group",
"EDIT": "Edit",
"DELETE": "Delete",
@ -336,8 +337,17 @@
"ADD_GROUP_SUCCESS": "Add group success",
"EDIT_GROUP_SUCCESS": "Edit group success",
"LDAP_TYPE": "LDAP",
"HTTP_TYPE": "HTTP",
"OF": "of",
"ITEMS": "items"
"ITEMS": "items",
"NEW_MEMBER": "New Group Member",
"NEW_USER_INFO": "Add a group to be a member of this project with specified role",
"ROLE": "Role",
"SYS_ADMIN": "System Admin",
"PROJECT_ADMIN": "Project Admin",
"PROJECT_MASTER": "Master",
"DEVELOPER": "Developer",
"GUEST": "Guest"
},
"AUDIT_LOG": {
"USERNAME": "Username",

View File

@ -325,6 +325,7 @@
"GROUP": "Group",
"GROUPS": "Groups",
"IMPORT_LDAP_GROUP": "Import LDAP Group",
"IMPORT_HTTP_GROUP": "New HTTP Group",
"ADD": "Add",
"EDIT": "Edit",
"DELETE": "Delete",
@ -336,8 +337,17 @@
"ADD_GROUP_SUCCESS": "Add group success",
"EDIT_GROUP_SUCCESS": "Edit group success",
"LDAP_TYPE": "LDAP",
"HTTP_TYPE": "HTTP",
"OF": "of",
"ITEMS": "items"
"ITEMS": "items",
"NEW_MEMBER": "New Group Member",
"NEW_USER_INFO": "Add a group to be a member of this project with specified role",
"ROLE": "Role",
"SYS_ADMIN": "System Admin",
"PROJECT_ADMIN": "Project Admin",
"PROJECT_MASTER": "Master",
"DEVELOPER": "Developer",
"GUEST": "Guest"
},
"AUDIT_LOG": {
"USERNAME": "Nombre de usuario",

View File

@ -316,6 +316,7 @@
"Group": "Group",
"GROUPS": "Groups",
"IMPORT_LDAP_GROUP": "Import LDAP Group",
"IMPORT_HTTP_GROUP": "New HTTP Group",
"ADD": "Add",
"EDIT": "Edit",
"DELETE": "Delete",
@ -328,8 +329,17 @@
"ADD_GROUP_SUCCESS": "Add group success",
"EDIT_GROUP_SUCCESS": "Edit group success",
"LDAP_TYPE": "LDAP",
"HTTP_TYPE": "HTTP",
"OF": "of",
"ITEMS": "items"
"ITEMS": "items",
"NEW_MEMBER": "New Group Member",
"NEW_USER_INFO": "Add a group to be a member of this project with specified role",
"ROLE": "Role",
"SYS_ADMIN": "System Admin",
"PROJECT_ADMIN": "Project Admin",
"PROJECT_MASTER": "Master",
"DEVELOPER": "Developer",
"GUEST": "Guest"
},
"AUDIT_LOG": {
"USERNAME": "Nom d'utilisateur",

View File

@ -322,6 +322,7 @@
"GROUP": "Grupo",
"GROUPS": "Grupos",
"IMPORT_LDAP_GROUP": "Importar grupo do LDAP",
"IMPORT_HTTP_GROUP": "New HTTP Group",
"ADD": "Novo Grupo",
"EDIT": "Editar",
"DELETE": "Remover",
@ -334,8 +335,17 @@
"ADD_GROUP_SUCCESS": "Grupo adicionado com sucesso",
"EDIT_GROUP_SUCCESS": "Grupo editado com sucesso",
"LDAP_TYPE": "LDAP",
"HTTP_TYPE": "HTTP",
"OF": "de",
"ITEMS": "itens"
"ITEMS": "itens",
"NEW_MEMBER": "New Group Member",
"NEW_USER_INFO": "Add a group to be a member of this project with specified role",
"ROLE": "Role",
"SYS_ADMIN": "System Admin",
"PROJECT_ADMIN": "Project Admin",
"PROJECT_MASTER": "Master",
"DEVELOPER": "Developer",
"GUEST": "Guest"
},
"AUDIT_LOG": {
"USERNAME": "Nome do usuário",

View File

@ -323,6 +323,7 @@
"GROUP": "组",
"GROUPS": "组",
"IMPORT_LDAP_GROUP": "导入LDAP组",
"IMPORT_HTTP_GROUP": "新建HTTP组",
"ADD": "新增",
"EDIT": "编辑",
"DELETE": "删除",
@ -335,8 +336,17 @@
"ADD_GROUP_SUCCESS": "添加组成功",
"EDIT_GROUP_SUCCESS": "修改组成功",
"LDAP_TYPE": "LDAP",
"HTTP_TYPE": "HTTP",
"OF": "共计",
"ITEMS": "条记录"
"ITEMS": "条记录",
"NEW_MEMBER": "新建组成员",
"NEW_USER_INFO": "添加一个组作为具有指定角色的此项目的成员",
"ROLE": "权限",
"SYS_ADMIN": "系统管理员",
"PROJECT_ADMIN": "项目管理员",
"PROJECT_MASTER": "维护人员",
"DEVELOPER": "开发者",
"GUEST": "访客"
},
"AUDIT_LOG": {
"USERNAME": "用户名",