Enhance swagger UI (#15168)

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
孙世军 2021-06-23 16:28:14 +08:00 committed by GitHub
parent 0464305bcc
commit 33301ec65e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 33 deletions

View File

@ -13,10 +13,11 @@ produces:
consumes: consumes:
- application/json - application/json
securityDefinitions: securityDefinitions:
basicAuth: basic:
type: basic type: basic
security: security:
- basicAuth: [] - basic: []
- {}
paths: paths:
/version: /version:
get: get:
@ -529,4 +530,4 @@ definitions:
description: A flag to indicate if the chart is signed description: A flag to indicate if the chart is signed
prov_file: prov_file:
type: string type: string
description: The URL of the provance file description: The URL of the provance file

View File

@ -14,10 +14,11 @@ produces:
consumes: consumes:
- application/json - application/json
securityDefinitions: securityDefinitions:
basicAuth: basic:
type: basic type: basic
security: security:
- basicAuth: [] - basic: []
- {}
paths: paths:
/email/ping: /email/ping:
post: post:

View File

@ -1,11 +1,11 @@
import { AfterViewInit, OnInit, Directive } from '@angular/core'; import { AfterViewInit, Component, Directive, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CookieService } from "ngx-cookie"; import { CookieService } from "ngx-cookie";
@Directive() @Directive()
export abstract class DevCenterBase implements OnInit, AfterViewInit { export abstract class DevCenterBaseDirective implements OnInit, AfterViewInit {
constructor( protected constructor(
public translate: TranslateService, public translate: TranslateService,
public cookieService: CookieService, public cookieService: CookieService,
public titleService: Title) { public titleService: Title) {
@ -20,20 +20,6 @@ export abstract class DevCenterBase implements OnInit, AfterViewInit {
this.titleService.setTitle(res); this.titleService.setTitle(res);
}); });
} }
public getCsrfInterceptor() {
return {
requestInterceptor: {
apply: (requestObj) => {
const csrfCookie = this.cookieService.get('__csrf');
const headers = requestObj.headers || {};
if (csrfCookie) {
headers["X-Harbor-CSRF-Token"] = csrfCookie;
}
return requestObj;
}
}
};
}
abstract getSwaggerUI(); abstract getSwaggerUI();
abstract ngAfterViewInit(); abstract ngAfterViewInit();
} }

View File

@ -7,7 +7,8 @@ import { TranslateService } from '@ngx-translate/core';
import { CookieService } from "ngx-cookie"; import { CookieService } from "ngx-cookie";
import * as SwaggerUI from 'swagger-ui'; import * as SwaggerUI from 'swagger-ui';
import { mergeDeep } from "../shared/units/utils"; import { mergeDeep } from "../shared/units/utils";
import { DevCenterBase } from "./dev-center-base"; import { DevCenterBaseDirective } from "./dev-center-base";
import { SAFE_METHODS } from "../services/intercept-http.service";
// @ts-ignore // @ts-ignore
window.Buffer = window.Buffer || require('buffer').Buffer; // this is for swagger UI window.Buffer = window.Buffer || require('buffer').Buffer; // this is for swagger UI
@ -16,13 +17,16 @@ enum SwaggerJsonUrls {
SWAGGER2 = '/swagger2.json' SWAGGER2 = '/swagger2.json'
} }
const helpInfo: string = " If you want to enable basic authorization," +
" please logout Harbor first or manually delete the cookies under the current domain.";
@Component({ @Component({
selector: 'dev-center', selector: 'dev-center',
templateUrl: 'dev-center.component.html', templateUrl: 'dev-center.component.html',
viewProviders: [Title], viewProviders: [Title],
styleUrls: ['dev-center.component.scss'] styleUrls: ['dev-center.component.scss']
}) })
export class DevCenterComponent extends DevCenterBase implements AfterViewInit, OnInit { export class DevCenterComponent extends DevCenterBaseDirective implements AfterViewInit, OnInit {
private ui: any; private ui: any;
constructor( constructor(
private el: ElementRef, private el: ElementRef,
@ -37,15 +41,15 @@ export class DevCenterComponent extends DevCenterBase implements AfterViewInit,
this.getSwaggerUI(); this.getSwaggerUI();
} }
getSwaggerUI() { getSwaggerUI() {
const _this = this;
forkJoin([this.http.get(SwaggerJsonUrls.SWAGGER1), this.http.get(SwaggerJsonUrls.SWAGGER2)]) forkJoin([this.http.get(SwaggerJsonUrls.SWAGGER1), this.http.get(SwaggerJsonUrls.SWAGGER2)])
.pipe(catchError(error => observableThrowError(error))) .pipe(catchError(error => observableThrowError(error)))
.subscribe(jsonArr => { .subscribe(jsonArr => {
const json: object = {}; const json: any = {};
mergeDeep(json, jsonArr[0], jsonArr[1]); mergeDeep(json, jsonArr[0], jsonArr[1]);
json['host'] = window.location.host; json['host'] = window.location.host;
const protocal = window.location.protocol; const protocal = window.location.protocol;
json['schemes'] = [protocal.replace(":", "")]; json['schemes'] = [protocal.replace(":", "")];
json.info.description = json.info.description + helpInfo;
this.ui = SwaggerUI({ this.ui = SwaggerUI({
spec: json, spec: json,
domNode: this.el.nativeElement.querySelector('.swagger-container'), domNode: this.el.nativeElement.querySelector('.swagger-container'),
@ -53,13 +57,26 @@ export class DevCenterComponent extends DevCenterBase implements AfterViewInit,
presets: [ presets: [
SwaggerUI.presets.apis SwaggerUI.presets.apis
], ],
requestInterceptor: this.getCsrfInterceptor().requestInterceptor, requestInterceptor: (request) => {
authorizations: { // Get the csrf token from localstorage
csrf: function () { const token = localStorage.getItem("__csrf");
this.headers['X-Harbor-CSRF-Token'] = _this.cookieService.get('__csrf'); const headers = request.headers || {};
return true; if (token ) {
if (request.method && SAFE_METHODS.indexOf(request.method.toUpperCase()) === -1) {
headers["X-Harbor-CSRF-Token"] = token;
}
} }
} return request;
},
responseInterceptor: (response) => {
const headers = response.headers || {};
const responseToken: string = headers["X-Harbor-CSRF-Token"];
if (responseToken) {
// Set the csrf token to localstorage
localStorage.setItem("__csrf", responseToken);
}
return response;
},
}); });
}); });
} }

View File

@ -3,7 +3,7 @@ import { HttpInterceptor, HttpRequest, HttpHandler, HttpResponse, HttpErrorRespo
import { Observable, throwError } from 'rxjs'; import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators'; import { catchError, tap } from 'rxjs/operators';
const SAFE_METHODS: string[] = ["GET", "HEAD", "OPTIONS", "TRACE"]; export const SAFE_METHODS: string[] = ["GET", "HEAD", "OPTIONS", "TRACE"];
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'