Skip to content

Commit 424152c

Browse files
geroplroboquat
authored andcommitted
[gitpod-db] Email domain blocklist: Add suffix matching capability
1 parent 9a7958b commit 424152c

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the Gitpod Enterprise Source Code License,
4+
* See License.enterprise.txt in the project root folder.
5+
*/
6+
7+
import * as chai from "chai";
8+
import { suite, test, timeout } from "mocha-typescript";
9+
import { testContainer } from "./test-container";
10+
import { TypeORM } from "./typeorm/typeorm";
11+
import { EmailDomainFilterDB } from "./email-domain-filter-db";
12+
import { DBEmailDomainFilterEntry } from "./typeorm/entity/db-email-domain-filter-entry";
13+
const expect = chai.expect;
14+
15+
@suite
16+
@timeout(5000)
17+
export class EmailDomainFilterDBSpec {
18+
typeORM = testContainer.get<TypeORM>(TypeORM);
19+
db = testContainer.get<EmailDomainFilterDB>(EmailDomainFilterDB);
20+
21+
async before() {
22+
await this.clear();
23+
}
24+
25+
async after() {
26+
await this.clear();
27+
}
28+
29+
protected async clear() {
30+
const connection = await this.typeORM.getConnection();
31+
const manager = connection.manager;
32+
await manager.clear(DBEmailDomainFilterEntry);
33+
}
34+
35+
@test public async filterSimple() {
36+
await this.db.storeFilterEntry({
37+
domain: "gitpod.io",
38+
negative: true,
39+
});
40+
41+
const actual = await this.db.isBlocked("gitpod.io");
42+
expect(actual, "isBlocked").to.equal(true);
43+
}
44+
45+
@test public async filterSimple_negative() {
46+
await this.db.storeFilterEntry({
47+
domain: "gitpod.io",
48+
negative: true,
49+
});
50+
51+
const actual = await this.db.isBlocked("example.org");
52+
expect(actual, "isBlocked").to.equal(false);
53+
54+
const actual2 = await this.db.isBlocked("sub.gitpod.io");
55+
expect(actual2, "isBlocked").to.equal(false);
56+
}
57+
58+
@test public async filterSuffixMatch() {
59+
await this.db.storeFilterEntry({
60+
domain: "%.gitpod.io",
61+
negative: true,
62+
});
63+
64+
const actual = await this.db.isBlocked("gitpod.io");
65+
expect(actual, "isBlocked").to.equal(false);
66+
67+
const actual2 = await this.db.isBlocked("sub.gitpod.io");
68+
expect(actual2, "isBlocked").to.equal(true);
69+
70+
const actual3 = await this.db.isBlocked("sub.gitpod.io.xyz");
71+
expect(actual3, "isBlocked").to.equal(false);
72+
}
73+
74+
@test public async filterSimple_guard_against_blocking_everyone() {
75+
await this.db.storeFilterEntry({
76+
domain: "%",
77+
negative: true,
78+
});
79+
80+
const actual = await this.db.isBlocked("example.org");
81+
expect(actual, "isBlocked").to.equal(false);
82+
83+
const actual2 = await this.db.isBlocked("sub.gitpod.io");
84+
expect(actual2, "isBlocked").to.equal(false);
85+
}
86+
}
87+
88+
module.exports = EmailDomainFilterDBSpec;

components/gitpod-db/src/typeorm/email-domain-filter-db-impl.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export class EmailDomainFilterDBImpl implements EmailDomainFilterDB {
3333
const repo = await this.getRepo();
3434
const result = await repo
3535
.createQueryBuilder("entry")
36-
.where(`entry.domain = :domain`, { domain: domain })
36+
.where(`:domain LIKE entry.domain`, { domain: domain })
37+
.andWhere(`entry.domain != '%'`) // this ensures we do not accidentally block _all_ new users
3738
.andWhere(`entry.negative = '1'`)
3839
.getOne();
3940
return !!result;

0 commit comments

Comments
 (0)