Add generate cli secret in user profile page

add cli secret button in user profile page, OIDC users can click this button to regenerate a cli secret, if the user does so, then the past cli secret will be abandoned.

Signed-off-by: Yogi_Wang <yawang@vmware.com>
This commit is contained in:
Yogi_Wang 2019-04-22 17:01:41 +08:00
parent d53f21bf3c
commit f164738246
11 changed files with 122 additions and 11 deletions

View File

@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';
import { AccountSettingsModalService } from './account-settings-modal-service.service';
describe('AccountSettingsModalServiceService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: AccountSettingsModalService = TestBed.get(AccountSettingsModalService);
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { catchError, map } from 'rxjs/operators';
import { throwError as observableThrowError, Observable } from 'rxjs';
@Injectable()
export class AccountSettingsModalService {
constructor(private http: Http) { }
generateCli(userId): Observable<any> {
return this.http.post(`/api/users/${userId}/gen_cli_secret`, {}).pipe( map(response => response)
, catchError(error => observableThrowError(error)));
}
}

View File

@ -51,7 +51,7 @@
</span>
</label>
</div>
<div class="form-group form-group-override" *ngIf="account.oidc_user_meta">
<div class="form-group form-group-override cli-secret" *ngIf="account.oidc_user_meta">
<label for="cli_password" aria-haspopup="true" class="form-group-label-override"><span class="label-inner-text">{{'PROFILE.CLI_PASSWORD' | translate}}</span>
<clr-tooltip>
<clr-icon clrTooltipTrigger shape="info-circle" size="20"></clr-icon>
@ -60,9 +60,13 @@
</clr-tooltip-content>
</clr-tooltip></label>
<input type="password" name="cli_password" disabled [ngModel]="'account.oidc_user_meta.secret'" size="33">
<div class="rename-tool">
<hbr-copy-input #copyInput (onCopySuccess)="onSuccess($event)" (onCopyError)="onCpError($event)" iconMode="true" defaultValue="{{account.oidc_user_meta.secret}}"></hbr-copy-input>
<button (click)="generateCli(account.user_id)" class="btn btn-outline btn-sm btn-padding-less" *ngIf="showGenerateCli">
{{'PROFILE.ADMIN_CIL_SECRET_BUTTON' | translate}}
</button>
<div class="rename-tool reset-cli">
<hbr-copy-input #copyInput (onCopySuccess)="onSuccess($event)" (onCopyError)="onError($event)" iconMode="true" [defaultValue]="account.oidc_user_meta.secret"></hbr-copy-input>
</div>
<div (click)="showGenerateCliFn()" *ngIf="!showGenerateCli" class="hidden-generate-cli">···</div>
</div>
</section>
</form>
@ -72,4 +76,5 @@
<button type="button" class="btn btn-outline" (click)="close()">{{'BUTTON.CANCEL' | translate}}</button>
<button type="button" class="btn btn-primary" [disabled]="!isValid || showProgress" (click)="submit()">{{'BUTTON.OK' | translate}}</button>
</div>
</clr-modal>
</clr-modal>
<confirmation-dialog #confirmationDialog (confirmAction)="confirmGenerate($event)"></confirmation-dialog>

View File

@ -14,4 +14,21 @@ clr-modal {
.label-inner-text{
margin: 0;
}
.cli-secret {
align-items: center;
.reset-cli {
height: 30px;
}
.btn-padding-less {
padding-left: 5px;
padding-right: 5px;
}
}
.hidden-generate-cli {
font-size: 30px;
color: grey;
margin-left: 0.5rem;
cursor: pointer;
line-height: 30px;
}
}

View File

@ -15,6 +15,7 @@ import { ChangeDetectorRef } from '@angular/core';
import { Component, OnInit, ViewChild, AfterViewChecked } from "@angular/core";
import { NgForm } from "@angular/forms";
import { Router, NavigationExtras } from "@angular/router";
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
import { SessionUser } from "../../shared/session-user";
import { SessionService } from "../../shared/session.service";
@ -23,6 +24,12 @@ import { MessageHandlerService } from "../../shared/message-handler/message-hand
import { SearchTriggerService } from "../../base/global-search/search-trigger.service";
import { CommonRoutes } from "../../shared/shared.const";
import { CopyInputComponent } from "@harbor/ui";
import { AccountSettingsModalService } from './account-settings-modal-service.service';
import { ConfirmationDialogComponent } from "../../shared/confirmation-dialog/confirmation-dialog.component";
import {
ConfirmationTargets,
ConfirmationButtons
} from "../../shared/shared.const";
@Component({
selector: "account-settings-modal",
templateUrl: "account-settings-modal.component.html",
@ -44,6 +51,9 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
newAdminName = "admin@harbor.local";
renameConfirmation = false;
// confirmRename = false;
showGenerateCli: boolean = false;
@ViewChild("confirmationDialog")
confirmationDialogComponent: ConfirmationDialogComponent;
accountFormRef: NgForm;
@ViewChild("accountSettingsFrom") accountForm: NgForm;
@ -55,6 +65,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
private msgHandler: MessageHandlerService,
private router: Router,
private searchTrigger: SearchTriggerService,
private accountSettingsService: AccountSettingsModalService,
private ref: ChangeDetectorRef
) {}
@ -236,7 +247,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
account_settings_email: true,
account_settings_full_name: true
};
this.showGenerateCli = false;
this.opened = true;
}
@ -327,4 +338,27 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
onError(event) {
this.inlineAlert.showInlineError({message: 'PROFILE.COPY_ERROR'});
}
generateCli(userId): void {
let generateCliMessage = new ConfirmationMessage(
'PROFILE.CONFIRM_TITLE_CLI_GENERATE',
'PROFILE.CONFIRM_BODY_CLI_GENERATE',
'',
userId,
ConfirmationTargets.TARGET,
ConfirmationButtons.CONFIRM_CANCEL);
this.confirmationDialogComponent.open(generateCliMessage);
}
showGenerateCliFn() {
this.showGenerateCli = !this.showGenerateCli;
}
confirmGenerate(confirmData): void {
let userId = confirmData.data;
this.accountSettingsService.generateCli(userId).subscribe(cliSecret => {
let secret = JSON.parse(cliSecret._body).secret;
this.account.oidc_user_meta.secret = secret;
this.inlineAlert.showInlineSuccess({message: 'PROFILE.GENERATE_SUCCESS'});
}, error => {
this.inlineAlert.showInlineError({message: 'PROFILE.GENERATE_ERROR'});
});
}
}

