refactor: throttler rate limits for oauth client & access token (#16962)

Co-authored-by: Morgan Vernay <morgan@cal.com>
This commit is contained in:
Lauris Skraucis
2024-10-08 17:34:41 +03:00
committed by GitHub
co-authored by Morgan Vernay
parent 5ed36a7fe1
commit c4cdba1015
3 changed files with 467 additions and 1855 deletions
+3
View File
@@ -21,6 +21,9 @@ export type Environment = {
API_KEY_PREFIX: string;
DOCS_URL: string;
RATE_LIMIT_DEFAULT_TTL_MS: number;
RATE_LIMIT_DEFAULT_LIMIT_API_KEY: number;
RATE_LIMIT_DEFAULT_LIMIT_OAUTH_CLIENT: number;
RATE_LIMIT_DEFAULT_LIMIT_ACCESS_TOKEN: number;
RATE_LIMIT_DEFAULT_LIMIT: number;
RATE_LIMIT_DEFAULT_BLOCK_DURATION_MS: number;
};
+23 -10
View File
@@ -22,18 +22,23 @@ const rateLimitSchema = z.object({
ttl: z.number(),
blockDuration: z.number(),
});
type RateLimitType = z.infer<typeof rateLimitSchema>;
const rateLimitsSchema = z.array(rateLimitSchema);
const sixtySecondsMs = 60 * 1000;
@Injectable()
export class CustomThrottlerGuard extends ThrottlerGuard {
private logger = new Logger("CustomThrottlerGuard");
private defaultTttl = Number(getEnv("RATE_LIMIT_DEFAULT_TTL_MS", 60 * 1000));
private defaultTttl = Number(getEnv("RATE_LIMIT_DEFAULT_TTL_MS", sixtySecondsMs));
private defaultLimitApiKey = Number(getEnv("RATE_LIMIT_DEFAULT_LIMIT_API_KEY", 120));
private defaultLimitOAuthClient = Number(getEnv("RATE_LIMIT_DEFAULT_LIMIT_OAUTH_CLIENT", 500));
private defaultLimitAccessToken = Number(getEnv("RATE_LIMIT_DEFAULT_LIMIT_ACCESS_TOKEN", 500));
private defaultLimit = Number(getEnv("RATE_LIMIT_DEFAULT_LIMIT", 120));
private defaultBlockDuration = Number(getEnv("RATE_LIMIT_DEFAULT_BLOCK_DURATION_MS", 60 * 1000));
private defaultBlockDuration = Number(getEnv("RATE_LIMIT_DEFAULT_BLOCK_DURATION_MS", sixtySecondsMs));
constructor(
options: ThrottlerModuleOptions,
@@ -83,7 +88,7 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
}
private async handleNonApiKeyRequest(tracker: string, response: Response): Promise<boolean> {
const rateLimit = this.getDefaultRateLimit();
const rateLimit = this.getDefaultRateLimit(tracker);
this.logger.log(`Tracker "${tracker}" uses default rate limits because it is not tracking api key:
${JSON.stringify(rateLimit, null, 2)}
`);
@@ -96,17 +101,25 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
return true;
}
private getDefaultRateLimit() {
private getDefaultRateLimit(tracker: string) {
return {
name: "default",
limit: this.getDefaultLimit(),
limit: this.getDefaultLimit(tracker),
ttl: this.getDefaultTtl(),
blockDuration: this.getDefaultBlockDuration(),
};
}
getDefaultLimit() {
return this.defaultLimit;
getDefaultLimit(tracker: string) {
if (tracker.startsWith("api_key_")) {
return this.defaultLimitApiKey;
} else if (tracker.startsWith("oauth_client_")) {
return this.defaultLimitOAuthClient;
} else if (tracker.startsWith("access_token_")) {
return this.defaultLimitAccessToken;
} else {
return this.defaultLimit;
}
}
getDefaultTtl() {
@@ -150,7 +163,7 @@ export class CustomThrottlerGuard extends ThrottlerGuard {
}
if (!rateLimits || rateLimits.length === 0) {
rateLimits = [this.getDefaultRateLimit()];
rateLimits = [this.getDefaultRateLimit(tracker)];
this.logger.log(`Tracker "${tracker}" rate limits not found in database. Using default rate limits:
${JSON.stringify(rateLimits, null, 2)}`);
}
File diff suppressed because it is too large Load Diff