refactor: User permission and limits to run flows

This commit is contained in:
Faruk AYDIN
2023-04-10 17:21:19 +02:00
parent 77e29050c8
commit 9cb4607f69
6 changed files with 55 additions and 72 deletions

View File

@@ -39,6 +39,7 @@ type AppConfig = {
smtpPassword: string;
fromEmail: string;
isCloud: boolean;
isSelfHosted: boolean;
paddleVendorId: number;
paddleVendorAuthCode: string;
paddlePublicKey: string;
@@ -110,6 +111,7 @@ const appConfig: AppConfig = {
smtpPassword: process.env.SMTP_PASSWORD,
fromEmail: process.env.FROM_EMAIL,
isCloud: process.env.AUTOMATISCH_CLOUD === 'true',
isSelfHosted: process.env.AUTOMATISCH_CLOUD !== 'true',
paddleVendorId: Number(process.env.PADDLE_VENDOR_ID),
paddleVendorAuthCode: process.env.PADDLE_VENDOR_AUTH_CODE,
paddlePublicKey: process.env.PADDLE_PUBLIC_KEY,

View File

@@ -6,17 +6,24 @@ import Flow from '../../models/flow';
import { processTrigger } from '../../services/trigger';
import actionQueue from '../../queues/action';
import globalVariable from '../../helpers/global-variable';
import { REMOVE_AFTER_30_DAYS_OR_150_JOBS, REMOVE_AFTER_7_DAYS_OR_50_JOBS } from '../../helpers/remove-job-configuration';
import QuotaExceededError from '../../errors/quote-exceeded';
import {
REMOVE_AFTER_30_DAYS_OR_150_JOBS,
REMOVE_AFTER_7_DAYS_OR_50_JOBS,
} from '../../helpers/remove-job-configuration';
export default async (request: IRequest, response: Response) => {
const flow = await Flow.query()
.findById(request.params.flowId)
.throwIfNotFound();
const testRun = !flow.active;
const user = await flow.$relatedQuery('user');
if (!testRun) {
await flow.throwIfQuotaExceeded();
const testRun = !flow.active;
const quotaExceeded = !testRun && !(await user.isAllowedToRunFlows());
if (quotaExceeded) {
throw new QuotaExceededError();
}
const triggerStep = await flow.getTriggerStep();
@@ -58,7 +65,7 @@ export default async (request: IRequest, response: Response) => {
headers: request.headers,
body: request.body,
query: request.query,
}
};
rawInternalId = JSON.stringify(payload);
}
@@ -74,7 +81,7 @@ export default async (request: IRequest, response: Response) => {
flowId: flow.id,
stepId: triggerStep.id,
triggerItem,
testRun
testRun,
});
if (testRun) {
@@ -93,7 +100,7 @@ export default async (request: IRequest, response: Response) => {
const jobOptions = {
removeOnComplete: REMOVE_AFTER_7_DAYS_OR_50_JOBS,
removeOnFail: REMOVE_AFTER_30_DAYS_OR_150_JOBS,
}
};
await actionQueue.add(jobName, jobPayload, jobOptions);

View File

@@ -1,13 +1,15 @@
import { ValidationError } from 'objection';
import type { ModelOptions, QueryContext, StaticHookArguments } from 'objection';
import appConfig from '../config/app';
import type {
ModelOptions,
QueryContext,
StaticHookArguments,
} from 'objection';
import ExtendedQueryBuilder from './query-builder';
import Base from './base';
import Step from './step';
import User from './user';
import Execution from './execution';
import Telemetry from '../helpers/telemetry';
import QuotaExceededError from '../errors/quote-exceeded';
class Flow extends Base {
id!: string;
@@ -155,36 +157,7 @@ class Flow extends Base {
async isPaused() {
const user = await this.$relatedQuery('user');
const currentUsageData = await user.$relatedQuery('currentUsageData');
return await currentUsageData.checkIfLimitExceeded();
}
async checkIfQuotaExceeded() {
if (!appConfig.isCloud) return;
const user = await this.$relatedQuery('user');
const usageData = await user.$relatedQuery('currentUsageData');
const hasExceeded = await usageData.checkIfLimitExceeded();
if (hasExceeded) {
return true;
}
return false;
}
async throwIfQuotaExceeded() {
if (!appConfig.isCloud) return;
const hasExceeded = await this.checkIfQuotaExceeded();
if (hasExceeded) {
throw new QuotaExceededError();
}
return this;
return await user.isAllowedToRunFlows();
}
}

View File

@@ -2,7 +2,6 @@ import { raw } from 'objection';
import Base from './base';
import User from './user';
import Subscription from './subscription.ee';
import { getPlanById } from '../helpers/billing/plans.ee';
class UsageData extends Base {
id!: string;
@@ -47,28 +46,6 @@ class UsageData extends Base {
},
});
async checkIfLimitExceeded() {
const user = await this.$relatedQuery('user');
if (await user.inTrial()) {
return false;
}
const subscription = await this.$relatedQuery('subscription');
if (!subscription) {
return true;
}
if (!subscription.isActive) {
return true;
}
const plan = subscription.plan;
return this.consumedTaskCount >= plan.quota;
}
async increaseConsumedTaskCountByOne() {
return await this.$query().patch({
consumedTaskCount: raw('consumed_task_count + 1'),

View File

@@ -165,18 +165,24 @@ class User extends Base {
this.trialExpiryDate = DateTime.now().plus({ days: 30 }).toISODate();
}
async hasActiveSubscription() {
if (!appConfig.isCloud) {
async isAllowedToRunFlows() {
if (appConfig.isSelfHosted) {
return true;
}
if (await this.inTrial()) {
return true;
}
if ((await this.hasActiveSubscription()) && (await this.withinLimits())) {
return true;
}
return false;
}
const subscription = await this.$relatedQuery('currentSubscription');
return subscription?.isActive;
}
async inTrial() {
if (!appConfig.isCloud) {
if (appConfig.isSelfHosted) {
return false;
}
@@ -196,6 +202,24 @@ class User extends Base {
return now < expiryDate;
}
async hasActiveSubscription() {
if (!appConfig.isCloud) {
return false;
}
const subscription = await this.$relatedQuery('currentSubscription');
return subscription?.isActive;
}
async withinLimits() {
const currentSubscription = await this.$relatedQuery('currentSubscription');
const plan = currentSubscription.plan;
const currentUsageData = await this.$relatedQuery('currentUsageData');
return currentUsageData.consumedTaskCount >= plan.quota;
}
async $beforeInsert(queryContext: QueryContext) {
await super.$beforeInsert(queryContext);
await this.generateHash();

View File

@@ -17,10 +17,10 @@ export const worker = new Worker(
const { flowId } = job.data;
const flow = await Flow.query().findById(flowId).throwIfNotFound();
const user = await flow.$relatedQuery('user');
const allowedToRunFlows = await user.isAllowedToRunFlows();
const quotaExceeded = await flow.checkIfQuotaExceeded();
if (quotaExceeded) {
if (!allowedToRunFlows) {
return;
}