mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-29 20:18:05 +01:00
commit
8260f204a0
@ -141,6 +141,18 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
||||
this.account = Object.assign({}, this.session.getCurrentUser());
|
||||
this.formValueChanged = false;
|
||||
|
||||
//Confirm inline alert is closed
|
||||
this.inlineAlert.close();
|
||||
|
||||
//Clear check history
|
||||
this.mailAlreadyChecked = {};
|
||||
|
||||
//Reset validation status
|
||||
this.validationStateMap = {
|
||||
"account_settings_email": true,
|
||||
"account_settings_full_name": true
|
||||
};
|
||||
|
||||
this.opened = true;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true">
|
||||
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
|
||||
<h3 class="modal-title">{{'RESET_PWD.TITLE' | translate}}</h3>
|
||||
<label class="modal-title reset-modal-title-override">{{'RESET_PWD.CAPTION' | translate}}</label>
|
||||
<inline-alert class="modal-title"></inline-alert>
|
||||
|
@ -32,10 +32,15 @@ export class ForgotPasswordComponent {
|
||||
}
|
||||
|
||||
public open(): void {
|
||||
this.opened = true;
|
||||
//Clear state data
|
||||
this.validationState = true;
|
||||
this.forceValid = true;
|
||||
this.onGoing = false;
|
||||
this.email = "";
|
||||
this.forgotPwdForm.resetForm();
|
||||
this.inlineAlert.close();
|
||||
|
||||
this.opened = true;
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
|
@ -93,9 +93,18 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
||||
|
||||
//Open modal dialog
|
||||
open(): void {
|
||||
this.opened = true;
|
||||
this.pwdForm.reset();
|
||||
//Reset state
|
||||
this.formValueChanged = false;
|
||||
this.onCalling = false;
|
||||
this.error = null;
|
||||
this.validationStateMap = {
|
||||
"newPassword": true,
|
||||
"reNewPassword": true
|
||||
};
|
||||
this.pwdForm.reset();
|
||||
this.inlineAlert.close();
|
||||
|
||||
this.opened = true;
|
||||
}
|
||||
|
||||
//Close the moal dialog
|
||||
|
@ -1,4 +1,4 @@
|
||||
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true">
|
||||
<clr-modal [(clrModalOpen)]="opened" [clrModalStaticBackdrop]="true" [clrModalClosable]="false">
|
||||
<h3 class="modal-title">{{'RESET_PWD.TITLE' | translate}}</h3>
|
||||
<label class="modal-title reset-modal-title-override">{{'RESET_PWD.CAPTION2' | translate}}</label>
|
||||
<div class="modal-body" style="overflow-y: hidden;">
|
||||
|
@ -15,7 +15,10 @@ export class ResetPasswordComponent implements OnInit {
|
||||
opened: boolean = true;
|
||||
private onGoing: boolean = false;
|
||||
private password: string = "";
|
||||
private validationState: any = {};
|
||||
private validationState: any = {
|
||||
"newPassword": true,
|
||||
"reNewPassword": true
|
||||
};
|
||||
private resetUuid: string = "";
|
||||
private resetOk: boolean = false;
|
||||
|
||||
@ -49,8 +52,15 @@ export class ResetPasswordComponent implements OnInit {
|
||||
|
||||
public open(): void {
|
||||
this.resetOk = false;
|
||||
this.opened = true;
|
||||
this.onGoing = false;
|
||||
this.validationState = {
|
||||
"newPassword": true,
|
||||
"reNewPassword": true
|
||||
};
|
||||
this.resetPwdForm.resetForm();
|
||||
this.inlineAlert.close();
|
||||
|
||||
this.opened = true;
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
|
@ -153,8 +153,7 @@ export class SignInComponent implements AfterViewChecked, OnInit {
|
||||
private handleUserCreation(user: User): void {
|
||||
if (user) {
|
||||
this.currentForm.setValue({
|
||||
"login_username": user.username,
|
||||
"login_password": user.password
|
||||
"login_username": user.username
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -59,8 +59,13 @@ export class SignUpComponent {
|
||||
}
|
||||
|
||||
open(): void {
|
||||
this.newUserForm.reset();//Reset form
|
||||
//Reset state
|
||||
this.newUserForm.reset();
|
||||
this.formValueChanged = false;
|
||||
this.error = null;
|
||||
this.onGoing = false;
|
||||
this.inlienAlert.close();
|
||||
|
||||
this.modal.open();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="javascript:void(0)" clrDropdownItem (click)="openAccountSettingsModal()">{{'ACCOUNT_SETTINGS.PROFILE' | translate}}</a>
|
||||
<a href="javascript:void(0)" clrDropdownItem (click)="openChangePwdModal()">{{'ACCOUNT_SETTINGS.CHANGE_PWD' | translate}}</a>
|
||||
<a *ngIf="canChangePassword" href="javascript:void(0)" clrDropdownItem (click)="openChangePwdModal()">{{'ACCOUNT_SETTINGS.CHANGE_PWD' | translate}}</a>
|
||||
<a *ngIf="canDownloadCert" href="/api/systeminfo/getcert" clrDropdownItem target="_blank">{{'ACCOUNT_SETTINGS.ROOT_CERT' | translate}}</a>
|
||||
<a href="javascript:void(0)" clrDropdownItem (click)="openAboutDialog()">{{'ACCOUNT_SETTINGS.ABOUT' | translate}}</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
|
@ -76,6 +76,12 @@ export class NavigatorComponent implements OnInit {
|
||||
this.appConfigService.getConfig().has_ca_root;
|
||||
}
|
||||
|
||||
public get canChangePassword(): boolean {
|
||||
return this.session.getCurrentUser() &&
|
||||
this.appConfigService.getConfig() &&
|
||||
this.appConfigService.getConfig().auth_mode != 'ldap_auth';
|
||||
}
|
||||
|
||||
matchLang(lang: string): boolean {
|
||||
return lang.trim() === this.selectedLang;
|
||||
}
|
||||
|
@ -13,4 +13,5 @@
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
line-height: 12px;
|
||||
left: 170px;
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
<div class="form-group">
|
||||
<label for="authMode">{{'CONFIG.AUTH_MODE' | translate }}</label>
|
||||
<div class="select">
|
||||
<select id="authMode" name="authMode" [disabled]="disabled(currentConfig.auth_mode)" [(ngModel)]="currentConfig.auth_mode.value">
|
||||
<select id="authMode" name="authMode" (change)="handleOnChange($event)" [disabled]="disabled(currentConfig.auth_mode)" [(ngModel)]="currentConfig.auth_mode.value">
|
||||
<option value="db_auth">{{'CONFIG.AUTH_MODE_DB' | translate }}</option>
|
||||
<option value="ldap_auth">{{'CONFIG.AUTH_MODE_LDAP' | translate }}</option>
|
||||
</select>
|
||||
@ -128,7 +128,7 @@
|
||||
<span class="tooltip-content">{{'CONFIG.TOOLTIP.PRO_CREATION_RESTRICTION' | translate}}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" *ngIf="showSelfReg">
|
||||
<label for="selfReg">{{'CONFIG.SELF_REGISTRATION' | translate}}</label>
|
||||
<clr-checkbox name="selfReg" id="selfReg" [(ngModel)]="currentConfig.self_registration.value" [disabled]="disabled(currentConfig.self_registration)">
|
||||
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right" style="top:-8px;">
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, Input, ViewChild } from '@angular/core';
|
||||
import { NgForm } from '@angular/forms';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
import { Configuration } from '../config';
|
||||
|
||||
@ -23,6 +23,14 @@ export class ConfigurationAuthComponent {
|
||||
this.currentConfig.auth_mode.value === 'ldap_auth';
|
||||
}
|
||||
|
||||
public get showSelfReg(): boolean {
|
||||
if (!this.currentConfig || !this.currentConfig.auth_mode) {
|
||||
return true;
|
||||
} else {
|
||||
return this.currentConfig.auth_mode.value != 'ldap_auth';
|
||||
}
|
||||
}
|
||||
|
||||
private disabled(prop: any): boolean {
|
||||
return !(prop && prop.editable);
|
||||
}
|
||||
@ -30,4 +38,15 @@ export class ConfigurationAuthComponent {
|
||||
public isValid(): boolean {
|
||||
return this.authForm && this.authForm.valid;
|
||||
}
|
||||
|
||||
private handleOnChange($event): void {
|
||||
if ($event && $event.target && $event.target["value"]) {
|
||||
let authMode = $event.target["value"];
|
||||
if (authMode === 'ldap_auth') {
|
||||
if (this.currentConfig.self_registration.value) {
|
||||
this.currentConfig.self_registration.value = false;//uncheck
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -280,14 +280,13 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
let allChanges = this.getChanges();
|
||||
for (let prop in allChanges) {
|
||||
if (prop.startsWith("ldap_")) {
|
||||
ldapSettings[prop] = allChanges[prop];
|
||||
}
|
||||
let ldapSearchPwd = allChanges["ldap_search_password"];
|
||||
if(ldapSearchPwd){
|
||||
ldapSettings['ldap_search_password'] = ldapSearchPwd;
|
||||
}else{
|
||||
delete ldapSettings['ldap_search_password'];
|
||||
}
|
||||
|
||||
console.info(ldapSettings);
|
||||
|
||||
this.testingOnGoing = true;
|
||||
this.configService.testLDAPServer(ldapSettings)
|
||||
.then(respone => {
|
||||
@ -300,7 +299,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
||||
if(!err){
|
||||
err = "UNKNOWN";
|
||||
}
|
||||
this.msgHandler.showError("CONFIG.TEST_LDAP_FAILED", err);
|
||||
this.msgHandler.showError("CONFIG.TEST_LDAP_FAILED", {'param': err});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ export class RecentLogComponent implements OnInit {
|
||||
let reg = new RegExp('.*' + terms + '.*', 'i');
|
||||
return reg.test(log.username) ||
|
||||
reg.test(log.repo_name) ||
|
||||
reg.test(log.operation);
|
||||
reg.test(log.operation) ||
|
||||
reg.test(log.repo_tag);
|
||||
}
|
||||
}
|
@ -21,7 +21,6 @@ import { SessionService } from '../../shared/session.service';
|
||||
|
||||
export class NewUserFormComponent implements AfterViewChecked, OnInit {
|
||||
newUser: User = new User();
|
||||
confirmedPwd: string = "";
|
||||
@Input() isSelfRegistration: boolean = false;
|
||||
|
||||
newUserFormRef: NgForm;
|
||||
@ -33,17 +32,10 @@ export class NewUserFormComponent implements AfterViewChecked, OnInit {
|
||||
constructor(private session: SessionService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.formValueChanged = false;
|
||||
this.resetState();
|
||||
}
|
||||
|
||||
private validationStateMap: any = {
|
||||
"username": true,
|
||||
"email": true,
|
||||
"realname": true,
|
||||
"newPassword": true,
|
||||
"confirmPassword": true,
|
||||
"comment": true
|
||||
};
|
||||
private validationStateMap: any = {};
|
||||
|
||||
private mailAlreadyChecked: any = {};
|
||||
private userNameAlreadyChecked: any = {};
|
||||
@ -51,10 +43,27 @@ export class NewUserFormComponent implements AfterViewChecked, OnInit {
|
||||
private usernameTooltip: string = 'TOOLTIP.USER_NAME';
|
||||
private formValueChanged: boolean = false;
|
||||
|
||||
private checkOnGoing: any = {
|
||||
"username": false,
|
||||
"email": false
|
||||
};
|
||||
private checkOnGoing: any = {};
|
||||
|
||||
private resetState(): void {
|
||||
this.mailAlreadyChecked = {};
|
||||
this.userNameAlreadyChecked = {};
|
||||
this.emailTooltip = 'TOOLTIP.EMAIL';
|
||||
this.usernameTooltip = 'TOOLTIP.USER_NAME';
|
||||
this.formValueChanged = false;
|
||||
this.checkOnGoing = {
|
||||
"username": false,
|
||||
"email": false
|
||||
};
|
||||
this.validationStateMap = {
|
||||
"username": true,
|
||||
"email": true,
|
||||
"realname": true,
|
||||
"newPassword": true,
|
||||
"confirmPassword": true,
|
||||
"comment": true
|
||||
};
|
||||
}
|
||||
|
||||
public isChecking(key: string): boolean {
|
||||
return !this.checkOnGoing[key];
|
||||
@ -161,7 +170,7 @@ export class NewUserFormComponent implements AfterViewChecked, OnInit {
|
||||
pwdEqualStatus = this.newUserForm.controls["confirmPassword"].value === this.newUserForm.controls["newPassword"].value;
|
||||
}
|
||||
return this.newUserForm &&
|
||||
this.newUserForm.valid &&
|
||||
this.newUserForm.valid &&
|
||||
pwdEqualStatus &&
|
||||
this.validationStateMap["username"] &&
|
||||
this.validationStateMap["email"];//Backend check should be valid as well
|
||||
@ -186,6 +195,7 @@ export class NewUserFormComponent implements AfterViewChecked, OnInit {
|
||||
|
||||
//Reset form
|
||||
reset(): void {
|
||||
this.resetState();
|
||||
if (this.newUserForm) {
|
||||
this.newUserForm.reset();
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import { CommonRoutes, AdmiralQueryParamKey } from '../../shared/shared.const';
|
||||
import { AppConfigService } from '../../app-config.service';
|
||||
import { maintainUrlQueryParmas } from '../../shared/shared.utils';
|
||||
import { MessageHandlerService } from '../message-handler/message-handler.service';
|
||||
import { SearchTriggerService } from '../../base/global-search/search-trigger.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuthCheckGuard implements CanActivate, CanActivateChild {
|
||||
@ -18,7 +19,8 @@ export class AuthCheckGuard implements CanActivate, CanActivateChild {
|
||||
private authService: SessionService,
|
||||
private router: Router,
|
||||
private appConfigService: AppConfigService,
|
||||
private msgHandler: MessageHandlerService) { }
|
||||
private msgHandler: MessageHandlerService,
|
||||
private searchTrigger: SearchTriggerService) { }
|
||||
|
||||
private isGuest(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
||||
const proRegExp = /\/harbor\/projects\/[\d]+\/.+/i;
|
||||
@ -33,6 +35,7 @@ export class AuthCheckGuard implements CanActivate, CanActivateChild {
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> | boolean {
|
||||
//When routing change, clear
|
||||
this.msgHandler.clear();
|
||||
this.searchTrigger.closeSearch(true);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
//Before activating, we firstly need to confirm whether the route is coming from peer part - admiral
|
||||
|
@ -16,7 +16,7 @@ export class SignInGuard implements CanActivate, CanActivateChild {
|
||||
//If user has logged in, should not login again
|
||||
return new Promise((resolve, reject) => {
|
||||
let user = this.authService.getCurrentUser();
|
||||
if (!user) {
|
||||
if (user === null) {
|
||||
this.authService.retrieveUser()
|
||||
.then(() => {
|
||||
this.router.navigate([CommonRoutes.HARBOR_DEFAULT]);
|
||||
|
@ -55,6 +55,10 @@ export class NewUserModalComponent {
|
||||
open(): void {
|
||||
this.newUserForm.reset();//Reset form
|
||||
this.formValueChanged = false;
|
||||
this.onGoing = false;
|
||||
this.error = null;
|
||||
this.inlineAlert.close();
|
||||
|
||||
this.opened = true;
|
||||
}
|
||||
|
||||
|
@ -1,37 +1,37 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<h2 class="custom-h2">{{'SIDE_NAV.SYSTEM_MGMT.USER' | translate}}</h2>
|
||||
<div class="action-panel-pos">
|
||||
<span>
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<h2 class="custom-h2">{{'SIDE_NAV.SYSTEM_MGMT.USER' | translate}}</h2>
|
||||
<div class="action-panel-pos">
|
||||
<span>
|
||||
<button *ngIf="canCreateUser" type="submit" class="btn btn-primary custom-add-button" (click)="addNewUser()"><clr-icon shape="add"></clr-icon> {{'USER.ADD_ACTION' | translate}}</button>
|
||||
</span>
|
||||
<grid-filter class="filter-pos" filterPlaceholder='{{"USER.FILTER_PLACEHOLDER" | translate}}' (filter)="doFilter($event)"></grid-filter>
|
||||
<span class="refresh-btn" (click)="refreshUser()">
|
||||
<grid-filter class="filter-pos" filterPlaceholder='{{"USER.FILTER_PLACEHOLDER" | translate}}' (filter)="doFilter($event)"></grid-filter>
|
||||
<span class="refresh-btn" (click)="refreshUser()">
|
||||
<clr-icon shape="refresh" [hidden]="inProgress" ng-disabled="inProgress"></clr-icon>
|
||||
<span class="spinner spinner-inline" [hidden]="inProgress === false"></span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<clr-datagrid>
|
||||
<clr-dg-column>{{'USER.COLUMN_NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'USER.COLUMN_ADMIN' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'USER.COLUMN_EMAIL' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'USER.COLUMN_REG_NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-row *ngFor="let user of users" [clrDgItem]="user">
|
||||
<clr-dg-action-overflow [hidden]="isMySelf(user.user_id)">
|
||||
<button class="action-item" (click)="changeAdminRole(user)">{{adminActions(user)}}</button>
|
||||
<button class="action-item" (click)="deleteUser(user)">{{'USER.DEL_ACTION' | translate}}</button>
|
||||
</clr-dg-action-overflow>
|
||||
<clr-dg-cell>{{user.username}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{isSystemAdmin(user)}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{user.email}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
{{user.creation_time}}
|
||||
</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>{{users.length}} {{'USER.ITEMS' | translate}}</clr-dg-footer>
|
||||
</clr-datagrid>
|
||||
</div>
|
||||
<new-user-modal (addNew)="addUserToList($event)"></new-user-modal>
|
||||
</div>
|
||||
<div>
|
||||
<clr-datagrid>
|
||||
<clr-dg-column>{{'USER.COLUMN_NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'USER.COLUMN_ADMIN' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'USER.COLUMN_EMAIL' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'USER.COLUMN_REG_NAME' | translate}}</clr-dg-column>
|
||||
<clr-dg-row *ngFor="let user of users" [clrDgItem]="user">
|
||||
<clr-dg-action-overflow [hidden]="isMySelf(user.user_id)">
|
||||
<button class="action-item" (click)="changeAdminRole(user)">{{adminActions(user)}}</button>
|
||||
<button class="action-item" (click)="deleteUser(user)">{{'USER.DEL_ACTION' | translate}}</button>
|
||||
</clr-dg-action-overflow>
|
||||
<clr-dg-cell>{{user.username}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{isSystemAdmin(user)}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{user.email}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
{{user.creation_time}}
|
||||
</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>{{users.length}} {{'USER.ADD_ACTION' | translate}}</clr-dg-footer>
|
||||
</clr-datagrid>
|
||||
</div>
|
||||
<new-user-modal (addNew)="addUserToList($event)"></new-user-modal>
|
||||
</div>
|
||||
</div>
|
@ -114,7 +114,8 @@
|
||||
"SAVE_SUCCESS": "New user added successfully",
|
||||
"DELETION_TITLE": "Confirm user deletion",
|
||||
"DELETION_SUMMARY": "Do you want to delete user {{param}}?",
|
||||
"DELETE_SUCCESS": "User deleted successfully"
|
||||
"DELETE_SUCCESS": "User deleted successfully",
|
||||
"ITEMS": "item(s)"
|
||||
},
|
||||
"PROJECT": {
|
||||
"PROJECTS": "Projects",
|
||||
|
@ -114,7 +114,8 @@
|
||||
"SAVE_SUCCESS": "添加用户成功",
|
||||
"DELETION_TITLE": "删除用户确认",
|
||||
"DELETION_SUMMARY": "你确认删除用户 {{param}}?",
|
||||
"DELETE_SUCCESS": "删除用户成功"
|
||||
"DELETE_SUCCESS": "删除用户成功",
|
||||
"ITEMS": "条记录"
|
||||
},
|
||||
"PROJECT": {
|
||||
"PROJECTS": "项目",
|
||||
|
Loading…
Reference in New Issue
Block a user