feat: cert download

This commit is contained in:
xiaojunnuo
2023-06-27 22:45:27 +08:00
parent 27a4c81c6d
commit 5a51c14de5
27 changed files with 207 additions and 75 deletions
@@ -4,7 +4,7 @@ import { BaseException } from './base-exception';
* 授权异常
*/
export class PermissionException extends BaseException {
constructor(message) {
constructor(message?: string) {
super(
'PermissionException',
Constants.res.permission.code,
@@ -25,6 +25,11 @@ export class AuthorityMiddleware implements IWebMiddleware {
ctx.path,
ctx.method
);
if (routeInfo == null) {
// 404
await next();
return;
}
const permission = routeInfo.summary;
if (permission == null || permission === '') {
ctx.status = 500;
@@ -41,6 +46,14 @@ export class AuthorityMiddleware implements IWebMiddleware {
let token = ctx.get('Authorization') || '';
token = token.replace('Bearer ', '').trim();
if (token === '') {
//尝试从cookie中获取token
token = ctx.cookies.get('token') || '';
}
if (token === '') {
//尝试从query中获取token
token = (ctx.query.token as string) || '';
}
try {
ctx.user = jwt.verify(token, this.secret);
} catch (err) {
@@ -23,6 +23,11 @@ export class LoginController extends BaseController {
user
) {
const token = await this.loginService.login(user);
this.ctx.cookies.set('token', token.token, {
maxAge: 1000 * token.expire,
});
return this.ok(token);
}
@@ -2,6 +2,7 @@ import {
ALL,
Body,
Controller,
Get,
Inject,
Post,
Provide,
@@ -13,7 +14,11 @@ import { HistoryService } from '../service/history-service';
import { HistoryLogService } from '../service/history-log-service';
import { HistoryEntity } from '../entity/history';
import { HistoryLogEntity } from '../entity/history-log';
import {Constants} from "../../../basic/constants";
import { Constants } from '../../../basic/constants';
import { PipelineService } from '../service/pipeline-service';
import { CommonException } from '../../../basic/exception/common-exception';
import { PermissionException } from '../../../basic/exception/permission-exception';
import * as fs from 'fs';
/**
* 证书
@@ -24,6 +29,8 @@ export class HistoryController extends CrudController<HistoryService> {
@Inject()
service: HistoryService;
@Inject()
pipelineService: PipelineService;
@Inject()
logService: HistoryLogService;
getService() {
@@ -104,4 +111,51 @@ export class HistoryController extends CrudController<HistoryService> {
const logInfo = await this.logService.info(id);
return this.ok(logInfo);
}
@Post('/files', { summary: Constants.per.authOnly })
async files(@Query('pipelineId') pipelineId, @Query('historyId') historyId) {
const files = await this.getFiles(historyId, pipelineId);
return this.ok(files);
}
private async getFiles(historyId, pipelineId) {
let history = null;
if (historyId != null) {
// nothing
history = await this.service.info(historyId);
} else if (pipelineId != null) {
history = await this.service.getLastHistory(pipelineId);
}
if (history == null) {
throw new CommonException('historyId is null');
}
if (history.userId !== this.ctx.user.id) {
throw new PermissionException();
}
return await this.service.getFiles(history);
}
@Get('/download', { summary: Constants.per.authOnly })
async download(
@Query('pipelineId') pipelineId,
@Query('historyId') historyId,
@Query('fileId') fileId
) {
const files = await this.getFiles(historyId, pipelineId);
const file = files.find(f => f.id === fileId);
if (file == null) {
throw new CommonException('file not found');
}
// koa send file
// 下载文件的名称
// const filename = file.filename;
// 要下载的文件的完整路径
const path = file.path;
// 以流的形式下载文件
this.ctx.attachment(path);
this.ctx.set('Content-Type', 'application/octet-stream');
return fs.createReadStream(path);
}
}
@@ -1,4 +1,4 @@
import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/decorator";
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { BaseService } from '../../../basic/base-service';
@@ -6,6 +6,7 @@ import { HistoryEntity } from '../entity/history';
import { PipelineEntity } from '../entity/pipeline';
import { HistoryDetail } from '../entity/vo/history-detail';
import { HistoryLogService } from './history-log-service';
import { FileItem, Pipeline, RunnableCollection } from '@certd/pipeline';
/**
* 证书申请
@@ -78,4 +79,29 @@ export class HistoryService extends BaseService<HistoryEntity> {
shouldDeleteCount -= deleteCountBatch;
}
}
async getLastHistory(pipelineId: number) {
return await this.repository.findOne({
where: {
pipelineId,
},
order: {
id: 'DESC',
},
});
}
async getFiles(history: HistoryEntity) {
const status: Pipeline = JSON.parse(history.pipeline);
const files: FileItem[] = [];
RunnableCollection.each([status], runnable => {
if (runnable.runnableType !== 'step') {
return;
}
if (runnable.status?.files != null) {
files.push(...runnable.status.files);
}
});
return files;
}
}