@@ -17,6 +17,8 @@ const Language = {
17
17
buildError : "Workspace action failed." ,
18
18
}
19
19
20
+ type Permissions = Record < keyof ReturnType < typeof permissionsToCheck > , boolean >
21
+
20
22
export interface WorkspaceContext {
21
23
workspace ?: TypesGen . Workspace
22
24
template ?: TypesGen . Template
@@ -26,14 +28,18 @@ export interface WorkspaceContext {
26
28
// error creating a new WorkspaceBuild
27
29
buildError ?: Error | unknown
28
30
// these are separate from getX errors because they don't make the page unusable
29
- refreshWorkspaceError : Error | unknown
30
- refreshTemplateError : Error | unknown
31
- getResourcesError : Error | unknown
31
+ refreshWorkspaceError ? : Error | unknown
32
+ refreshTemplateError ? : Error | unknown
33
+ getResourcesError ? : Error | unknown
32
34
// Builds
33
35
builds ?: TypesGen . WorkspaceBuild [ ]
34
36
getBuildsError ?: Error | unknown
35
37
loadMoreBuildsError ?: Error | unknown
36
- cancellationMessage : string
38
+ cancellationMessage ?: string
39
+ // permissions
40
+ permissions ?: Permissions
41
+ checkPermissionsError ?: Error | unknown
42
+ userId ?: string
37
43
}
38
44
39
45
export type WorkspaceEvent =
@@ -48,6 +54,30 @@ export type WorkspaceEvent =
48
54
| { type : "LOAD_MORE_BUILDS" }
49
55
| { type : "REFRESH_TIMELINE" }
50
56
57
+ export const checks = {
58
+ readWorkspace : "readWorkspace" ,
59
+ updateWorkspace : "updateWorkspace" ,
60
+ } as const
61
+
62
+ const permissionsToCheck = ( workspace : TypesGen . Workspace ) => ( {
63
+ [ checks . readWorkspace ] : {
64
+ object : {
65
+ resource_type : "workspace" ,
66
+ resource_id : workspace . id ,
67
+ owner_id : workspace . owner_id ,
68
+ } ,
69
+ action : "read" ,
70
+ } ,
71
+ [ checks . updateWorkspace ] : {
72
+ object : {
73
+ resource_type : "workspace" ,
74
+ resource_id : workspace . id ,
75
+ owner_id : workspace . owner_id ,
76
+ } ,
77
+ action : "update" ,
78
+ } ,
79
+ } )
80
+
51
81
export const workspaceMachine = createMachine (
52
82
{
53
83
tsTypes : { } as import ( "./workspaceXService.typegen" ) . Typegen0 ,
@@ -82,6 +112,9 @@ export const workspaceMachine = createMachine(
82
112
loadMoreBuilds : {
83
113
data : TypesGen . WorkspaceBuild [ ]
84
114
}
115
+ checkPermissions : {
116
+ data : TypesGen . UserAuthorizationResponse
117
+ }
85
118
} ,
86
119
} ,
87
120
id : "workspaceState" ,
@@ -99,7 +132,7 @@ export const workspaceMachine = createMachine(
99
132
src : "getWorkspace" ,
100
133
id : "getWorkspace" ,
101
134
onDone : {
102
- target : "ready " ,
135
+ target : "gettingPermissions " ,
103
136
actions : [ "assignWorkspace" ] ,
104
137
} ,
105
138
onError : {
@@ -109,6 +142,25 @@ export const workspaceMachine = createMachine(
109
142
} ,
110
143
tags : "loading" ,
111
144
} ,
145
+ gettingPermissions : {
146
+ entry : "clearGetPermissionsError" ,
147
+ invoke : {
148
+ src : "checkPermissions" ,
149
+ id : "checkPermissions" ,
150
+ onDone : [
151
+ {
152
+ actions : [ "assignPermissions" ] ,
153
+ target : "ready" ,
154
+ } ,
155
+ ] ,
156
+ onError : [
157
+ {
158
+ actions : "assignGetPermissionsError" ,
159
+ target : "error" ,
160
+ } ,
161
+ ] ,
162
+ } ,
163
+ } ,
112
164
ready : {
113
165
type : "parallel" ,
114
166
states : {
@@ -312,6 +364,7 @@ export const workspaceMachine = createMachine(
312
364
workspace : undefined ,
313
365
template : undefined ,
314
366
build : undefined ,
367
+ permissions : undefined ,
315
368
} ) ,
316
369
assignWorkspace : assign ( {
317
370
workspace : ( _ , event ) => event . data ,
@@ -323,6 +376,17 @@ export const workspaceMachine = createMachine(
323
376
assignTemplate : assign ( {
324
377
template : ( _ , event ) => event . data ,
325
378
} ) ,
379
+ assignPermissions : assign ( {
380
+ // Setting event.data as Permissions to be more stricted. So we know
381
+ // what permissions we asked for.
382
+ permissions : ( _ , event ) => event . data as Permissions ,
383
+ } ) ,
384
+ assignGetPermissionsError : assign ( {
385
+ checkPermissionsError : ( _ , event ) => event . data ,
386
+ } ) ,
387
+ clearGetPermissionsError : assign ( {
388
+ checkPermissionsError : ( _ ) => undefined ,
389
+ } ) ,
326
390
assignBuild : ( _ , event ) =>
327
391
assign ( {
328
392
build : event . data ,
@@ -347,7 +411,7 @@ export const workspaceMachine = createMachine(
347
411
cancellationMessage : undefined ,
348
412
} ) ,
349
413
displayCancellationError : ( context ) => {
350
- displayError ( context . cancellationMessage )
414
+ displayError ( context . cancellationMessage || "Cancellation failed" )
351
415
} ,
352
416
assignRefreshWorkspaceError : ( _ , event ) =>
353
417
assign ( {
@@ -487,14 +551,23 @@ export const workspaceMachine = createMachine(
487
551
if ( context . workspace ) {
488
552
return await API . getWorkspaceBuilds ( context . workspace . id )
489
553
} else {
490
- throw Error ( "Cannot refresh workspace without id" )
554
+ throw Error ( "Cannot get builds without id" )
491
555
}
492
556
} ,
493
557
loadMoreBuilds : async ( context ) => {
494
558
if ( context . workspace ) {
495
559
return await API . getWorkspaceBuilds ( context . workspace . id )
496
560
} else {
497
- throw Error ( "Cannot refresh workspace without id" )
561
+ throw Error ( "Cannot load more builds without id" )
562
+ }
563
+ } ,
564
+ checkPermissions : async ( context ) => {
565
+ if ( context . workspace && context . userId ) {
566
+ return await API . checkUserPermissions ( context . userId , {
567
+ checks : permissionsToCheck ( context . workspace ) ,
568
+ } )
569
+ } else {
570
+ throw Error ( "Cannot check permissions without both workspace and user id" )
498
571
}
499
572
} ,
500
573
} ,
0 commit comments