Skip to content

Commit

Permalink
Merge pull request #1968 from Infisical/misc/migrated-custom-rate-lim…
Browse files Browse the repository at this point in the history
…its-to-enterprise

misc: migrated custom rate limits to enterprise
  • Loading branch information
maidul98 committed Jun 14, 2024
2 parents 2645d4d + d4ef927 commit fb1b816
Show file tree
Hide file tree
Showing 12 changed files with 44 additions and 19 deletions.
2 changes: 1 addition & 1 deletion backend/src/@types/fastify.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TLdapConfigServiceFactory } from "@app/ee/services/ldap-config/ldap-con
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { TProjectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-service";
import { TRateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-service";
import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-service";
import { TScimServiceFactory } from "@app/ee/services/scim/scim-service";
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
Expand Down Expand Up @@ -48,7 +49,6 @@ import { TProjectEnvServiceFactory } from "@app/services/project-env/project-env
import { TProjectKeyServiceFactory } from "@app/services/project-key/project-key-service";
import { TProjectMembershipServiceFactory } from "@app/services/project-membership/project-membership-service";
import { TProjectRoleServiceFactory } from "@app/services/project-role/project-role-service";
import { TRateLimitServiceFactory } from "@app/services/rate-limit/rate-limit-service";
import { TSecretServiceFactory } from "@app/services/secret/secret-service";
import { TSecretBlindIndexServiceFactory } from "@app/services/secret-blind-index/secret-blind-index-service";
import { TSecretFolderServiceFactory } from "@app/services/secret-folder/secret-folder-service";
Expand Down
2 changes: 2 additions & 0 deletions backend/src/ee/routes/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { registerLicenseRouter } from "./license-router";
import { registerOrgRoleRouter } from "./org-role-router";
import { registerProjectRoleRouter } from "./project-role-router";
import { registerProjectRouter } from "./project-router";
import { registerRateLimitRouter } from "./rate-limit-router";
import { registerSamlRouter } from "./saml-router";
import { registerScimRouter } from "./scim-router";
import { registerSecretApprovalPolicyRouter } from "./secret-approval-policy-router";
Expand Down Expand Up @@ -45,6 +46,7 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {

await server.register(registerAccessApprovalPolicyRouter, { prefix: "/access-approvals/policies" });
await server.register(registerAccessApprovalRequestRouter, { prefix: "/access-approvals/requests" });
await server.register(registerRateLimitRouter, { prefix: "/rate-limit" });

await server.register(
async (dynamicSecretRouter) => {
Expand Down
3 changes: 3 additions & 0 deletions backend/src/ee/services/license/license-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,9 @@ export const licenseServiceFactory = ({
getInstanceType() {
return instanceType;
},
get onPremFeatures() {
return onPremFeatures;
},
getPlan,
updateSubscriptionOrgMemberCount,
refreshPlan,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CronJob } from "cron";

import { logger } from "@app/lib/logger";

import { TLicenseServiceFactory } from "../license/license-service";
import { TRateLimitDALFactory } from "./rate-limit-dal";
import { TRateLimit, TRateLimitUpdateDTO } from "./rate-limit-types";

Expand All @@ -24,11 +25,12 @@ export const getRateLimiterConfig = () => {

type TRateLimitServiceFactoryDep = {
rateLimitDAL: TRateLimitDALFactory;
licenseService: Pick<TLicenseServiceFactory, "onPremFeatures">;
};

export type TRateLimitServiceFactory = ReturnType<typeof rateLimitServiceFactory>;

export const rateLimitServiceFactory = ({ rateLimitDAL }: TRateLimitServiceFactoryDep) => {
export const rateLimitServiceFactory = ({ rateLimitDAL, licenseService }: TRateLimitServiceFactoryDep) => {
const DEFAULT_RATE_LIMIT_CONFIG_ID = "00000000-0000-0000-0000-000000000000";

const getRateLimits = async (): Promise<TRateLimit | undefined> => {
Expand Down Expand Up @@ -78,7 +80,16 @@ export const rateLimitServiceFactory = ({ rateLimitDAL }: TRateLimitServiceFacto
}
};

const initializeBackgroundSync = () => {
const initializeBackgroundSync = async () => {
if (!licenseService.onPremFeatures.customRateLimits) {
logger.info("Current license does not support custom rate limit configuration");
return;
}

logger.info("Setting up background sync process for rate limits");
// initial sync upon startup
await syncRateLimitConfiguration();

// sync rate limits configuration every 10 minutes
const job = new CronJob("*/10 * * * *", syncRateLimitConfiguration);
job.start();
Expand Down
5 changes: 0 additions & 5 deletions backend/src/server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import { Logger } from "pino";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env";
import { TQueueServiceFactory } from "@app/queue";
import { rateLimitDALFactory } from "@app/services/rate-limit/rate-limit-dal";
import { rateLimitServiceFactory } from "@app/services/rate-limit/rate-limit-service";
import { TSmtpService } from "@app/services/smtp/smtp-service";

import { globalRateLimiterCfg } from "./config/rateLimiter";
Expand Down Expand Up @@ -71,9 +69,6 @@ export const main = async ({ db, smtp, logger, queue, keyStore }: TMain) => {

// Rate limiters and security headers
if (appCfg.isProductionMode) {
const rateLimitDAL = rateLimitDALFactory(db);
const rateLimitService = rateLimitServiceFactory({ rateLimitDAL });
await rateLimitService.syncRateLimitConfiguration();
await server.register<FastifyRateLimitOptions>(ratelimiter, globalRateLimiterCfg());
}

Expand Down
2 changes: 1 addition & 1 deletion backend/src/server/config/rateLimiter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { RateLimitOptions, RateLimitPluginOptions } from "@fastify/rate-limit";
import { Redis } from "ioredis";

import { getRateLimiterConfig } from "@app/ee/services/rate-limit/rate-limit-service";
import { getConfig } from "@app/lib/config/env";
import { getRateLimiterConfig } from "@app/services/rate-limit/rate-limit-service";

export const globalRateLimiterCfg = (): RateLimitPluginOptions => {
const appCfg = getConfig();
Expand Down
12 changes: 8 additions & 4 deletions backend/src/server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import { permissionDALFactory } from "@app/ee/services/permission/permission-dal
import { permissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { projectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal";
import { projectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-service";
import { rateLimitDALFactory } from "@app/ee/services/rate-limit/rate-limit-dal";
import { rateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-service";
import { samlConfigDALFactory } from "@app/ee/services/saml-config/saml-config-dal";
import { samlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-service";
import { scimDALFactory } from "@app/ee/services/scim/scim-dal";
Expand Down Expand Up @@ -122,8 +124,6 @@ import { projectMembershipServiceFactory } from "@app/services/project-membershi
import { projectUserMembershipRoleDALFactory } from "@app/services/project-membership/project-user-membership-role-dal";
import { projectRoleDALFactory } from "@app/services/project-role/project-role-dal";
import { projectRoleServiceFactory } from "@app/services/project-role/project-role-service";
import { rateLimitDALFactory } from "@app/services/rate-limit/rate-limit-dal";
import { rateLimitServiceFactory } from "@app/services/rate-limit/rate-limit-service";
import { dailyResourceCleanUpQueueServiceFactory } from "@app/services/resource-cleanup/resource-cleanup-queue";
import { secretDALFactory } from "@app/services/secret/secret-dal";
import { secretQueueFactory } from "@app/services/secret/secret-queue";
Expand Down Expand Up @@ -449,7 +449,8 @@ export const registerRoutes = async (
keyStore
});
const rateLimitService = rateLimitServiceFactory({
rateLimitDAL
rateLimitDAL,
licenseService
});
const apiKeyService = apiKeyServiceFactory({ apiKeyDAL, userDAL });

Expand Down Expand Up @@ -910,7 +911,10 @@ export const registerRoutes = async (

const cronJobs: CronJob[] = [];
if (appCfg.isProductionMode) {
cronJobs.push(rateLimitService.initializeBackgroundSync());
const rateLimitSyncJob = await rateLimitService.initializeBackgroundSync();
if (rateLimitSyncJob) {
cronJobs.push(rateLimitSyncJob);
}
}

server.decorate<FastifyZodProvider["store"]>("store", {
Expand Down
2 changes: 0 additions & 2 deletions backend/src/server/routes/v1/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { registerProjectEnvRouter } from "./project-env-router";
import { registerProjectKeyRouter } from "./project-key-router";
import { registerProjectMembershipRouter } from "./project-membership-router";
import { registerProjectRouter } from "./project-router";
import { registerRateLimitRouter } from "./rate-limit-router";
import { registerSecretFolderRouter } from "./secret-folder-router";
import { registerSecretImportRouter } from "./secret-import-router";
import { registerSecretSharingRouter } from "./secret-sharing-router";
Expand All @@ -44,7 +43,6 @@ export const registerV1Routes = async (server: FastifyZodProvider) => {
await server.register(registerPasswordRouter, { prefix: "/password" });
await server.register(registerOrgRouter, { prefix: "/organization" });
await server.register(registerAdminRouter, { prefix: "/admin" });
await server.register(registerRateLimitRouter, { prefix: "/rate-limit" });
await server.register(registerUserRouter, { prefix: "/user" });
await server.register(registerInviteOrgRouter, { prefix: "/invite-org" });
await server.register(registerUserActionRouter, { prefix: "/user-action" });
Expand Down
20 changes: 16 additions & 4 deletions frontend/src/views/admin/DashboardPage/RateLimitPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";

import { createNotification } from "@app/components/notifications";
import { Button, ContentLoader, FormControl, Input } from "@app/components/v2";
import { Button, ContentLoader, FormControl, Input, UpgradePlanModal } from "@app/components/v2";
import { useSubscription } from "@app/context";
import { usePopUp } from "@app/hooks";
import { useGetRateLimit, useUpdateRateLimit } from "@app/hooks/api";

const formSchema = z.object({
Expand All @@ -21,7 +23,9 @@ type TRateLimitForm = z.infer<typeof formSchema>;

export const RateLimitPanel = () => {
const { data: rateLimit, isLoading } = useGetRateLimit();
const { subscription } = useSubscription();
const { mutateAsync: updateRateLimit } = useUpdateRateLimit();
const { handlePopUpToggle, handlePopUpOpen, popUp } = usePopUp(["upgradePlan"] as const);

const {
control,
Expand All @@ -44,6 +48,11 @@ export const RateLimitPanel = () => {

const onRateLimitFormSubmit = async (formData: TRateLimitForm) => {
try {
if (subscription && !subscription.customRateLimits) {
handlePopUpOpen("upgradePlan");
return;
}

const {
readRateLimit,
writeRateLimit,
Expand Down Expand Up @@ -86,9 +95,7 @@ export const RateLimitPanel = () => {
onSubmit={handleSubmit(onRateLimitFormSubmit)}
>
<div className="mb-8 flex flex-col justify-start">
<div className="mb-4 text-xl font-semibold text-mineshaft-100">
Configure rate limits
</div>
<div className="mb-4 text-xl font-semibold text-mineshaft-100">Configure rate limits</div>
<Controller
control={control}
name="readRateLimit"
Expand Down Expand Up @@ -245,6 +252,11 @@ export const RateLimitPanel = () => {
<Button type="submit" isLoading={isSubmitting} isDisabled={isSubmitting || !isDirty}>
Save
</Button>
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You can configure custom rate limits if you switch to Infisical's Enterprise plan."
/>
</form>
);
};

0 comments on commit fb1b816

Please sign in to comment.