Skip to content

Commit

Permalink
feature userAccessPolicy: grouping
Browse files Browse the repository at this point in the history
  • Loading branch information
light-source committed Jan 7, 2025
1 parent 52d5c21 commit 5ca9507
Show file tree
Hide file tree
Showing 42 changed files with 1,443 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { TestsBase } from "../../testsBase.js";
import RequestRulesInspector from "./requestRulesInspector.js";
import type RulesStorage from "../storage/rulesStorage.js";
import type Rule from "../rule.js";
import type SearchRuleFilters from "../storage/filters/search/searchRuleFilters.js";
import type SearchRuleFilterSettings from "../storage/filters/search/searchRuleFilterSettings.js";
import type DeleteRuleFilters from "../storage/filters/deleteRuleFilters.js";
import { Address4 } from "ip-address";
import type RuleRecord from "../storage/record/ruleRecord.js";
import type SearchRuleFilters from "../storage/search/searchRuleFilters.js";
import type SearchRuleFilterSettings from "../storage/search/searchRuleFilterSettings.js";
import type DeleteRuleFilters from "../storage/delete/deleteRuleFilters.js";

class TestRequestRulesInspector extends TestsBase {
protected getTests(): {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import TestIpV4MaskUniqueIndex from "./testIpV4MaskUniqueIndex.js";

describe("MongooseIpV4MaskUniqueIndex", async () => {
const mongooseRulesStorage = new TestMongooseRulesStorage();
const tests = new TestIpV4MaskUniqueIndex(mongooseRulesStorage);

await mongooseRulesStorage.setup();

const tests = new TestIpV4MaskUniqueIndex(mongooseRulesStorage);
tests.runAll();
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import TestMongooseRulesStorage from "../../../../test/testMongooseRulesStorage.

describe("MongooseIpV4UniqueIndex", async () => {
const mongooseRulesStorage = new TestMongooseRulesStorage();
const tests = new TestIpV4UniqueIndex(mongooseRulesStorage);

await mongooseRulesStorage.setup();

const tests = new TestIpV4UniqueIndex(mongooseRulesStorage);
tests.runAll();
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { TestIpV6MaskUniqueIndex } from "./testIpV6MaskUniqueIndex.js";

describe("MongooseIpV6MaskUniqueIndex", async () => {
const mongooseRulesStorage = new TestMongooseRulesStorage();
const tests = new TestIpV6MaskUniqueIndex(mongooseRulesStorage);

await mongooseRulesStorage.setup();

const tests = new TestIpV6MaskUniqueIndex(mongooseRulesStorage);
tests.runAll();
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import TestIpV6UniqueIndex from "./testIpV6UniqueIndex.js";

describe("MongooseIpV6UniqueIndex", async () => {
const mongooseRulesStorage = new TestMongooseRulesStorage();
const tests = new TestIpV6UniqueIndex(mongooseRulesStorage);

await mongooseRulesStorage.setup();

const tests = new TestIpV6UniqueIndex(mongooseRulesStorage);
tests.runAll();
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ const globalIpIndexes: MongooseIndex[] = [
"userIp.v4.asNumeric": 1,
},
options: {
name: "globalIpV4",
unique: true,
partialFilterExpression: {
clientId: { $exists: false },
clientId: null,
"userIp.v4.asNumeric": { $exists: true },
"userIp.v4.mask.asNumeric": { $exists: false },
"userIp.v4.mask.asNumeric": null,
},
},
},
Expand All @@ -19,11 +20,12 @@ const globalIpIndexes: MongooseIndex[] = [
"userIp.v6.asNumericString": 1,
},
options: {
name: "globalIpV6",
unique: true,
partialFilterExpression: {
clientId: { $exists: false },
clientId: null,
"userIp.v6.asNumericString": { $exists: true },
"userIp.v6.mask.asNumeric": { $exists: false },
"userIp.v6.mask.asNumeric": null,
},
},
},
Expand All @@ -36,9 +38,10 @@ const globalIpMaskIndexes: MongooseIndex[] = [
"userIp.v4.mask.asNumeric": 1,
},
options: {
name: "globalIpMaskV4",
unique: true,
partialFilterExpression: {
clientId: { $exists: false },
clientId: null,
"userIp.v4.asNumeric": { $exists: true },
"userIp.v4.mask.asNumeric": { $exists: true },
},
Expand All @@ -50,75 +53,80 @@ const globalIpMaskIndexes: MongooseIndex[] = [
"userIp.v6.mask.asNumeric": 1,
},
options: {
name: "globalIpMaskV6",
unique: true,
partialFilterExpression: {
clientId: { $exists: false },
clientId: null,
"userIp.v6.asNumericString": { $exists: true },
"userIp.v6.mask.asNumeric": { $exists: true },
},
},
},
];

const ipMaskPerClientIndexes: MongooseIndex[] = [
const ipPerClientIndexes: MongooseIndex[] = [
{
definition: {
clientId: 1,
"userIp.v4.asNumeric": 1,
"userIp.v4.mask.asNumeric": 1,
},
options: {
name: "clientIpV4",
unique: true,
partialFilterExpression: {
clientId: { $exists: true },
"userIp.v4.asNumeric": { $exists: true },
"userIp.v4.mask.asNumeric": { $exists: true },
"userIp.v4.mask.asNumeric": null,
},
},
},
{
definition: {
clientId: 1,
"userIp.v6.asNumericString": 1,
"userIp.v6.mask.asNumeric": 1,
},
options: {
name: "clientIpV6",
unique: true,
partialFilterExpression: {
clientId: { $exists: true },
"userIp.v6.asNumericString": { $exists: true },
"userIp.v6.mask.asNumeric": { $exists: true },
"userIp.v6.mask.asNumeric": null,
},
},
},
];

const ipPerClientIndexes: MongooseIndex[] = [
const ipMaskPerClientIndexes: MongooseIndex[] = [
{
definition: {
clientId: 1,
"userIp.v4.asNumeric": 1,
"userIp.v4.mask.asNumeric": 1,
},
options: {
name: "clientIpV4Mask",
unique: true,
partialFilterExpression: {
clientId: { $exists: true },
"userIp.v4.asNumeric": { $exists: true },
"userIp.v4.mask.asNumeric": { $exists: false },
"userIp.v4.mask.asNumeric": { $exists: true },
},
},
},
{
definition: {
clientId: 1,
"userIp.v6.asNumericString": 1,
"userIp.v6.mask.asNumeric": 1,
},
options: {
name: "clientIpV6Mask",
unique: true,
partialFilterExpression: {
clientId: { $exists: true },
"userIp.v6.asNumericString": { $exists: true },
"userIp.v6.mask.asNumeric": { $exists: false },
"userIp.v6.mask.asNumeric": { $exists: true },
},
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { expect } from "vitest";
import { TestsBase } from "../../../../testsBase.js";
import type TestRulesStorage from "../../test/testRulesStorage.js";
import type Ip from "../../../../ip/ip.js";
import TestRulesBase from "../../test/testRulesBase.js";

abstract class TestUniqueIndexBase extends TestsBase {
abstract class TestUniqueIndexBase extends TestRulesBase {
protected abstract getFirstUserIpObject(): Ip;

protected abstract getSecondUserIpObject(): Ip;

public constructor(private readonly rulesStorage: TestRulesStorage) {
super();
}

protected override getTests(): {
name: string;
method: () => Promise<void>;
Expand All @@ -21,18 +16,18 @@ abstract class TestUniqueIndexBase extends TestsBase {
name: "globalRuleAcceptsUniqueIp",
method: async () => this.globalRuleAcceptsUniqueIp(),
},
{
{
name: "globalRuleRejectsNotUniqueIp",
method: async () => this.globalRuleRejectsNotUniqueIp(),
},
{
{
name: "clientRuleAcceptsUniqueIp",
method: async () => this.clientRuleAcceptsUniqueIp(),
},
/*fixme {
{
name: "clientRuleRejectsNotUniqueIp",
method: async () => this.clientRuleRejectsNotUniqueIp(),
},*/
},
{
name: "globalAndClientRulesCanHaveSameIp",
method: async () => this.globalAndClientRulesCanHaveSameIp(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import { Address4, type Address6 } from "ip-address";
import type { Model } from "mongoose";
import type RulesStorage from "./rulesStorage.js";
import type Rule from "../rule.js";
import type SearchRuleFilters from "./filters/search/searchRuleFilters.js";
import type SearchRuleFilterSettings from "./filters/search/searchRuleFilterSettings.js";
import IpVersion from "../../ip/ipVersion.js";
import type RuleRecord from "./record/ruleRecord.js";
import type MongooseRuleRecord from "./record/mongooseRuleRecord.js";
import type SearchRuleFilters from "./search/searchRuleFilters.js";
import type SearchRuleFilterSettings from "./search/searchRuleFilterSettings.js";

class MongooseRulesStorage implements RulesStorage {
private model: Model<Rule> | null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { expect } from "vitest";
import TestRulesBase from "../../../../test/testRulesBase.js";
import IPV6_NUMERIC_MAX_LENGTH from "../../../../../../ip/v6/ipV6NumericMaxLength.js";

class TestIpV6MaskFormatting extends TestRulesBase {

protected override getTests(): {
name: string;
method: () => Promise<void>;
}[] {
return [
{
name: "insertAddsZerosToShortRangeMin",
method: async () => this.insertAddsZerosToShortRangeMin(),
},
{
name: "insertDoesNotAddZerosToFullRangeMin",
method: async () => this.insertDoesNotAddZerosToFullRangeMin(),
},
{
name: "insertAddsZerosToShortRangeMax",
method: async () => this.insertAddsZerosToShortRangeMax(),
},
{
name: "insertDoesNotAddZerosToFullRangeMax",
method: async () => this.insertDoesNotAddZerosToFullRangeMax(),
},
];
}

protected async insertAddsZerosToShortRangeMin(): Promise<void> {
// given
const rangeMinAsNumericString = "1";
const fullLengthRangeMinNumericString = "1".padStart(
IPV6_NUMERIC_MAX_LENGTH,
"0",
);

// when
const record = await this.rulesStorage.insert({
isUserBlocked: true,
userIp: {
v6: {
asNumericString: "0",
asString: "0",
mask: {
rangeMinAsNumericString: rangeMinAsNumericString,
rangeMaxAsNumericString: "0",
asNumeric: 0,
},
},
},
});

// then
expect(record.userIp?.v6?.mask?.rangeMinAsNumericString).toBe(
fullLengthRangeMinNumericString,
);
}

protected async insertDoesNotAddZerosToFullRangeMin(): Promise<void> {
// given
const rangeMinAsNumericString = "42541956123769884636017138956568135816";

// when
const record = await this.rulesStorage.insert({
isUserBlocked: true,
userIp: {
v6: {
asNumericString: "0",
asString: "0",
mask: {
rangeMinAsNumericString: rangeMinAsNumericString,
rangeMaxAsNumericString: "0",
asNumeric: 0,
},
},
},
});

// then
expect(record.userIp?.v6?.mask?.rangeMinAsNumericString).toBe(
rangeMinAsNumericString,
);
}

protected async insertAddsZerosToShortRangeMax(): Promise<void> {
// given
const rangeMaxAsNumericString = "1";
const fullLengthRangeMaxNumericString = "1".padStart(
IPV6_NUMERIC_MAX_LENGTH,
"0",
);

// when
const record = await this.rulesStorage.insert({
isUserBlocked: true,
userIp: {
v6: {
asNumericString: "0",
asString: "0",
mask: {
rangeMinAsNumericString: "0",
rangeMaxAsNumericString: rangeMaxAsNumericString,
asNumeric: 0,
},
},
},
});

// then
expect(record.userIp?.v6?.mask?.rangeMaxAsNumericString).toBe(
fullLengthRangeMaxNumericString,
);
}

protected async insertDoesNotAddZerosToFullRangeMax(): Promise<void> {
// given
const rangeMaxAsNumericString = "42541956123769884636017138956568135816";

// when
const record = await this.rulesStorage.insert({
isUserBlocked: true,
userIp: {
v6: {
asNumericString: "0",
asString: "0",
mask: {
rangeMinAsNumericString: "0",
rangeMaxAsNumericString: rangeMaxAsNumericString,
asNumeric: 0,
},
},
},
});

// then
expect(record.userIp?.v6?.mask?.rangeMaxAsNumericString).toBe(
rangeMaxAsNumericString,
);
}
}

export default TestIpV6MaskFormatting;
Loading

0 comments on commit 5ca9507

Please sign in to comment.