feat: 权限控制

pull/21/merge
xiaojunnuo 2023-06-27 09:29:43 +08:00
parent fdc25dc0d7
commit 27a4c81c6d
37 changed files with 325 additions and 134 deletions

View File

@ -1,5 +1,11 @@
import { request, requestForMock } from "../service"; import { request, requestForMock } from "../service";
import { env } from "/@/utils/util.env"; import { env } from "/@/utils/util.env";
export interface RegisterReq {
username: string;
password: string;
confirmPassword: string;
}
/** /**
* @description: Login interface parameters * @description: Login interface parameters
*/ */
@ -19,6 +25,14 @@ export interface LoginRes {
expire: number; expire: number;
} }
export async function register(user: RegisterReq): Promise<UserInfoRes> {
return await request({
url: "/register",
method: "post",
data: user
});
}
export async function login(data: LoginReq): Promise<LoginRes> { export async function login(data: LoginReq): Promise<LoginRes> {
if (env.PM_ENABLED === "false") { if (env.PM_ENABLED === "false") {
//没有开启权限模块,模拟登录 //没有开启权限模块,模拟登录

View File

@ -31,7 +31,7 @@ function createService() {
const { code } = dataAxios; const { code } = dataAxios;
// 根据 code 进行判断 // 根据 code 进行判断
if (code === undefined) { if (code === undefined) {
// 如果没有 code 代表这不是项目后端开发的接口 比如可能是 D2Admin 请求最新版本 // 如果没有 code 代表这不是项目后端开发的接口
errorCreate(`非标准返回:${dataAxios} ${response.config.url}`); errorCreate(`非标准返回:${dataAxios} ${response.config.url}`);
return dataAxios; return dataAxios;
} else { } else {

View File

@ -63,5 +63,7 @@ export function errorLog(error: any) {
* @param {String} msg * @param {String} msg
*/ */
export function errorCreate(msg: string) { export function errorCreate(msg: string) {
throw new Error(msg); const err = new Error(msg);
uiContext.get().notification.error({ message: err.message });
throw err;
} }

View File

@ -12,7 +12,7 @@ export const frameworkResource = [
component: LayoutFramework, component: LayoutFramework,
meta: { meta: {
icon: "ion:accessibility", icon: "ion:accessibility",
auth: true authOnly: true
}, },
children: [ children: [
{ {

View File

@ -6,7 +6,7 @@ export const certdResources = [
redirect: "/certd/pipeline", redirect: "/certd/pipeline",
meta: { meta: {
icon: "ion:key-outline", icon: "ion:key-outline",
auth: true authOnly: true
}, },
children: [ children: [
{ {
@ -43,7 +43,7 @@ export const certdResources = [
redirect: "/certd/settings/email", redirect: "/certd/settings/email",
meta: { meta: {
icon: "ion:settings-outline", icon: "ion:settings-outline",
auth: true authOnly: true
}, },
children: [ children: [
{ {
@ -53,7 +53,7 @@ export const certdResources = [
component: "/certd/settings/email-setting.vue", component: "/certd/settings/email-setting.vue",
meta: { meta: {
icon: "ion:mail-outline", icon: "ion:mail-outline",
auth: true authOnly: true
} }
} }
] ]

View File

@ -15,6 +15,14 @@ export const outsideResource = [
name: "login", name: "login",
path: "/login", path: "/login",
component: "/framework/login/index.vue" component: "/framework/login/index.vue"
},
{
meta: {
title: "注册"
},
name: "register",
path: "/register",
component: "/framework/register/index.vue"
} }
] ]
}, },

View File

@ -35,7 +35,7 @@ export const usePageStore = defineStore({
fullPath: "/index", fullPath: "/index",
meta: { meta: {
title: "首页", title: "首页",
auth: false authOnly: false
} }
} }
], ],

View File

@ -7,10 +7,11 @@ import { LocalStorage } from "/src/utils/util.storage";
import * as UserApi from "/src/api/modules/api.user"; import * as UserApi from "/src/api/modules/api.user";
// @ts-ignore // @ts-ignore
import { LoginReq, UserInfoRes } from "/@/api/modules/api.user"; import { LoginReq, UserInfoRes } from "/@/api/modules/api.user";
import { Modal } from "ant-design-vue"; import { Modal, notification } from "ant-design-vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { mitter } from "/src/utils/util.mitt"; import { mitter } from "/src/utils/util.mitt";
import { RegisterReq } from "/src/api/modules/api.user";
interface UserState { interface UserState {
userInfo: Nullable<UserInfoRes>; userInfo: Nullable<UserInfoRes>;
@ -50,6 +51,14 @@ export const useUserStore = defineStore({
LocalStorage.remove(TOKEN_KEY); LocalStorage.remove(TOKEN_KEY);
LocalStorage.remove(USER_INFO_KEY); LocalStorage.remove(USER_INFO_KEY);
}, },
async register(user: RegisterReq) {
await UserApi.register(user);
notification.success({
message: "注册成功,请登录"
});
await router.replace("/login");
},
/** /**
* @description: login * @description: login
*/ */

View File

@ -66,7 +66,7 @@
</a-form-item> </a-form-item>
<a-form-item class="user-login-other"> <a-form-item class="user-login-other">
<!-- <router-link class="register" :to="{ name: 'index' }"> 注册 </router-link>--> <router-link class="register" :to="{ name: 'register' }"> 注册 </router-link>
</a-form-item> </a-form-item>
</a-form> </a-form>
</div> </div>

View File

@ -1,15 +1,8 @@
<template> <template>
<div class="main"> <div class="main">
<a-form <a-form ref="formRef" class="user-layout-register" name="custom-validation" :model="formState" :rules="rules" v-bind="layout" @finish="handleFinish" @finishFailed="handleFinishFailed">
ref="formRef" <div class="login-title">用户注册</div>
class="user-layout-login"
name="custom-validation"
:model="formState"
:rules="rules"
v-bind="layout"
@finish="handleFinish"
@finishFailed="handleFinishFailed"
>
<a-form-item required has-feedback name="username"> <a-form-item required has-feedback name="username">
<a-input v-model:value="formState.username" size="large" autocomplete="off"> <a-input v-model:value="formState.username" size="large" autocomplete="off">
<template #prefix> <template #prefix>
@ -46,13 +39,14 @@
import { defineComponent, reactive, ref, toRaw } from "vue"; import { defineComponent, reactive, ref, toRaw } from "vue";
import { useUserStore } from "/src/store/modules/user"; import { useUserStore } from "/src/store/modules/user";
export default defineComponent({ export default defineComponent({
name: "Register", name: "RegisterPage",
setup() { setup() {
const userStore = useUserStore(); const userStore = useUserStore();
const formRef = ref(); const formRef = ref();
const formState = reactive({ const formState = reactive({
username: "", username: "",
password: "" password: "",
confirmPassword: ""
}); });
const rules = { const rules = {
@ -88,8 +82,7 @@ export default defineComponent({
}; };
const handleFinish = async (values) => { const handleFinish = async (values) => {
console.log(values, formState); await userStore.register(
const userInfo = await userStore.login(
toRaw({ toRaw({
password: formState.password, password: formState.password,
username: formState.username username: formState.username
@ -120,16 +113,17 @@ export default defineComponent({
<style lang="less"> <style lang="less">
@import "../../../style/theme/index.less"; @import "../../../style/theme/index.less";
.user-layout-login { .user-layout-register {
label { label {
font-size: 14px; font-size: 14px;
} }
.login-title { .login-title {
color: @primary-color; // color: @primary-color;
font-size: 18px; font-size: 18px;
text-align: center; text-align: center;
margin: 20px; margin: 30px;
margin-top: 50px;
} }
.getCaptcha { .getCaptcha {
display: block; display: block;

View File

@ -0,0 +1 @@
INSERT INTO sys_role (id, name, create_time, update_time) VALUES (3, '普通用户', 1, 1623749138537);

View File

@ -52,6 +52,7 @@
"kubernetes-client": "^9.0.0", "kubernetes-client": "^9.0.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"log4js": "^6.7.1", "log4js": "^6.7.1",
"lru-cache": "^10.0.0",
"md5": "^2.3.0", "md5": "^2.3.0",
"midway-flyway-js": "^3.0.0", "midway-flyway-js": "^3.0.0",
"node-cron": "^3.0.2", "node-cron": "^3.0.2",

View File

@ -1,19 +1,25 @@
import { Inject } from '@midwayjs/decorator';
import { ValidateException } from './exception/validation-exception'; import { ValidateException } from './exception/validation-exception';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { Context } from '@midwayjs/koa';
import { PermissionException } from './exception/permission-exception'; import { PermissionException } from './exception/permission-exception';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { Inject } from '@midwayjs/decorator';
import { TypeORMDataSourceManager } from '@midwayjs/typeorm';
import { EntityManager } from 'typeorm/entity-manager/EntityManager';
/** /**
* *
*/ */
export abstract class BaseService<T> { export abstract class BaseService<T> {
@Inject() @Inject()
ctx: Context; dataSourceManager: TypeORMDataSourceManager;
abstract getRepository(): Repository<T>; abstract getRepository(): Repository<T>;
async transaction(callback: (entityManager: EntityManager) => Promise<any>) {
const dataSource = this.dataSourceManager.getDataSource('default');
await dataSource.transaction(callback);
}
/** /**
* ID * ID
* @param id ID * @param id ID
@ -34,7 +40,7 @@ export abstract class BaseService<T> {
/** /**
* *
* @param option * @param options
*/ */
async find(options) { async find(options) {
return await this.getRepository().find(options); return await this.getRepository().find(options);
@ -187,23 +193,19 @@ export abstract class BaseService<T> {
return await qb.getMany(); return await qb.getMany();
} }
async checkUserId( async checkUserId(id: any = 0, userId, userKey = 'userId') {
id: any = 0,
userId,
userKey = 'userId',
queryIdKey = 'id'
) {
// @ts-ignore // @ts-ignore
const res = await this.getRepository().findOne({ const res = await this.getRepository().findOne({
// @ts-ignore // @ts-ignore
select: { [userKey]: true }, select: { [userKey]: true },
// @ts-ignore // @ts-ignore
where: { where: {
[queryIdKey]: id, // @ts-ignore
id,
}, },
}); });
// @ts-ignore // @ts-ignore
if (!res || res.userId === userId) { if (!res || res[userKey] === userId) {
return; return;
} }
throw new PermissionException('权限不足'); throw new PermissionException('权限不足');

View File

@ -1,8 +1,27 @@
export const Constants = { export const Constants = {
role: {
defaultUser: 3,
},
per: {
//无需登录
guest: '_guest_',
//无需登录
anonymous: '_guest_',
//仅需要登录
authOnly: '_authOnly_',
//仅需要登录
loginOnly: '_authOnly_',
},
res: { res: {
serverError(message: string) {
return {
code: 1,
message,
};
},
error: { error: {
code: 1, code: 1,
message: 'error', message: 'Internal server error',
}, },
success: { success: {
code: 0, code: 0,

View File

@ -71,7 +71,7 @@ const development = {
secret: 'certd666', secret: 'certd666',
expire: 7 * 24 * 60, //单位秒 expire: 7 * 24 * 60, //单位秒
}, },
auth: { authOnly: {
ignoreUrls: ['/', '/public', '/api/login', '/api/register'], ignoreUrls: ['/', '/public', '/api/login', '/api/register'],
}, },
}, },

View File

@ -1,8 +1,10 @@
import { Config, Provide } from '@midwayjs/decorator'; import { Config, Inject, Provide } from '@midwayjs/decorator';
import { IWebMiddleware, IMidwayKoaContext, NextFunction } from '@midwayjs/koa'; import { IMidwayKoaContext, IWebMiddleware, NextFunction } from '@midwayjs/koa';
import * as _ from 'lodash';
import * as jwt from 'jsonwebtoken'; import * as jwt from 'jsonwebtoken';
import { Constants } from '../basic/constants'; import { Constants } from '../basic/constants';
import { MidwayWebRouterService } from '@midwayjs/core';
import { RoleService } from '../modules/authority/service/role-service';
import { logger } from '../utils/logger';
/** /**
* *
@ -11,27 +13,34 @@ import { Constants } from '../basic/constants';
export class AuthorityMiddleware implements IWebMiddleware { export class AuthorityMiddleware implements IWebMiddleware {
@Config('biz.jwt.secret') @Config('biz.jwt.secret')
private secret: string; private secret: string;
@Config('biz.auth.ignoreUrls') @Inject()
private ignoreUrls: string[]; webRouterService: MidwayWebRouterService;
@Inject()
roleService: RoleService;
resolve() { resolve() {
return async (ctx: IMidwayKoaContext, next: NextFunction) => { return async (ctx: IMidwayKoaContext, next: NextFunction) => {
const { url } = ctx; // 查询当前路由是否在路由表中注册
let token = ctx.get('Authorization') || ''; const routeInfo = await this.webRouterService.getMatchedRouterInfo(
token = token.replace('Bearer ', '').trim(); ctx.path,
// 路由地址为 admin前缀的 需要权限校验 ctx.method
// console.log('ctx', ctx); );
const queryIndex = url.indexOf('?'); const permission = routeInfo.summary;
let uri = url; if (permission == null || permission === '') {
if (queryIndex >= 0) { ctx.status = 500;
uri = url.substring(0, queryIndex); ctx.body = Constants.res.serverError(
'该路由未配置权限控制:' + ctx.path
);
return;
} }
const yes = this.ignoreUrls.includes(uri);
if (yes) { if (permission === Constants.per.guest) {
await next(); await next();
return; return;
} }
let token = ctx.get('Authorization') || '';
token = token.replace('Bearer ', '').trim();
try { try {
ctx.user = jwt.verify(token, this.secret); ctx.user = jwt.verify(token, this.secret);
} catch (err) { } catch (err) {
@ -39,6 +48,20 @@ export class AuthorityMiddleware implements IWebMiddleware {
ctx.body = Constants.res.auth; ctx.body = Constants.res.auth;
return; return;
} }
if (permission !== Constants.per.authOnly) {
//如果不是仅校验登录,还需要校验是否拥有权限
const roleIds: number[] = ctx.user.roles;
const permissions =
await this.roleService.getCachedPermissionSetByRoleIds(roleIds);
if (!permissions.has(permission)) {
logger.info('not permission: ', ctx.req.url);
ctx.status = 401;
ctx.body = Constants.res.permission;
return;
}
}
await next(); await next();
}; };
} }

View File

@ -23,7 +23,7 @@ export class PermissionController extends CrudController<PermissionService> {
return this.service; return this.service;
} }
@Post('/page') @Post('/page', { summary: 'sys:auth:per:view' })
async page( async page(
@Body(ALL) @Body(ALL)
body body
@ -31,7 +31,7 @@ export class PermissionController extends CrudController<PermissionService> {
return await super.page(body); return await super.page(body);
} }
@Post('/add') @Post('/add', { summary: 'sys:auth:per:add' })
async add( async add(
@Body(ALL) @Body(ALL)
bean bean
@ -39,14 +39,14 @@ export class PermissionController extends CrudController<PermissionService> {
return await super.add(bean); return await super.add(bean);
} }
@Post('/update') @Post('/update', { summary: 'sys:auth:per:edit' })
async update( async update(
@Body(ALL) @Body(ALL)
bean bean
) { ) {
return await super.update(bean); return await super.update(bean);
} }
@Post('/delete') @Post('/delete', { summary: 'sys:auth:per:remove' })
async delete( async delete(
@Query('id') @Query('id')
id id
@ -54,7 +54,7 @@ export class PermissionController extends CrudController<PermissionService> {
return await super.delete(id); return await super.delete(id);
} }
@Post('/tree') @Post('/tree', { summary: 'sys:auth:per:view' })
async tree() { async tree() {
const tree = await this.service.tree({}); const tree = await this.service.tree({});
return this.ok(tree); return this.ok(tree);

View File

@ -23,7 +23,7 @@ export class RoleController extends CrudController<RoleService> {
return this.service; return this.service;
} }
@Post('/page') @Post('/page', { summary: 'sys:auth:role:view' })
async page( async page(
@Body(ALL) @Body(ALL)
body body
@ -31,13 +31,13 @@ export class RoleController extends CrudController<RoleService> {
return await super.page(body); return await super.page(body);
} }
@Post('/list') @Post('/list', { summary: 'sys:auth:role:view' })
async list() { async list() {
const ret = await this.service.find({}); const ret = await this.service.find({});
return this.ok(ret); return this.ok(ret);
} }
@Post('/add') @Post('/add', { summary: 'sys:auth:role:add' })
async add( async add(
@Body(ALL) @Body(ALL)
bean bean
@ -45,14 +45,14 @@ export class RoleController extends CrudController<RoleService> {
return await super.add(bean); return await super.add(bean);
} }
@Post('/update') @Post('/update', { summary: 'sys:auth:role:edit' })
async update( async update(
@Body(ALL) @Body(ALL)
bean bean
) { ) {
return await super.update(bean); return await super.update(bean);
} }
@Post('/delete') @Post('/delete', { summary: 'sys:auth:role:remove' })
async delete( async delete(
@Query('id') @Query('id')
id id
@ -60,7 +60,7 @@ export class RoleController extends CrudController<RoleService> {
return await super.delete(id); return await super.delete(id);
} }
@Post('/getPermissionTree') @Post('/getPermissionTree', { summary: 'sys:auth:role:view' })
async getPermissionTree( async getPermissionTree(
@Query('id') @Query('id')
id id
@ -69,7 +69,7 @@ export class RoleController extends CrudController<RoleService> {
return this.ok(ret); return this.ok(ret);
} }
@Post('/getPermissionIds') @Post('/getPermissionIds', { summary: 'sys:auth:role:view' })
async getPermissionIds( async getPermissionIds(
@Query('id') @Query('id')
id id
@ -80,9 +80,10 @@ export class RoleController extends CrudController<RoleService> {
/** /**
* *
* @param id * @param roleId
* @param permissionIds
*/ */
@Post('/authz') @Post('/authz', { summary: 'sys:auth:role:edit' })
async authz( async authz(
@Body('roleId') @Body('roleId')
roleId, roleId,
@ -93,4 +94,3 @@ export class RoleController extends CrudController<RoleService> {
return this.ok(null); return this.ok(null);
} }
} }

View File

@ -11,6 +11,7 @@ import { UserService } from '../service/user-service';
import { CrudController } from '../../../basic/crud-controller'; import { CrudController } from '../../../basic/crud-controller';
import { RoleService } from '../service/role-service'; import { RoleService } from '../service/role-service';
import { PermissionService } from '../service/permission-service'; import { PermissionService } from '../service/permission-service';
import { Constants } from '../../../basic/constants';
/** /**
* *
@ -30,7 +31,7 @@ export class UserController extends CrudController<UserService> {
return this.service; return this.service;
} }
@Post('/page') @Post('/page', { summary: 'sys:auth:user:view' })
async page( async page(
@Body(ALL) @Body(ALL)
body body
@ -62,7 +63,7 @@ export class UserController extends CrudController<UserService> {
return ret; return ret;
} }
@Post('/add') @Post('/add', { summary: 'sys:auth:user:add' })
async add( async add(
@Body(ALL) @Body(ALL)
bean bean
@ -70,14 +71,14 @@ export class UserController extends CrudController<UserService> {
return await super.add(bean); return await super.add(bean);
} }
@Post('/update') @Post('/update', { summary: 'sys:auth:user:edit' })
async update( async update(
@Body(ALL) @Body(ALL)
bean bean
) { ) {
return await super.update(bean); return await super.update(bean);
} }
@Post('/delete') @Post('/delete', { summary: 'sys:auth:user:remove' })
async delete( async delete(
@Query('id') @Query('id')
id id
@ -88,7 +89,7 @@ export class UserController extends CrudController<UserService> {
/** /**
* *
*/ */
@Post('/mine') @Post('/mine', { summary: Constants.per.authOnly })
public async mine() { public async mine() {
const id = this.ctx.user.id; const id = this.ctx.user.id;
const info = await this.service.info(id, ['password']); const info = await this.service.info(id, ['password']);
@ -98,7 +99,7 @@ export class UserController extends CrudController<UserService> {
/** /**
* *
*/ */
@Post('/permissions') @Post('/permissions', { summary: Constants.per.authOnly })
public async permissions() { public async permissions() {
const id = this.ctx.user.id; const id = this.ctx.user.id;
const permissions = await this.service.getUserPermissions(id); const permissions = await this.service.getUserPermissions(id);
@ -108,7 +109,7 @@ export class UserController extends CrudController<UserService> {
/** /**
* *
*/ */
@Post('/permissionTree') @Post('/permissionTree', { summary: Constants.per.authOnly })
public async permissionTree() { public async permissionTree() {
const id = this.ctx.user.id; const id = this.ctx.user.id;
const permissions = await this.service.getUserPermissions(id); const permissions = await this.service.getUserPermissions(id);

View File

@ -9,4 +9,8 @@ export class UserRoleEntity {
roleId: number; roleId: number;
@PrimaryColumn({ name: 'user_id' }) @PrimaryColumn({ name: 'user_id' })
userId: number; userId: number;
static of(userId: number, roleId: number): UserRoleEntity {
return Object.assign(new UserRoleEntity(), { userId, roleId });
}
} }

View File

@ -60,4 +60,7 @@ export class UserEntity {
// }, // },
// }) // })
// roles: RoleEntity[]; // roles: RoleEntity[];
static of(user: Partial<UserEntity>) {
return Object.assign(new UserEntity(), user);
}
} }

View File

@ -1,4 +1,4 @@
import { Provide } from '@midwayjs/decorator'; import { Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm'; import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { BaseService } from '../../../basic/base-service'; import { BaseService } from '../../../basic/base-service';
@ -8,6 +8,7 @@ import { PermissionEntity } from '../entity/permission';
* *
*/ */
@Provide() @Provide()
@Scope(ScopeEnum.Singleton)
export class PermissionService extends BaseService<PermissionEntity> { export class PermissionService extends BaseService<PermissionEntity> {
@InjectEntityModel(PermissionEntity) @InjectEntityModel(PermissionEntity)
repository: Repository<PermissionEntity>; repository: Repository<PermissionEntity>;

View File

@ -1,4 +1,4 @@
import { Provide } from '@midwayjs/decorator'; import { Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm'; import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { BaseService } from '../../../basic/base-service'; import { BaseService } from '../../../basic/base-service';
@ -8,6 +8,7 @@ import { RolePermissionEntity } from '../entity/role-permission';
* -> * ->
*/ */
@Provide() @Provide()
@Scope(ScopeEnum.Singleton)
export class RolePermissionService extends BaseService<RolePermissionEntity> { export class RolePermissionService extends BaseService<RolePermissionEntity> {
@InjectEntityModel(RolePermissionEntity) @InjectEntityModel(RolePermissionEntity)
repository: Repository<RolePermissionEntity>; repository: Repository<RolePermissionEntity>;

View File

@ -1,4 +1,4 @@
import { Inject, Provide } from '@midwayjs/decorator'; import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm'; import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, Repository } from 'typeorm'; import { In, Repository } from 'typeorm';
import { BaseService } from '../../../basic/base-service'; import { BaseService } from '../../../basic/base-service';
@ -8,10 +8,12 @@ import { RolePermissionEntity } from '../entity/role-permission';
import { PermissionService } from './permission-service'; import { PermissionService } from './permission-service';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { RolePermissionService } from './role-permission-service'; import { RolePermissionService } from './role-permission-service';
import { LRUCache } from 'lru-cache';
/** /**
* *
*/ */
@Provide() @Provide()
@Scope(ScopeEnum.Singleton)
export class RoleService extends BaseService<RoleEntity> { export class RoleService extends BaseService<RoleEntity> {
@InjectEntityModel(RoleEntity) @InjectEntityModel(RoleEntity)
repository: Repository<RoleEntity>; repository: Repository<RoleEntity>;
@ -22,6 +24,11 @@ export class RoleService extends BaseService<RoleEntity> {
@Inject() @Inject()
rolePermissionService: RolePermissionService; rolePermissionService: RolePermissionService;
permissionCache = new LRUCache<string, any>({
max: 1000,
ttl: 1000 * 60 * 10,
});
getRepository() { getRepository() {
return this.repository; return this.repository;
} }
@ -77,6 +84,8 @@ export class RoleService extends BaseService<RoleEntity> {
await this.userRoleService.delete({ userId }); await this.userRoleService.delete({ userId });
//再添加 //再添加
await this.addRoles(userId, roles); await this.addRoles(userId, roles);
this.permissionCache.clear();
} }
async getPermissionTreeByRoleId(id: any) { async getPermissionTreeByRoleId(id: any) {
@ -97,5 +106,29 @@ export class RoleService extends BaseService<RoleEntity> {
permissionId, permissionId,
}); });
} }
this.permissionCache.clear();
}
async getPermissionSetByRoleIds(roleIds: number[]): Promise<Set<string>> {
const list = await this.getPermissionByRoleIds(roleIds);
const permissionSet = new Set<string>();
for (const entity of list) {
permissionSet.add(entity.permission);
}
return permissionSet;
}
async getCachedPermissionSetByRoleIds(
roleIds: number[]
): Promise<Set<string>> {
const roleIdsKey = roleIds.join(',');
let permissionSet = this.permissionCache.get(roleIdsKey);
if (permissionSet) {
return permissionSet;
}
permissionSet = await this.getPermissionSetByRoleIds(roleIds);
this.permissionCache.set(roleIdsKey, permissionSet);
return permissionSet;
} }
} }

View File

@ -1,4 +1,4 @@
import { Provide } from '@midwayjs/decorator'; import { Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm'; import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { BaseService } from '../../../basic/base-service'; import { BaseService } from '../../../basic/base-service';
@ -8,6 +8,7 @@ import { UserRoleEntity } from '../entity/user-role';
* -> * ->
*/ */
@Provide() @Provide()
@Scope(ScopeEnum.Singleton)
export class UserRoleService extends BaseService<UserRoleEntity> { export class UserRoleService extends BaseService<UserRoleEntity> {
@InjectEntityModel(UserRoleEntity) @InjectEntityModel(UserRoleEntity)
repository: Repository<UserRoleEntity>; repository: Repository<UserRoleEntity>;

View File

@ -1,4 +1,4 @@
import { Inject, Provide } from '@midwayjs/decorator'; import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm'; import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { UserEntity } from '../entity/user'; import { UserEntity } from '../entity/user';
@ -6,15 +6,18 @@ import * as _ from 'lodash';
import md5 from 'md5'; import md5 from 'md5';
import { CommonException } from '../../../basic/exception/common-exception'; import { CommonException } from '../../../basic/exception/common-exception';
import { BaseService } from '../../../basic/base-service'; import { BaseService } from '../../../basic/base-service';
import { logger } from '../../../utils/logger';
import { RoleService } from './role-service'; import { RoleService } from './role-service';
import { PermissionService } from './permission-service'; import { PermissionService } from './permission-service';
import { UserRoleService } from './user-role-service'; import { UserRoleService } from './user-role-service';
import { Constants } from '../../../basic/constants';
import { UserRoleEntity } from '../entity/user-role';
import { randomText } from 'svg-captcha';
/** /**
* *
*/ */
@Provide() @Provide()
@Scope(ScopeEnum.Singleton)
export class UserService extends BaseService<UserEntity> { export class UserService extends BaseService<UserEntity> {
@InjectEntityModel(UserEntity) @InjectEntityModel(UserEntity)
repository: Repository<UserEntity>; repository: Repository<UserEntity>;
@ -32,10 +35,10 @@ export class UserService extends BaseService<UserEntity> {
/** /**
* *
*/ */
async mine() { async mine(userId: number) {
const info = await this.repository.findOne({ const info = await this.repository.findOne({
where: { where: {
id: this.ctx.user.id, id: userId,
}, },
}); });
delete info.password; delete info.password;
@ -55,7 +58,7 @@ export class UserService extends BaseService<UserEntity> {
if (!_.isEmpty(exists)) { if (!_.isEmpty(exists)) {
throw new CommonException('用户名已经存在'); throw new CommonException('用户名已经存在');
} }
const password = param.password ?? '123456'; const password = param.password ?? randomText(6);
param.password = md5(password); // 默认密码 建议未改密码不能登陆 param.password = md5(password); // 默认密码 建议未改密码不能登陆
await super.add(param); await super.add(param);
//添加角色 //添加角色
@ -97,7 +100,7 @@ export class UserService extends BaseService<UserEntity> {
} }
checkPassword(rawPassword: any, md5Password: any) { checkPassword(rawPassword: any, md5Password: any) {
logger.info('md5', md5('123456')); // logger.info('md5', md5('123456'));
return md5(rawPassword) === md5Password; return md5(rawPassword) === md5Password;
} }
@ -107,7 +110,36 @@ export class UserService extends BaseService<UserEntity> {
*/ */
async getUserPermissions(id: any) { async getUserPermissions(id: any) {
const roleIds = await this.roleService.getRoleIdsByUserId(id); const roleIds = await this.roleService.getRoleIdsByUserId(id);
return await this.roleService.getPermissionByRoleIds(roleIds); return await this.roleService.getPermissionByRoleIds(roleIds);
} }
async register(user: UserEntity) {
const old = await this.findOne({ username: user.username });
if (old != null) {
throw new CommonException('用户名已经存在');
}
let newUser: UserEntity = UserEntity.of({
username: user.username,
password: user.password,
nickName: user.nickName || user.username,
avatar: user.avatar || '',
email: user.email || '',
mobile: user.mobile || '',
phoneCode: user.phoneCode || '',
status: 1,
});
newUser.password = md5(newUser.password);
await this.transaction(async txManager => {
newUser = await txManager.save(newUser);
const userRole: UserRoleEntity = UserRoleEntity.of(
newUser.id,
Constants.role.defaultUser
);
await txManager.save(userRole);
});
delete newUser.password;
return newUser;
}
} }

View File

@ -5,6 +5,7 @@ import { Controller, Post, Provide } from '@midwayjs/decorator';
import { BaseController } from '../../../basic/base-controller'; import { BaseController } from '../../../basic/base-controller';
import { CodeService } from '../service/code-service'; import { CodeService } from '../service/code-service';
import { EmailService } from '../service/email-service'; import { EmailService } from '../service/email-service';
import { Constants } from '../../../basic/constants';
export class SmsCodeReq { export class SmsCodeReq {
@Rule(RuleType.number().required()) @Rule(RuleType.number().required())
phoneCode: number; phoneCode: number;
@ -30,7 +31,7 @@ export class BasicController extends BaseController {
@Inject() @Inject()
emailService: EmailService; emailService: EmailService;
@Post('/sendSmsCode') @Post('/sendSmsCode', { summary: Constants.per.guest })
public sendSmsCode( public sendSmsCode(
@Body(ALL) @Body(ALL)
body: SmsCodeReq body: SmsCodeReq
@ -39,7 +40,7 @@ export class BasicController extends BaseController {
return this.ok(null); return this.ok(null);
} }
@Post('/captcha') @Post('/captcha', { summary: Constants.per.guest })
public async getCaptcha( public async getCaptcha(
@Body() @Body()
randomStr randomStr

View File

@ -1,6 +1,7 @@
import { Body, Controller, Inject, Post, Provide } from '@midwayjs/decorator'; import { Body, Controller, Inject, Post, Provide } from '@midwayjs/decorator';
import { BaseController } from '../../../basic/base-controller'; import { BaseController } from '../../../basic/base-controller';
import { EmailService } from '../service/email-service'; import { EmailService } from '../service/email-service';
import { Constants } from '../../../basic/constants';
/** /**
*/ */
@ -10,7 +11,7 @@ export class EmailController extends BaseController {
@Inject() @Inject()
emailService: EmailService; emailService: EmailService;
@Post('/test') @Post('/test', { summary: Constants.per.authOnly })
public async test( public async test(
@Body('receiver') @Body('receiver')
receiver receiver

View File

@ -8,6 +8,7 @@ import {
} from '@midwayjs/decorator'; } from '@midwayjs/decorator';
import { LoginService } from '../service/login-service'; import { LoginService } from '../service/login-service';
import { BaseController } from '../../../basic/base-controller'; import { BaseController } from '../../../basic/base-controller';
import { Constants } from '../../../basic/constants';
/** /**
*/ */
@ -16,7 +17,7 @@ import { BaseController } from '../../../basic/base-controller';
export class LoginController extends BaseController { export class LoginController extends BaseController {
@Inject() @Inject()
loginService: LoginService; loginService: LoginService;
@Post('/login') @Post('/login', { summary: Constants.per.guest })
public async login( public async login(
@Body(ALL) @Body(ALL)
user user
@ -25,7 +26,6 @@ export class LoginController extends BaseController {
return this.ok(token); return this.ok(token);
} }
@Post('/logout') @Post('/logout', { summary: Constants.per.authOnly })
public logout() {} public logout() {}
} }

View File

@ -0,0 +1,29 @@
import {
ALL,
Body,
Controller,
Inject,
Post,
Provide,
} from '@midwayjs/decorator';
import { BaseController } from '../../../basic/base-controller';
import { Constants } from '../../../basic/constants';
import { UserService } from '../../authority/service/user-service';
import { UserEntity } from '../../authority/entity/user';
/**
*/
@Provide()
@Controller('/api/')
export class RegisterController extends BaseController {
@Inject()
userService: UserService;
@Post('/register', { summary: Constants.per.guest })
public async register(
@Body(ALL)
user: UserEntity
) {
const newUser = await this.userService.register(user);
return this.ok(newUser);
}
}

View File

@ -2,6 +2,8 @@ import { Config, Inject, Provide } from '@midwayjs/decorator';
import { UserService } from '../../authority/service/user-service'; import { UserService } from '../../authority/service/user-service';
import * as jwt from 'jsonwebtoken'; import * as jwt from 'jsonwebtoken';
import { CommonException } from '../../../basic/exception/common-exception'; import { CommonException } from '../../../basic/exception/common-exception';
import { RoleService } from '../../authority/service/role-service';
import { UserEntity } from '../../authority/entity/user';
/** /**
* *
@ -10,6 +12,8 @@ import { CommonException } from '../../../basic/exception/common-exception';
export class LoginService { export class LoginService {
@Inject() @Inject()
userService: UserService; userService: UserService;
@Inject()
roleService: RoleService;
@Config('biz.jwt') @Config('biz.jwt')
private jwt: any; private jwt: any;
@ -27,17 +31,20 @@ export class LoginService {
throw new CommonException('用户名或密码错误'); throw new CommonException('用户名或密码错误');
} }
return this.generateToken(info); const roleIds = await this.roleService.getRoleIdsByUserId(info.id);
return this.generateToken(info, roleIds);
} }
/** /**
* token * token
* @param user * @param user
* @param roleIds
*/ */
async generateToken(user) { async generateToken(user: UserEntity, roleIds: number[]) {
const tokenInfo = { const tokenInfo = {
username: user.username, username: user.username,
id: user.id, id: user.id,
roles: roleIds,
}; };
const expire = this.jwt.expire; const expire = this.jwt.expire;
const token = jwt.sign(tokenInfo, this.jwt.secret, { const token = jwt.sign(tokenInfo, this.jwt.secret, {

View File

@ -9,6 +9,7 @@ import {
} from '@midwayjs/decorator'; } from '@midwayjs/decorator';
import { CrudController } from '../../../basic/crud-controller'; import { CrudController } from '../../../basic/crud-controller';
import { AccessService } from '../service/access-service'; import { AccessService } from '../service/access-service';
import { Constants } from '../../../basic/constants';
/** /**
* *
@ -23,49 +24,49 @@ export class AccessController extends CrudController<AccessService> {
return this.service; return this.service;
} }
@Post('/page') @Post('/page', { summary: Constants.per.authOnly })
async page(@Body(ALL) body) { async page(@Body(ALL) body) {
body.query = body.query ?? {}; body.query = body.query ?? {};
body.query.userId = this.ctx.user.id; body.query.userId = this.ctx.user.id;
return super.page(body); return super.page(body);
} }
@Post('/list') @Post('/list', { summary: Constants.per.authOnly })
async list(@Body(ALL) body) { async list(@Body(ALL) body) {
body.userId = this.ctx.user.id; body.userId = this.ctx.user.id;
return super.list(body); return super.list(body);
} }
@Post('/add') @Post('/add', { summary: Constants.per.authOnly })
async add(@Body(ALL) bean) { async add(@Body(ALL) bean) {
bean.userId = this.ctx.user.id; bean.userId = this.ctx.user.id;
return super.add(bean); return super.add(bean);
} }
@Post('/update') @Post('/update', { summary: Constants.per.authOnly })
async update(@Body(ALL) bean) { async update(@Body(ALL) bean) {
await this.service.checkUserId(bean.id, this.ctx.user.id); await this.service.checkUserId(bean.id, this.ctx.user.id);
return super.update(bean); return super.update(bean);
} }
@Post('/info') @Post('/info', { summary: Constants.per.authOnly })
async info(@Query('id') id) { async info(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
return super.info(id); return super.info(id);
} }
@Post('/delete') @Post('/delete', { summary: Constants.per.authOnly })
async delete(@Query('id') id) { async delete(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
return super.delete(id); return super.delete(id);
} }
@Post('/define') @Post('/define', { summary: Constants.per.authOnly })
async define(@Query('type') type) { async define(@Query('type') type) {
const provider = this.service.getDefineByType(type); const provider = this.service.getDefineByType(type);
return this.ok(provider); return this.ok(provider);
} }
@Post('/accessTypeDict') @Post('/accessTypeDict', { summary: Constants.per.authOnly })
async getAccessTypeDict() { async getAccessTypeDict() {
const list = this.service.getDefineList(); const list = this.service.getDefineList();
const dict = []; const dict = [];

View File

@ -8,6 +8,7 @@ import {
} from '@midwayjs/decorator'; } from '@midwayjs/decorator';
import { DnsProviderService } from '../service/dns-provider-service'; import { DnsProviderService } from '../service/dns-provider-service';
import { BaseController } from '../../../basic/base-controller'; import { BaseController } from '../../../basic/base-controller';
import {Constants} from "../../../basic/constants";
/** /**
* *
@ -18,14 +19,14 @@ export class DnsProviderController extends BaseController {
@Inject() @Inject()
service: DnsProviderService; service: DnsProviderService;
@Post('/list') @Post('/list', { summary: Constants.per.authOnly })
async list(@Query(ALL) query) { async list(@Query(ALL) query) {
query.userId = this.ctx.user.id; query.userId = this.ctx.user.id;
const list = this.service.getList(); const list = this.service.getList();
return this.ok(list); return this.ok(list);
} }
@Post('/dnsProviderTypeDict') @Post('/dnsProviderTypeDict', { summary: Constants.per.authOnly })
async getDnsProviderTypeDict() { async getDnsProviderTypeDict() {
const list = this.service.getList(); const list = this.service.getList();
const dict = []; const dict = [];

View File

@ -13,6 +13,7 @@ import { HistoryService } from '../service/history-service';
import { HistoryLogService } from '../service/history-log-service'; import { HistoryLogService } from '../service/history-log-service';
import { HistoryEntity } from '../entity/history'; import { HistoryEntity } from '../entity/history';
import { HistoryLogEntity } from '../entity/history-log'; import { HistoryLogEntity } from '../entity/history-log';
import {Constants} from "../../../basic/constants";
/** /**
* *
@ -29,13 +30,13 @@ export class HistoryController extends CrudController<HistoryService> {
return this.service; return this.service;
} }
@Post('/page') @Post('/page', { summary: Constants.per.authOnly })
async page(@Body(ALL) body) { async page(@Body(ALL) body) {
body.query.userId = this.ctx.user.id; body.query.userId = this.ctx.user.id;
return super.page(body); return super.page(body);
} }
@Post('/list') @Post('/list', { summary: Constants.per.authOnly })
async list(@Body(ALL) body) { async list(@Body(ALL) body) {
body.userId = this.ctx.user.id; body.userId = this.ctx.user.id;
if (body.pipelineId == null) { if (body.pipelineId == null) {
@ -52,19 +53,19 @@ export class HistoryController extends CrudController<HistoryService> {
return this.ok(listRet); return this.ok(listRet);
} }
@Post('/add') @Post('/add', { summary: Constants.per.authOnly })
async add(@Body(ALL) bean: PipelineEntity) { async add(@Body(ALL) bean: PipelineEntity) {
bean.userId = this.ctx.user.id; bean.userId = this.ctx.user.id;
return super.add(bean); return super.add(bean);
} }
@Post('/update') @Post('/update', { summary: Constants.per.authOnly })
async update(@Body(ALL) bean) { async update(@Body(ALL) bean) {
await this.service.checkUserId(bean.id, this.ctx.user.id); await this.service.checkUserId(bean.id, this.ctx.user.id);
return super.update(bean); return super.update(bean);
} }
@Post('/save') @Post('/save', { summary: Constants.per.authOnly })
async save(@Body(ALL) bean: HistoryEntity) { async save(@Body(ALL) bean: HistoryEntity) {
bean.userId = this.ctx.user.id; bean.userId = this.ctx.user.id;
if (bean.id > 0) { if (bean.id > 0) {
@ -74,7 +75,7 @@ export class HistoryController extends CrudController<HistoryService> {
return this.ok(bean.id); return this.ok(bean.id);
} }
@Post('/saveLog') @Post('/saveLog', { summary: Constants.per.authOnly })
async saveLog(@Body(ALL) bean: HistoryLogEntity) { async saveLog(@Body(ALL) bean: HistoryLogEntity) {
bean.userId = this.ctx.user.id; bean.userId = this.ctx.user.id;
if (bean.id > 0) { if (bean.id > 0) {
@ -84,20 +85,20 @@ export class HistoryController extends CrudController<HistoryService> {
return this.ok(bean.id); return this.ok(bean.id);
} }
@Post('/delete') @Post('/delete', { summary: Constants.per.authOnly })
async delete(@Query('id') id) { async delete(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
return super.delete(id); return super.delete(id);
} }
@Post('/detail') @Post('/detail', { summary: Constants.per.authOnly })
async detail(@Query('id') id) { async detail(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
const detail = await this.service.detail(id); const detail = await this.service.detail(id);
return this.ok(detail); return this.ok(detail);
} }
@Post('/logs') @Post('/logs', { summary: Constants.per.authOnly })
async logs(@Query('id') id) { async logs(@Query('id') id) {
await this.logService.checkUserId(id, this.ctx.user.id); await this.logService.checkUserId(id, this.ctx.user.id);
const logInfo = await this.logService.info(id); const logInfo = await this.logService.info(id);

View File

@ -10,6 +10,7 @@ import {
import { CrudController } from '../../../basic/crud-controller'; import { CrudController } from '../../../basic/crud-controller';
import { PipelineService } from '../service/pipeline-service'; import { PipelineService } from '../service/pipeline-service';
import { PipelineEntity } from '../entity/pipeline'; import { PipelineEntity } from '../entity/pipeline';
import { Constants } from '../../../basic/constants';
/** /**
* *
@ -24,7 +25,7 @@ export class PipelineController extends CrudController<PipelineService> {
return this.service; return this.service;
} }
@Post('/page') @Post('/page', { summary: Constants.per.authOnly })
async page(@Body(ALL) body) { async page(@Body(ALL) body) {
body.query.userId = this.ctx.user.id; body.query.userId = this.ctx.user.id;
const buildQuery = qb => { const buildQuery = qb => {
@ -33,19 +34,19 @@ export class PipelineController extends CrudController<PipelineService> {
return super.page({ ...body, buildQuery }); return super.page({ ...body, buildQuery });
} }
@Post('/add') @Post('/add', { summary: Constants.per.authOnly })
async add(@Body(ALL) bean: PipelineEntity) { async add(@Body(ALL) bean: PipelineEntity) {
bean.userId = this.ctx.user.id; bean.userId = this.ctx.user.id;
return super.add(bean); return super.add(bean);
} }
@Post('/update') @Post('/update', { summary: Constants.per.authOnly })
async update(@Body(ALL) bean) { async update(@Body(ALL) bean) {
await this.service.checkUserId(bean.id, this.ctx.user.id); await this.service.checkUserId(bean.id, this.ctx.user.id);
return super.update(bean); return super.update(bean);
} }
@Post('/save') @Post('/save', { summary: Constants.per.authOnly })
async save(@Body(ALL) bean: PipelineEntity) { async save(@Body(ALL) bean: PipelineEntity) {
bean.userId = this.ctx.user.id; bean.userId = this.ctx.user.id;
if (bean.id > 0) { if (bean.id > 0) {
@ -56,20 +57,20 @@ export class PipelineController extends CrudController<PipelineService> {
return this.ok(bean.id); return this.ok(bean.id);
} }
@Post('/delete') @Post('/delete', { summary: Constants.per.authOnly })
async delete(@Query('id') id) { async delete(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
return super.delete(id); return super.delete(id);
} }
@Post('/detail') @Post('/detail', { summary: Constants.per.authOnly })
async detail(@Query('id') id) { async detail(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
const detail = await this.service.detail(id); const detail = await this.service.detail(id);
return this.ok(detail); return this.ok(detail);
} }
@Post('/trigger') @Post('/trigger', { summary: Constants.per.authOnly })
async trigger(@Query('id') id) { async trigger(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
await this.service.trigger(id); await this.service.trigger(id);

View File

@ -8,6 +8,7 @@ import {
} from '@midwayjs/decorator'; } from '@midwayjs/decorator';
import { BaseController } from '../../../basic/base-controller'; import { BaseController } from '../../../basic/base-controller';
import { PluginService } from '../service/plugin-service'; import { PluginService } from '../service/plugin-service';
import { Constants } from '../../../basic/constants';
/** /**
* *
@ -18,7 +19,7 @@ export class PluginController extends BaseController {
@Inject() @Inject()
service: PluginService; service: PluginService;
@Post('/list') @Post('/list', { summary: Constants.per.authOnly })
async list(@Query(ALL) query) { async list(@Query(ALL) query) {
query.userId = this.ctx.user.id; query.userId = this.ctx.user.id;
const list = this.service.getList(); const list = this.service.getList();

View File

@ -10,6 +10,7 @@ import {
import { CrudController } from '../../../basic/crud-controller'; import { CrudController } from '../../../basic/crud-controller';
import { SettingsService } from '../service/settings-service'; import { SettingsService } from '../service/settings-service';
import { SettingsEntity } from '../entity/settings'; import { SettingsEntity } from '../entity/settings';
import { Constants } from '../../../basic/constants';
/** /**
*/ */
@ -23,53 +24,51 @@ export class SettingsController extends CrudController<SettingsService> {
return this.service; return this.service;
} }
@Post('/page') @Post('/page', { summary: Constants.per.authOnly })
async page(@Body(ALL) body) { async page(@Body(ALL) body) {
body.query = body.query ?? {}; body.query = body.query ?? {};
body.query.userId = this.ctx.user.id; body.query.userId = this.ctx.user.id;
return super.page(body); return super.page(body);
} }
@Post('/list') @Post('/list', { summary: Constants.per.authOnly })
async list(@Body(ALL) body) { async list(@Body(ALL) body) {
body.userId = this.ctx.user.id; body.userId = this.ctx.user.id;
return super.list(body); return super.list(body);
} }
@Post('/add') @Post('/add', { summary: Constants.per.authOnly })
async add(@Body(ALL) bean) { async add(@Body(ALL) bean) {
bean.userId = this.ctx.user.id; bean.userId = this.ctx.user.id;
return super.add(bean); return super.add(bean);
} }
@Post('/update') @Post('/update', { summary: Constants.per.authOnly })
async update(@Body(ALL) bean) { async update(@Body(ALL) bean) {
await this.service.checkUserId(bean.id, this.ctx.user.id); await this.service.checkUserId(bean.id, this.ctx.user.id);
return super.update(bean); return super.update(bean);
} }
@Post('/info') @Post('/info', { summary: Constants.per.authOnly })
async info(@Query('id') id) { async info(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
return super.info(id); return super.info(id);
} }
@Post('/delete') @Post('/delete', { summary: Constants.per.authOnly })
async delete(@Query('id') id) { async delete(@Query('id') id) {
await this.service.checkUserId(id, this.ctx.user.id); await this.service.checkUserId(id, this.ctx.user.id);
return super.delete(id); return super.delete(id);
} }
@Post('/save') @Post('/save', { summary: Constants.per.authOnly })
async save(@Body(ALL) bean: SettingsEntity) { async save(@Body(ALL) bean: SettingsEntity) {
await this.service.checkUserId(bean.key, this.ctx.user.id, 'userId', 'key');
bean.userId = this.ctx.user.id; bean.userId = this.ctx.user.id;
await this.service.save(bean); await this.service.save(bean);
return this.ok({}); return this.ok({});
} }
@Post('/get') @Post('/get', { summary: Constants.per.authOnly })
async get(@Query('key') key: string) { async get(@Query('key') key: string) {
await this.service.checkUserId(key, this.ctx.user.id, 'userId', 'key');
const entity = await this.service.getByKey(key, this.ctx.user.id); const entity = await this.service.getByKey(key, this.ctx.user.id);
return this.ok(entity); return this.ok(entity);
} }