@@ -8,13 +8,22 @@ import { inject, injectable } from "inversify";
88import { Config } from "../config" ;
99import { UserDB } from "@gitpod/gitpod-db/lib" ;
1010import { 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" ;
1220import { ApplicationError , ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error" ;
1321import { log } from "@gitpod/gitpod-protocol/lib/util/logging" ;
1422import { CreateUserParams } from "./user-authentication" ;
1523import { IAnalyticsWriter } from "@gitpod/gitpod-protocol/lib/analytics" ;
1624import { TransactionalContext } from "@gitpod/gitpod-db/lib/typeorm/transactional-db-impl" ;
1725import { RelationshipUpdater } from "../authorization/relationship-updater" ;
26+ import { EntitlementService } from "../billing/entitlement-service" ;
1827
1928@injectable ( )
2029export class UserService {
@@ -24,6 +33,7 @@ export class UserService {
2433 @inject ( Authorizer ) private readonly authorizer : Authorizer ,
2534 @inject ( IAnalyticsWriter ) private readonly analytics : IAnalyticsWriter ,
2635 @inject ( RelationshipUpdater ) private readonly relationshipUpdater : RelationshipUpdater ,
36+ @inject ( EntitlementService ) private readonly entitlementService : EntitlementService ,
2737 ) { }
2838
2939 public async createUser (
@@ -124,34 +134,104 @@ export class UserService {
124134 return user ;
125135 }
126136
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+ }
135150 }
136151
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 [ ] } > {
137175 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 ) ;
143187 } else {
144- await this . authorizer . removeInstallationAdminRole ( target . id ) ;
188+ result . total -- ;
145189 }
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 ) ;
151209 } 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+ }
153233 }
154- throw err ;
234+ throw error ;
155235 }
156236 }
157237}
0 commit comments