diff --git a/src/portal/src/app/account/account-settings/account-settings-modal-service.service.spec.ts b/src/portal/src/app/account/account-settings/account-settings-modal-service.service.spec.ts new file mode 100644 index 000000000..665bad62f --- /dev/null +++ b/src/portal/src/app/account/account-settings/account-settings-modal-service.service.spec.ts @@ -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(); + }); +}); diff --git a/src/portal/src/app/account/account-settings/account-settings-modal-service.service.ts b/src/portal/src/app/account/account-settings/account-settings-modal-service.service.ts new file mode 100644 index 000000000..c1a9ea56c --- /dev/null +++ b/src/portal/src/app/account/account-settings/account-settings-modal-service.service.ts @@ -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 { + return this.http.post(`/api/users/${userId}/gen_cli_secret`, {}).pipe( map(response => response) + , catchError(error => observableThrowError(error))); + } +} diff --git a/src/portal/src/app/account/account-settings/account-settings-modal.component.html b/src/portal/src/app/account/account-settings/account-settings-modal.component.html index f9a32e790..bdf1c2da2 100644 --- a/src/portal/src/app/account/account-settings/account-settings-modal.component.html +++ b/src/portal/src/app/account/account-settings/account-settings-modal.component.html @@ -51,7 +51,7 @@ -
+
-
- + +
+
+
···
@@ -72,4 +76,5 @@
- \ No newline at end of file + + diff --git a/src/portal/src/app/account/account-settings/account-settings-modal.component.scss b/src/portal/src/app/account/account-settings/account-settings-modal.component.scss index c0ea6022d..b15f82a0f 100644 --- a/src/portal/src/app/account/account-settings/account-settings-modal.component.scss +++ b/src/portal/src/app/account/account-settings/account-settings-modal.component.scss @@ -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; + } } \ No newline at end of file diff --git a/src/portal/src/app/account/account-settings/account-settings-modal.component.ts b/src/portal/src/app/account/account-settings/account-settings-modal.component.ts index 2f81b64ed..b0a409672 100644 --- a/src/portal/src/app/account/account-settings/account-settings-modal.component.ts +++ b/src/portal/src/app/account/account-settings/account-settings-modal.component.ts @@ -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'}); + }); + } } diff --git a/src/portal/src/app/account/account.module.ts b/src/portal/src/app/account/account.module.ts index 74662a609..3789bfea7 100644 --- a/src/portal/src/app/account/account.module.ts +++ b/src/portal/src/app/account/account.module.ts @@ -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 { } diff --git a/src/portal/src/i18n/lang/en-us-lang.json b/src/portal/src/i18n/lang/en-us-lang.json index f546b72ed..7d2725cb7 100644 --- a/src/portal/src/i18n/lang/en-us-lang.json +++ b/src/portal/src/i18n/lang/en-us-lang.json @@ -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", diff --git a/src/portal/src/i18n/lang/es-es-lang.json b/src/portal/src/i18n/lang/es-es-lang.json index e4ac159d5..13b304b4c 100644 --- a/src/portal/src/i18n/lang/es-es-lang.json +++ b/src/portal/src/i18n/lang/es-es-lang.json @@ -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", diff --git a/src/portal/src/i18n/lang/fr-fr-lang.json b/src/portal/src/i18n/lang/fr-fr-lang.json index dc0bb20fc..a9b3589b0 100644 --- a/src/portal/src/i18n/lang/fr-fr-lang.json +++ b/src/portal/src/i18n/lang/fr-fr-lang.json @@ -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", diff --git a/src/portal/src/i18n/lang/pt-br-lang.json b/src/portal/src/i18n/lang/pt-br-lang.json index d5376c250..a06adf96a 100644 --- a/src/portal/src/i18n/lang/pt-br-lang.json +++ b/src/portal/src/i18n/lang/pt-br-lang.json @@ -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", diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json index 2a14340b2..f84b98419 100644 --- a/src/portal/src/i18n/lang/zh-cn-lang.json +++ b/src/portal/src/i18n/lang/zh-cn-lang.json @@ -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": "修改密码",