@@ -9,6 +9,8 @@ use common::{
9
9
components:: {
10
10
CanonicalizedComponentFunctionPath ,
11
11
ComponentId ,
12
+ ComponentPath ,
13
+ ExportPath ,
12
14
} ,
13
15
http:: ResolvedHost ,
14
16
pause:: PauseClient ,
@@ -96,7 +98,25 @@ pub trait ApplicationApi: Send + Sync {
96
98
auth_token : AuthenticationToken ,
97
99
) -> anyhow:: Result < Identity > ;
98
100
101
+ /// Execute a public query on the root app. This method is used by the sync
102
+ /// worker and HTTP API for the majority of traffic as the main entry point
103
+ /// for queries.
99
104
async fn execute_public_query (
105
+ & self ,
106
+ host : & ResolvedHost ,
107
+ request_id : RequestId ,
108
+ identity : Identity ,
109
+ path : ExportPath ,
110
+ args : Vec < JsonValue > ,
111
+ caller : FunctionCaller ,
112
+ ts : ExecuteQueryTimestamp ,
113
+ journal : Option < SerializedQueryJournal > ,
114
+ ) -> anyhow:: Result < RedactedQueryReturn > ;
115
+
116
+ /// Execute an admin query for a particular component. This method is used
117
+ /// by the sync worker for running queries for the dashboard and only works
118
+ /// for admin or system identity.
119
+ async fn execute_admin_query (
100
120
& self ,
101
121
host : & ResolvedHost ,
102
122
request_id : RequestId ,
@@ -108,44 +128,54 @@ pub trait ApplicationApi: Send + Sync {
108
128
journal : Option < SerializedQueryJournal > ,
109
129
) -> anyhow:: Result < RedactedQueryReturn > ;
110
130
131
+ /// Execute a public mutation on the root app.
111
132
async fn execute_public_mutation (
112
133
& self ,
113
134
host : & ResolvedHost ,
114
135
request_id : RequestId ,
115
136
identity : Identity ,
116
- path : CanonicalizedComponentFunctionPath ,
137
+ path : ExportPath ,
117
138
args : Vec < JsonValue > ,
118
139
caller : FunctionCaller ,
119
140
// Identifier used to make this mutation idempotent.
120
141
mutation_identifier : Option < SessionRequestIdentifier > ,
121
142
) -> anyhow:: Result < Result < RedactedMutationReturn , RedactedMutationError > > ;
122
143
123
- async fn execute_public_action (
144
+ /// Execute an admin mutation for a particular component for the dashboard.
145
+ async fn execute_admin_mutation (
124
146
& self ,
125
147
host : & ResolvedHost ,
126
148
request_id : RequestId ,
127
149
identity : Identity ,
128
150
path : CanonicalizedComponentFunctionPath ,
129
151
args : Vec < JsonValue > ,
130
152
caller : FunctionCaller ,
131
- ) -> anyhow:: Result < Result < RedactedActionReturn , RedactedActionError > > ;
153
+ mutation_identifier : Option < SessionRequestIdentifier > ,
154
+ ) -> anyhow:: Result < Result < RedactedMutationReturn , RedactedMutationError > > ;
132
155
133
- async fn execute_any_function (
156
+ /// Execute a public action on the root app.
157
+ async fn execute_public_action (
134
158
& self ,
135
159
host : & ResolvedHost ,
136
160
request_id : RequestId ,
137
161
identity : Identity ,
138
- path : CanonicalizedComponentFunctionPath ,
162
+ path : ExportPath ,
139
163
args : Vec < JsonValue > ,
140
164
caller : FunctionCaller ,
141
- ) -> anyhow:: Result < Result < FunctionReturn , FunctionError > > ;
165
+ ) -> anyhow:: Result < Result < RedactedActionReturn , RedactedActionError > > ;
142
166
143
- async fn latest_timestamp (
167
+ /// Execute an admin action for a particular component for the dashboard.
168
+ async fn execute_admin_action (
144
169
& self ,
145
170
host : & ResolvedHost ,
146
171
request_id : RequestId ,
147
- ) -> anyhow:: Result < RepeatableTimestamp > ;
172
+ identity : Identity ,
173
+ path : CanonicalizedComponentFunctionPath ,
174
+ args : Vec < JsonValue > ,
175
+ caller : FunctionCaller ,
176
+ ) -> anyhow:: Result < Result < RedactedActionReturn , RedactedActionError > > ;
148
177
178
+ /// Execute an HTTP action on the root app.
149
179
async fn execute_http_action (
150
180
& self ,
151
181
host : & ResolvedHost ,
@@ -156,6 +186,25 @@ pub trait ApplicationApi: Send + Sync {
156
186
response_streamer : HttpActionResponseStreamer ,
157
187
) -> anyhow:: Result < ( ) > ;
158
188
189
+ /// For the dashboard (and the CLI), run any function in any component
190
+ /// without knowing its type. This function requires admin identity for
191
+ /// calling functions outside the root component.
192
+ async fn execute_any_function (
193
+ & self ,
194
+ host : & ResolvedHost ,
195
+ request_id : RequestId ,
196
+ identity : Identity ,
197
+ path : CanonicalizedComponentFunctionPath ,
198
+ args : Vec < JsonValue > ,
199
+ caller : FunctionCaller ,
200
+ ) -> anyhow:: Result < Result < FunctionReturn , FunctionError > > ;
201
+
202
+ async fn latest_timestamp (
203
+ & self ,
204
+ host : & ResolvedHost ,
205
+ request_id : RequestId ,
206
+ ) -> anyhow:: Result < RepeatableTimestamp > ;
207
+
159
208
async fn check_store_file_authorization (
160
209
& self ,
161
210
host : & ResolvedHost ,
@@ -226,7 +275,7 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
226
275
_host : & ResolvedHost ,
227
276
request_id : RequestId ,
228
277
identity : Identity ,
229
- path : CanonicalizedComponentFunctionPath ,
278
+ path : ExportPath ,
230
279
args : Vec < JsonValue > ,
231
280
caller : FunctionCaller ,
232
281
ts : ExecuteQueryTimestamp ,
@@ -236,7 +285,34 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
236
285
caller. allowed_visibility( ) == AllowedVisibility :: PublicOnly ,
237
286
"This method should not be used by internal callers."
238
287
) ;
288
+ let ts = match ts {
289
+ ExecuteQueryTimestamp :: Latest => * self . now_ts_for_reads ( ) ,
290
+ ExecuteQueryTimestamp :: At ( ts) => ts,
291
+ } ;
292
+ // Public queries always start with the root component.
293
+ let path = CanonicalizedComponentFunctionPath {
294
+ component : ComponentPath :: root ( ) ,
295
+ udf_path : path. into ( ) ,
296
+ } ;
297
+ self . read_only_udf_at_ts ( request_id, path, args, identity, ts, journal, caller)
298
+ . await
299
+ }
239
300
301
+ async fn execute_admin_query (
302
+ & self ,
303
+ _host : & ResolvedHost ,
304
+ request_id : RequestId ,
305
+ identity : Identity ,
306
+ path : CanonicalizedComponentFunctionPath ,
307
+ args : Vec < JsonValue > ,
308
+ caller : FunctionCaller ,
309
+ ts : ExecuteQueryTimestamp ,
310
+ journal : Option < SerializedQueryJournal > ,
311
+ ) -> anyhow:: Result < RedactedQueryReturn > {
312
+ anyhow:: ensure!(
313
+ path. component. is_root( ) || identity. is_admin( ) || identity. is_system( ) ,
314
+ "Only admin or system users can call functions on non-root components directly"
315
+ ) ;
240
316
let ts = match ts {
241
317
ExecuteQueryTimestamp :: Latest => * self . now_ts_for_reads ( ) ,
242
318
ExecuteQueryTimestamp :: At ( ts) => ts,
@@ -250,7 +326,7 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
250
326
_host : & ResolvedHost ,
251
327
request_id : RequestId ,
252
328
identity : Identity ,
253
- path : CanonicalizedComponentFunctionPath ,
329
+ path : ExportPath ,
254
330
args : Vec < JsonValue > ,
255
331
caller : FunctionCaller ,
256
332
// Identifier used to make this mutation idempotent.
@@ -260,7 +336,36 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
260
336
caller. allowed_visibility( ) == AllowedVisibility :: PublicOnly ,
261
337
"This method should not be used by internal callers."
262
338
) ;
339
+ let path = CanonicalizedComponentFunctionPath {
340
+ component : ComponentPath :: root ( ) ,
341
+ udf_path : path. into ( ) ,
342
+ } ;
343
+ self . mutation_udf (
344
+ request_id,
345
+ path,
346
+ args,
347
+ identity,
348
+ mutation_identifier,
349
+ caller,
350
+ PauseClient :: new ( ) ,
351
+ )
352
+ . await
353
+ }
263
354
355
+ async fn execute_admin_mutation (
356
+ & self ,
357
+ _host : & ResolvedHost ,
358
+ request_id : RequestId ,
359
+ identity : Identity ,
360
+ path : CanonicalizedComponentFunctionPath ,
361
+ args : Vec < JsonValue > ,
362
+ caller : FunctionCaller ,
363
+ mutation_identifier : Option < SessionRequestIdentifier > ,
364
+ ) -> anyhow:: Result < Result < RedactedMutationReturn , RedactedMutationError > > {
365
+ anyhow:: ensure!(
366
+ path. component. is_root( ) || identity. is_admin( ) || identity. is_system( ) ,
367
+ "Only admin or system users can call functions on non-root components directly"
368
+ ) ;
264
369
self . mutation_udf (
265
370
request_id,
266
371
path,
@@ -278,15 +383,35 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
278
383
_host : & ResolvedHost ,
279
384
request_id : RequestId ,
280
385
identity : Identity ,
281
- path : CanonicalizedComponentFunctionPath ,
386
+ path : ExportPath ,
282
387
args : Vec < JsonValue > ,
283
388
caller : FunctionCaller ,
284
389
) -> anyhow:: Result < Result < RedactedActionReturn , RedactedActionError > > {
285
390
anyhow:: ensure!(
286
391
caller. allowed_visibility( ) == AllowedVisibility :: PublicOnly ,
287
392
"This method should not be used by internal callers."
288
393
) ;
394
+ let path = CanonicalizedComponentFunctionPath {
395
+ component : ComponentPath :: root ( ) ,
396
+ udf_path : path. into ( ) ,
397
+ } ;
398
+ self . action_udf ( request_id, path, args, identity, caller)
399
+ . await
400
+ }
289
401
402
+ async fn execute_admin_action (
403
+ & self ,
404
+ _host : & ResolvedHost ,
405
+ request_id : RequestId ,
406
+ identity : Identity ,
407
+ path : CanonicalizedComponentFunctionPath ,
408
+ args : Vec < JsonValue > ,
409
+ caller : FunctionCaller ,
410
+ ) -> anyhow:: Result < Result < RedactedActionReturn , RedactedActionError > > {
411
+ anyhow:: ensure!(
412
+ path. component. is_root( ) || identity. is_admin( ) || identity. is_system( ) ,
413
+ "Only admin or system users can call functions on non-root components directly"
414
+ ) ;
290
415
self . action_udf ( request_id, path, args, identity, caller)
291
416
. await
292
417
}
@@ -300,6 +425,10 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
300
425
args : Vec < JsonValue > ,
301
426
caller : FunctionCaller ,
302
427
) -> anyhow:: Result < Result < FunctionReturn , FunctionError > > {
428
+ anyhow:: ensure!(
429
+ path. component. is_root( ) || identity. is_admin( ) || identity. is_system( ) ,
430
+ "Only admin or system users can call functions on non-root components directly"
431
+ ) ;
303
432
self . any_udf ( request_id, path, args, identity, caller) . await
304
433
}
305
434
0 commit comments