mirror of
https://github.com/whyour/qinglong.git
synced 2025-11-10 08:36:07 +08:00
Add user-scoped data filtering for subscription and dependence operations
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
parent
4cf2858ab0
commit
777fd3fb23
|
|
@ -22,7 +22,7 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const dependenceService = Container.get(DependenceService);
|
||||
const data = await dependenceService.dependencies(req.query as any);
|
||||
const data = await dependenceService.dependencies(req.query as any, [], {}, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
logger.error('🔥 error: %o', e);
|
||||
|
|
@ -45,7 +45,7 @@ export default (app: Router) => {
|
|||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const dependenceService = Container.get(DependenceService);
|
||||
const data = await dependenceService.create(req.body);
|
||||
const data = await dependenceService.create(req.body, req.user?.userId);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
|
|
@ -82,10 +82,10 @@ export default (app: Router) => {
|
|||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const dependenceService = Container.get(DependenceService);
|
||||
const data = await dependenceService.remove(req.body);
|
||||
const data = await dependenceService.remove(req.body, false, 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 });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -98,10 +98,10 @@ export default (app: Router) => {
|
|||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const dependenceService = Container.get(DependenceService);
|
||||
const data = await dependenceService.remove(req.body, true);
|
||||
const data = await dependenceService.remove(req.body, true, 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 });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -132,10 +132,10 @@ export default (app: Router) => {
|
|||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const dependenceService = Container.get(DependenceService);
|
||||
const data = await dependenceService.reInstall(req.body);
|
||||
const data = await dependenceService.reInstall(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 });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -148,10 +148,10 @@ export default (app: Router) => {
|
|||
async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const dependenceService = Container.get(DependenceService);
|
||||
await dependenceService.cancel(req.body);
|
||||
await dependenceService.cancel(req.body, req.user?.userId);
|
||||
return res.send({ code: 200 });
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
} catch (e: any) {
|
||||
return res.send({ code: 400, message: e.message });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export default (app: Router) => {
|
|||
const data = await subscriptionService.list(
|
||||
req.query.searchValue as string,
|
||||
req.query.ids as string,
|
||||
req.user?.userId,
|
||||
);
|
||||
return res.send({ code: 200, data });
|
||||
} catch (e) {
|
||||
|
|
@ -63,7 +64,10 @@ export default (app: Router) => {
|
|||
cron_parser.parseExpression(req.body.schedule).hasNext()
|
||||
) {
|
||||
const subscriptionService = Container.get(SubscriptionService);
|
||||
const data = await subscriptionService.create(req.body);
|
||||
const data = await subscriptionService.create({
|
||||
...req.body,
|
||||
userId: req.user?.userId,
|
||||
});
|
||||
return res.send({ code: 200, data });
|
||||
} else {
|
||||
return res.send({ code: 400, message: 'param schedule error' });
|
||||
|
|
@ -83,10 +87,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const subscriptionService = Container.get(SubscriptionService);
|
||||
const data = await subscriptionService.run(req.body);
|
||||
const data = await subscriptionService.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 });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -100,10 +104,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const subscriptionService = Container.get(SubscriptionService);
|
||||
const data = await subscriptionService.stop(req.body);
|
||||
const data = await subscriptionService.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 });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -117,10 +121,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const subscriptionService = Container.get(SubscriptionService);
|
||||
const data = await subscriptionService.disabled(req.body);
|
||||
const data = await subscriptionService.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 });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -134,10 +138,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const subscriptionService = Container.get(SubscriptionService);
|
||||
const data = await subscriptionService.enabled(req.body);
|
||||
const data = await subscriptionService.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 });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -220,10 +224,10 @@ export default (app: Router) => {
|
|||
const logger: Logger = Container.get('logger');
|
||||
try {
|
||||
const subscriptionService = Container.get(SubscriptionService);
|
||||
const data = await subscriptionService.remove(req.body, req.query);
|
||||
const data = await subscriptionService.remove(req.body, req.query, 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 });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -30,9 +30,33 @@ export default class DependenceService {
|
|||
private sockService: SockService,
|
||||
) { }
|
||||
|
||||
public async create(payloads: Dependence[]): Promise<Dependence[]> {
|
||||
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 dependencies
|
||||
return;
|
||||
}
|
||||
const dependencies = await DependenceModel.findAll({
|
||||
where: { id: ids },
|
||||
attributes: ['id', 'userId'],
|
||||
});
|
||||
const unauthorized = dependencies.filter(
|
||||
(dep) => dep.userId !== undefined && dep.userId !== userId
|
||||
);
|
||||
if (unauthorized.length > 0) {
|
||||
throw new Error('无权限操作该依赖');
|
||||
}
|
||||
}
|
||||
|
||||
public async create(payloads: Dependence[], userId?: number): Promise<Dependence[]> {
|
||||
const tabs = payloads.map((x) => {
|
||||
const tab = new Dependence({ ...x, status: DependenceStatus.queued });
|
||||
const tab = new Dependence({ ...x, status: DependenceStatus.queued, userId });
|
||||
return tab;
|
||||
});
|
||||
const docs = await this.insert(tabs);
|
||||
|
|
@ -65,7 +89,8 @@ export default class DependenceService {
|
|||
return await this.getDb({ id: payload.id });
|
||||
}
|
||||
|
||||
public async remove(ids: number[], force = false): Promise<Dependence[]> {
|
||||
public async remove(ids: number[], force = false, userId?: number): Promise<Dependence[]> {
|
||||
await this.checkOwnership(ids, userId);
|
||||
const docs = await DependenceModel.findAll({ where: { id: ids } });
|
||||
for (const doc of docs) {
|
||||
taskLimit.removeQueuedDependency(doc);
|
||||
|
|
@ -105,8 +130,10 @@ export default class DependenceService {
|
|||
},
|
||||
sort: any = [],
|
||||
query: any = {},
|
||||
userId?: number,
|
||||
): Promise<Dependence[]> {
|
||||
let condition = query;
|
||||
this.addUserIdFilter(condition, userId);
|
||||
if (DependenceTypes[type]) {
|
||||
condition.type = DependenceTypes[type];
|
||||
}
|
||||
|
|
@ -141,7 +168,8 @@ export default class DependenceService {
|
|||
return taskLimit.waitDependencyQueueDone();
|
||||
}
|
||||
|
||||
public async reInstall(ids: number[]): Promise<Dependence[]> {
|
||||
public async reInstall(ids: number[], userId?: number): Promise<Dependence[]> {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await DependenceModel.update(
|
||||
{ status: DependenceStatus.queued, log: [] },
|
||||
{ where: { id: ids } },
|
||||
|
|
@ -155,7 +183,8 @@ export default class DependenceService {
|
|||
return docs;
|
||||
}
|
||||
|
||||
public async cancel(ids: number[]) {
|
||||
public async cancel(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
const docs = await DependenceModel.findAll({ where: { id: ids } });
|
||||
for (const doc of docs) {
|
||||
taskLimit.removeQueuedDependency(doc);
|
||||
|
|
|
|||
|
|
@ -42,11 +42,37 @@ export default class SubscriptionService {
|
|||
private crontabService: CrontabService,
|
||||
) {}
|
||||
|
||||
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 subscriptions
|
||||
return;
|
||||
}
|
||||
const subscriptions = await SubscriptionModel.findAll({
|
||||
where: { id: ids },
|
||||
attributes: ['id', 'userId'],
|
||||
});
|
||||
const unauthorized = subscriptions.filter(
|
||||
(sub) => sub.userId !== undefined && sub.userId !== userId
|
||||
);
|
||||
if (unauthorized.length > 0) {
|
||||
throw new Error('无权限操作该订阅');
|
||||
}
|
||||
}
|
||||
|
||||
public async list(
|
||||
searchText?: string,
|
||||
ids?: string,
|
||||
userId?: number,
|
||||
): Promise<SubscriptionInstance[]> {
|
||||
let query = {};
|
||||
let query: any = {};
|
||||
this.addUserIdFilter(query, userId);
|
||||
const subIds = JSON.parse(ids || '[]');
|
||||
if (searchText) {
|
||||
const reg = {
|
||||
|
|
@ -262,7 +288,8 @@ export default class SubscriptionService {
|
|||
);
|
||||
}
|
||||
|
||||
public async remove(ids: number[], query: { force?: boolean }) {
|
||||
public async remove(ids: number[], query: { force?: boolean }, userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
||||
for (const doc of docs) {
|
||||
await this.handleTask(doc.get({ plain: true }), false);
|
||||
|
|
@ -273,7 +300,7 @@ export default class SubscriptionService {
|
|||
if (query?.force === true) {
|
||||
const crons = await CrontabModel.findAll({ where: { sub_id: ids } });
|
||||
if (crons?.length) {
|
||||
await this.crontabService.remove(crons.map((x) => x.id!));
|
||||
await this.crontabService.remove(crons.map((x) => x.id!), userId);
|
||||
}
|
||||
for (const doc of docs) {
|
||||
const filePath = join(config.scriptPath, doc.alias);
|
||||
|
|
@ -294,7 +321,8 @@ export default class SubscriptionService {
|
|||
return doc.get({ plain: true });
|
||||
}
|
||||
|
||||
public async run(ids: number[]) {
|
||||
public async run(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await SubscriptionModel.update(
|
||||
{ status: SubscriptionStatus.queued },
|
||||
{ where: { id: ids } },
|
||||
|
|
@ -304,7 +332,8 @@ export default class SubscriptionService {
|
|||
});
|
||||
}
|
||||
|
||||
public async stop(ids: number[]) {
|
||||
public async stop(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
||||
for (const doc of docs) {
|
||||
if (doc.pid) {
|
||||
|
|
@ -339,7 +368,8 @@ export default class SubscriptionService {
|
|||
});
|
||||
}
|
||||
|
||||
public async disabled(ids: number[]) {
|
||||
public async disabled(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await SubscriptionModel.update({ is_disabled: 1 }, { where: { id: ids } });
|
||||
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
||||
await this.setSshConfig();
|
||||
|
|
@ -348,7 +378,8 @@ export default class SubscriptionService {
|
|||
}
|
||||
}
|
||||
|
||||
public async enabled(ids: number[]) {
|
||||
public async enabled(ids: number[], userId?: number) {
|
||||
await this.checkOwnership(ids, userId);
|
||||
await SubscriptionModel.update({ is_disabled: 0 }, { where: { id: ids } });
|
||||
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
||||
await this.setSshConfig();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user