View File

@ -25,6 +25,7 @@ import { ForgotPasswordComponent } from './password-setting/forgot-password/forg
import { ResetPasswordComponent } from './password-setting/reset-password/reset-password.component';
import { SignUpPageComponent } from './sign-up/sign-up-page.component';
import { PasswordSettingService } from './password-setting/password-setting.service';
import { AccountSettingsModalService } from './account-settings/account-settings-modal-service.service';
@NgModule({
@ -49,6 +50,6 @@ import { PasswordSettingService } from './password-setting/password-setting.serv
SignUpComponent,
SignUpPageComponent],
providers: [PasswordSettingService]
providers: [PasswordSettingService, AccountSettingsModalService]
})
export class AccountModule { }

View File

@ -106,7 +106,12 @@
"CLI_PASSWORD": "CLI secret",
"CLI_PASSWORD_TIP": "You can use this cli secret as password when using docker/helm cli to access Harbor.",
"COPY_SUCCESS": "copy success",
"COPY_ERROR": "copy failed"
"COPY_ERROR": "copy failed",
"ADMIN_CIL_SECRET_BUTTON": "GENERATE SECRET",
"GENERATE_SUCCESS": "generate CLI secret success",
"GENERATE_ERROR": "generate CLI secret failed",
"CONFIRM_TITLE_CLI_GENERATE": "Are you sure you can regenerate secret?",
"CONFIRM_BODY_CLI_GENERATE": "If you regenerate cli secret, the old cli secret will be discarded"
},
"CHANGE_PWD": {
"TITLE": "Change Password",

View File

@ -106,7 +106,12 @@
"CLI_PASSWORD": "CLI secreto",
"CLI_PASSWORD_TIP": "Puede utilizar este generador CLI secreto como utilizando Docker / Helm CLI para acceder a puerto.",
"COPY_SUCCESS": "Copiar el éxito",
"COPY_ERROR": "Copia no"
"COPY_ERROR": "Copia no",
"ADMIN_CIL_SECRET_BUTTON": "GENERATE SECRET",
"GENERATE_SUCCESS": "generate CLI secret success",
"GENERATE_ERROR": "generate CLI secret failed",
"CONFIRM_TITLE_CLI_GENERATE": "Are you sure you can regenerate secret?",
"CONFIRM_BODY_CLI_GENERATE": "If you regenerate cli secret, the old cli secret will be discarded"
},
"CHANGE_PWD": {
"TITLE": "Cambiar contraseña",

View File

@ -93,7 +93,12 @@
"CLI_PASSWORD": "CLI secret",
"CLI_PASSWORD_TIP": "vous pouvez utiliser ce cli secret comme mot de passe quand utiliser docker / barre l'accès à harbor.",
"COPY_SUCCESS": "copie de succès",
"COPY_ERROR": "copie a échoué"
"COPY_ERROR": "copie a échoué",
"ADMIN_CIL_SECRET_BUTTON": "GENERATE SECRET",
"GENERATE_SUCCESS": "generate CLI secret success",
"GENERATE_ERROR": "generate CLI secret failed",
"CONFIRM_TITLE_CLI_GENERATE": "Are you sure you can regenerate secret?",
"CONFIRM_BODY_CLI_GENERATE": "If you regenerate cli secret, the old cli secret will be discarded"
},
"CHANGE_PWD": {
"TITLE": "Modifier le mot de passe",

View File

@ -104,7 +104,12 @@
"CLI_PASSWORD": "Segredo CLI",
"CLI_PASSWORD_TIP": "Você Pode USAR este Segredo de clitóris Como senha Ao USAR clitóris de estivador /leme para acessar Harbor.",
"COPY_SUCCESS": "SUCESSO de cópia",
"COPY_ERROR": "Cópia falhou"
"COPY_ERROR": "Cópia falhou",
"ADMIN_CIL_SECRET_BUTTON": "GENERATE SECRET",
"GENERATE_SUCCESS": "generate CLI secret success",
"GENERATE_ERROR": "generate CLI secret failed",
"CONFIRM_TITLE_CLI_GENERATE": "Are you sure you can regenerate secret?",
"CONFIRM_BODY_CLI_GENERATE": "If you regenerate cli secret, the old cli secret will be discarded"
},
"CHANGE_PWD": {
"TITLE": "Alterar Senha",

View File

@ -105,7 +105,12 @@
"CLI_PASSWORD": "CLI密码",
"CLI_PASSWORD_TIP": "使用docker/helm cli访问Harbor时可以使用此cli密码作为密码。",
"COPY_SUCCESS": "复制成功",
"COPY_ERROR": "复制失败"
"COPY_ERROR": "复制失败",
"ADMIN_CIL_SECRET_BUTTON": "生成新的CLI密码",
"GENERATE_SUCCESS": "成功生成新的CLI密码",
"GENERATE_ERROR": "生成新的CLI密码失败",
"CONFIRM_TITLE_CLI_GENERATE": "您确定需要重新生成cli secret吗?",
"CONFIRM_BODY_CLI_GENERATE": "如果您重新生成cli secret那么旧的cli secret将会被弃用"
},
"CHANGE_PWD": {
"TITLE": "修改密码",