mirror of
https://github.com/whyour/qinglong.git
synced 2025-11-08 15:06:08 +08:00
Add user-scoped data filtering for cron operations
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
parent
db93ca9aa9
commit
489454daa0
|
|
@ -145,7 +145,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.crontabs(req.query as any);
|
||||
const data = await cronService.crontabs({
|
||||
...req.query as any,
|
||||
userId: req.user?.userId
|
||||
});
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
logger.error('🔥 error: %o', e);
|
||||
|
|
@ -177,7 +180,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.create(req.body);
|
||||
const data = await cronService.create({
|
||||
...req.body,
|
||||
userId: req.user?.userId
|
||||
});
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
|
|
@ -194,10 +200,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.run(req.body);
|
||||
const data = await cronService.run(req.body, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -211,10 +217,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.stop(req.body);
|
||||
const data = await cronService.stop(req.body, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -234,10 +240,11 @@ export default (app: Router) => {
|
|||
const data = await cronService.removeLabels(
|
||||
req.body.ids,
|
||||
req.body.labels,
|
||||
req.user?.userId,
|
||||
);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -254,10 +261,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.addLabels(req.body.ids, req.body.labels);
|
||||
const data = await cronService.addLabels(req.body.ids, req.body.labels, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -271,10 +278,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.disabled(req.body);
|
||||
const data = await cronService.disabled(req.body, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -288,10 +295,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.enabled(req.body);
|
||||
const data = await cronService.enabled(req.body, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -344,10 +351,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.remove(req.body);
|
||||
const data = await cronService.remove(req.body, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -361,10 +368,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.pin(req.body);
|
||||
const data = await cronService.pin(req.body, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -378,10 +385,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const cronService = Container.get(CronService);
|
||||
const data = await cronService.unPin(req.body);
|
||||
const data = await cronService.unPin(req.body, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,30 @@ import { ScheduleType } from '../interface/schedule';
|
|||
export default class CronService {
|
||||
constructor(@Inject('logger') private logger: winston.Logger) {}
|
||||
|
||||
private addUserIdFilter(query: any, userId?: number) {
|
||||
if (userId !== undefined) {
|
||||
query.userId = userId;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
private async checkOwnership(ids: number[], userId?: number): Promise<void> {
|
||||
if (userId === undefined) {
|
||||
// Admin can access all crons
|
||||
return;
|
||||
}
|
||||
const crons = await CrontabModel.findAll({
|
||||
where: { id: ids },
|
||||
attributes: ['id', 'userId'],
|
||||
});
|
||||
const unauthorized = crons.filter(
|
||||
(cron) => cron.userId !== userId && cron.userId !== undefined
|
||||
);
|
||||
if (unauthorized.length > 0) {
|
||||
throw new Error('无权限操作该定时任务');
|
||||
}
|
||||
}
|
||||
|
||||
private isNodeCron(cron: Crontab) {
|
||||
const { schedule, extra_schedules } = cron;
|
||||
if (Number(schedule?.split(/ +/).length) > 5 || extra_schedules?.length) {
|
||||
|
|
@ -156,21 +180,26 @@ export default class CronService {
|
|||
}
|
||||
}
|
||||
|
||||
public async remove(ids: number[]) {
|
||||
public async remove(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await CrontabModel.destroy({ where: { id: ids } });
|
||||
await cronClient.delCron(ids.map(String));
|
||||
await this.setCrontab();
|
||||
}
|
||||
|
||||
public async pin(ids: number[]) {
|
||||
public async pin(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await CrontabModel.update({ isPinned: 1 }, { where: { id: ids } });
|
||||
}
|
||||
|
||||
public async unPin(ids: number[]) {
|
||||
public async unPin(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await CrontabModel.update({ isPinned: 0 }, { where: { id: ids } });
|
||||
}
|
||||
|
||||
public async addLabels(ids: string[], labels: string[]) {
|
||||
public async addLabels(ids: string[], labels: string[], userId?: number) {
|
||||
const numIds = ids.map(Number);
|
||||
await this.checkOwnership(numIds, userId);
|
||||
const docs = await CrontabModel.findAll({ where: { id: ids } });
|
||||
for (const doc of docs) {
|
||||
await CrontabModel.update(
|
||||
|
|
@ -182,7 +211,9 @@ export default class CronService {
|
|||
}
|
||||
}
|
||||
|
||||
public async removeLabels(ids: string[], labels: string[]) {
|
||||
public async removeLabels(ids: string[], labels: string[], userId?: number) {
|
||||
const numIds = ids.map(Number);
|
||||
await this.checkOwnership(numIds, userId);
|
||||
const docs = await CrontabModel.findAll({ where: { id: ids } });
|
||||
for (const doc of docs) {
|
||||
await CrontabModel.update(
|
||||
|
|
@ -377,6 +408,7 @@ export default class CronService {
|
|||
sorter: string;
|
||||
filters: string;
|
||||
queryString: string;
|
||||
userId?: number;
|
||||
}): Promise<{ data: Crontab[]; total: number }> {
|
||||
const searchText = params?.searchValue;
|
||||
const page = Number(params?.page || '0');
|
||||
|
|
@ -397,6 +429,7 @@ export default class CronService {
|
|||
this.formatSearchText(query, searchText);
|
||||
this.formatFilterQuery(query, filterQuery);
|
||||
this.formatViewSort(order, viewQuery);
|
||||
this.addUserIdFilter(query, params?.userId);
|
||||
|
||||
if (sorterQuery) {
|
||||
const { field, type } = sorterQuery;
|
||||
|
|
@ -429,7 +462,8 @@ export default class CronService {
|
|||
return doc.get({ plain: true });
|
||||
}
|
||||
|
||||
public async run(ids: number[]) {
|
||||
public async run(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await CrontabModel.update(
|
||||
{ status: CrontabStatus.queued },
|
||||
{ where: { id: ids } },
|
||||
|
|
@ -439,7 +473,8 @@ export default class CronService {
|
|||
});
|
||||
}
|
||||
|
||||
public async stop(ids: number[]) {
|
||||
public async stop(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
const docs = await CrontabModel.findAll({ where: { id: ids } });
|
||||
for (const doc of docs) {
|
||||
if (doc.pid) {
|
||||
|
|
@ -533,13 +568,15 @@ export default class CronService {
|
|||
});
|
||||
}
|
||||
|
||||
public async disabled(ids: number[]) {
|
||||
public async disabled(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await CrontabModel.update({ isDisabled: 1 }, { where: { id: ids } });
|
||||
await cronClient.delCron(ids.map(String));
|
||||
await this.setCrontab();
|
||||
}
|
||||
|
||||
public async enabled(ids: number[]) {
|
||||
public async enabled(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await CrontabModel.update({ isDisabled: 0 }, { where: { id: ids } });
|
||||
const docs = await CrontabModel.findAll({ where: { id: ids } });
|
||||
const sixCron = docs
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user