Skip to content

Commit 79c87eb

Browse files
authored
Merge pull request #3431 from SeedCompany/neo4j/current-user
2 parents fe182c8 + 4b841a0 commit 79c87eb

File tree

44 files changed

+209
-293
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+209
-293
lines changed

.eslintrc.cjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,17 @@ const config = {
198198
],
199199
// TODO Enable this and fix errors (both types & logic changes will be needed)
200200
'@typescript-eslint/no-unnecessary-condition': 'off',
201+
202+
// Allow unused session while we migrate
203+
'@seedcompany/no-unused-vars': [
204+
'warn',
205+
{
206+
args: 'after-used',
207+
ignoreRestSiblings: true,
208+
argsIgnorePattern: '(^_|^session$)',
209+
varsIgnorePattern: '^_',
210+
},
211+
],
201212
},
202213
overrides: [
203214
{

src/components/authentication/authentication.repository.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { type ID, ServerException, type Session } from '~/common';
55
import { DatabaseService, DbTraceLayer, OnIndex } from '~/core/database';
66
import {
77
ACTIVE,
8+
currentUser,
89
matchUserGloballyScopedRoles,
9-
requestingUser,
1010
variable,
1111
} from '~/core/database/query';
1212
import { type ScopedRole } from '../authorization/dto';
@@ -226,7 +226,7 @@ export class AuthenticationRepository {
226226
const result = await this.db
227227
.query()
228228
.match([
229-
requestingUser(session),
229+
currentUser,
230230
relation('out', '', 'password', ACTIVE),
231231
node('password', 'Property'),
232232
])
@@ -243,7 +243,7 @@ export class AuthenticationRepository {
243243
await this.db
244244
.query()
245245
.match([
246-
requestingUser(session),
246+
currentUser,
247247
relation('out', '', 'password', ACTIVE),
248248
node('password', 'Property'),
249249
])
@@ -331,7 +331,7 @@ export class AuthenticationRepository {
331331
await this.db
332332
.query()
333333
.match([
334-
requestingUser(session),
334+
currentUser,
335335
relation('out', 'oldRel', 'token', ACTIVE),
336336
node('token', 'Token'),
337337
])

src/components/authorization/policies/conditions/creator.condition.ts

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Logger } from '@nestjs/common';
2-
import { type Query } from 'cypher-query-builder';
32
import { inspect, type InspectOptionsStylized } from 'util';
43
import {
54
type ID,
@@ -11,14 +10,11 @@ import {
1110
} from '~/common';
1211
import { type LinkTo } from '~/core/resources';
1312
import {
14-
type AsCypherParams,
1513
type Condition,
1614
type IsAllowedParams,
1715
MissingContextException,
1816
} from '../../policy/conditions';
1917

20-
const CQL_VAR = 'requestingUser';
21-
2218
export interface HasCreator {
2319
creator: MaybeSecuredProp<ID | LinkTo<'User'>>;
2420
}
@@ -49,24 +45,8 @@ class CreatorCondition<TResourceStatic extends ResourceShape<HasCreator>>
4945
return creator === session.userId;
5046
}
5147

52-
setupCypherContext(
53-
query: Query,
54-
prevApplied: Set<any>,
55-
other: AsCypherParams<TResourceStatic>,
56-
) {
57-
if (prevApplied.has('creator')) {
58-
return query;
59-
}
60-
prevApplied.add('creator');
61-
62-
const param = query.params.addParam(other.session.userId, CQL_VAR);
63-
Reflect.set(other, CQL_VAR, param);
64-
65-
return query;
66-
}
67-
68-
asCypherCondition(_query: Query, other: AsCypherParams<TResourceStatic>) {
69-
const requester = String(Reflect.get(other, CQL_VAR));
48+
asCypherCondition() {
49+
const requester = '$currentUser';
7050
return [
7151
`node.creator = ${requester}`,
7252
`exists((node)-[:creator { active: true }]->(:Property { value: ${requester} }))`,

src/components/authorization/policies/conditions/member.condition.ts

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import { type Query } from 'cypher-query-builder';
22
import { intersection } from 'lodash';
33
import { inspect, type InspectOptionsStylized } from 'util';
44
import { type ResourceShape, type Role } from '~/common';
5-
import { matchProjectScopedRoles, variable } from '~/core/database/query';
5+
import { matchProjectScopedRoles } from '~/core/database/query';
66
import { rolesForScope, type ScopedRole, splitScope } from '../../dto/role.dto';
77
import {
8-
type AsCypherParams,
98
type AsEdgeQLParams,
109
type Condition,
1110
eqlDoesIntersect,
@@ -32,24 +31,8 @@ class MemberCondition<TResourceStatic extends ResourceWithScope>
3231
return getScope(object).includes('member:true');
3332
}
3433

35-
setupCypherContext(
36-
query: Query,
37-
prevApplied: Set<any>,
38-
other: AsCypherParams<TResourceStatic>,
39-
) {
40-
if (prevApplied.has('membership')) {
41-
return query;
42-
}
43-
prevApplied.add('membership');
44-
45-
const param = query.params.addParam(other.session.userId, 'requestingUser');
46-
Reflect.set(other, CQL_VAR, param);
47-
return query;
48-
}
49-
50-
asCypherCondition(query: Query, other: AsCypherParams<TResourceStatic>) {
51-
const requester = String(Reflect.get(other, CQL_VAR));
52-
return `exists((project)-[:member { active: true }]->(:ProjectMember)-[:user]->(:User { id: ${requester} }))`;
34+
asCypherCondition() {
35+
return 'exists((project)-[:member { active: true }]->(:ProjectMember)-[:user]->(:User { id: $currentUser }))';
5336
}
5437

5538
setupEdgeQLContext({
@@ -101,7 +84,6 @@ class MemberWithRolesCondition<TResourceStatic extends ResourceWithScope>
10184

10285
return query.apply(
10386
matchProjectScopedRoles({
104-
session: variable('requestingUser'),
10587
outputVar: CQL_VAR,
10688
}),
10789
);

src/components/authorization/policies/conditions/self.condition.ts

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1-
import { type Query } from 'cypher-query-builder';
21
import { inspect, type InspectOptionsStylized } from 'util';
32
import { type User } from '../../../user/dto';
43
import {
5-
type AsCypherParams,
64
type AsEdgeQLParams,
75
type Condition,
86
fqnRelativeTo,
97
type IsAllowedParams,
108
MissingContextException,
119
} from '../../policy/conditions';
1210

13-
const CQL_VAR = 'requestingUser';
14-
1511
class SelfCondition<TResourceStatic extends typeof User>
1612
implements Condition<TResourceStatic>
1713
{
@@ -22,25 +18,8 @@ class SelfCondition<TResourceStatic extends typeof User>
2218
return object.id === session.userId;
2319
}
2420

25-
setupCypherContext(
26-
query: Query,
27-
prevApplied: Set<any>,
28-
other: AsCypherParams<TResourceStatic>,
29-
) {
30-
if (prevApplied.has('self')) {
31-
return query;
32-
}
33-
prevApplied.add('self');
34-
35-
const param = query.params.addParam(other.session.userId, CQL_VAR);
36-
Reflect.set(other, CQL_VAR, param);
37-
38-
return query;
39-
}
40-
41-
asCypherCondition(_query: Query, other: AsCypherParams<TResourceStatic>) {
42-
const requester = String(Reflect.get(other, CQL_VAR));
43-
return `node:User AND node.id = ${requester}`;
21+
asCypherCondition() {
22+
return 'node:User AND node.id = $currentUser';
4423
}
4524

4625
asEdgeQLCondition({ namespace }: AsEdgeQLParams<any>) {

src/components/budget/budget-record.repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ export class BudgetRecordRepository extends DtoRepository<
177177
node('organization', 'Organization'),
178178
])
179179
.apply(matchChangesetAndChangedProps(view?.changeset))
180-
.apply(matchPropsAndProjectSensAndScopedRoles(session, { view }))
180+
.apply(matchPropsAndProjectSensAndScopedRoles({ view }))
181181
.return<{ dto: UnsecuredDto<BudgetRecord> }>(
182182
merge('props', 'changedProps', {
183183
parent: 'budget',

src/components/budget/budget.repository.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {
2222
merge,
2323
oncePerProject,
2424
paginate,
25-
requestingUser,
2625
sorting,
2726
} from '~/core/database/query';
2827
import { type FileId } from '../file/dto';
@@ -90,7 +89,7 @@ export class BudgetRepository extends DtoRepository<
9089
node('node', label),
9190
])
9291
.where({ 'node.id': inArray(ids) })
93-
.apply(matchPropsAndProjectSensAndScopedRoles(session, { view }))
92+
.apply(matchPropsAndProjectSensAndScopedRoles({ view }))
9493
.apply(matchChangesetAndChangedProps(view?.changeset))
9594
.return<{ dto: UnsecuredDto<Budget> }>(
9695
merge('props', 'changedProps', {
@@ -110,7 +109,6 @@ export class BudgetRepository extends DtoRepository<
110109
relation('in', '', 'budget', ACTIVE),
111110
node('project', 'Project', pickBy({ id: filter?.projectId })),
112111
])
113-
.match(requestingUser(session))
114112
.apply(
115113
this.privileges.forUser(session).filterToReadable({
116114
wrapContext: oncePerProject,

src/components/ceremony/ceremony.repository.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
matchPropsAndProjectSensAndScopedRoles,
1414
oncePerProject,
1515
paginate,
16-
requestingUser,
1716
sorting,
1817
} from '~/core/database/query';
1918
import {
@@ -64,7 +63,7 @@ export class CeremonyRepository extends DtoRepository<
6463
relation('out', '', ACTIVE),
6564
node('node'),
6665
])
67-
.apply(matchPropsAndProjectSensAndScopedRoles(session))
66+
.apply(matchPropsAndProjectSensAndScopedRoles())
6867
.return<{ dto: UnsecuredDto<Ceremony> }>('props as dto');
6968
}
7069

@@ -84,7 +83,6 @@ export class CeremonyRepository extends DtoRepository<
8483
]
8584
: []),
8685
])
87-
.match(requestingUser(session))
8886
.apply(
8987
this.privileges.forUser(session).filterToReadable({
9088
wrapContext: oncePerProject,

src/components/comments/comment-thread.repository.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import {
66
ACTIVE,
77
createNode,
88
createRelationships,
9+
currentUser,
910
merge,
1011
paginate,
11-
requestingUser,
1212
sorting,
1313
} from '~/core/database/query';
1414
import { CommentRepository } from './comment.repository';
@@ -31,7 +31,7 @@ export class CommentThreadRepository extends DtoRepository(CommentThread) {
3131
.apply(
3232
createRelationships(CommentThread, {
3333
in: { commentThread: ['BaseNode', parent] },
34-
out: { creator: ['User', session.userId] },
34+
out: { creator: currentUser },
3535
}),
3636
)
3737
.return('node as thread');
@@ -83,7 +83,6 @@ export class CommentThreadRepository extends DtoRepository(CommentThread) {
8383
) {
8484
const result = await this.db
8585
.query()
86-
.match(requestingUser(session))
8786
.match([
8887
node('node', 'CommentThread'),
8988
...(parent

src/components/comments/comment.repository.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import {
88
ACTIVE,
99
createNode,
1010
createRelationships,
11+
currentUser,
1112
matchProps,
1213
merge,
1314
paginate,
14-
requestingUser,
1515
sorting,
1616
variable,
1717
} from '~/core/database/query';
@@ -51,7 +51,7 @@ export class CommentRepository extends DtoRepository(Comment) {
5151
.apply(
5252
createRelationships(Comment, {
5353
in: { comment: variable('thread') },
54-
out: { creator: ['User', session.userId] },
54+
out: { creator: currentUser },
5555
}),
5656
)
5757
.return<{ id: ID; threadId: ID }>([
@@ -92,7 +92,6 @@ export class CommentRepository extends DtoRepository(Comment) {
9292
async list(threadId: ID, input: CommentListInput, session: Session) {
9393
const result = await this.db
9494
.query()
95-
.match(requestingUser(session))
9695
.match([
9796
node('thread', 'CommentThread', { id: threadId }),
9897
relation('out', '', 'comment', ACTIVE),

0 commit comments

Comments
 (0)