@nymphjs/tilmeld 1.0.0-beta.13 → 1.0.0-beta.130
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +598 -0
- package/README.md +21 -5
- package/dist/AbleObject.d.ts +15 -0
- package/dist/AbleObject.js +18 -6
- package/dist/AbleObject.js.map +1 -1
- package/dist/Group.d.ts +186 -19
- package/dist/Group.js +817 -440
- package/dist/Group.js.map +1 -1
- package/dist/Group.testArtifacts.d.ts +3 -0
- package/dist/Group.testArtifacts.js +120 -0
- package/dist/Group.testArtifacts.js.map +1 -0
- package/dist/Tilmeld.d.ts +241 -12
- package/dist/Tilmeld.js +725 -286
- package/dist/Tilmeld.js.map +1 -1
- package/dist/Tilmeld.types.d.ts +5 -5
- package/dist/Tilmeld.types.js +1 -2
- package/dist/User.d.ts +399 -26
- package/dist/User.js +1955 -1055
- package/dist/User.js.map +1 -1
- package/dist/User.testArtifacts.d.ts +3 -0
- package/dist/User.testArtifacts.js +175 -0
- package/dist/User.testArtifacts.js.map +1 -0
- package/dist/conf/defaults.d.ts +1 -1
- package/dist/conf/defaults.js +196 -141
- package/dist/conf/defaults.js.map +1 -1
- package/dist/conf/index.d.ts +355 -2
- package/dist/conf/index.js +2 -8
- package/dist/conf/index.js.map +1 -1
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +3 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/requireAbility.d.ts +10 -0
- package/dist/decorators/requireAbility.js +21 -0
- package/dist/decorators/requireAbility.js.map +1 -0
- package/dist/decorators/requireAuthentication.d.ts +8 -0
- package/dist/decorators/requireAuthentication.js +16 -0
- package/dist/decorators/requireAuthentication.js.map +1 -0
- package/dist/enforceTilmeld.d.ts +3 -0
- package/dist/enforceTilmeld.js +18 -0
- package/dist/enforceTilmeld.js.map +1 -0
- package/dist/errors/AccessControlError.d.ts +2 -1
- package/dist/errors/AccessControlError.js +3 -6
- package/dist/errors/AccessControlError.js.map +1 -1
- package/dist/errors/BadDataError.d.ts +2 -1
- package/dist/errors/BadDataError.js +3 -6
- package/dist/errors/BadDataError.js.map +1 -1
- package/dist/errors/BadEmailError.d.ts +2 -1
- package/dist/errors/BadEmailError.js +3 -6
- package/dist/errors/BadEmailError.js.map +1 -1
- package/dist/errors/BadUsernameError.d.ts +2 -1
- package/dist/errors/BadUsernameError.js +3 -6
- package/dist/errors/BadUsernameError.js.map +1 -1
- package/dist/errors/CouldNotChangeDefaultPrimaryGroupError.js +1 -5
- package/dist/errors/CouldNotChangeDefaultPrimaryGroupError.js.map +1 -1
- package/dist/errors/EmailChangeRateLimitExceededError.js +1 -5
- package/dist/errors/EmailChangeRateLimitExceededError.js.map +1 -1
- package/dist/errors/index.d.ts +6 -6
- package/dist/errors/index.js +6 -22
- package/dist/errors/index.js.map +1 -1
- package/dist/index.d.ts +12 -10
- package/dist/index.js +17 -35
- package/dist/index.js.map +1 -1
- package/dist/testArtifacts.d.ts +23 -0
- package/dist/testArtifacts.js +1317 -0
- package/dist/testArtifacts.js.map +1 -0
- package/dist/tilmeldJoiProps.d.ts +3 -3
- package/dist/tilmeldJoiProps.js +13 -18
- package/dist/tilmeldJoiProps.js.map +1 -1
- package/jest.config.js +31 -5
- package/package.json +49 -36
- package/src/AbleObject.ts +2 -2
- package/src/Group.testArtifacts.ts +159 -0
- package/src/Group.ts +647 -238
- package/src/Tilmeld.ts +550 -315
- package/src/Tilmeld.types.ts +5 -5
- package/src/User.testArtifacts.ts +226 -0
- package/src/User.ts +1657 -634
- package/src/conf/defaults.ts +172 -109
- package/src/conf/index.ts +370 -2
- package/src/decorators/index.ts +2 -0
- package/src/decorators/requireAbility.ts +26 -0
- package/src/decorators/requireAuthentication.ts +19 -0
- package/src/enforceTilmeld.ts +20 -0
- package/src/errors/AccessControlError.ts +4 -2
- package/src/errors/BadDataError.ts +4 -2
- package/src/errors/BadEmailError.ts +4 -2
- package/src/errors/BadUsernameError.ts +4 -2
- package/src/errors/index.ts +6 -6
- package/src/index.ts +13 -10
- package/src/testArtifacts.ts +2098 -0
- package/src/tilmeldJoiProps.ts +8 -23
- package/tsconfig.json +6 -3
- package/typedoc.json +4 -0
- package/dist/Group.test.d.ts +0 -1
- package/dist/Group.test.js +0 -48
- package/dist/Group.test.js.map +0 -1
- package/dist/User.test.d.ts +0 -1
- package/dist/User.test.js +0 -51
- package/dist/User.test.js.map +0 -1
- package/dist/conf/d.d.ts +0 -55
- package/dist/conf/d.js +0 -3
- package/dist/conf/d.js.map +0 -1
- package/src/Group.test.ts +0 -58
- package/src/User.test.ts +0 -61
- package/src/conf/d.ts +0 -303
|
@@ -0,0 +1,2098 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Entity,
|
|
3
|
+
Nymph,
|
|
4
|
+
HttpError,
|
|
5
|
+
TilmeldAccessLevels,
|
|
6
|
+
TilmeldAccessRequest,
|
|
7
|
+
} from '@nymphjs/nymph';
|
|
8
|
+
|
|
9
|
+
import Tilmeld from './Tilmeld.js';
|
|
10
|
+
import { requireAbility, requireAuthentication } from './decorators/index.js';
|
|
11
|
+
import { AccessControlError } from './errors/index.js';
|
|
12
|
+
import type { AccessControlData } from './Tilmeld.types.js';
|
|
13
|
+
import type UserClass from './User.js';
|
|
14
|
+
import { UserTest } from './User.testArtifacts.js';
|
|
15
|
+
import type GroupClass from './Group.js';
|
|
16
|
+
import { GroupTest } from './Group.testArtifacts.js';
|
|
17
|
+
|
|
18
|
+
export type TestModelData = {
|
|
19
|
+
name?: string;
|
|
20
|
+
} & AccessControlData;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* This class is a test class that extends the Entity class.
|
|
24
|
+
*/
|
|
25
|
+
export class TestModel extends Entity<TestModelData> {
|
|
26
|
+
static ETYPE = 'tilmeld_test_model';
|
|
27
|
+
static class = 'TestModel';
|
|
28
|
+
/**
|
|
29
|
+
* This should only be used by the backend.
|
|
30
|
+
*/
|
|
31
|
+
private $skipAcWhenDeleting = false;
|
|
32
|
+
|
|
33
|
+
@requireAuthentication
|
|
34
|
+
public $testRequireAuthenticationDecorator() {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@requireAuthentication
|
|
39
|
+
public async $testRequireAuthenticationDecoratorAsync() {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@requireAbility('test-ability')
|
|
44
|
+
public $testRequireAbilityDecorator() {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@requireAbility('test-ability')
|
|
49
|
+
public async $testRequireAbilityDecoratorAsync() {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* This should *never* be accessible on the client.
|
|
55
|
+
*/
|
|
56
|
+
async $deleteSkipAC() {
|
|
57
|
+
this.$skipAcWhenDeleting = true;
|
|
58
|
+
return await this.$delete();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
$tilmeldDeleteSkipAC() {
|
|
62
|
+
if (this.$skipAcWhenDeleting) {
|
|
63
|
+
this.$skipAcWhenDeleting = false;
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const TestModelClass = TestModel;
|
|
71
|
+
|
|
72
|
+
export function TilmeldTest(
|
|
73
|
+
nymphBase: Nymph,
|
|
74
|
+
describe: (name: string, fn: () => void) => void,
|
|
75
|
+
it: (name: string, fn: () => void) => void,
|
|
76
|
+
) {
|
|
77
|
+
const tilmeld = new Tilmeld({
|
|
78
|
+
appName: 'My App',
|
|
79
|
+
appUrl: 'http://localhost:8080',
|
|
80
|
+
cookieDomain: 'localhost',
|
|
81
|
+
cookiePath: '/',
|
|
82
|
+
setupPath: '/user',
|
|
83
|
+
emailUsernames: false,
|
|
84
|
+
domainSupport: true,
|
|
85
|
+
verifyRedirect: 'http://localhost:8080',
|
|
86
|
+
verifyChangeRedirect: 'http://localhost:8080',
|
|
87
|
+
cancelChangeRedirect: 'http://localhost:8080',
|
|
88
|
+
jwtSecret: 'shhhhh',
|
|
89
|
+
sendEmail: async (_tilmeld, _options, _user) => {
|
|
90
|
+
return true;
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
const nymph = new Nymph(nymphBase.config, nymphBase.driver, tilmeld);
|
|
94
|
+
|
|
95
|
+
describe('Tilmeld', () => {
|
|
96
|
+
UserTest(nymph, tilmeld, describe, it);
|
|
97
|
+
GroupTest(nymph, tilmeld, describe, it);
|
|
98
|
+
|
|
99
|
+
const User = tilmeld.User;
|
|
100
|
+
const Group = tilmeld.Group;
|
|
101
|
+
const TestModel = nymph.addEntityClass(TestModelClass);
|
|
102
|
+
|
|
103
|
+
async function deleteTestData() {
|
|
104
|
+
let all: (TestModel | UserClass | GroupClass)[] = await nymph.getEntities(
|
|
105
|
+
{
|
|
106
|
+
class: TestModel,
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
expect(Array.isArray(all)).toEqual(true);
|
|
110
|
+
for (const cur of all) {
|
|
111
|
+
await cur.$deleteSkipAC();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
all = await nymph.getEntities({ class: TestModel });
|
|
115
|
+
expect(all.length).toEqual(0);
|
|
116
|
+
|
|
117
|
+
all = await nymph.getEntities({ class: User });
|
|
118
|
+
expect(Array.isArray(all)).toEqual(true);
|
|
119
|
+
for (const cur of all) {
|
|
120
|
+
await cur.$deleteSkipAC();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
all = await nymph.getEntities({ class: User });
|
|
124
|
+
expect(all.length).toEqual(0);
|
|
125
|
+
|
|
126
|
+
all = await nymph.getEntities({ class: Group });
|
|
127
|
+
expect(Array.isArray(all)).toEqual(true);
|
|
128
|
+
for (const cur of all) {
|
|
129
|
+
await cur.$deleteSkipAC();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
all = await nymph.getEntities({ class: Group });
|
|
133
|
+
expect(all.length).toEqual(0);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function makeUsers() {
|
|
137
|
+
const admin = await User.factoryUsername('admin');
|
|
138
|
+
const bob = await User.factoryUsername('bob');
|
|
139
|
+
const alice = await User.factoryUsername('alice');
|
|
140
|
+
const abgroup = await Group.factoryGroupname('abgroup');
|
|
141
|
+
|
|
142
|
+
if (admin.guid == null) {
|
|
143
|
+
admin.username = 'admin';
|
|
144
|
+
admin.email = 'admin@localhost';
|
|
145
|
+
admin.nameFirst = 'Admin';
|
|
146
|
+
admin.nameLast = 'User';
|
|
147
|
+
admin.name = 'Admin User';
|
|
148
|
+
admin.$password('password');
|
|
149
|
+
admin.$grant('system/admin');
|
|
150
|
+
await admin.$saveSkipAC();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (abgroup.guid == null) {
|
|
154
|
+
abgroup.groupname = 'abgroup';
|
|
155
|
+
abgroup.email = 'abgroup@localhost';
|
|
156
|
+
abgroup.name = 'AB Group';
|
|
157
|
+
await abgroup.$saveSkipAC();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (bob.guid == null) {
|
|
161
|
+
bob.username = 'bob';
|
|
162
|
+
bob.email = 'bob@localhost';
|
|
163
|
+
bob.nameFirst = 'Bob';
|
|
164
|
+
bob.nameLast = 'User';
|
|
165
|
+
bob.name = 'Bob User';
|
|
166
|
+
bob.$password('password');
|
|
167
|
+
bob.$addGroup(abgroup);
|
|
168
|
+
await bob.$saveSkipAC();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (alice.guid == null) {
|
|
172
|
+
alice.username = 'alice';
|
|
173
|
+
alice.email = 'alice@localhost';
|
|
174
|
+
alice.nameFirst = 'Alice';
|
|
175
|
+
alice.nameLast = 'User';
|
|
176
|
+
alice.name = 'Alice User';
|
|
177
|
+
alice.$password('password');
|
|
178
|
+
alice.$addGroup(abgroup);
|
|
179
|
+
await alice.$saveSkipAC();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { admin, bob, alice, abgroup };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
it('delete old test data', async () => {
|
|
186
|
+
await deleteTestData();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('users can log in', async () => {
|
|
190
|
+
const { admin, bob, alice } = await makeUsers();
|
|
191
|
+
|
|
192
|
+
let result = await admin.$login({
|
|
193
|
+
username: 'admin',
|
|
194
|
+
password: 'password',
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
expect(result.result).toEqual(true);
|
|
198
|
+
expect(admin.$is(User.current())).toEqual(true);
|
|
199
|
+
|
|
200
|
+
result = await admin.$logout();
|
|
201
|
+
|
|
202
|
+
expect(result.result).toEqual(true);
|
|
203
|
+
expect(User.current()).toBeNull();
|
|
204
|
+
|
|
205
|
+
result = await bob.$login({
|
|
206
|
+
username: 'bob',
|
|
207
|
+
password: 'password',
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
expect(result.result).toEqual(true);
|
|
211
|
+
expect(bob.$is(User.current())).toEqual(true);
|
|
212
|
+
|
|
213
|
+
result = await bob.$logout();
|
|
214
|
+
|
|
215
|
+
expect(result.result).toEqual(true);
|
|
216
|
+
expect(User.current()).toBeNull();
|
|
217
|
+
|
|
218
|
+
result = await alice.$login({
|
|
219
|
+
username: 'alice',
|
|
220
|
+
password: 'password',
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
expect(result.result).toEqual(true);
|
|
224
|
+
expect(alice.$is(User.current())).toEqual(true);
|
|
225
|
+
|
|
226
|
+
result = await alice.$logout();
|
|
227
|
+
|
|
228
|
+
expect(result.result).toEqual(true);
|
|
229
|
+
expect(User.current()).toBeNull();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('creates tables for test model', async () => {
|
|
233
|
+
const testEntity = await nymph.getEntity({ class: TestModel });
|
|
234
|
+
expect(testEntity).toBeNull();
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('user ownership, group ownership, and access controls are added on entities', async () => {
|
|
238
|
+
const { bob } = await makeUsers();
|
|
239
|
+
|
|
240
|
+
await tilmeld.fillSession(bob);
|
|
241
|
+
|
|
242
|
+
const bobsEntity = await TestModel.factory();
|
|
243
|
+
bobsEntity.name = "Bob's Entity";
|
|
244
|
+
await bobsEntity.$save();
|
|
245
|
+
|
|
246
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
247
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
248
|
+
|
|
249
|
+
const testEntityBob = await nymph.getEntity(
|
|
250
|
+
{ class: TestModel },
|
|
251
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
expect(testEntityBob).not.toBeNull();
|
|
255
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
256
|
+
expect(testEntityBob?.user?.$is(bob)).toEqual(true);
|
|
257
|
+
expect(testEntityBob?.group?.$is(bob.group)).toEqual(true);
|
|
258
|
+
expect(testEntityBob?.acUser).toEqual(TilmeldAccessLevels.FULL_ACCESS);
|
|
259
|
+
expect(testEntityBob?.acGroup).toEqual(TilmeldAccessLevels.READ_ACCESS);
|
|
260
|
+
expect(testEntityBob?.acOther).toEqual(TilmeldAccessLevels.NO_ACCESS);
|
|
261
|
+
expect(testEntityBob?.acRead).toEqual([]);
|
|
262
|
+
expect(testEntityBob?.acWrite).toEqual([]);
|
|
263
|
+
expect(testEntityBob?.acFull).toEqual([]);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it('require authentication decorator', async () => {
|
|
267
|
+
const { bob } = await makeUsers();
|
|
268
|
+
|
|
269
|
+
await tilmeld.fillSession(bob);
|
|
270
|
+
|
|
271
|
+
const bobsEntity = await TestModel.factory();
|
|
272
|
+
bobsEntity.name = "Bob's Entity";
|
|
273
|
+
await bobsEntity.$save();
|
|
274
|
+
|
|
275
|
+
expect(bobsEntity.$testRequireAuthenticationDecorator()).toEqual(true);
|
|
276
|
+
expect(
|
|
277
|
+
await bobsEntity.$testRequireAuthenticationDecoratorAsync(),
|
|
278
|
+
).toEqual(true);
|
|
279
|
+
|
|
280
|
+
tilmeld.clearSession();
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
bobsEntity.$testRequireAuthenticationDecorator();
|
|
284
|
+
|
|
285
|
+
throw new Error('Should have thrown.');
|
|
286
|
+
} catch (e: any) {
|
|
287
|
+
expect(e).toBeInstanceOf(HttpError);
|
|
288
|
+
expect(e.status).toEqual(403);
|
|
289
|
+
expect(e.message).toEqual('Forbidden');
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
await bobsEntity.$testRequireAuthenticationDecoratorAsync();
|
|
294
|
+
|
|
295
|
+
throw new Error('Should have thrown.');
|
|
296
|
+
} catch (e: any) {
|
|
297
|
+
expect(e).toBeInstanceOf(HttpError);
|
|
298
|
+
expect(e.status).toEqual(403);
|
|
299
|
+
expect(e.message).toEqual('Forbidden');
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it('require ability decorator', async () => {
|
|
304
|
+
const { bob } = await makeUsers();
|
|
305
|
+
|
|
306
|
+
await tilmeld.fillSession(bob);
|
|
307
|
+
|
|
308
|
+
const bobsEntity = await TestModel.factory();
|
|
309
|
+
bobsEntity.name = "Bob's Entity";
|
|
310
|
+
await bobsEntity.$save();
|
|
311
|
+
|
|
312
|
+
try {
|
|
313
|
+
bobsEntity.$testRequireAbilityDecorator();
|
|
314
|
+
|
|
315
|
+
throw new Error('Should have thrown.');
|
|
316
|
+
} catch (e: any) {
|
|
317
|
+
expect(e).toBeInstanceOf(HttpError);
|
|
318
|
+
expect(e.status).toEqual(403);
|
|
319
|
+
expect(e.message).toEqual('Forbidden');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
await bobsEntity.$testRequireAbilityDecoratorAsync();
|
|
324
|
+
|
|
325
|
+
throw new Error('Should have thrown.');
|
|
326
|
+
} catch (e: any) {
|
|
327
|
+
expect(e).toBeInstanceOf(HttpError);
|
|
328
|
+
expect(e.status).toEqual(403);
|
|
329
|
+
expect(e.message).toEqual('Forbidden');
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
tilmeld.clearSession();
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
bobsEntity.$testRequireAbilityDecorator();
|
|
336
|
+
|
|
337
|
+
throw new Error('Should have thrown.');
|
|
338
|
+
} catch (e: any) {
|
|
339
|
+
expect(e).toBeInstanceOf(HttpError);
|
|
340
|
+
expect(e.status).toEqual(403);
|
|
341
|
+
expect(e.message).toEqual('Forbidden');
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
try {
|
|
345
|
+
await bobsEntity.$testRequireAbilityDecoratorAsync();
|
|
346
|
+
|
|
347
|
+
throw new Error('Should have thrown.');
|
|
348
|
+
} catch (e: any) {
|
|
349
|
+
expect(e).toBeInstanceOf(HttpError);
|
|
350
|
+
expect(e.status).toEqual(403);
|
|
351
|
+
expect(e.message).toEqual('Forbidden');
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
bob.$grant('test-ability');
|
|
355
|
+
await tilmeld.fillSession(bob);
|
|
356
|
+
|
|
357
|
+
expect(bobsEntity.$testRequireAbilityDecorator()).toEqual(true);
|
|
358
|
+
expect(await bobsEntity.$testRequireAbilityDecoratorAsync()).toEqual(
|
|
359
|
+
true,
|
|
360
|
+
);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("alice can't access an entity owned by bob", async () => {
|
|
364
|
+
const { bob, alice } = await makeUsers();
|
|
365
|
+
|
|
366
|
+
await tilmeld.fillSession(bob);
|
|
367
|
+
|
|
368
|
+
const bobsEntity = await TestModel.factory();
|
|
369
|
+
bobsEntity.name = "Bob's Entity";
|
|
370
|
+
await bobsEntity.$save();
|
|
371
|
+
|
|
372
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
373
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
374
|
+
|
|
375
|
+
const testEntityBob = await nymph.getEntity(
|
|
376
|
+
{ class: TestModel },
|
|
377
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
expect(testEntityBob).not.toBeNull();
|
|
381
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
382
|
+
|
|
383
|
+
tilmeld.clearSession();
|
|
384
|
+
await tilmeld.fillSession(alice);
|
|
385
|
+
|
|
386
|
+
const testEntityAlice = await nymph.getEntity(
|
|
387
|
+
{ class: TestModel },
|
|
388
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
expect(testEntityAlice).toBeNull();
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
it("alice can't write to an entity she doesn't have write permission for", async () => {
|
|
395
|
+
const { bob, alice } = await makeUsers();
|
|
396
|
+
|
|
397
|
+
await tilmeld.fillSession(bob);
|
|
398
|
+
|
|
399
|
+
const bobsEntity = await TestModel.factory();
|
|
400
|
+
bobsEntity.name = "Bob's Entity";
|
|
401
|
+
bobsEntity.acRead = [alice.guid ?? ''];
|
|
402
|
+
await bobsEntity.$save();
|
|
403
|
+
|
|
404
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
405
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
406
|
+
|
|
407
|
+
const testEntityBob = await nymph.getEntity(
|
|
408
|
+
{ class: TestModel },
|
|
409
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
expect(testEntityBob).not.toBeNull();
|
|
413
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
414
|
+
|
|
415
|
+
tilmeld.clearSession();
|
|
416
|
+
await tilmeld.fillSession(alice);
|
|
417
|
+
|
|
418
|
+
const testEntityAlice = await nymph.getEntity(
|
|
419
|
+
{ class: TestModel },
|
|
420
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
421
|
+
);
|
|
422
|
+
|
|
423
|
+
expect(testEntityAlice).not.toBeNull();
|
|
424
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
425
|
+
|
|
426
|
+
if (testEntityAlice == null) {
|
|
427
|
+
throw new Error();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
testEntityAlice.name = "Haha! It's mine now!";
|
|
431
|
+
try {
|
|
432
|
+
await testEntityAlice.$save();
|
|
433
|
+
throw new Error('It should have thrown AccessControlError.');
|
|
434
|
+
} catch (e: any) {
|
|
435
|
+
expect(e).toBeInstanceOf(AccessControlError);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
439
|
+
expect(testEntityAlice.name).toEqual("Bob's Entity");
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
it('alice can write to an entity she has write permission for', async () => {
|
|
443
|
+
const { bob, alice } = await makeUsers();
|
|
444
|
+
|
|
445
|
+
await tilmeld.fillSession(bob);
|
|
446
|
+
|
|
447
|
+
const bobsEntity = await TestModel.factory();
|
|
448
|
+
bobsEntity.name = "Bob's Entity";
|
|
449
|
+
bobsEntity.acWrite = [alice.guid ?? ''];
|
|
450
|
+
await bobsEntity.$save();
|
|
451
|
+
|
|
452
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
453
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
454
|
+
|
|
455
|
+
const testEntityBob = await nymph.getEntity(
|
|
456
|
+
{ class: TestModel },
|
|
457
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
expect(testEntityBob).not.toBeNull();
|
|
461
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
462
|
+
|
|
463
|
+
tilmeld.clearSession();
|
|
464
|
+
await tilmeld.fillSession(alice);
|
|
465
|
+
|
|
466
|
+
const testEntityAlice = await nymph.getEntity(
|
|
467
|
+
{ class: TestModel },
|
|
468
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
expect(testEntityAlice).not.toBeNull();
|
|
472
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
473
|
+
|
|
474
|
+
if (testEntityAlice == null) {
|
|
475
|
+
throw new Error();
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
testEntityAlice.name = "Haha! It's mine now!";
|
|
479
|
+
await testEntityAlice.$save();
|
|
480
|
+
|
|
481
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
482
|
+
expect(testEntityAlice.name).toEqual("Haha! It's mine now!");
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it("alice can't delete an entity she doesn't have full permission for", async () => {
|
|
486
|
+
const { bob, alice } = await makeUsers();
|
|
487
|
+
|
|
488
|
+
await tilmeld.fillSession(bob);
|
|
489
|
+
|
|
490
|
+
const bobsEntity = await TestModel.factory();
|
|
491
|
+
bobsEntity.name = "Bob's Entity";
|
|
492
|
+
bobsEntity.acWrite = [alice.guid ?? ''];
|
|
493
|
+
await bobsEntity.$save();
|
|
494
|
+
|
|
495
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
496
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
497
|
+
|
|
498
|
+
const testEntityBob = await nymph.getEntity(
|
|
499
|
+
{ class: TestModel },
|
|
500
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
501
|
+
);
|
|
502
|
+
|
|
503
|
+
expect(testEntityBob).not.toBeNull();
|
|
504
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
505
|
+
|
|
506
|
+
tilmeld.clearSession();
|
|
507
|
+
await tilmeld.fillSession(alice);
|
|
508
|
+
|
|
509
|
+
const testEntityAlice = await nymph.getEntity(
|
|
510
|
+
{ class: TestModel },
|
|
511
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
512
|
+
);
|
|
513
|
+
|
|
514
|
+
expect(testEntityAlice).not.toBeNull();
|
|
515
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
516
|
+
|
|
517
|
+
if (testEntityAlice == null) {
|
|
518
|
+
throw new Error();
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
try {
|
|
522
|
+
await testEntityAlice.$delete();
|
|
523
|
+
throw new Error('It should have thrown AccessControlError.');
|
|
524
|
+
} catch (e: any) {
|
|
525
|
+
expect(e).toBeInstanceOf(AccessControlError);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
529
|
+
expect(testEntityAlice.guid).toEqual(bobsEntity.guid);
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it('alice can delete an entity she has full permission for', async () => {
|
|
533
|
+
const { bob, alice } = await makeUsers();
|
|
534
|
+
|
|
535
|
+
await tilmeld.fillSession(bob);
|
|
536
|
+
|
|
537
|
+
const bobsEntity = await TestModel.factory();
|
|
538
|
+
bobsEntity.name = "Bob's Entity";
|
|
539
|
+
bobsEntity.acFull = [alice.guid ?? ''];
|
|
540
|
+
await bobsEntity.$save();
|
|
541
|
+
|
|
542
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
543
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
544
|
+
|
|
545
|
+
const testEntityBob = await nymph.getEntity(
|
|
546
|
+
{ class: TestModel },
|
|
547
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
548
|
+
);
|
|
549
|
+
|
|
550
|
+
expect(testEntityBob).not.toBeNull();
|
|
551
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
552
|
+
|
|
553
|
+
tilmeld.clearSession();
|
|
554
|
+
await tilmeld.fillSession(alice);
|
|
555
|
+
|
|
556
|
+
const testEntityAlice = await nymph.getEntity(
|
|
557
|
+
{ class: TestModel },
|
|
558
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
559
|
+
);
|
|
560
|
+
|
|
561
|
+
expect(testEntityAlice).not.toBeNull();
|
|
562
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
563
|
+
|
|
564
|
+
if (testEntityAlice == null) {
|
|
565
|
+
throw new Error();
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
await testEntityAlice.$delete();
|
|
569
|
+
const verifyEntityAlice = await nymph.getEntity(
|
|
570
|
+
{ class: TestModel },
|
|
571
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
572
|
+
);
|
|
573
|
+
expect(verifyEntityAlice).toBeNull();
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
it('alice can access an entity her group has permission for', async () => {
|
|
577
|
+
const { bob, alice, abgroup } = await makeUsers();
|
|
578
|
+
|
|
579
|
+
await tilmeld.fillSession(bob);
|
|
580
|
+
|
|
581
|
+
const bobsEntity = await TestModel.factory();
|
|
582
|
+
bobsEntity.name = "Bob's Entity";
|
|
583
|
+
bobsEntity.acRead = [abgroup.guid ?? ''];
|
|
584
|
+
await bobsEntity.$save();
|
|
585
|
+
|
|
586
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
587
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
588
|
+
|
|
589
|
+
const testEntityBob = await nymph.getEntity(
|
|
590
|
+
{ class: TestModel },
|
|
591
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
592
|
+
);
|
|
593
|
+
|
|
594
|
+
expect(testEntityBob).not.toBeNull();
|
|
595
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
596
|
+
|
|
597
|
+
tilmeld.clearSession();
|
|
598
|
+
await tilmeld.fillSession(alice);
|
|
599
|
+
|
|
600
|
+
const testEntityAlice = await nymph.getEntity(
|
|
601
|
+
{ class: TestModel },
|
|
602
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
603
|
+
);
|
|
604
|
+
|
|
605
|
+
expect(testEntityAlice).not.toBeNull();
|
|
606
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
it("alice can't write to an entity her group doesn't have write permission for", async () => {
|
|
610
|
+
const { bob, alice, abgroup } = await makeUsers();
|
|
611
|
+
|
|
612
|
+
await tilmeld.fillSession(bob);
|
|
613
|
+
|
|
614
|
+
const bobsEntity = await TestModel.factory();
|
|
615
|
+
bobsEntity.name = "Bob's Entity";
|
|
616
|
+
bobsEntity.acRead = [abgroup.guid ?? ''];
|
|
617
|
+
await bobsEntity.$save();
|
|
618
|
+
|
|
619
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
620
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
621
|
+
|
|
622
|
+
const testEntityBob = await nymph.getEntity(
|
|
623
|
+
{ class: TestModel },
|
|
624
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
expect(testEntityBob).not.toBeNull();
|
|
628
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
629
|
+
|
|
630
|
+
tilmeld.clearSession();
|
|
631
|
+
await tilmeld.fillSession(alice);
|
|
632
|
+
|
|
633
|
+
const testEntityAlice = await nymph.getEntity(
|
|
634
|
+
{ class: TestModel },
|
|
635
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
expect(testEntityAlice).not.toBeNull();
|
|
639
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
640
|
+
|
|
641
|
+
if (testEntityAlice == null) {
|
|
642
|
+
throw new Error();
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
testEntityAlice.name = "Haha! It's mine now!";
|
|
646
|
+
try {
|
|
647
|
+
await testEntityAlice.$save();
|
|
648
|
+
throw new Error('It should have thrown AccessControlError.');
|
|
649
|
+
} catch (e: any) {
|
|
650
|
+
expect(e).toBeInstanceOf(AccessControlError);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
654
|
+
expect(testEntityAlice.name).toEqual("Bob's Entity");
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
it('alice can write to an entity her group has write permission for', async () => {
|
|
658
|
+
const { bob, alice, abgroup } = await makeUsers();
|
|
659
|
+
|
|
660
|
+
await tilmeld.fillSession(bob);
|
|
661
|
+
|
|
662
|
+
const bobsEntity = await TestModel.factory();
|
|
663
|
+
bobsEntity.name = "Bob's Entity";
|
|
664
|
+
bobsEntity.acWrite = [abgroup.guid ?? ''];
|
|
665
|
+
await bobsEntity.$save();
|
|
666
|
+
|
|
667
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
668
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
669
|
+
|
|
670
|
+
const testEntityBob = await nymph.getEntity(
|
|
671
|
+
{ class: TestModel },
|
|
672
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
expect(testEntityBob).not.toBeNull();
|
|
676
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
677
|
+
|
|
678
|
+
tilmeld.clearSession();
|
|
679
|
+
await tilmeld.fillSession(alice);
|
|
680
|
+
|
|
681
|
+
const testEntityAlice = await nymph.getEntity(
|
|
682
|
+
{ class: TestModel },
|
|
683
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
684
|
+
);
|
|
685
|
+
|
|
686
|
+
expect(testEntityAlice).not.toBeNull();
|
|
687
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
688
|
+
|
|
689
|
+
if (testEntityAlice == null) {
|
|
690
|
+
throw new Error();
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
testEntityAlice.name = "Haha! It's mine now!";
|
|
694
|
+
await testEntityAlice.$save();
|
|
695
|
+
|
|
696
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
697
|
+
expect(testEntityAlice.name).toEqual("Haha! It's mine now!");
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
it("alice can't delete an entity her group doesn't have full permission for", async () => {
|
|
701
|
+
const { bob, alice, abgroup } = await makeUsers();
|
|
702
|
+
|
|
703
|
+
await tilmeld.fillSession(bob);
|
|
704
|
+
|
|
705
|
+
const bobsEntity = await TestModel.factory();
|
|
706
|
+
bobsEntity.name = "Bob's Entity";
|
|
707
|
+
bobsEntity.acWrite = [abgroup.guid ?? ''];
|
|
708
|
+
await bobsEntity.$save();
|
|
709
|
+
|
|
710
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
711
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
712
|
+
|
|
713
|
+
const testEntityBob = await nymph.getEntity(
|
|
714
|
+
{ class: TestModel },
|
|
715
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
716
|
+
);
|
|
717
|
+
|
|
718
|
+
expect(testEntityBob).not.toBeNull();
|
|
719
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
720
|
+
|
|
721
|
+
tilmeld.clearSession();
|
|
722
|
+
await tilmeld.fillSession(alice);
|
|
723
|
+
|
|
724
|
+
const testEntityAlice = await nymph.getEntity(
|
|
725
|
+
{ class: TestModel },
|
|
726
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
727
|
+
);
|
|
728
|
+
|
|
729
|
+
expect(testEntityAlice).not.toBeNull();
|
|
730
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
731
|
+
|
|
732
|
+
if (testEntityAlice == null) {
|
|
733
|
+
throw new Error();
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
try {
|
|
737
|
+
await testEntityAlice.$delete();
|
|
738
|
+
throw new Error('It should have thrown AccessControlError.');
|
|
739
|
+
} catch (e: any) {
|
|
740
|
+
expect(e).toBeInstanceOf(AccessControlError);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
744
|
+
expect(testEntityAlice.guid).toEqual(bobsEntity.guid);
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it('alice can delete an entity her group has full permission for', async () => {
|
|
748
|
+
const { bob, alice, abgroup } = await makeUsers();
|
|
749
|
+
|
|
750
|
+
await tilmeld.fillSession(bob);
|
|
751
|
+
|
|
752
|
+
const bobsEntity = await TestModel.factory();
|
|
753
|
+
bobsEntity.name = "Bob's Entity";
|
|
754
|
+
bobsEntity.acFull = [abgroup.guid ?? ''];
|
|
755
|
+
await bobsEntity.$save();
|
|
756
|
+
|
|
757
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
758
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
759
|
+
|
|
760
|
+
const testEntityBob = await nymph.getEntity(
|
|
761
|
+
{ class: TestModel },
|
|
762
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
763
|
+
);
|
|
764
|
+
|
|
765
|
+
expect(testEntityBob).not.toBeNull();
|
|
766
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
767
|
+
|
|
768
|
+
tilmeld.clearSession();
|
|
769
|
+
await tilmeld.fillSession(alice);
|
|
770
|
+
|
|
771
|
+
const testEntityAlice = await nymph.getEntity(
|
|
772
|
+
{ class: TestModel },
|
|
773
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
774
|
+
);
|
|
775
|
+
|
|
776
|
+
expect(testEntityAlice).not.toBeNull();
|
|
777
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
778
|
+
|
|
779
|
+
if (testEntityAlice == null) {
|
|
780
|
+
throw new Error();
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
await testEntityAlice.$delete();
|
|
784
|
+
const verifyEntityAlice = await nymph.getEntity(
|
|
785
|
+
{ class: TestModel },
|
|
786
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
787
|
+
);
|
|
788
|
+
expect(verifyEntityAlice).toBeNull();
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
it('alice can access an entity her primary group has permission for', async () => {
|
|
792
|
+
const { bob, alice } = await makeUsers();
|
|
793
|
+
|
|
794
|
+
await tilmeld.fillSession(bob);
|
|
795
|
+
|
|
796
|
+
const bobsEntity = await TestModel.factory();
|
|
797
|
+
bobsEntity.name = "Bob's Entity";
|
|
798
|
+
bobsEntity.group = alice.group;
|
|
799
|
+
await bobsEntity.$save();
|
|
800
|
+
|
|
801
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
802
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
803
|
+
|
|
804
|
+
const testEntityBob = await nymph.getEntity(
|
|
805
|
+
{ class: TestModel },
|
|
806
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
807
|
+
);
|
|
808
|
+
|
|
809
|
+
expect(testEntityBob).not.toBeNull();
|
|
810
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
811
|
+
|
|
812
|
+
tilmeld.clearSession();
|
|
813
|
+
await tilmeld.fillSession(alice);
|
|
814
|
+
|
|
815
|
+
const testEntityAlice = await nymph.getEntity(
|
|
816
|
+
{ class: TestModel },
|
|
817
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
818
|
+
);
|
|
819
|
+
|
|
820
|
+
expect(testEntityAlice).not.toBeNull();
|
|
821
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
it("alice can't write to an entity her primary group doesn't have write permission for", async () => {
|
|
825
|
+
const { bob, alice } = await makeUsers();
|
|
826
|
+
|
|
827
|
+
await tilmeld.fillSession(bob);
|
|
828
|
+
|
|
829
|
+
const bobsEntity = await TestModel.factory();
|
|
830
|
+
bobsEntity.name = "Bob's Entity";
|
|
831
|
+
bobsEntity.group = alice.group;
|
|
832
|
+
await bobsEntity.$save();
|
|
833
|
+
|
|
834
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
835
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
836
|
+
|
|
837
|
+
const testEntityBob = await nymph.getEntity(
|
|
838
|
+
{ class: TestModel },
|
|
839
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
840
|
+
);
|
|
841
|
+
|
|
842
|
+
expect(testEntityBob).not.toBeNull();
|
|
843
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
844
|
+
|
|
845
|
+
tilmeld.clearSession();
|
|
846
|
+
await tilmeld.fillSession(alice);
|
|
847
|
+
|
|
848
|
+
const testEntityAlice = await nymph.getEntity(
|
|
849
|
+
{ class: TestModel },
|
|
850
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
851
|
+
);
|
|
852
|
+
|
|
853
|
+
expect(testEntityAlice).not.toBeNull();
|
|
854
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
855
|
+
|
|
856
|
+
if (testEntityAlice == null) {
|
|
857
|
+
throw new Error();
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
testEntityAlice.name = "Haha! It's mine now!";
|
|
861
|
+
try {
|
|
862
|
+
await testEntityAlice.$save();
|
|
863
|
+
throw new Error('It should have thrown AccessControlError.');
|
|
864
|
+
} catch (e: any) {
|
|
865
|
+
expect(e).toBeInstanceOf(AccessControlError);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
869
|
+
expect(testEntityAlice.name).toEqual("Bob's Entity");
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
it('alice can write to an entity her primary group has write permission for', async () => {
|
|
873
|
+
const { bob, alice } = await makeUsers();
|
|
874
|
+
|
|
875
|
+
await tilmeld.fillSession(bob);
|
|
876
|
+
|
|
877
|
+
const bobsEntity = await TestModel.factory();
|
|
878
|
+
bobsEntity.name = "Bob's Entity";
|
|
879
|
+
bobsEntity.group = alice.group;
|
|
880
|
+
bobsEntity.acGroup = TilmeldAccessLevels.WRITE_ACCESS;
|
|
881
|
+
await bobsEntity.$save();
|
|
882
|
+
|
|
883
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
884
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
885
|
+
|
|
886
|
+
const testEntityBob = await nymph.getEntity(
|
|
887
|
+
{ class: TestModel },
|
|
888
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
889
|
+
);
|
|
890
|
+
|
|
891
|
+
expect(testEntityBob).not.toBeNull();
|
|
892
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
893
|
+
|
|
894
|
+
tilmeld.clearSession();
|
|
895
|
+
await tilmeld.fillSession(alice);
|
|
896
|
+
|
|
897
|
+
const testEntityAlice = await nymph.getEntity(
|
|
898
|
+
{ class: TestModel },
|
|
899
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
900
|
+
);
|
|
901
|
+
|
|
902
|
+
expect(testEntityAlice).not.toBeNull();
|
|
903
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
904
|
+
|
|
905
|
+
if (testEntityAlice == null) {
|
|
906
|
+
throw new Error();
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
testEntityAlice.name = "Haha! It's mine now!";
|
|
910
|
+
await testEntityAlice.$save();
|
|
911
|
+
|
|
912
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
913
|
+
expect(testEntityAlice.name).toEqual("Haha! It's mine now!");
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
it("alice can't delete an entity her primary group doesn't have full permission for", async () => {
|
|
917
|
+
const { bob, alice } = await makeUsers();
|
|
918
|
+
|
|
919
|
+
await tilmeld.fillSession(bob);
|
|
920
|
+
|
|
921
|
+
const bobsEntity = await TestModel.factory();
|
|
922
|
+
bobsEntity.name = "Bob's Entity";
|
|
923
|
+
bobsEntity.group = alice.group;
|
|
924
|
+
bobsEntity.acGroup = TilmeldAccessLevels.WRITE_ACCESS;
|
|
925
|
+
await bobsEntity.$save();
|
|
926
|
+
|
|
927
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
928
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
929
|
+
|
|
930
|
+
const testEntityBob = await nymph.getEntity(
|
|
931
|
+
{ class: TestModel },
|
|
932
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
933
|
+
);
|
|
934
|
+
|
|
935
|
+
expect(testEntityBob).not.toBeNull();
|
|
936
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
937
|
+
|
|
938
|
+
tilmeld.clearSession();
|
|
939
|
+
await tilmeld.fillSession(alice);
|
|
940
|
+
|
|
941
|
+
const testEntityAlice = await nymph.getEntity(
|
|
942
|
+
{ class: TestModel },
|
|
943
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
944
|
+
);
|
|
945
|
+
|
|
946
|
+
expect(testEntityAlice).not.toBeNull();
|
|
947
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
948
|
+
|
|
949
|
+
if (testEntityAlice == null) {
|
|
950
|
+
throw new Error();
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
try {
|
|
954
|
+
await testEntityAlice.$delete();
|
|
955
|
+
throw new Error('It should have thrown AccessControlError.');
|
|
956
|
+
} catch (e: any) {
|
|
957
|
+
expect(e).toBeInstanceOf(AccessControlError);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
961
|
+
expect(testEntityAlice.guid).toEqual(bobsEntity.guid);
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
it('alice can delete an entity her primary group has full permission for', async () => {
|
|
965
|
+
const { bob, alice } = await makeUsers();
|
|
966
|
+
|
|
967
|
+
await tilmeld.fillSession(bob);
|
|
968
|
+
|
|
969
|
+
const bobsEntity = await TestModel.factory();
|
|
970
|
+
bobsEntity.name = "Bob's Entity";
|
|
971
|
+
bobsEntity.group = alice.group;
|
|
972
|
+
bobsEntity.acGroup = TilmeldAccessLevels.FULL_ACCESS;
|
|
973
|
+
await bobsEntity.$save();
|
|
974
|
+
|
|
975
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
976
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
977
|
+
|
|
978
|
+
const testEntityBob = await nymph.getEntity(
|
|
979
|
+
{ class: TestModel },
|
|
980
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
981
|
+
);
|
|
982
|
+
|
|
983
|
+
expect(testEntityBob).not.toBeNull();
|
|
984
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
985
|
+
|
|
986
|
+
tilmeld.clearSession();
|
|
987
|
+
await tilmeld.fillSession(alice);
|
|
988
|
+
|
|
989
|
+
const testEntityAlice = await nymph.getEntity(
|
|
990
|
+
{ class: TestModel },
|
|
991
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
992
|
+
);
|
|
993
|
+
|
|
994
|
+
expect(testEntityAlice).not.toBeNull();
|
|
995
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
996
|
+
|
|
997
|
+
if (testEntityAlice == null) {
|
|
998
|
+
throw new Error();
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
await testEntityAlice.$delete();
|
|
1002
|
+
const verifyEntityAlice = await nymph.getEntity(
|
|
1003
|
+
{ class: TestModel },
|
|
1004
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1005
|
+
);
|
|
1006
|
+
expect(verifyEntityAlice).toBeNull();
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
it('alice can access an entity everyone has permission for', async () => {
|
|
1010
|
+
const { bob, alice } = await makeUsers();
|
|
1011
|
+
|
|
1012
|
+
await tilmeld.fillSession(bob);
|
|
1013
|
+
|
|
1014
|
+
const bobsEntity = await TestModel.factory();
|
|
1015
|
+
bobsEntity.name = "Bob's Entity";
|
|
1016
|
+
bobsEntity.acOther = TilmeldAccessLevels.READ_ACCESS;
|
|
1017
|
+
await bobsEntity.$save();
|
|
1018
|
+
|
|
1019
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1020
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1021
|
+
|
|
1022
|
+
const testEntityBob = await nymph.getEntity(
|
|
1023
|
+
{ class: TestModel },
|
|
1024
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1025
|
+
);
|
|
1026
|
+
|
|
1027
|
+
expect(testEntityBob).not.toBeNull();
|
|
1028
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1029
|
+
|
|
1030
|
+
tilmeld.clearSession();
|
|
1031
|
+
await tilmeld.fillSession(alice);
|
|
1032
|
+
|
|
1033
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1034
|
+
{ class: TestModel },
|
|
1035
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1036
|
+
);
|
|
1037
|
+
|
|
1038
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1039
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
it("alice can't write to an entity everyone doesn't have write permission for", async () => {
|
|
1043
|
+
const { bob, alice } = await makeUsers();
|
|
1044
|
+
|
|
1045
|
+
await tilmeld.fillSession(bob);
|
|
1046
|
+
|
|
1047
|
+
const bobsEntity = await TestModel.factory();
|
|
1048
|
+
bobsEntity.name = "Bob's Entity";
|
|
1049
|
+
bobsEntity.acOther = TilmeldAccessLevels.READ_ACCESS;
|
|
1050
|
+
await bobsEntity.$save();
|
|
1051
|
+
|
|
1052
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1053
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1054
|
+
|
|
1055
|
+
const testEntityBob = await nymph.getEntity(
|
|
1056
|
+
{ class: TestModel },
|
|
1057
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1058
|
+
);
|
|
1059
|
+
|
|
1060
|
+
expect(testEntityBob).not.toBeNull();
|
|
1061
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1062
|
+
|
|
1063
|
+
tilmeld.clearSession();
|
|
1064
|
+
await tilmeld.fillSession(alice);
|
|
1065
|
+
|
|
1066
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1067
|
+
{ class: TestModel },
|
|
1068
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1069
|
+
);
|
|
1070
|
+
|
|
1071
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1072
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1073
|
+
|
|
1074
|
+
if (testEntityAlice == null) {
|
|
1075
|
+
throw new Error();
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
testEntityAlice.name = "Haha! It's mine now!";
|
|
1079
|
+
try {
|
|
1080
|
+
await testEntityAlice.$save();
|
|
1081
|
+
throw new Error('It should have thrown AccessControlError.');
|
|
1082
|
+
} catch (e: any) {
|
|
1083
|
+
expect(e).toBeInstanceOf(AccessControlError);
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
1087
|
+
expect(testEntityAlice.name).toEqual("Bob's Entity");
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
it('alice can write to an entity everyone has write permission for', async () => {
|
|
1091
|
+
const { bob, alice } = await makeUsers();
|
|
1092
|
+
|
|
1093
|
+
await tilmeld.fillSession(bob);
|
|
1094
|
+
|
|
1095
|
+
const bobsEntity = await TestModel.factory();
|
|
1096
|
+
bobsEntity.name = "Bob's Entity";
|
|
1097
|
+
bobsEntity.acOther = TilmeldAccessLevels.WRITE_ACCESS;
|
|
1098
|
+
await bobsEntity.$save();
|
|
1099
|
+
|
|
1100
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1101
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1102
|
+
|
|
1103
|
+
const testEntityBob = await nymph.getEntity(
|
|
1104
|
+
{ class: TestModel },
|
|
1105
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1106
|
+
);
|
|
1107
|
+
|
|
1108
|
+
expect(testEntityBob).not.toBeNull();
|
|
1109
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1110
|
+
|
|
1111
|
+
tilmeld.clearSession();
|
|
1112
|
+
await tilmeld.fillSession(alice);
|
|
1113
|
+
|
|
1114
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1115
|
+
{ class: TestModel },
|
|
1116
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1117
|
+
);
|
|
1118
|
+
|
|
1119
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1120
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1121
|
+
|
|
1122
|
+
if (testEntityAlice == null) {
|
|
1123
|
+
throw new Error();
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
testEntityAlice.name = "Haha! It's mine now!";
|
|
1127
|
+
await testEntityAlice.$save();
|
|
1128
|
+
|
|
1129
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
1130
|
+
expect(testEntityAlice.name).toEqual("Haha! It's mine now!");
|
|
1131
|
+
});
|
|
1132
|
+
|
|
1133
|
+
it("alice can't delete an entity everyone doesn't have full permission for", async () => {
|
|
1134
|
+
const { bob, alice } = await makeUsers();
|
|
1135
|
+
|
|
1136
|
+
await tilmeld.fillSession(bob);
|
|
1137
|
+
|
|
1138
|
+
const bobsEntity = await TestModel.factory();
|
|
1139
|
+
bobsEntity.name = "Bob's Entity";
|
|
1140
|
+
bobsEntity.acOther = TilmeldAccessLevels.WRITE_ACCESS;
|
|
1141
|
+
await bobsEntity.$save();
|
|
1142
|
+
|
|
1143
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1144
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1145
|
+
|
|
1146
|
+
const testEntityBob = await nymph.getEntity(
|
|
1147
|
+
{ class: TestModel },
|
|
1148
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1149
|
+
);
|
|
1150
|
+
|
|
1151
|
+
expect(testEntityBob).not.toBeNull();
|
|
1152
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1153
|
+
|
|
1154
|
+
tilmeld.clearSession();
|
|
1155
|
+
await tilmeld.fillSession(alice);
|
|
1156
|
+
|
|
1157
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1158
|
+
{ class: TestModel },
|
|
1159
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1160
|
+
);
|
|
1161
|
+
|
|
1162
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1163
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1164
|
+
|
|
1165
|
+
if (testEntityAlice == null) {
|
|
1166
|
+
throw new Error();
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
try {
|
|
1170
|
+
await testEntityAlice.$delete();
|
|
1171
|
+
throw new Error('It should have thrown AccessControlError.');
|
|
1172
|
+
} catch (e: any) {
|
|
1173
|
+
expect(e).toBeInstanceOf(AccessControlError);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
expect(await testEntityAlice.$refresh()).toEqual(true);
|
|
1177
|
+
expect(testEntityAlice.guid).toEqual(bobsEntity.guid);
|
|
1178
|
+
});
|
|
1179
|
+
|
|
1180
|
+
it('alice can delete an entity everyone has full permission for', async () => {
|
|
1181
|
+
const { bob, alice } = await makeUsers();
|
|
1182
|
+
|
|
1183
|
+
await tilmeld.fillSession(bob);
|
|
1184
|
+
|
|
1185
|
+
const bobsEntity = await TestModel.factory();
|
|
1186
|
+
bobsEntity.name = "Bob's Entity";
|
|
1187
|
+
bobsEntity.acOther = TilmeldAccessLevels.FULL_ACCESS;
|
|
1188
|
+
await bobsEntity.$save();
|
|
1189
|
+
|
|
1190
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1191
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1192
|
+
|
|
1193
|
+
const testEntityBob = await nymph.getEntity(
|
|
1194
|
+
{ class: TestModel },
|
|
1195
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1196
|
+
);
|
|
1197
|
+
|
|
1198
|
+
expect(testEntityBob).not.toBeNull();
|
|
1199
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1200
|
+
|
|
1201
|
+
tilmeld.clearSession();
|
|
1202
|
+
await tilmeld.fillSession(alice);
|
|
1203
|
+
|
|
1204
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1205
|
+
{ class: TestModel },
|
|
1206
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1207
|
+
);
|
|
1208
|
+
|
|
1209
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1210
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1211
|
+
|
|
1212
|
+
if (testEntityAlice == null) {
|
|
1213
|
+
throw new Error();
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
await testEntityAlice.$delete();
|
|
1217
|
+
const verifyEntityAlice = await nymph.getEntity(
|
|
1218
|
+
{ class: TestModel },
|
|
1219
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1220
|
+
);
|
|
1221
|
+
expect(verifyEntityAlice).toBeNull();
|
|
1222
|
+
});
|
|
1223
|
+
|
|
1224
|
+
it('a clear session can delete an entity everyone has full permission for', async () => {
|
|
1225
|
+
const { bob } = await makeUsers();
|
|
1226
|
+
|
|
1227
|
+
await tilmeld.fillSession(bob);
|
|
1228
|
+
|
|
1229
|
+
const bobsEntity = await TestModel.factory();
|
|
1230
|
+
bobsEntity.name = "Bob's Entity";
|
|
1231
|
+
bobsEntity.acOther = TilmeldAccessLevels.FULL_ACCESS;
|
|
1232
|
+
await bobsEntity.$save();
|
|
1233
|
+
|
|
1234
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1235
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1236
|
+
|
|
1237
|
+
const testEntityBob = await nymph.getEntity(
|
|
1238
|
+
{ class: TestModel },
|
|
1239
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1240
|
+
);
|
|
1241
|
+
|
|
1242
|
+
expect(testEntityBob).not.toBeNull();
|
|
1243
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1244
|
+
|
|
1245
|
+
tilmeld.clearSession();
|
|
1246
|
+
|
|
1247
|
+
const testEntityNobody = await nymph.getEntity(
|
|
1248
|
+
{ class: TestModel },
|
|
1249
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1250
|
+
);
|
|
1251
|
+
|
|
1252
|
+
expect(testEntityNobody).not.toBeNull();
|
|
1253
|
+
expect(testEntityNobody?.guid).toEqual(bobsEntity.guid);
|
|
1254
|
+
|
|
1255
|
+
if (testEntityNobody == null) {
|
|
1256
|
+
throw new Error();
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
await testEntityNobody.$delete();
|
|
1260
|
+
const verifyEntityNobody = await nymph.getEntity(
|
|
1261
|
+
{ class: TestModel },
|
|
1262
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1263
|
+
);
|
|
1264
|
+
expect(verifyEntityNobody).toBeNull();
|
|
1265
|
+
});
|
|
1266
|
+
|
|
1267
|
+
it('allows skip ac deletions', async () => {
|
|
1268
|
+
const allEntities = [
|
|
1269
|
+
...(await nymph.getEntities({ class: TestModel, skipAc: true })),
|
|
1270
|
+
...(await nymph.getEntities({ class: User, skipAc: true })),
|
|
1271
|
+
...(await nymph.getEntities({ class: Group, skipAc: true })),
|
|
1272
|
+
];
|
|
1273
|
+
for (let entity of allEntities) {
|
|
1274
|
+
await entity.$deleteSkipAC();
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
|
|
1278
|
+
it('entity can be retrieved by queries on ac properties', async () => {
|
|
1279
|
+
const { bob, alice } = await makeUsers();
|
|
1280
|
+
|
|
1281
|
+
await tilmeld.fillSession(bob);
|
|
1282
|
+
|
|
1283
|
+
const bobsEntity = await TestModel.factory();
|
|
1284
|
+
bobsEntity.name = "Bob's Entity";
|
|
1285
|
+
bobsEntity.acRead = [
|
|
1286
|
+
alice.guid ?? '',
|
|
1287
|
+
bob.guid ?? '',
|
|
1288
|
+
...(bob.group ? [bob.group.guid ?? ''] : []),
|
|
1289
|
+
];
|
|
1290
|
+
bobsEntity.acWrite = [alice.guid ?? '', bob.guid ?? ''];
|
|
1291
|
+
bobsEntity.acFull = [bob.guid ?? ''];
|
|
1292
|
+
await bobsEntity.$save();
|
|
1293
|
+
|
|
1294
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1295
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1296
|
+
|
|
1297
|
+
const testEntityBob = await nymph.getEntity(
|
|
1298
|
+
{ class: TestModel },
|
|
1299
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1300
|
+
);
|
|
1301
|
+
|
|
1302
|
+
expect(testEntityBob).not.toBeNull();
|
|
1303
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1304
|
+
|
|
1305
|
+
tilmeld.clearSession();
|
|
1306
|
+
await tilmeld.fillSession(alice);
|
|
1307
|
+
|
|
1308
|
+
// Equals queries.
|
|
1309
|
+
|
|
1310
|
+
let testEntityAlice = await nymph.getEntity(
|
|
1311
|
+
{ class: TestModel },
|
|
1312
|
+
{
|
|
1313
|
+
type: '&',
|
|
1314
|
+
guid: bobsEntity.guid || '',
|
|
1315
|
+
equal: ['user', bob.guid],
|
|
1316
|
+
},
|
|
1317
|
+
);
|
|
1318
|
+
|
|
1319
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1320
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1321
|
+
|
|
1322
|
+
testEntityAlice = await nymph.getEntity(
|
|
1323
|
+
{ class: TestModel },
|
|
1324
|
+
{
|
|
1325
|
+
type: '&',
|
|
1326
|
+
guid: bobsEntity.guid || '',
|
|
1327
|
+
equal: ['user', '000000000000000000000000'],
|
|
1328
|
+
},
|
|
1329
|
+
);
|
|
1330
|
+
|
|
1331
|
+
expect(testEntityAlice).toBeNull();
|
|
1332
|
+
|
|
1333
|
+
testEntityAlice = await nymph.getEntity(
|
|
1334
|
+
{ class: TestModel },
|
|
1335
|
+
{
|
|
1336
|
+
type: '&',
|
|
1337
|
+
guid: bobsEntity.guid || '',
|
|
1338
|
+
equal: ['group', bob.group?.guid],
|
|
1339
|
+
},
|
|
1340
|
+
);
|
|
1341
|
+
|
|
1342
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1343
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1344
|
+
|
|
1345
|
+
testEntityAlice = await nymph.getEntity(
|
|
1346
|
+
{ class: TestModel },
|
|
1347
|
+
{
|
|
1348
|
+
type: '&',
|
|
1349
|
+
guid: bobsEntity.guid || '',
|
|
1350
|
+
equal: ['group', '000000000000000000000000'],
|
|
1351
|
+
},
|
|
1352
|
+
);
|
|
1353
|
+
|
|
1354
|
+
expect(testEntityAlice).toBeNull();
|
|
1355
|
+
|
|
1356
|
+
// Contains queries.
|
|
1357
|
+
|
|
1358
|
+
testEntityAlice = await nymph.getEntity(
|
|
1359
|
+
{ class: TestModel },
|
|
1360
|
+
{
|
|
1361
|
+
type: '&',
|
|
1362
|
+
guid: bobsEntity.guid || '',
|
|
1363
|
+
contain: ['user', bob.guid],
|
|
1364
|
+
},
|
|
1365
|
+
);
|
|
1366
|
+
|
|
1367
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1368
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1369
|
+
|
|
1370
|
+
testEntityAlice = await nymph.getEntity(
|
|
1371
|
+
{ class: TestModel },
|
|
1372
|
+
{
|
|
1373
|
+
type: '&',
|
|
1374
|
+
guid: bobsEntity.guid || '',
|
|
1375
|
+
contain: ['user', '000000000000000000000000'],
|
|
1376
|
+
},
|
|
1377
|
+
);
|
|
1378
|
+
|
|
1379
|
+
expect(testEntityAlice).toBeNull();
|
|
1380
|
+
|
|
1381
|
+
testEntityAlice = await nymph.getEntity(
|
|
1382
|
+
{ class: TestModel },
|
|
1383
|
+
{
|
|
1384
|
+
type: '&',
|
|
1385
|
+
guid: bobsEntity.guid || '',
|
|
1386
|
+
contain: ['group', bob.group?.guid],
|
|
1387
|
+
},
|
|
1388
|
+
);
|
|
1389
|
+
|
|
1390
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1391
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1392
|
+
|
|
1393
|
+
testEntityAlice = await nymph.getEntity(
|
|
1394
|
+
{ class: TestModel },
|
|
1395
|
+
{
|
|
1396
|
+
type: '&',
|
|
1397
|
+
guid: bobsEntity.guid || '',
|
|
1398
|
+
contain: ['group', '000000000000000000000000'],
|
|
1399
|
+
},
|
|
1400
|
+
);
|
|
1401
|
+
|
|
1402
|
+
expect(testEntityAlice).toBeNull();
|
|
1403
|
+
|
|
1404
|
+
testEntityAlice = await nymph.getEntity(
|
|
1405
|
+
{ class: TestModel },
|
|
1406
|
+
{
|
|
1407
|
+
type: '&',
|
|
1408
|
+
guid: bobsEntity.guid || '',
|
|
1409
|
+
contain: ['acRead', alice.guid],
|
|
1410
|
+
},
|
|
1411
|
+
);
|
|
1412
|
+
|
|
1413
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1414
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1415
|
+
|
|
1416
|
+
testEntityAlice = await nymph.getEntity(
|
|
1417
|
+
{ class: TestModel },
|
|
1418
|
+
{
|
|
1419
|
+
type: '&',
|
|
1420
|
+
guid: bobsEntity.guid || '',
|
|
1421
|
+
contain: ['acRead', '000000000000000000000000'],
|
|
1422
|
+
},
|
|
1423
|
+
);
|
|
1424
|
+
|
|
1425
|
+
expect(testEntityAlice).toBeNull();
|
|
1426
|
+
|
|
1427
|
+
testEntityAlice = await nymph.getEntity(
|
|
1428
|
+
{ class: TestModel },
|
|
1429
|
+
{
|
|
1430
|
+
type: '&',
|
|
1431
|
+
guid: bobsEntity.guid || '',
|
|
1432
|
+
contain: ['acWrite', bob.guid],
|
|
1433
|
+
},
|
|
1434
|
+
);
|
|
1435
|
+
|
|
1436
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1437
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1438
|
+
|
|
1439
|
+
testEntityAlice = await nymph.getEntity(
|
|
1440
|
+
{ class: TestModel },
|
|
1441
|
+
{
|
|
1442
|
+
type: '&',
|
|
1443
|
+
guid: bobsEntity.guid || '',
|
|
1444
|
+
contain: ['acWrite', '000000000000000000000000'],
|
|
1445
|
+
},
|
|
1446
|
+
);
|
|
1447
|
+
|
|
1448
|
+
expect(testEntityAlice).toBeNull();
|
|
1449
|
+
|
|
1450
|
+
testEntityAlice = await nymph.getEntity(
|
|
1451
|
+
{ class: TestModel },
|
|
1452
|
+
{
|
|
1453
|
+
type: '&',
|
|
1454
|
+
guid: bobsEntity.guid || '',
|
|
1455
|
+
contain: ['acFull', bob.guid],
|
|
1456
|
+
},
|
|
1457
|
+
);
|
|
1458
|
+
|
|
1459
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1460
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1461
|
+
|
|
1462
|
+
testEntityAlice = await nymph.getEntity(
|
|
1463
|
+
{ class: TestModel },
|
|
1464
|
+
{
|
|
1465
|
+
type: '&',
|
|
1466
|
+
guid: bobsEntity.guid || '',
|
|
1467
|
+
contain: ['acFull', '000000000000000000000000'],
|
|
1468
|
+
},
|
|
1469
|
+
);
|
|
1470
|
+
|
|
1471
|
+
expect(testEntityAlice).toBeNull();
|
|
1472
|
+
|
|
1473
|
+
// Ref queries.
|
|
1474
|
+
|
|
1475
|
+
testEntityAlice = await nymph.getEntity(
|
|
1476
|
+
{ class: TestModel },
|
|
1477
|
+
{
|
|
1478
|
+
type: '&',
|
|
1479
|
+
guid: bobsEntity.guid || '',
|
|
1480
|
+
ref: ['user', bob],
|
|
1481
|
+
},
|
|
1482
|
+
);
|
|
1483
|
+
|
|
1484
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1485
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1486
|
+
|
|
1487
|
+
testEntityAlice = await nymph.getEntity(
|
|
1488
|
+
{ class: TestModel },
|
|
1489
|
+
{
|
|
1490
|
+
type: '&',
|
|
1491
|
+
guid: bobsEntity.guid || '',
|
|
1492
|
+
ref: ['user', '000000000000000000000000'],
|
|
1493
|
+
},
|
|
1494
|
+
);
|
|
1495
|
+
|
|
1496
|
+
expect(testEntityAlice).toBeNull();
|
|
1497
|
+
|
|
1498
|
+
testEntityAlice = await nymph.getEntity(
|
|
1499
|
+
{ class: TestModel },
|
|
1500
|
+
{
|
|
1501
|
+
type: '&',
|
|
1502
|
+
guid: bobsEntity.guid || '',
|
|
1503
|
+
ref: ['group', bob.group ?? ''],
|
|
1504
|
+
},
|
|
1505
|
+
);
|
|
1506
|
+
|
|
1507
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1508
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1509
|
+
|
|
1510
|
+
testEntityAlice = await nymph.getEntity(
|
|
1511
|
+
{ class: TestModel },
|
|
1512
|
+
{
|
|
1513
|
+
type: '&',
|
|
1514
|
+
guid: bobsEntity.guid || '',
|
|
1515
|
+
ref: ['group', '000000000000000000000000'],
|
|
1516
|
+
},
|
|
1517
|
+
);
|
|
1518
|
+
|
|
1519
|
+
expect(testEntityAlice).toBeNull();
|
|
1520
|
+
|
|
1521
|
+
testEntityAlice = await nymph.getEntity(
|
|
1522
|
+
{ class: TestModel },
|
|
1523
|
+
{
|
|
1524
|
+
type: '&',
|
|
1525
|
+
guid: bobsEntity.guid || '',
|
|
1526
|
+
ref: ['acRead', alice],
|
|
1527
|
+
},
|
|
1528
|
+
);
|
|
1529
|
+
|
|
1530
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1531
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1532
|
+
|
|
1533
|
+
testEntityAlice = await nymph.getEntity(
|
|
1534
|
+
{ class: TestModel },
|
|
1535
|
+
{
|
|
1536
|
+
type: '&',
|
|
1537
|
+
guid: bobsEntity.guid || '',
|
|
1538
|
+
ref: ['acRead', '000000000000000000000000'],
|
|
1539
|
+
},
|
|
1540
|
+
);
|
|
1541
|
+
|
|
1542
|
+
expect(testEntityAlice).toBeNull();
|
|
1543
|
+
|
|
1544
|
+
testEntityAlice = await nymph.getEntity(
|
|
1545
|
+
{ class: TestModel },
|
|
1546
|
+
{
|
|
1547
|
+
type: '&',
|
|
1548
|
+
guid: bobsEntity.guid || '',
|
|
1549
|
+
ref: ['acWrite', bob],
|
|
1550
|
+
},
|
|
1551
|
+
);
|
|
1552
|
+
|
|
1553
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1554
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1555
|
+
|
|
1556
|
+
testEntityAlice = await nymph.getEntity(
|
|
1557
|
+
{ class: TestModel },
|
|
1558
|
+
{
|
|
1559
|
+
type: '&',
|
|
1560
|
+
guid: bobsEntity.guid || '',
|
|
1561
|
+
ref: ['acWrite', '000000000000000000000000'],
|
|
1562
|
+
},
|
|
1563
|
+
);
|
|
1564
|
+
|
|
1565
|
+
expect(testEntityAlice).toBeNull();
|
|
1566
|
+
|
|
1567
|
+
testEntityAlice = await nymph.getEntity(
|
|
1568
|
+
{ class: TestModel },
|
|
1569
|
+
{
|
|
1570
|
+
type: '&',
|
|
1571
|
+
guid: bobsEntity.guid || '',
|
|
1572
|
+
ref: ['acFull', bob],
|
|
1573
|
+
},
|
|
1574
|
+
);
|
|
1575
|
+
|
|
1576
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1577
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1578
|
+
|
|
1579
|
+
testEntityAlice = await nymph.getEntity(
|
|
1580
|
+
{ class: TestModel },
|
|
1581
|
+
{
|
|
1582
|
+
type: '&',
|
|
1583
|
+
guid: bobsEntity.guid || '',
|
|
1584
|
+
ref: ['acFull', '000000000000000000000000'],
|
|
1585
|
+
},
|
|
1586
|
+
);
|
|
1587
|
+
|
|
1588
|
+
expect(testEntityAlice).toBeNull();
|
|
1589
|
+
|
|
1590
|
+
// QRef queries.
|
|
1591
|
+
|
|
1592
|
+
testEntityAlice = await nymph.getEntity(
|
|
1593
|
+
{ class: TestModel },
|
|
1594
|
+
{
|
|
1595
|
+
type: '&',
|
|
1596
|
+
guid: bobsEntity.guid || '',
|
|
1597
|
+
qref: [
|
|
1598
|
+
'user',
|
|
1599
|
+
[
|
|
1600
|
+
{ class: User },
|
|
1601
|
+
{ type: '&', equal: ['username', bob.username ?? ''] },
|
|
1602
|
+
],
|
|
1603
|
+
],
|
|
1604
|
+
},
|
|
1605
|
+
);
|
|
1606
|
+
|
|
1607
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1608
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1609
|
+
|
|
1610
|
+
testEntityAlice = await nymph.getEntity(
|
|
1611
|
+
{ class: TestModel },
|
|
1612
|
+
{
|
|
1613
|
+
type: '&',
|
|
1614
|
+
guid: bobsEntity.guid || '',
|
|
1615
|
+
qref: [
|
|
1616
|
+
'user',
|
|
1617
|
+
[{ class: User }, { type: '&', equal: ['username', 'pickle'] }],
|
|
1618
|
+
],
|
|
1619
|
+
},
|
|
1620
|
+
);
|
|
1621
|
+
|
|
1622
|
+
expect(testEntityAlice).toBeNull();
|
|
1623
|
+
|
|
1624
|
+
testEntityAlice = await nymph.getEntity(
|
|
1625
|
+
{ class: TestModel },
|
|
1626
|
+
{
|
|
1627
|
+
type: '&',
|
|
1628
|
+
guid: bobsEntity.guid || '',
|
|
1629
|
+
qref: [
|
|
1630
|
+
'acRead',
|
|
1631
|
+
[
|
|
1632
|
+
{ class: User },
|
|
1633
|
+
{ type: '&', equal: ['username', alice.username ?? ''] },
|
|
1634
|
+
],
|
|
1635
|
+
],
|
|
1636
|
+
},
|
|
1637
|
+
);
|
|
1638
|
+
|
|
1639
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1640
|
+
expect(testEntityAlice?.guid).toEqual(bobsEntity.guid);
|
|
1641
|
+
|
|
1642
|
+
testEntityAlice = await nymph.getEntity(
|
|
1643
|
+
{ class: TestModel },
|
|
1644
|
+
{
|
|
1645
|
+
type: '&',
|
|
1646
|
+
guid: bobsEntity.guid || '',
|
|
1647
|
+
qref: [
|
|
1648
|
+
'acRead',
|
|
1649
|
+
[{ class: User }, { type: '&', equal: ['username', 'pickle'] }],
|
|
1650
|
+
],
|
|
1651
|
+
},
|
|
1652
|
+
);
|
|
1653
|
+
|
|
1654
|
+
expect(testEntityAlice).toBeNull();
|
|
1655
|
+
});
|
|
1656
|
+
|
|
1657
|
+
it('alice can access an entity with an access request', async () => {
|
|
1658
|
+
const { bob, alice } = await makeUsers();
|
|
1659
|
+
|
|
1660
|
+
await tilmeld.fillSession(alice);
|
|
1661
|
+
|
|
1662
|
+
const alicesEntity = await TestModel.factory();
|
|
1663
|
+
alicesEntity.name = "Alice's Entity";
|
|
1664
|
+
await alicesEntity.$save();
|
|
1665
|
+
|
|
1666
|
+
expect(alicesEntity.guid).not.toBeNull();
|
|
1667
|
+
expect(alice.$is(alicesEntity.user)).toEqual(true);
|
|
1668
|
+
|
|
1669
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1670
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_OWNED },
|
|
1671
|
+
{ type: '&', guid: alicesEntity.guid || '' },
|
|
1672
|
+
);
|
|
1673
|
+
|
|
1674
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1675
|
+
expect(testEntityAlice?.guid).toEqual(alicesEntity.guid);
|
|
1676
|
+
|
|
1677
|
+
tilmeld.clearSession();
|
|
1678
|
+
});
|
|
1679
|
+
|
|
1680
|
+
it("access request for user owned doesn't return group owned entity", async () => {
|
|
1681
|
+
const { bob, alice } = await makeUsers();
|
|
1682
|
+
|
|
1683
|
+
await tilmeld.fillSession(bob);
|
|
1684
|
+
|
|
1685
|
+
const bobsEntity = await TestModel.factory();
|
|
1686
|
+
bobsEntity.name = "Bob's Entity";
|
|
1687
|
+
bobsEntity.group = alice.group;
|
|
1688
|
+
await bobsEntity.$save();
|
|
1689
|
+
|
|
1690
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1691
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1692
|
+
|
|
1693
|
+
const testEntityBob = await nymph.getEntity(
|
|
1694
|
+
{ class: TestModel },
|
|
1695
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1696
|
+
);
|
|
1697
|
+
|
|
1698
|
+
expect(testEntityBob).not.toBeNull();
|
|
1699
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1700
|
+
|
|
1701
|
+
tilmeld.clearSession();
|
|
1702
|
+
await tilmeld.fillSession(alice);
|
|
1703
|
+
|
|
1704
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1705
|
+
{ class: TestModel },
|
|
1706
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1707
|
+
);
|
|
1708
|
+
|
|
1709
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1710
|
+
|
|
1711
|
+
const testFailureEntityAlice = await nymph.getEntity(
|
|
1712
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_OWNED },
|
|
1713
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1714
|
+
);
|
|
1715
|
+
|
|
1716
|
+
expect(testFailureEntityAlice).toBeNull();
|
|
1717
|
+
|
|
1718
|
+
const testSuccessEntityAlice = await nymph.getEntity(
|
|
1719
|
+
{
|
|
1720
|
+
class: TestModel,
|
|
1721
|
+
acRequest: TilmeldAccessRequest.PRIMARY_GROUP_OWNED,
|
|
1722
|
+
},
|
|
1723
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1724
|
+
);
|
|
1725
|
+
|
|
1726
|
+
expect(testSuccessEntityAlice).not.toBeNull();
|
|
1727
|
+
});
|
|
1728
|
+
|
|
1729
|
+
it("access request for user owned doesn't return acOther accessible entity", async () => {
|
|
1730
|
+
const { bob, alice } = await makeUsers();
|
|
1731
|
+
|
|
1732
|
+
await tilmeld.fillSession(bob);
|
|
1733
|
+
|
|
1734
|
+
const bobsEntity = await TestModel.factory();
|
|
1735
|
+
bobsEntity.name = "Bob's Entity";
|
|
1736
|
+
bobsEntity.acOther = TilmeldAccessLevels.READ_ACCESS;
|
|
1737
|
+
await bobsEntity.$save();
|
|
1738
|
+
|
|
1739
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1740
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1741
|
+
|
|
1742
|
+
const testEntityBob = await nymph.getEntity(
|
|
1743
|
+
{ class: TestModel },
|
|
1744
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1745
|
+
);
|
|
1746
|
+
|
|
1747
|
+
expect(testEntityBob).not.toBeNull();
|
|
1748
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1749
|
+
|
|
1750
|
+
tilmeld.clearSession();
|
|
1751
|
+
await tilmeld.fillSession(alice);
|
|
1752
|
+
|
|
1753
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1754
|
+
{ class: TestModel },
|
|
1755
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1756
|
+
);
|
|
1757
|
+
|
|
1758
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1759
|
+
|
|
1760
|
+
const testFailureEntityAlice = await nymph.getEntity(
|
|
1761
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_OWNED },
|
|
1762
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1763
|
+
);
|
|
1764
|
+
|
|
1765
|
+
expect(testFailureEntityAlice).toBeNull();
|
|
1766
|
+
|
|
1767
|
+
const testSuccessEntityAlice = await nymph.getEntity(
|
|
1768
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.OTHER_ACCESSIBLE },
|
|
1769
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1770
|
+
);
|
|
1771
|
+
|
|
1772
|
+
expect(testSuccessEntityAlice).not.toBeNull();
|
|
1773
|
+
});
|
|
1774
|
+
|
|
1775
|
+
it("access request for user owned doesn't return user acRead accessible entity", async () => {
|
|
1776
|
+
const { bob, alice } = await makeUsers();
|
|
1777
|
+
|
|
1778
|
+
await tilmeld.fillSession(bob);
|
|
1779
|
+
|
|
1780
|
+
const bobsEntity = await TestModel.factory();
|
|
1781
|
+
bobsEntity.name = "Bob's Entity";
|
|
1782
|
+
bobsEntity.acRead = [alice.guid ?? ''];
|
|
1783
|
+
await bobsEntity.$save();
|
|
1784
|
+
|
|
1785
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1786
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1787
|
+
|
|
1788
|
+
const testEntityBob = await nymph.getEntity(
|
|
1789
|
+
{ class: TestModel },
|
|
1790
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1791
|
+
);
|
|
1792
|
+
|
|
1793
|
+
expect(testEntityBob).not.toBeNull();
|
|
1794
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1795
|
+
|
|
1796
|
+
tilmeld.clearSession();
|
|
1797
|
+
await tilmeld.fillSession(alice);
|
|
1798
|
+
|
|
1799
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1800
|
+
{ class: TestModel },
|
|
1801
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1802
|
+
);
|
|
1803
|
+
|
|
1804
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1805
|
+
|
|
1806
|
+
const testFailureEntityAlice = await nymph.getEntity(
|
|
1807
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_OWNED },
|
|
1808
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1809
|
+
);
|
|
1810
|
+
|
|
1811
|
+
expect(testFailureEntityAlice).toBeNull();
|
|
1812
|
+
|
|
1813
|
+
const testSuccessEntityAlice = await nymph.getEntity(
|
|
1814
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_ACCESSIBLE },
|
|
1815
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1816
|
+
);
|
|
1817
|
+
|
|
1818
|
+
expect(testSuccessEntityAlice).not.toBeNull();
|
|
1819
|
+
});
|
|
1820
|
+
|
|
1821
|
+
it("access request for user owned doesn't return group acRead accessible entity", async () => {
|
|
1822
|
+
const { bob, alice } = await makeUsers();
|
|
1823
|
+
|
|
1824
|
+
await tilmeld.fillSession(bob);
|
|
1825
|
+
|
|
1826
|
+
const bobsEntity = await TestModel.factory();
|
|
1827
|
+
bobsEntity.name = "Bob's Entity";
|
|
1828
|
+
bobsEntity.acWrite = [alice.group?.guid ?? ''];
|
|
1829
|
+
await bobsEntity.$save();
|
|
1830
|
+
|
|
1831
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1832
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1833
|
+
|
|
1834
|
+
const testEntityBob = await nymph.getEntity(
|
|
1835
|
+
{ class: TestModel },
|
|
1836
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1837
|
+
);
|
|
1838
|
+
|
|
1839
|
+
expect(testEntityBob).not.toBeNull();
|
|
1840
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1841
|
+
|
|
1842
|
+
tilmeld.clearSession();
|
|
1843
|
+
await tilmeld.fillSession(alice);
|
|
1844
|
+
|
|
1845
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1846
|
+
{ class: TestModel },
|
|
1847
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1848
|
+
);
|
|
1849
|
+
|
|
1850
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1851
|
+
|
|
1852
|
+
const testFailureEntityAlice = await nymph.getEntity(
|
|
1853
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_OWNED },
|
|
1854
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1855
|
+
);
|
|
1856
|
+
|
|
1857
|
+
expect(testFailureEntityAlice).toBeNull();
|
|
1858
|
+
|
|
1859
|
+
const testSuccessEntityAlice = await nymph.getEntity(
|
|
1860
|
+
{
|
|
1861
|
+
class: TestModel,
|
|
1862
|
+
acRequest: TilmeldAccessRequest.PRIMARY_GROUP_ACCESSIBLE,
|
|
1863
|
+
},
|
|
1864
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1865
|
+
);
|
|
1866
|
+
|
|
1867
|
+
expect(testSuccessEntityAlice).not.toBeNull();
|
|
1868
|
+
});
|
|
1869
|
+
|
|
1870
|
+
it("access request for user owned doesn't return secondary group owned entity", async () => {
|
|
1871
|
+
const { bob, alice, abgroup } = await makeUsers();
|
|
1872
|
+
|
|
1873
|
+
await tilmeld.fillSession(bob);
|
|
1874
|
+
|
|
1875
|
+
const bobsEntity = await TestModel.factory();
|
|
1876
|
+
bobsEntity.name = "Bob's Entity";
|
|
1877
|
+
bobsEntity.group = abgroup;
|
|
1878
|
+
await bobsEntity.$save();
|
|
1879
|
+
|
|
1880
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1881
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1882
|
+
|
|
1883
|
+
const testEntityBob = await nymph.getEntity(
|
|
1884
|
+
{ class: TestModel },
|
|
1885
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1886
|
+
);
|
|
1887
|
+
|
|
1888
|
+
expect(testEntityBob).not.toBeNull();
|
|
1889
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1890
|
+
|
|
1891
|
+
tilmeld.clearSession();
|
|
1892
|
+
await tilmeld.fillSession(alice);
|
|
1893
|
+
|
|
1894
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1895
|
+
{ class: TestModel },
|
|
1896
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1897
|
+
);
|
|
1898
|
+
|
|
1899
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1900
|
+
|
|
1901
|
+
const testFailureEntityAlice = await nymph.getEntity(
|
|
1902
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_OWNED },
|
|
1903
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1904
|
+
);
|
|
1905
|
+
|
|
1906
|
+
expect(testFailureEntityAlice).toBeNull();
|
|
1907
|
+
|
|
1908
|
+
const testSuccessEntityAlice = await nymph.getEntity(
|
|
1909
|
+
{
|
|
1910
|
+
class: TestModel,
|
|
1911
|
+
acRequest: TilmeldAccessRequest.SECONDARY_GROUP_OWNED,
|
|
1912
|
+
},
|
|
1913
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1914
|
+
);
|
|
1915
|
+
|
|
1916
|
+
expect(testSuccessEntityAlice).not.toBeNull();
|
|
1917
|
+
});
|
|
1918
|
+
|
|
1919
|
+
it("access request for user owned doesn't return secondary group accessible entity", async () => {
|
|
1920
|
+
const { bob, alice, abgroup } = await makeUsers();
|
|
1921
|
+
|
|
1922
|
+
await tilmeld.fillSession(bob);
|
|
1923
|
+
|
|
1924
|
+
const bobsEntity = await TestModel.factory();
|
|
1925
|
+
bobsEntity.name = "Bob's Entity";
|
|
1926
|
+
bobsEntity.acFull = [abgroup.guid ?? ''];
|
|
1927
|
+
await bobsEntity.$save();
|
|
1928
|
+
|
|
1929
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1930
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1931
|
+
|
|
1932
|
+
const testEntityBob = await nymph.getEntity(
|
|
1933
|
+
{ class: TestModel },
|
|
1934
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1935
|
+
);
|
|
1936
|
+
|
|
1937
|
+
expect(testEntityBob).not.toBeNull();
|
|
1938
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
1939
|
+
|
|
1940
|
+
tilmeld.clearSession();
|
|
1941
|
+
await tilmeld.fillSession(alice);
|
|
1942
|
+
|
|
1943
|
+
const testEntityAlice = await nymph.getEntity(
|
|
1944
|
+
{ class: TestModel },
|
|
1945
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1946
|
+
);
|
|
1947
|
+
|
|
1948
|
+
expect(testEntityAlice).not.toBeNull();
|
|
1949
|
+
|
|
1950
|
+
const testFailureEntityAlice = await nymph.getEntity(
|
|
1951
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_OWNED },
|
|
1952
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1953
|
+
);
|
|
1954
|
+
|
|
1955
|
+
expect(testFailureEntityAlice).toBeNull();
|
|
1956
|
+
|
|
1957
|
+
const testSuccessEntityAlice = await nymph.getEntity(
|
|
1958
|
+
{
|
|
1959
|
+
class: TestModel,
|
|
1960
|
+
acRequest: TilmeldAccessRequest.SECONDARY_GROUP_ACCESSIBLE,
|
|
1961
|
+
},
|
|
1962
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1963
|
+
);
|
|
1964
|
+
|
|
1965
|
+
expect(testSuccessEntityAlice).not.toBeNull();
|
|
1966
|
+
|
|
1967
|
+
// Test or-ing two levels together.
|
|
1968
|
+
const testSuccessEntityAlice2 = await nymph.getEntity(
|
|
1969
|
+
{
|
|
1970
|
+
class: TestModel,
|
|
1971
|
+
acRequest:
|
|
1972
|
+
TilmeldAccessRequest.SECONDARY_GROUP_ACCESSIBLE |
|
|
1973
|
+
TilmeldAccessRequest.PRIMARY_GROUP_ACCESSIBLE,
|
|
1974
|
+
},
|
|
1975
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1976
|
+
);
|
|
1977
|
+
|
|
1978
|
+
expect(testSuccessEntityAlice2).not.toBeNull();
|
|
1979
|
+
});
|
|
1980
|
+
|
|
1981
|
+
it('access request for entity still works when filtering user owned entities manually', async () => {
|
|
1982
|
+
const { bob, alice } = await makeUsers();
|
|
1983
|
+
|
|
1984
|
+
await tilmeld.fillSession(bob);
|
|
1985
|
+
|
|
1986
|
+
const bobsEntity = await TestModel.factory();
|
|
1987
|
+
bobsEntity.name = "Bob's Entity";
|
|
1988
|
+
bobsEntity.acFull = [alice.guid ?? ''];
|
|
1989
|
+
await bobsEntity.$save();
|
|
1990
|
+
|
|
1991
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
1992
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
1993
|
+
|
|
1994
|
+
const testEntityBob = await nymph.getEntity(
|
|
1995
|
+
{ class: TestModel },
|
|
1996
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
1997
|
+
);
|
|
1998
|
+
|
|
1999
|
+
expect(testEntityBob).not.toBeNull();
|
|
2000
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
2001
|
+
|
|
2002
|
+
tilmeld.clearSession();
|
|
2003
|
+
await tilmeld.fillSession(alice);
|
|
2004
|
+
|
|
2005
|
+
const alicesEntity = await TestModel.factory();
|
|
2006
|
+
alicesEntity.name = "Alice's Entity";
|
|
2007
|
+
await alicesEntity.$save();
|
|
2008
|
+
|
|
2009
|
+
expect(alicesEntity.guid).not.toBeNull();
|
|
2010
|
+
expect(alice.$is(alicesEntity.user)).toEqual(true);
|
|
2011
|
+
|
|
2012
|
+
const testEntityAlice = await nymph.getEntity(
|
|
2013
|
+
{ class: TestModel },
|
|
2014
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
2015
|
+
);
|
|
2016
|
+
|
|
2017
|
+
expect(testEntityAlice).not.toBeNull();
|
|
2018
|
+
|
|
2019
|
+
const testWithoutFiltering = await nymph.getEntities(
|
|
2020
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.USER_OWNED },
|
|
2021
|
+
{ type: '|', guid: [alicesEntity.guid || '', bobsEntity.guid || ''] },
|
|
2022
|
+
);
|
|
2023
|
+
|
|
2024
|
+
expect(testWithoutFiltering.length).toEqual(1);
|
|
2025
|
+
expect(testWithoutFiltering[0].guid).toEqual(alicesEntity?.guid || '');
|
|
2026
|
+
|
|
2027
|
+
const testWithFiltering = await nymph.getEntities(
|
|
2028
|
+
{
|
|
2029
|
+
class: TestModel,
|
|
2030
|
+
acRequest: TilmeldAccessRequest.USER_OWNED,
|
|
2031
|
+
},
|
|
2032
|
+
{ type: '|', guid: [alicesEntity.guid || '', bobsEntity.guid || ''] },
|
|
2033
|
+
{ type: '!&', ref: ['user', alice] },
|
|
2034
|
+
);
|
|
2035
|
+
|
|
2036
|
+
expect(testWithFiltering.length).toEqual(0);
|
|
2037
|
+
|
|
2038
|
+
const testInclusive = await nymph.getEntities({ class: TestModel });
|
|
2039
|
+
|
|
2040
|
+
const testInclusiveWithFiltering = await nymph.getEntities(
|
|
2041
|
+
{ class: TestModel },
|
|
2042
|
+
{ type: '!&', ref: ['user', alice] },
|
|
2043
|
+
);
|
|
2044
|
+
|
|
2045
|
+
expect(testInclusiveWithFiltering.length).toBeGreaterThanOrEqual(1);
|
|
2046
|
+
const guids = testInclusiveWithFiltering.map((entity) => entity.guid);
|
|
2047
|
+
expect(guids).not.toContain(alicesEntity?.guid || '');
|
|
2048
|
+
expect(guids).toContain(bobsEntity?.guid || '');
|
|
2049
|
+
|
|
2050
|
+
const allDefaultGuids = testInclusive.map((entity) => entity.guid);
|
|
2051
|
+
for (let guid of guids) {
|
|
2052
|
+
expect(allDefaultGuids).toContain(guid);
|
|
2053
|
+
}
|
|
2054
|
+
});
|
|
2055
|
+
|
|
2056
|
+
it("access request for invalid access control doesn't return any inaccessible entities", async () => {
|
|
2057
|
+
const { bob, alice, abgroup } = await makeUsers();
|
|
2058
|
+
|
|
2059
|
+
await tilmeld.fillSession(bob);
|
|
2060
|
+
|
|
2061
|
+
const bobsEntity = await TestModel.factory();
|
|
2062
|
+
bobsEntity.name = "Bob's Entity";
|
|
2063
|
+
await bobsEntity.$save();
|
|
2064
|
+
|
|
2065
|
+
expect(bobsEntity.guid).not.toBeNull();
|
|
2066
|
+
expect(bob.$is(bobsEntity.user)).toEqual(true);
|
|
2067
|
+
|
|
2068
|
+
const testEntityBob = await nymph.getEntity(
|
|
2069
|
+
{ class: TestModel },
|
|
2070
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
2071
|
+
);
|
|
2072
|
+
|
|
2073
|
+
expect(testEntityBob).not.toBeNull();
|
|
2074
|
+
expect(testEntityBob?.guid).toEqual(bobsEntity.guid);
|
|
2075
|
+
|
|
2076
|
+
tilmeld.clearSession();
|
|
2077
|
+
await tilmeld.fillSession(alice);
|
|
2078
|
+
|
|
2079
|
+
const testEntityAlice = await nymph.getEntity(
|
|
2080
|
+
{ class: TestModel },
|
|
2081
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
2082
|
+
);
|
|
2083
|
+
|
|
2084
|
+
expect(testEntityAlice).toBeNull();
|
|
2085
|
+
|
|
2086
|
+
const testFailureEntityAlice = await nymph.getEntity(
|
|
2087
|
+
{ class: TestModel, acRequest: TilmeldAccessRequest.UNOWNED * 2 },
|
|
2088
|
+
{ type: '&', guid: bobsEntity.guid || '' },
|
|
2089
|
+
);
|
|
2090
|
+
|
|
2091
|
+
expect(testFailureEntityAlice).toBeNull();
|
|
2092
|
+
});
|
|
2093
|
+
|
|
2094
|
+
it('delete test data again', async () => {
|
|
2095
|
+
await deleteTestData();
|
|
2096
|
+
});
|
|
2097
|
+
});
|
|
2098
|
+
}
|