@@ -58,6 +58,15 @@ import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messag
5858import { ContextService } from "../workspace/context-service" ;
5959import { UserService } from "../user/user-service" ;
6060import { ContextParser } from "../workspace/context-parser-service" ;
61+ import { workspaceIDRegex } from "@gitpod/gitpod-protocol/lib/util/gitpod-host-url" ;
62+
63+ const isWorkspaceId = ( workspaceId ?: string ) => {
64+ if ( ! workspaceId ) {
65+ return false ;
66+ }
67+
68+ return workspaceIDRegex . test ( workspaceId ) ;
69+ } ;
6170
6271@injectable ( )
6372export class WorkspaceServiceAPI implements ServiceImpl < typeof WorkspaceServiceInterface > {
@@ -68,8 +77,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
6877 @inject ( ContextParser ) private contextParser : ContextParser ;
6978
7079 async getWorkspace ( req : GetWorkspaceRequest , _ : HandlerContext ) : Promise < GetWorkspaceResponse > {
71- if ( ! req . workspaceId ) {
72- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
80+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
81+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
7382 }
7483 const info = await this . workspaceService . getWorkspace ( ctxUserId ( ) , req . workspaceId ) ;
7584 const response = new GetWorkspaceResponse ( ) ;
@@ -198,8 +207,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
198207
199208 async startWorkspace ( req : StartWorkspaceRequest ) : Promise < StartWorkspaceResponse > {
200209 // We rely on FGA to do the permission checking
201- if ( ! req . workspaceId ) {
202- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
210+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
211+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
203212 }
204213 const user = await this . userService . findUserById ( ctxUserId ( ) , ctxUserId ( ) ) ;
205214 const { workspace, latestInstance : instance } = await this . workspaceService . getWorkspace (
@@ -227,8 +236,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
227236 req : GetWorkspaceDefaultImageRequest ,
228237 _ : HandlerContext ,
229238 ) : Promise < GetWorkspaceDefaultImageResponse > {
230- if ( ! req . workspaceId ) {
231- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
239+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
240+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
232241 }
233242 const result = await this . workspaceService . getWorkspaceDefaultImage ( ctxUserId ( ) , req . workspaceId ) ;
234243 const response = new GetWorkspaceDefaultImageResponse ( {
@@ -246,8 +255,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
246255 }
247256
248257 async sendHeartBeat ( req : SendHeartBeatRequest , _ : HandlerContext ) : Promise < SendHeartBeatResponse > {
249- if ( ! req . workspaceId ) {
250- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
258+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
259+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
251260 }
252261 const info = await this . workspaceService . getWorkspace ( ctxUserId ( ) , req . workspaceId ) ;
253262 if ( ! info . latestInstance ?. id || info . latestInstance . status . phase !== "running" ) {
@@ -265,8 +274,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
265274 req : GetWorkspaceOwnerTokenRequest ,
266275 _ : HandlerContext ,
267276 ) : Promise < GetWorkspaceOwnerTokenResponse > {
268- if ( ! req . workspaceId ) {
269- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
277+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
278+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
270279 }
271280 const ownerToken = await this . workspaceService . getOwnerToken ( ctxUserId ( ) , req . workspaceId ) ;
272281 const response = new GetWorkspaceOwnerTokenResponse ( ) ;
@@ -278,8 +287,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
278287 req : GetWorkspaceEditorCredentialsRequest ,
279288 _ : HandlerContext ,
280289 ) : Promise < GetWorkspaceEditorCredentialsResponse > {
281- if ( ! req . workspaceId ) {
282- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
290+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
291+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
283292 }
284293 const credentials = await this . workspaceService . getIDECredentials ( ctxUserId ( ) , req . workspaceId ) ;
285294 const response = new GetWorkspaceEditorCredentialsResponse ( ) ;
@@ -288,8 +297,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
288297 }
289298
290299 async updateWorkspace ( req : UpdateWorkspaceRequest ) : Promise < UpdateWorkspaceResponse > {
291- if ( ! req . workspaceId ) {
292- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
300+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
301+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
293302 }
294303 if ( req . spec ?. timeout ?. inactivity ?. seconds || ( req . spec ?. sshPublicKeys && req . spec ?. sshPublicKeys . length > 0 ) ) {
295304 throw new ApplicationError ( ErrorCodes . UNIMPLEMENTED , "not implemented" ) ;
@@ -363,17 +372,17 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
363372 }
364373
365374 async stopWorkspace ( req : StopWorkspaceRequest ) : Promise < StopWorkspaceResponse > {
366- if ( ! req . workspaceId ) {
367- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
375+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
376+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
368377 }
369378 await this . workspaceService . stopWorkspace ( ctxUserId ( ) , req . workspaceId , "stopped via API" ) ;
370379 const response = new StopWorkspaceResponse ( ) ;
371380 return response ;
372381 }
373382
374383 async deleteWorkspace ( req : DeleteWorkspaceRequest ) : Promise < DeleteWorkspaceResponse > {
375- if ( ! req . workspaceId ) {
376- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
384+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
385+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
377386 }
378387 await this . workspaceService . deleteWorkspace ( ctxUserId ( ) , req . workspaceId , "user" ) ;
379388 const response = new DeleteWorkspaceResponse ( ) ;
@@ -389,8 +398,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
389398 }
390399
391400 async createWorkspaceSnapshot ( req : CreateWorkspaceSnapshotRequest ) : Promise < CreateWorkspaceSnapshotResponse > {
392- if ( ! req . workspaceId ) {
393- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
401+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
402+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
394403 }
395404 const snapshot = await this . workspaceService . takeSnapshot ( ctxUserId ( ) , {
396405 workspaceId : req . workspaceId ,
@@ -410,8 +419,8 @@ export class WorkspaceServiceAPI implements ServiceImpl<typeof WorkspaceServiceI
410419 }
411420
412421 async updateWorkspacePort ( req : UpdateWorkspacePortRequest ) : Promise < UpdateWorkspacePortResponse > {
413- if ( ! req . workspaceId ) {
414- throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "workspaceId is required" ) ;
422+ if ( ! isWorkspaceId ( req . workspaceId ) ) {
423+ throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "a valid workspaceId is required" ) ;
415424 }
416425 if ( ! req . port ) {
417426 throw new ApplicationError ( ErrorCodes . BAD_REQUEST , "port is required" ) ;
0 commit comments