mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-27 19:17:47 +01:00
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:
parent
93ac2e8111
commit
10cb2fd2c7
@ -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\"",
|
||||
|
@ -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\"",
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
@ -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))
|
||||
);
|
||||
}
|
||||
}
|
@ -346,4 +346,4 @@
|
||||
</clr-modal>
|
||||
<confirmation-dialog
|
||||
#confirmationDialog
|
||||
(confirmAction)="confirmGenerate($event)"></confirmation-dialog>
|
||||
(confirmAction)="confirmGenerate()"></confirmation-dialog>
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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() {
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user