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');
|
const logger: Logger = Container.get('logger');
|
||||||
try {
|
try {
|
||||||
const dependenceService = Container.get(DependenceService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('🔥 error: %o', e);
|
logger.error('🔥 error: %o', e);
|
||||||
|
|
@ -45,7 +45,7 @@ export default (app: Router) => {
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const dependenceService = Container.get(DependenceService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return next(e);
|
return next(e);
|
||||||
|
|
@ -82,10 +82,10 @@ export default (app: Router) => {
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const dependenceService = Container.get(DependenceService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -98,10 +98,10 @@ export default (app: Router) => {
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const dependenceService = Container.get(DependenceService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -132,10 +132,10 @@ export default (app: Router) => {
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const dependenceService = Container.get(DependenceService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -148,10 +148,10 @@ export default (app: Router) => {
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
const dependenceService = Container.get(DependenceService);
|
const dependenceService = Container.get(DependenceService);
|
||||||
await dependenceService.cancel(req.body);
|
await dependenceService.cancel(req.body, req.user?.userId);
|
||||||
return res.send({ code: 200 });
|
return res.send({ code: 200 });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ export default (app: Router) => {
|
||||||
const data = await subscriptionService.list(
|
const data = await subscriptionService.list(
|
||||||
req.query.searchValue as string,
|
req.query.searchValue as string,
|
||||||
req.query.ids as string,
|
req.query.ids as string,
|
||||||
|
req.user?.userId,
|
||||||
);
|
);
|
||||||
return res.send({ code: 200, data });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -63,7 +64,10 @@ export default (app: Router) => {
|
||||||
cron_parser.parseExpression(req.body.schedule).hasNext()
|
cron_parser.parseExpression(req.body.schedule).hasNext()
|
||||||
) {
|
) {
|
||||||
const subscriptionService = Container.get(SubscriptionService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} else {
|
} else {
|
||||||
return res.send({ code: 400, message: 'param schedule error' });
|
return res.send({ code: 400, message: 'param schedule error' });
|
||||||
|
|
@ -83,10 +87,10 @@ export default (app: Router) => {
|
||||||
const logger: Logger = Container.get('logger');
|
const logger: Logger = Container.get('logger');
|
||||||
try {
|
try {
|
||||||
const subscriptionService = Container.get(SubscriptionService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -100,10 +104,10 @@ export default (app: Router) => {
|
||||||
const logger: Logger = Container.get('logger');
|
const logger: Logger = Container.get('logger');
|
||||||
try {
|
try {
|
||||||
const subscriptionService = Container.get(SubscriptionService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -117,10 +121,10 @@ export default (app: Router) => {
|
||||||
const logger: Logger = Container.get('logger');
|
const logger: Logger = Container.get('logger');
|
||||||
try {
|
try {
|
||||||
const subscriptionService = Container.get(SubscriptionService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -134,10 +138,10 @@ export default (app: Router) => {
|
||||||
const logger: Logger = Container.get('logger');
|
const logger: Logger = Container.get('logger');
|
||||||
try {
|
try {
|
||||||
const subscriptionService = Container.get(SubscriptionService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -220,10 +224,10 @@ export default (app: Router) => {
|
||||||
const logger: Logger = Container.get('logger');
|
const logger: Logger = Container.get('logger');
|
||||||
try {
|
try {
|
||||||
const subscriptionService = Container.get(SubscriptionService);
|
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 });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
return next(e);
|
return res.send({ code: 400, message: e.message });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,33 @@ export default class DependenceService {
|
||||||
private sockService: SockService,
|
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 tabs = payloads.map((x) => {
|
||||||
const tab = new Dependence({ ...x, status: DependenceStatus.queued });
|
const tab = new Dependence({ ...x, status: DependenceStatus.queued, userId });
|
||||||
return tab;
|
return tab;
|
||||||
});
|
});
|
||||||
const docs = await this.insert(tabs);
|
const docs = await this.insert(tabs);
|
||||||
|
|
@ -65,7 +89,8 @@ export default class DependenceService {
|
||||||
return await this.getDb({ id: payload.id });
|
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 } });
|
const docs = await DependenceModel.findAll({ where: { id: ids } });
|
||||||
for (const doc of docs) {
|
for (const doc of docs) {
|
||||||
taskLimit.removeQueuedDependency(doc);
|
taskLimit.removeQueuedDependency(doc);
|
||||||
|
|
@ -105,8 +130,10 @@ export default class DependenceService {
|
||||||
},
|
},
|
||||||
sort: any = [],
|
sort: any = [],
|
||||||
query: any = {},
|
query: any = {},
|
||||||
|
userId?: number,
|
||||||
): Promise<Dependence[]> {
|
): Promise<Dependence[]> {
|
||||||
let condition = query;
|
let condition = query;
|
||||||
|
this.addUserIdFilter(condition, userId);
|
||||||
if (DependenceTypes[type]) {
|
if (DependenceTypes[type]) {
|
||||||
condition.type = DependenceTypes[type];
|
condition.type = DependenceTypes[type];
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +168,8 @@ export default class DependenceService {
|
||||||
return taskLimit.waitDependencyQueueDone();
|
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(
|
await DependenceModel.update(
|
||||||
{ status: DependenceStatus.queued, log: [] },
|
{ status: DependenceStatus.queued, log: [] },
|
||||||
{ where: { id: ids } },
|
{ where: { id: ids } },
|
||||||
|
|
@ -155,7 +183,8 @@ export default class DependenceService {
|
||||||
return docs;
|
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 } });
|
const docs = await DependenceModel.findAll({ where: { id: ids } });
|
||||||
for (const doc of docs) {
|
for (const doc of docs) {
|
||||||
taskLimit.removeQueuedDependency(doc);
|
taskLimit.removeQueuedDependency(doc);
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,37 @@ export default class SubscriptionService {
|
||||||
private crontabService: CrontabService,
|
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(
|
public async list(
|
||||||
searchText?: string,
|
searchText?: string,
|
||||||
ids?: string,
|
ids?: string,
|
||||||
|
userId?: number,
|
||||||
): Promise<SubscriptionInstance[]> {
|
): Promise<SubscriptionInstance[]> {
|
||||||
let query = {};
|
let query: any = {};
|
||||||
|
this.addUserIdFilter(query, userId);
|
||||||
const subIds = JSON.parse(ids || '[]');
|
const subIds = JSON.parse(ids || '[]');
|
||||||
if (searchText) {
|
if (searchText) {
|
||||||
const reg = {
|
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 } });
|
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
||||||
for (const doc of docs) {
|
for (const doc of docs) {
|
||||||
await this.handleTask(doc.get({ plain: true }), false);
|
await this.handleTask(doc.get({ plain: true }), false);
|
||||||
|
|
@ -273,7 +300,7 @@ export default class SubscriptionService {
|
||||||
if (query?.force === true) {
|
if (query?.force === true) {
|
||||||
const crons = await CrontabModel.findAll({ where: { sub_id: ids } });
|
const crons = await CrontabModel.findAll({ where: { sub_id: ids } });
|
||||||
if (crons?.length) {
|
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) {
|
for (const doc of docs) {
|
||||||
const filePath = join(config.scriptPath, doc.alias);
|
const filePath = join(config.scriptPath, doc.alias);
|
||||||
|
|
@ -294,7 +321,8 @@ export default class SubscriptionService {
|
||||||
return doc.get({ plain: true });
|
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(
|
await SubscriptionModel.update(
|
||||||
{ status: SubscriptionStatus.queued },
|
{ status: SubscriptionStatus.queued },
|
||||||
{ where: { id: ids } },
|
{ 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 } });
|
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
||||||
for (const doc of docs) {
|
for (const doc of docs) {
|
||||||
if (doc.pid) {
|
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 } });
|
await SubscriptionModel.update({ is_disabled: 1 }, { where: { id: ids } });
|
||||||
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
||||||
await this.setSshConfig();
|
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 } });
|
await SubscriptionModel.update({ is_disabled: 0 }, { where: { id: ids } });
|
||||||
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
const docs = await SubscriptionModel.findAll({ where: { id: ids } });
|
||||||
await this.setSshConfig();
|
await this.setSshConfig();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user