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

View File

@ -14,4 +14,21 @@ clr-modal {
.label-inner-text{ .label-inner-text{
margin: 0; 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 { Component, OnInit, ViewChild, AfterViewChecked } from "@angular/core";
import { NgForm } from "@angular/forms"; import { NgForm } from "@angular/forms";
import { Router, NavigationExtras } from "@angular/router"; import { Router, NavigationExtras } from "@angular/router";
import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
import { SessionUser } from "../../shared/session-user"; import { SessionUser } from "../../shared/session-user";
import { SessionService } from "../../shared/session.service"; 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 { SearchTriggerService } from "../../base/global-search/search-trigger.service";
import { CommonRoutes } from "../../shared/shared.const"; import { CommonRoutes } from "../../shared/shared.const";
import { CopyInputComponent } from "@harbor/ui"; 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({ @Component({
selector: "account-settings-modal", selector: "account-settings-modal",
templateUrl: "account-settings-modal.component.html", templateUrl: "account-settings-modal.component.html",
@ -44,6 +51,9 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
newAdminName = "admin@harbor.local"; newAdminName = "admin@harbor.local";
renameConfirmation = false; renameConfirmation = false;
// confirmRename = false; // confirmRename = false;
showGenerateCli: boolean = false;
@ViewChild("confirmationDialog")
confirmationDialogComponent: ConfirmationDialogComponent;
accountFormRef: NgForm; accountFormRef: NgForm;
@ViewChild("accountSettingsFrom") accountForm: NgForm; @ViewChild("accountSettingsFrom") accountForm: NgForm;
@ -55,6 +65,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
private msgHandler: MessageHandlerService, private msgHandler: MessageHandlerService,
private router: Router, private router: Router,
private searchTrigger: SearchTriggerService, private searchTrigger: SearchTriggerService,
private accountSettingsService: AccountSettingsModalService,
private ref: ChangeDetectorRef private ref: ChangeDetectorRef
) {} ) {}
@ -236,7 +247,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
account_settings_email: true, account_settings_email: true,
account_settings_full_name: true account_settings_full_name: true
}; };
this.showGenerateCli = false;
this.opened = true; this.opened = true;
} }
@ -327,4 +338,27 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
onError(event) { onError(event) {
this.inlineAlert.showInlineError({message: 'PROFILE.COPY_ERROR'}); 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 { ResetPasswordComponent } from './password-setting/reset-password/reset-password.component';
import { SignUpPageComponent } from './sign-up/sign-up-page.component'; import { SignUpPageComponent } from './sign-up/sign-up-page.component';
import { PasswordSettingService } from './password-setting/password-setting.service'; import { PasswordSettingService } from './password-setting/password-setting.service';
import { AccountSettingsModalService } from './account-settings/account-settings-modal-service.service';
@NgModule({ @NgModule({
@ -49,6 +50,6 @@ import { PasswordSettingService } from './password-setting/password-setting.serv
SignUpComponent, SignUpComponent,
SignUpPageComponent], SignUpPageComponent],
providers: [PasswordSettingService] providers: [PasswordSettingService, AccountSettingsModalService]
}) })
export class AccountModule { } export class AccountModule { }

View File

@ -106,7 +106,12 @@
"CLI_PASSWORD": "CLI secret", "CLI_PASSWORD": "CLI secret",
"CLI_PASSWORD_TIP": "You can use this cli secret as password when using docker/helm cli to access Harbor.", "CLI_PASSWORD_TIP": "You can use this cli secret as password when using docker/helm cli to access Harbor.",
"COPY_SUCCESS": "copy success", "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": { "CHANGE_PWD": {
"TITLE": "Change Password", "TITLE": "Change Password",

View File

@ -106,7 +106,12 @@
"CLI_PASSWORD": "CLI secreto", "CLI_PASSWORD": "CLI secreto",
"CLI_PASSWORD_TIP": "Puede utilizar este generador CLI secreto como utilizando Docker / Helm CLI para acceder a puerto.", "CLI_PASSWORD_TIP": "Puede utilizar este generador CLI secreto como utilizando Docker / Helm CLI para acceder a puerto.",
"COPY_SUCCESS": "Copiar el éxito", "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": { "CHANGE_PWD": {
"TITLE": "Cambiar contraseña", "TITLE": "Cambiar contraseña",

View File

@ -93,7 +93,12 @@
"CLI_PASSWORD": "CLI secret", "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.", "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_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": { "CHANGE_PWD": {
"TITLE": "Modifier le mot de passe", "TITLE": "Modifier le mot de passe",

View File

@ -104,7 +104,12 @@
"CLI_PASSWORD": "Segredo CLI", "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.", "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_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": { "CHANGE_PWD": {
"TITLE": "Alterar Senha", "TITLE": "Alterar Senha",

View File

@ -105,7 +105,12 @@
"CLI_PASSWORD": "CLI密码", "CLI_PASSWORD": "CLI密码",
"CLI_PASSWORD_TIP": "使用docker/helm cli访问Harbor时可以使用此cli密码作为密码。", "CLI_PASSWORD_TIP": "使用docker/helm cli访问Harbor时可以使用此cli密码作为密码。",
"COPY_SUCCESS": "复制成功", "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": { "CHANGE_PWD": {
"TITLE": "修改密码", "TITLE": "修改密码",