feat: change permission for mino -resources

This commit is contained in:
2025-03-22 12:48:49 +08:00
parent ea094ee519
commit 5c3d48abab
12 changed files with 478 additions and 81 deletions

View File

@@ -1,13 +1,12 @@
import { useContextKey } from '@kevisual/use-config/context';
import { sequelize } from '../../../modules/sequelize.ts';
import { DataTypes, Model } from 'sequelize';
import { Permission } from '@kevisual/permission';
export interface ConfigData {
key?: string;
version?: string;
permission?: {
share?: 'public' | 'private';
};
permission?: Permission;
}
export type Config = Partial<InstanceType<typeof ConfigModel>>;

View File

@@ -1,7 +1,9 @@
import { ConfigModel } from '../models/model.ts';
import { ConfigModel, Config } from '../models/model.ts';
import { CustomError } from '@kevisual/router';
import { redis } from '@/app.ts';
import { User } from '@/models/user.ts';
import { UserPermission, UserPermissionOptions } from '@kevisual/permission';
export class ShareConfigService extends ConfigModel {
/**
* 获取分享的配置
@@ -9,10 +11,23 @@ export class ShareConfigService extends ConfigModel {
* @param username 分享者的username
* @returns 配置
*/
static async getShareConfig(key: string, username: string) {
const shareCacheConfig = await redis.get(`config:share:${username}:${key}`);
static async getShareConfig(key: string, username: string, options: UserPermissionOptions) {
const shareCacheConfigString = await redis.get(`config:share:${username}:${key}`);
let shareCacheConfig: Config;
try {
shareCacheConfig = JSON.parse(shareCacheConfigString);
} catch (e) {
await redis.set(`config:share:${username}:${key}`, '', 'EX', 0); // 删除缓存
throw new CustomError(400, 'config parse error');
}
const owner = username;
if (shareCacheConfig) {
return JSON.parse(shareCacheConfig);
const permission = new UserPermission({ permission: shareCacheConfig?.data?.permission, owner });
const result = permission.checkPermissionSuccess(options);
if (!result.success) {
throw new CustomError(403, 'no permission');
}
return shareCacheConfig;
}
const user = await User.findOne({
where: { username },
@@ -26,8 +41,9 @@ export class ShareConfigService extends ConfigModel {
if (!config) {
throw new CustomError(404, 'config not found');
}
const configData = config?.data?.permission;
if (configData?.share !== 'public') {
const permission = new UserPermission({ permission: config?.data?.permission, owner });
const result = permission.checkPermissionSuccess(options);
if (!result.success) {
throw new CustomError(403, 'no permission');
}
await redis.set(`config:share:${username}:${key}`, JSON.stringify(config), 'EX', 60 * 60 * 24 * 7); // 7天
@@ -35,7 +51,7 @@ export class ShareConfigService extends ConfigModel {
}
static async expireShareConfig(key: string, username: string) {
if (key && username) {
await redis.del(`config:share:${username}:${key}`);
await redis.set(`config:share:${username}:${key}`, '', 'EX', 0);
}
}
}

View File

@@ -7,15 +7,22 @@ app
middleware: ['auth'],
})
.define(async (ctx) => {
const { key, username } = ctx.query?.data || {};
if (!key) {
ctx.throw(400, 'key is required');
const tokenUser = ctx.state.tokenUser;
const { p, username, configKey } = ctx.query || {};
const queryUsername = tokenUser?.username;
const password = p;
if (!configKey) {
ctx.throw(400, 'configKey is required');
}
if (!username) {
ctx.throw(400, 'username is required');
}
try {
const config = await ShareConfigService.getShareConfig(key, username);
const config = await ShareConfigService.getShareConfig(configKey, username, {
username: queryUsername,
password,
});
ctx.body = config;
} catch (error) {
if (error?.code === 500) {