@@ -13,6 +13,7 @@ import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messag
13
13
import { getExperimentsClientForBackend } from "@gitpod/gitpod-protocol/lib/experiments/configcat-server" ;
14
14
import { v1 } from "@authzed/authzed-node" ;
15
15
import { fgaRelationsUpdateClientLatency } from "../prometheus-metrics" ;
16
+ import { RedisMutex } from "../redis/mutex" ;
16
17
17
18
@injectable ( )
18
19
export class RelationshipUpdater {
@@ -23,6 +24,7 @@ export class RelationshipUpdater {
23
24
@inject ( TeamDB ) private readonly orgDB : TeamDB ,
24
25
@inject ( ProjectDB ) private readonly projectDB : ProjectDB ,
25
26
@inject ( Authorizer ) private readonly authorizer : Authorizer ,
27
+ @inject ( RedisMutex ) private readonly mutex : RedisMutex ,
26
28
) { }
27
29
28
30
/**
@@ -42,6 +44,12 @@ export class RelationshipUpdater {
42
44
} ,
43
45
} ) ;
44
46
if ( ! fgaEnabled ) {
47
+ if ( user . additionalData ?. fgaRelationshipsVersion !== undefined ) {
48
+ log . info ( { userId : user . id } , `User has been removed from FGA.` ) ;
49
+ // reset the fgaRelationshipsVersion to undefined, so the migration is triggered again when the feature is enabled
50
+ AdditionalUserData . set ( user , { fgaRelationshipsVersion : undefined } ) ;
51
+ return await this . userDB . storeUser ( user ) ;
52
+ }
45
53
return user ;
46
54
}
47
55
if ( user . additionalData ?. fgaRelationshipsVersion === this . version ) {
@@ -53,41 +61,40 @@ export class RelationshipUpdater {
53
61
fromVersion : user ?. additionalData ?. fgaRelationshipsVersion ,
54
62
toVersion : this . version ,
55
63
} ) ;
56
- // TODO run in distributed lock
57
- // return this.mutex.using([`fga-migration-${user.id}`], 2000, async () => {
58
- const before = new Date ( ) . getTime ( ) ;
64
+ return this . mutex . using ( [ `fga-migration-${ user . id } ` ] , 2000 , async ( ) => {
65
+ const before = new Date ( ) . getTime ( ) ;
59
66
60
- const updatedUser = await this . userDB . findUserById ( user . id ) ;
61
- if ( ! updatedUser ) {
62
- throw new ApplicationError ( ErrorCodes . NOT_FOUND , "User not found" ) ;
63
- }
64
- user = updatedUser ;
65
- if ( user . additionalData ?. fgaRelationshipsVersion === this . version ) {
66
- return user ;
67
- }
68
- log . info ( { userId : user . id } , `Updating FGA relationships for user.` , {
69
- fromVersion : user ?. additionalData ?. fgaRelationshipsVersion ,
70
- toVersion : this . version ,
71
- } ) ;
72
- const orgs = await this . findAffectedOrganizations ( user . id ) ;
67
+ const updatedUser = await this . userDB . findUserById ( user . id ) ;
68
+ if ( ! updatedUser ) {
69
+ throw new ApplicationError ( ErrorCodes . NOT_FOUND , "User not found" ) ;
70
+ }
71
+ user = updatedUser ;
72
+ if ( user . additionalData ?. fgaRelationshipsVersion === this . version ) {
73
+ return user ;
74
+ }
75
+ log . info ( { userId : user . id } , `Updating FGA relationships for user.` , {
76
+ fromVersion : user ?. additionalData ?. fgaRelationshipsVersion ,
77
+ toVersion : this . version ,
78
+ } ) ;
79
+ const orgs = await this . findAffectedOrganizations ( user . id ) ;
73
80
74
- // Add relationships
75
- await this . updateUser ( user ) ;
76
- for ( const org of orgs ) {
77
- await this . updateOrganization ( user . id , org ) ;
78
- }
79
- AdditionalUserData . set ( user , {
80
- fgaRelationshipsVersion : this . version ,
81
- } ) ;
82
- await this . userDB . updateUserPartial ( {
83
- id : user . id ,
84
- additionalData : user . additionalData ,
85
- } ) ;
86
- log . info ( { userId : user . id } , `Finished updating relationships.` , {
87
- duration : new Date ( ) . getTime ( ) - before ,
81
+ // Add relationships
82
+ await this . updateUser ( user ) ;
83
+ for ( const org of orgs ) {
84
+ await this . updateOrganization ( user . id , org ) ;
85
+ }
86
+ AdditionalUserData . set ( user , {
87
+ fgaRelationshipsVersion : this . version ,
88
+ } ) ;
89
+ await this . userDB . updateUserPartial ( {
90
+ id : user . id ,
91
+ additionalData : user . additionalData ,
92
+ } ) ;
93
+ log . info ( { userId : user . id } , `Finished updating relationships.` , {
94
+ duration : new Date ( ) . getTime ( ) - before ,
95
+ } ) ;
96
+ return user ;
88
97
} ) ;
89
- return user ;
90
- // });
91
98
} catch ( error ) {
92
99
log . error ( { userId : user . id } , `Error updating relationships.` , error ) ;
93
100
return user ;
0 commit comments