Skip to content

Commit

Permalink
Allow user ip maskss to be passed via the API
Browse files Browse the repository at this point in the history
  • Loading branch information
forgetso committed Feb 12, 2025
1 parent 60441c0 commit 203a2b7
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class ApiExpressDefaultEndpointAdapter implements ApiExpressEndpointAdapter {

response.json(apiEndpointResponse);
} catch (error) {
this.logger.error(error);
this.logger.error((error as Error).message);

response.status(500).send("An internal server error occurred.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
enum ApiEndpointResponseStatus {
SUCCESS = "SUCCESS",
FAIL = "FAIL",
PROCESSING = "PROCESSING",
}

export { ApiEndpointResponseStatus };
6 changes: 6 additions & 0 deletions packages/user-access-policy/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import type { BlacklistInspector } from "./blacklistInspector.js";
import { apiRulePaths } from "./rules/api/apiRulePaths.js";
import { ApiRuleRoutesProvider } from "./rules/api/apiRuleRoutesProvider.js";
import { getExpressApiRuleRateLimits } from "./rules/api/getExpressApiRuleRateLimits.js";
import type {
ApiInsertManyRulesArgsOutputSchema,
ApiInsertManyRulesArgsSchema,
} from "./rules/api/insertMany/apiInsertManyRulesArgsSchema.js";
import { BlacklistRulesInspector } from "./rules/blacklistRulesInspector.js";
import { ImageCaptchaConfigRulesResolver } from "./rules/imageCaptchaConfigRulesResolver.js";
import { RulesMongooseStorage } from "./rules/mongoose/rulesMongooseStorage.js";
Expand Down Expand Up @@ -58,6 +62,8 @@ export {
type Rule,
type RulesStorage,
type BlacklistInspector,
type ApiInsertManyRulesArgsSchema,
type ApiInsertManyRulesArgsOutputSchema,
createMongooseRulesStorage,
createImageCaptchaConfigResolver,
createBlacklistInspector,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { boolean, number, object, string } from "zod";
import { boolean, number, object, type output, string } from "zod";
import { ruleConfigSchema } from "../../rule/config/ruleConfigSchema.js";

const apiInsertManyRulesArgsSchema = object({
Expand All @@ -23,11 +23,33 @@ const apiInsertManyRulesArgsSchema = object({
v4: string().array().optional(),
v6: string().array().optional(),
}),
userIpMasks: object({
v4: object({
min: string(),
max: string(),
})
.array()
.optional(),
v6: object({
min: string(),
max: string(),
})
.array()
.optional(),
}),
userIds: string().array().optional(),
config: ruleConfigSchema.optional(),
score: number().optional(),
});

type ApiInsertManyRulesArgsSchema = typeof apiInsertManyRulesArgsSchema;

export { apiInsertManyRulesArgsSchema, type ApiInsertManyRulesArgsSchema };
type ApiInsertManyRulesArgsOutputSchema = output<
typeof apiInsertManyRulesArgsSchema
>;

export {
apiInsertManyRulesArgsSchema,
type ApiInsertManyRulesArgsSchema,
type ApiInsertManyRulesArgsOutputSchema,
};
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,26 @@ class ApiInsertManyRulesEndpoint
): Promise<ApiEndpointResponse> {
const rules: Rule[] = [
...this.getUserIpRules(args),
...this.getUserIPMaskRules(args),
...this.getUserIdRules(args),
];

await this.rulesStorage.insertMany(rules);
let response: ApiEndpointResponse;

return {
status: ApiEndpointResponseStatus.SUCCESS,
response = {
status: ApiEndpointResponseStatus.PROCESSING,
};

this.rulesStorage.insertMany(rules).then(() => {
response = {
status: ApiEndpointResponseStatus.SUCCESS,
};
});

// wait to see if the promise resolves, otherwise return the processing status
await new Promise((resolve) => setTimeout(resolve, 5000));

return response;
}

public getRequestArgsSchema(): ApiInsertManyRulesArgsSchema {
Expand Down Expand Up @@ -94,6 +106,58 @@ class ApiInsertManyRulesEndpoint
return rules;
}

protected getUserIPMaskRules(
args: z.infer<ApiInsertManyRulesArgsSchema>,
): Rule[] {
const rules: Rule[] = [];
const userIpMasks = args.userIpMasks || [];
for (const userMask of userIpMasks.v4 || []) {
const min = new Address4(userMask.min);
const max = new Address4(userMask.max);
rules.push({
userIp: ruleIpSchema.parse({
v4: {
asNumeric: min.bigInt(),
asString: min.address,
mask: {
rangeMinAsNumeric: min.bigInt(),
rangeMaxAsNumeric: max.bigInt(),
asNumeric: Number(min.bigInt()),
},
},
}),
isUserBlocked: args.isUserBlocked,
description: args.description,
clientId: args.clientId,
config: args.config,
score: args.score,
});
}
for (const userMask of userIpMasks.v6 || []) {
const min = new Address6(userMask.min);
const max = new Address6(userMask.max);
rules.push({
userIp: ruleIpSchema.parse({
v6: {
asNumeric: min.bigInt(),
asString: min.address,
mask: {
rangeMinAsNumeric: min.bigInt(),
rangeMaxAsNumeric: max.bigInt(),
asNumeric: Number(min.bigInt()),
},
},
}),
isUserBlocked: args.isUserBlocked,
description: args.description,
clientId: args.clientId,
config: args.config,
score: args.score,
});
}
return rules;
}

protected getUserIdRules(
args: z.infer<ApiInsertManyRulesArgsSchema>,
): Rule[] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,11 @@ class RulesMongooseStorage implements RulesStorage {
throw this.modelNotSetProsopoError();
}

// Delete the existing records to avoid duplicates.
// Delete the existing ip records to avoid duplicates.
await this.writingModel.bulkWrite(
records.map((record) => ({
deleteOne: {
filter: {
userId: record.userId,
clientId: record.clientId,
userIp: record.userIp,
} as Pick<Rule, "userId" | "userIp" | "clientId">,
Expand Down

0 comments on commit 203a2b7

Please sign in to comment.