@@ -8,13 +8,22 @@ import { inject, injectable } from "inversify";
8
8
import { Config } from "../config" ;
9
9
import { UserDB } from "@gitpod/gitpod-db/lib" ;
10
10
import { Authorizer } from "../authorization/authorizer" ;
11
- import { AdditionalUserData , Identity , TokenEntry , User } from "@gitpod/gitpod-protocol" ;
11
+ import {
12
+ AdditionalUserData ,
13
+ Identity ,
14
+ RoleOrPermission ,
15
+ TokenEntry ,
16
+ User ,
17
+ WorkspaceTimeoutDuration ,
18
+ WorkspaceTimeoutSetting ,
19
+ } from "@gitpod/gitpod-protocol" ;
12
20
import { ApplicationError , ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error" ;
13
21
import { log } from "@gitpod/gitpod-protocol/lib/util/logging" ;
14
22
import { CreateUserParams } from "./user-authentication" ;
15
23
import { IAnalyticsWriter } from "@gitpod/gitpod-protocol/lib/analytics" ;
16
24
import { TransactionalContext } from "@gitpod/gitpod-db/lib/typeorm/transactional-db-impl" ;
17
25
import { RelationshipUpdater } from "../authorization/relationship-updater" ;
26
+ import { EntitlementService } from "../billing/entitlement-service" ;
18
27
19
28
@injectable ( )
20
29
export class UserService {
@@ -24,6 +33,7 @@ export class UserService {
24
33
@inject ( Authorizer ) private readonly authorizer : Authorizer ,
25
34
@inject ( IAnalyticsWriter ) private readonly analytics : IAnalyticsWriter ,
26
35
@inject ( RelationshipUpdater ) private readonly relationshipUpdater : RelationshipUpdater ,
36
+ @inject ( EntitlementService ) private readonly entitlementService : EntitlementService ,
27
37
) { }
28
38
29
39
public async createUser (
@@ -124,34 +134,104 @@ export class UserService {
124
134
return user ;
125
135
}
126
136
127
- async setAdminRole ( userId : string , targetUserId : string , admin : boolean ) : Promise < User > {
128
- await this . authorizer . checkPermissionOnUser ( userId , "make_admin" , targetUserId ) ;
129
- const target = await this . findUserById ( userId , targetUserId ) ;
130
- const rolesAndPermissions = target . rolesOrPermissions || [ ] ;
131
- const newRoles = [ ...rolesAndPermissions . filter ( ( r ) => r !== "admin" ) ] ;
132
- if ( admin ) {
133
- // add admin role
134
- newRoles . push ( "admin" ) ;
137
+ async updateWorkspaceTimeoutSetting (
138
+ userId : string ,
139
+ targetUserId : string ,
140
+ setting : Partial < WorkspaceTimeoutSetting > ,
141
+ ) : Promise < void > {
142
+ await this . authorizer . checkPermissionOnUser ( userId , "write_info" , targetUserId ) ;
143
+
144
+ if ( setting . workspaceTimeout ) {
145
+ try {
146
+ WorkspaceTimeoutDuration . validate ( setting . workspaceTimeout ) ;
147
+ } catch ( err ) {
148
+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , err . message ) ;
149
+ }
135
150
}
136
151
152
+ if ( ! ( await this . entitlementService . maySetTimeout ( targetUserId ) ) ) {
153
+ throw new ApplicationError (
154
+ ErrorCodes . PERMISSION_DENIED ,
155
+ "Configure workspace timeout only available for paid user." ,
156
+ ) ;
157
+ }
158
+
159
+ const user = await this . findUserById ( userId , targetUserId ) ;
160
+ AdditionalUserData . set ( user , setting ) ;
161
+ await this . userDb . updateUserPartial ( user ) ;
162
+ }
163
+
164
+ async listUsers (
165
+ userId : string ,
166
+ req : {
167
+ //
168
+ offset ?: number ;
169
+ limit ?: number ;
170
+ orderBy ?: keyof User ;
171
+ orderDir ?: "ASC" | "DESC" ;
172
+ searchTerm ?: string ;
173
+ } ,
174
+ ) : Promise < { total : number ; rows : User [ ] } > {
137
175
try {
138
- return await this . userDb . transaction ( async ( userDb ) => {
139
- target . rolesOrPermissions = newRoles ;
140
- const updatedUser = await userDb . storeUser ( target ) ;
141
- if ( admin ) {
142
- await this . authorizer . addInstallationAdminRole ( target . id ) ;
176
+ const res = await this . userDb . findAllUsers (
177
+ req . offset || 0 ,
178
+ req . limit || 100 ,
179
+ req . orderBy || "creationDate" ,
180
+ req . orderDir || "DESC" ,
181
+ req . searchTerm ,
182
+ ) ;
183
+ const result = { total : res . total , rows : [ ] as User [ ] } ;
184
+ for ( const user of res . rows ) {
185
+ if ( await this . authorizer . hasPermissionOnUser ( userId , "read_info" , user . id ) ) {
186
+ result . rows . push ( user ) ;
143
187
} else {
144
- await this . authorizer . removeInstallationAdminRole ( target . id ) ;
188
+ result . total -- ;
145
189
}
146
- return updatedUser ;
147
- } ) ;
148
- } catch ( err ) {
149
- if ( admin ) {
150
- await this . authorizer . removeInstallationAdminRole ( target . id ) ;
190
+ }
191
+ return result ;
192
+ } catch ( e ) {
193
+ throw new ApplicationError ( ErrorCodes . INTERNAL_SERVER_ERROR , e . toString ( ) ) ;
194
+ }
195
+ }
196
+
197
+ async updateRoleOrPermission (
198
+ userId : string ,
199
+ targetUserId : string ,
200
+ modifications : { role : RoleOrPermission ; add ?: boolean } [ ] ,
201
+ ) : Promise < void > {
202
+ await this . authorizer . checkPermissionOnUser ( userId , "make_admin" , targetUserId ) ;
203
+ const target = await this . findUserById ( userId , targetUserId ) ;
204
+ const rolesOrPermissions = new Set ( ( target . rolesOrPermissions || [ ] ) as string [ ] ) ;
205
+ const adminBefore = rolesOrPermissions . has ( "admin" ) ;
206
+ modifications . forEach ( ( e ) => {
207
+ if ( e . add ) {
208
+ rolesOrPermissions . add ( e . role as string ) ;
151
209
} else {
152
- await this . authorizer . addInstallationAdminRole ( target . id ) ;
210
+ rolesOrPermissions . delete ( e . role as string ) ;
211
+ }
212
+ } ) ;
213
+ target . rolesOrPermissions = Array . from ( rolesOrPermissions . values ( ) ) as RoleOrPermission [ ] ;
214
+ const adminAfter = new Set ( target . rolesOrPermissions ) . has ( "admin" ) ;
215
+ try {
216
+ await this . userDb . transaction ( async ( userDb ) => {
217
+ await userDb . storeUser ( target ) ;
218
+ if ( adminBefore !== adminAfter ) {
219
+ if ( adminAfter ) {
220
+ await this . authorizer . addInstallationAdminRole ( target . id ) ;
221
+ } else {
222
+ await this . authorizer . removeInstallationAdminRole ( target . id ) ;
223
+ }
224
+ }
225
+ } ) ;
226
+ } catch ( error ) {
227
+ if ( adminBefore !== adminAfter ) {
228
+ if ( adminAfter ) {
229
+ await this . authorizer . removeInstallationAdminRole ( target . id ) ;
230
+ } else {
231
+ await this . authorizer . addInstallationAdminRole ( target . id ) ;
232
+ }
153
233
}
154
- throw err ;
234
+ throw error ;
155
235
}
156
236
}
157
237
}
0 commit comments