Update the way for generating new cli secret (#17744)

Update the way for refreshing cli-secret

Signed-off-by: AllForNothing <sshijun@vmware.com>

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
Shijun Sun 2022-11-03 21:04:04 +08:00 committed by GitHub
parent 93ac2e8111
commit 10cb2fd2c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 54 additions and 158 deletions

View File

@ -12,7 +12,8 @@
// For developing
"start": "node --max_old_space_size=2048 ./node_modules/@angular/cli/bin/ng serve --ssl true --host 0.0.0.0 --proxy-config proxy.config.json",
"start:prod": "node --max_old_space_size=2048 ./node_modules/@angular/cli/bin/ng serve --ssl true --host 0.0.0.0 --proxy-config proxy.config.json --configuration production",
"start_default_port": "node --max_old_space_size=2048 ./node_modules/@angular/cli/bin/ng serve --ssl true --host 0.0.0.0 --port 443 --disable-host-check --proxy-config proxy.config.json",
// For code grammar checking
"lint": "tslint \"src/**/*.ts\"",
"lint_fix": "tslint --fix \"src/**/*.ts\"",

View File

@ -7,6 +7,7 @@
"postinstall": "node scripts/convert-yaml-to-json.js && ng-swagger-gen -i ng-swagger-gen/swagger.json -o ng-swagger-gen && node scripts/delete-swagger-json.js",
"start": "node --max_old_space_size=2048 ./node_modules/@angular/cli/bin/ng serve --ssl true --host 0.0.0.0 --proxy-config proxy.config.json",
"start:prod": "node --max_old_space_size=2048 ./node_modules/@angular/cli/bin/ng serve --ssl true --host 0.0.0.0 --proxy-config proxy.config.json --configuration production",
"start_default_port": "node --max_old_space_size=2048 ./node_modules/@angular/cli/bin/ng serve --ssl true --host 0.0.0.0 --port 443 --disable-host-check --proxy-config proxy.config.json",
"lint": "ng lint",
"lint_fix": "ng lint --fix",
"lint:style": "npx stylelint \"**/*.scss\"",

View File

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

View File

@ -1,20 +0,0 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { catchError, map } from 'rxjs/operators';
import { throwError as observableThrowError, Observable } from 'rxjs';
import { CURRENT_BASE_HREF } from '../../shared/units/utils';
@Injectable({
providedIn: 'root',
})
export class AccountSettingsModalService {
constructor(private http: HttpClient) {}
saveNewCli(userId, secretObj): Observable<any> {
return this.http
.put(`${CURRENT_BASE_HREF}/users/${userId}/cli_secret`, secretObj)
.pipe(
map(response => response),
catchError(error => observableThrowError(error))
);
}
}

View File

@ -346,4 +346,4 @@
</clr-modal>
<confirmation-dialog
#confirmationDialog
(confirmAction)="confirmGenerate($event)"></confirmation-dialog>
(confirmAction)="confirmGenerate()"></confirmation-dialog>

View File

@ -4,7 +4,6 @@ import { AccountSettingsModalComponent } from './account-settings-modal.componen
import { SessionService } from '../../shared/services/session.service';
import { MessageHandlerService } from '../../shared/services/message-handler.service';
import { SearchTriggerService } from '../../shared/components/global-search/search-trigger.service';
import { AccountSettingsModalService } from './account-settings-modal-service.service';
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectorRef } from '@angular/core';
import { ClarityModule } from '@clr/angular';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
@ -18,6 +17,7 @@ import { ConfirmationDialogComponent } from '../../shared/components/confirmatio
import { InlineAlertComponent } from '../../shared/components/inline-alert/inline-alert.component';
import { ConfirmationDialogService } from '../global-confirmation-dialog/confirmation-dialog.service';
import { ConfirmationMessage } from '../global-confirmation-dialog/confirmation-message';
import { UserService } from '../../../../ng-swagger-gen/services/user.service';
describe('AccountSettingsModalComponent', () => {
let component: AccountSettingsModalComponent;
@ -54,9 +54,6 @@ describe('AccountSettingsModalComponent', () => {
let fakeSearchTriggerService = {
closeSearch: () => {},
};
let fakeAccountSettingsModalService = {
saveNewCli: () => of(null),
};
let fakeConfirmationDialogService = {
cancel: () => of(null),
confirm: () => of(null),
@ -68,6 +65,15 @@ describe('AccountSettingsModalComponent', () => {
navigate: () => {},
};
const fakedUserService = {
getCurrentUserInfo() {
return of({});
},
setCliSecret() {
return of(null);
},
};
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
@ -96,8 +102,8 @@ describe('AccountSettingsModalComponent', () => {
useValue: fakeSearchTriggerService,
},
{
provide: AccountSettingsModalService,
useValue: fakeAccountSettingsModalService,
provide: UserService,
useValue: fakedUserService,
},
{ provide: Router, useValue: fakeRouter },
{
@ -261,7 +267,7 @@ describe('AccountSettingsModalComponent', () => {
ConfirmationDialogComponent
).componentInstance;
generateCliButton.dispatchEvent(new Event('click'));
component.confirmGenerate(null);
component.confirmGenerate();
await fixture.whenStable();
expect(component.showGenerateCli).toEqual(false);
});

View File

@ -19,8 +19,6 @@ import { SessionUser } from '../../shared/entities/session-user';
import { SessionService } from '../../shared/services/session.service';
import { MessageHandlerService } from '../../shared/services/message-handler.service';
import { SearchTriggerService } from '../../shared/components/global-search/search-trigger.service';
import { AccountSettingsModalService } from './account-settings-modal-service.service';
import { randomWord } from '../../shared/units/shared.utils';
import { ResetSecret } from './account';
import { CopyInputComponent } from '../../shared/components/push-image/copy-input.component';
import {
@ -31,6 +29,7 @@ import {
import { ConfirmationDialogComponent } from '../../shared/components/confirmation-dialog';
import { InlineAlertComponent } from '../../shared/components/inline-alert/inline-alert.component';
import { ConfirmationMessage } from '../global-confirmation-dialog/confirmation-message';
import { UserService } from 'ng-swagger-gen/services/user.service';
@Component({
selector: 'account-settings-modal',
@ -73,7 +72,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
private msgHandler: MessageHandlerService,
private router: Router,
private searchTrigger: SearchTriggerService,
private accountSettingsService: AccountSettingsModalService
private userService: UserService
) {}
private validationStateMap: any = {
@ -392,29 +391,41 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
this.showGenerateCli = !this.showGenerateCli;
}
confirmGenerate(event): void {
this.account.oidc_user_meta.secret = randomWord(9);
this.resetCliSecret(this.account.oidc_user_meta.secret);
confirmGenerate(): void {
this.resetCliSecret(null);
}
resetCliSecret(secret) {
let userId = this.account.user_id;
this.accountSettingsService
.saveNewCli(userId, { secret: secret })
.subscribe(
cliSecret => {
this.account.oidc_user_meta.secret = secret;
this.userService
.setCliSecret({
userId: this.account.user_id,
secret: secret
? {
secret: secret,
}
: {},
})
.subscribe({
next: res => {
if (secret) {
this.account.oidc_user_meta.secret = secret;
} else {
this.userService.getCurrentUserInfo().subscribe(res => {
this.account.oidc_user_meta.secret =
res?.oidc_user_meta?.secret;
});
}
this.closeReset();
this.inlineAlert.showInlineSuccess({
message: 'PROFILE.GENERATE_SUCCESS',
});
},
error => {
error: err => {
this.resetSecretInlineAlert.showInlineError({
message: 'PROFILE.GENERATE_ERROR',
});
}
);
},
});
}
disableChangeCliSecret() {

View File

@ -19,11 +19,11 @@ import { AppConfigService } from '../../services/app-config.service';
import { ErrorHandler } from '../../shared/units/error-handler';
import { AccountSettingsModalComponent } from '../account-settings/account-settings-modal.component';
import { InlineAlertComponent } from '../../shared/components/inline-alert/inline-alert.component';
import { AccountSettingsModalService } from '../account-settings/account-settings-modal-service.service';
import { ScannerService } from '../../../../ng-swagger-gen/services/scanner.service';
import { HttpHeaders, HttpResponse } from '@angular/common/http';
import { Registry } from '../../../../ng-swagger-gen/models/registry';
import { delay } from 'rxjs/operators';
import { UserService } from '../../../../ng-swagger-gen/services/user.service';
describe('HarborShellComponent', () => {
let component: HarborShellComponent;
@ -38,7 +38,6 @@ describe('HarborShellComponent', () => {
searchCloseChan$: of(null),
};
let mockMessageHandlerService = null;
let mockAccountSettingsModalService = null;
let mockPasswordSettingService = null;
let mockSkinableConfig = {
getSkinConfig: function () {
@ -89,6 +88,14 @@ describe('HarborShellComponent', () => {
return of([]).pipe(delay(0));
},
};
const fakedUserService = {
getCurrentUserInfo() {
return of({});
},
setCliSecret() {
return of(null);
},
};
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
@ -119,8 +126,8 @@ describe('HarborShellComponent', () => {
useValue: mockMessageHandlerService,
},
{
provide: AccountSettingsModalService,
useValue: mockAccountSettingsModalService,
provide: UserService,
useValue: fakedUserService,
},
{
provide: PasswordSettingService,

View File

@ -99,97 +99,6 @@ export const maintainUrlQueryParmas = function (
}
}
};
/**
* the password or secret must longer than 8 chars with at least 1 uppercase letter, 1 lowercase letter and 1 number
* @param randomFlag
* @param min
* @param max
* @returns {string}
*/
export function randomWord(max) {
let str = '';
let contentArray = [
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
[
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
],
[
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
],
];
for (let i = 0; i < max; i++) {
let randomNumber = getRandomInt(contentArray.length);
str +=
contentArray[randomNumber][
getRandomInt(contentArray[randomNumber].length)
];
}
if (!str.match(/\d+/g)) {
str += contentArray[0][getRandomInt(contentArray[0].length)];
}
if (!str.match(/[a-z]+/g)) {
str += contentArray[1][getRandomInt(contentArray[1].length)];
}
if (!str.match(/[A-Z]+/g)) {
str += contentArray[2][getRandomInt(contentArray[2].length)];
}
return str;
}
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
/**
* handle docker client response error