Skip to content

Commit 004602c

Browse files
pranshi06hasura-bot
authored andcommitted
server: fix HTTP request structure leak in Async Actions
PR-URL: hasura/graphql-engine-mono#10549 GitOrigin-RevId: e628fc161546c4899dc39a571290ddf0af2e2d83
1 parent e6ca36d commit 004602c

File tree

12 files changed

+179
-25
lines changed

12 files changed

+179
-25
lines changed

server/src-lib/Hasura/GraphQL/Execute.hs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ buildSubscriptionPlan ::
131131
ParameterizedQueryHash ->
132132
[HTTP.Header] ->
133133
Maybe G.Name ->
134+
Init.ResponseInternalErrorsConfig ->
134135
m ((SubscriptionExecution, Maybe (Endo JO.Value)), [ModelInfoPart])
135-
buildSubscriptionPlan userInfo rootFields parameterizedQueryHash reqHeaders operationName = do
136+
buildSubscriptionPlan userInfo rootFields parameterizedQueryHash reqHeaders operationName responseErrorsConfig = do
136137
(((liveQueryOnSourceFields, noRelationActionFields), streamingFields), modifier) <- foldlM go (((mempty, mempty), mempty), mempty) (InsOrdHashMap.toList rootFields)
137138

138139
if
@@ -267,7 +268,7 @@ buildSubscriptionPlan userInfo rootFields parameterizedQueryHash reqHeaders oper
267268
case noRelsDBAST of
268269
IR.AQAsync q -> do
269270
let actionId = IR._aaaqActionId q
270-
case EA.resolveAsyncActionQuery userInfo q of
271+
case EA.resolveAsyncActionQuery userInfo q responseErrorsConfig of
271272
EA.AAQENoRelationships respMaker ->
272273
pure $ ((second (InsOrdHashMap.insert gName (actionId, respMaker)) accLiveQueryFields, accStreamingFields), modifier)
273274
EA.AAQEOnSourceDB srcConfig dbExecution ->
@@ -361,6 +362,7 @@ getResolvedExecPlan ::
361362
SingleOperation -> -- the first step of the execution plan
362363
Maybe G.Name ->
363364
RequestId ->
365+
Init.ResponseInternalErrorsConfig ->
364366
m (ParameterizedQueryHash, ResolvedExecutionPlan, [ModelInfoPart])
365367
getResolvedExecPlan
366368
env
@@ -375,7 +377,8 @@ getResolvedExecPlan
375377
reqUnparsed
376378
queryParts -- the first step of the execution plan
377379
maybeOperationName
378-
reqId = do
380+
reqId
381+
responseErrorsConfig = do
379382
let gCtx = makeGQLContext userInfo sc queryType
380383
tracesPropagator = getOtelTracesPropagator $ scOpenTelemetryConfig sc
381384

@@ -400,6 +403,7 @@ getResolvedExecPlan
400403
(scSetGraphqlIntrospectionOptions sc)
401404
reqId
402405
maybeOperationName
406+
responseErrorsConfig
403407
Tracing.attachMetadata [("graphql.operation.type", "query"), ("parameterized_query_hash", bsToTxt $ unParamQueryHash parameterizedQueryHash)]
404408
pure (parameterizedQueryHash, QueryExecutionPlan executionPlan queryRootFields dirMap, modelInfoList)
405409
G.TypedOperationDefinition G.OperationTypeMutation _ varDefs directives inlinedSelSet -> Tracing.newSpan "Resolve mutation execution plan" $ do
@@ -450,7 +454,7 @@ getResolvedExecPlan
450454
_ ->
451455
unless (allowMultipleRootFields && isSingleNamespace unpreparedAST)
452456
$ throw400 ValidationFailed "subscriptions must select one top level field"
453-
(subscriptionPlan, modelInfoList) <- buildSubscriptionPlan userInfo unpreparedAST parameterizedQueryHash reqHeaders maybeOperationName
457+
(subscriptionPlan, modelInfoList) <- buildSubscriptionPlan userInfo unpreparedAST parameterizedQueryHash reqHeaders maybeOperationName responseErrorsConfig
454458
Tracing.attachMetadata [("graphql.operation.type", "subscription")]
455459
pure (parameterizedQueryHash, SubscriptionExecutionPlan subscriptionPlan, modelInfoList)
456460
-- the parameterized query hash is calculated here because it is used in multiple

server/src-lib/Hasura/GraphQL/Execute/Action.hs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Control.Monad.Trans.Control (MonadBaseControl)
2727
import Data.Aeson qualified as J
2828
import Data.Aeson.Key qualified as K
2929
import Data.Aeson.KeyMap qualified as KM
30+
import Data.Aeson.Lens
3031
import Data.Aeson.Ordered qualified as AO
3132
import Data.ByteString.Lazy qualified as BL
3233
import Data.CaseInsensitive qualified as CI
@@ -78,7 +79,7 @@ import Hasura.RQL.Types.OpenTelemetry (getOtelTracesPropagator)
7879
import Hasura.RQL.Types.Roles (adminRoleName)
7980
import Hasura.RQL.Types.Schema.Options qualified as Options
8081
import Hasura.RQL.Types.SchemaCache
81-
import Hasura.Server.Init.Config (OptionalInterval (..))
82+
import Hasura.Server.Init.Config (OptionalInterval (..), ResponseInternalErrorsConfig (..), shouldIncludeInternal)
8283
import Hasura.Server.Prometheus (PrometheusMetrics (..))
8384
import Hasura.Server.Utils
8485
( mkClientHeadersForward,
@@ -342,8 +343,9 @@ Resolving async action query happens in two steps;
342343
resolveAsyncActionQuery ::
343344
UserInfo ->
344345
IR.AnnActionAsyncQuery ('Postgres 'Vanilla) Void ->
346+
ResponseInternalErrorsConfig ->
345347
AsyncActionQueryExecution (IR.UnpreparedValue ('Postgres 'Vanilla))
346-
resolveAsyncActionQuery userInfo annAction =
348+
resolveAsyncActionQuery userInfo annAction responseErrorsConfig =
347349
case actionSource of
348350
IR.ASINoSource -> AAQENoRelationships \actionLogResponse -> runExcept do
349351
let ActionLogResponse {..} = actionLogResponse
@@ -357,7 +359,7 @@ resolveAsyncActionQuery userInfo annAction =
357359
\response -> makeActionResponseNoRelations annFields outputType HashMap.empty False <$> decodeValue response
358360
IR.AsyncId -> pure $ AO.String $ actionIdToText actionId
359361
IR.AsyncCreatedAt -> pure $ AO.toOrdered $ J.toJSON _alrCreatedAt
360-
IR.AsyncErrors -> pure $ AO.toOrdered $ J.toJSON _alrErrors
362+
IR.AsyncErrors -> pure $ AO.toOrdered $ J.toJSON $ mkQErrFromErrorValue _alrErrors
361363
pure $ encJFromOrderedValue $ AO.object resolvedFields
362364
IR.ASISource sourceName sourceConfig ->
363365
let jsonAggSelect = mkJsonAggSelect outputType
@@ -373,7 +375,20 @@ resolveAsyncActionQuery userInfo annAction =
373375
$ processOutputSelectionSet TF.AEActionResponsePayload outputType definitionList annFields stringifyNumerics
374376
IR.AsyncId -> mkAnnFldFromPGCol idColumn
375377
IR.AsyncCreatedAt -> mkAnnFldFromPGCol createdAtColumn
376-
IR.AsyncErrors -> mkAnnFldFromPGCol errorsColumn
378+
IR.AsyncErrors ->
379+
if (shouldIncludeInternal (_uiRole userInfo) responseErrorsConfig)
380+
then RS.mkAnnColumnField (fst errorsColumn) (ColumnScalar (snd errorsColumn)) NoRedaction Nothing
381+
else
382+
RS.mkAnnColumnField
383+
(fst errorsColumn)
384+
(ColumnScalar (snd errorsColumn))
385+
NoRedaction
386+
( Just
387+
$ S.ColumnOp
388+
{ _colOp = S.jsonbDeleteOp,
389+
_colExp = S.SELit "internal"
390+
}
391+
)
377392

378393
jsonbToRecordSet = QualifiedObject "pg_catalog" $ FunctionName "jsonb_to_recordset"
379394
actionLogInput =
@@ -394,6 +409,14 @@ resolveAsyncActionQuery userInfo annAction =
394409
tablePermissions = RS.TablePerm annBoolExpTrue Nothing
395410
in RS.AnnSelectG annotatedFields tableFromExp tablePermissions tableArguments stringifyNumerics Nothing
396411
where
412+
mkQErrFromErrorValue :: Maybe J.Value -> QErr
413+
mkQErrFromErrorValue actionLogResponseError =
414+
let internal = ExtraInternal <$> (actionLogResponseError >>= (^? key "internal"))
415+
internal' = if shouldIncludeInternal (_uiRole userInfo) responseErrorsConfig then internal else Nothing
416+
errorMessageText = fromMaybe "internal: error in parsing the action log" $ actionLogResponseError >>= (^? key "error" . _String)
417+
codeMaybe = actionLogResponseError >>= (^? key "code" . _String)
418+
code = maybe Unexpected ActionWebhookCode codeMaybe
419+
in QErr [] HTTP.status500 errorMessageText code internal'
397420
IR.AnnActionAsyncQuery _ actionId outputType asyncFields definitionList stringifyNumerics _ actionSource = annAction
398421

399422
idColumn = (unsafePGCol "id", PGUUID)

server/src-lib/Hasura/GraphQL/Execute/Query.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import Hasura.RQL.Types.GraphqlSchemaIntrospection
3737
import Hasura.RQL.Types.Schema.Options as Options
3838
import Hasura.RemoteSchema.Metadata.Base (RemoteSchemaName (..))
3939
import Hasura.SQL.AnyBackend qualified as AB
40+
import Hasura.Server.Init.Config (ResponseInternalErrorsConfig (..))
4041
import Hasura.Server.Prometheus (PrometheusMetrics (..))
4142
import Hasura.Server.Types (MonadGetPolicies, RequestId (..))
4243
import Hasura.Services.Network
@@ -91,6 +92,7 @@ convertQuerySelSet ::
9192
RequestId ->
9293
-- | Graphql Operation Name
9394
Maybe G.Name ->
95+
ResponseInternalErrorsConfig ->
9496
m (ExecutionPlan, [QueryRootField UnpreparedValue], DirectiveMap, ParameterizedQueryHash, [ModelInfoPart])
9597
convertQuerySelSet
9698
env
@@ -107,7 +109,8 @@ convertQuerySelSet
107109
gqlUnparsed
108110
introspectionDisabledRoles
109111
reqId
110-
maybeOperationName = do
112+
maybeOperationName
113+
responseErrorsConfig = do
111114
-- 1. Parse the GraphQL query into the 'RootFieldMap' and a 'SelectionSet'
112115
(unpreparedQueries, normalizedDirectives, normalizedSelectionSet) <-
113116
Tracing.newSpan "Parse query IR" $ parseGraphQLQuery nullInNonNullableVariables gqlContext varDefs (GH._grVariables gqlUnparsed) directives fields
@@ -162,7 +165,7 @@ convertQuerySelSet
162165
_aaeName s,
163166
_aaeForwardClientHeaders s
164167
)
165-
AQAsync s -> (AEPAsyncQuery $ AsyncActionQueryExecutionPlan (_aaaqActionId s) $ resolveAsyncActionQuery userInfo s, _aaaqName s, _aaaqForwardClientHeaders s)
168+
AQAsync s -> (AEPAsyncQuery $ AsyncActionQueryExecutionPlan (_aaaqActionId s) $ resolveAsyncActionQuery userInfo s responseErrorsConfig, _aaaqName s, _aaaqForwardClientHeaders s)
166169
let actionsModel = ModelInfoPart (toTxt actionName) ModelTypeAction Nothing Nothing (ModelOperationType G.OperationTypeQuery)
167170
pure $ (ExecStepAction actionExecution (ActionsInfo actionName fch) remoteJoins, [actionsModel])
168171
RFRaw r -> fmap (,[]) $ flip onLeft throwError =<< executeIntrospection userInfo r introspectionDisabledRoles

server/src-lib/Hasura/GraphQL/Explain.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import Hasura.RQL.Types.Roles (adminRoleName)
3434
import Hasura.RQL.Types.Schema.Options qualified as Options
3535
import Hasura.RQL.Types.SchemaCache
3636
import Hasura.SQL.AnyBackend qualified as AB
37+
import Hasura.Server.Init.Config (ResponseInternalErrorsConfig)
3738
import Hasura.Session (UserAdminSecret (..), UserInfo, UserRoleBuild (..), mkSessionVariablesText, mkUserInfo)
3839
import Hasura.Tracing (MonadTrace)
3940
import Language.GraphQL.Draft.Syntax qualified as G
@@ -99,8 +100,9 @@ explainGQLQuery ::
99100
Maybe (CredentialCache AgentLicenseKey) ->
100101
[HTTP.Header] ->
101102
GQLExplain ->
103+
ResponseInternalErrorsConfig ->
102104
m EncJSON
103-
explainGQLQuery nullInNonNullableVariables sc agentLicenseKey reqHeaders (GQLExplain query userVarsRaw maybeIsRelay) = do
105+
explainGQLQuery nullInNonNullableVariables sc agentLicenseKey reqHeaders (GQLExplain query userVarsRaw maybeIsRelay) responseErrorsConfig = do
104106
-- NOTE!: we will be executing what follows as though admin role. See e.g. notes in explainField:
105107
userInfo <-
106108
mkUserInfo
@@ -133,7 +135,7 @@ explainGQLQuery nullInNonNullableVariables sc agentLicenseKey reqHeaders (GQLExp
133135
-- TODO: validate directives here
134136
-- query-tags are not necessary for EXPLAIN API
135137
-- RequestContext are not necessary for EXPLAIN API
136-
((validSubscription, _), _) <- E.buildSubscriptionPlan userInfo unpreparedQueries parameterizedQueryHash reqHeaders (_unOperationName <$> _grOperationName query)
138+
((validSubscription, _), _) <- E.buildSubscriptionPlan userInfo unpreparedQueries parameterizedQueryHash reqHeaders (_unOperationName <$> _grOperationName query) responseErrorsConfig
137139
case validSubscription of
138140
E.SEAsyncActionsWithNoRelationships _ -> throw400 NotSupported "async action query fields without relationships to table cannot be explained"
139141
E.SEOnSourceDB (E.SSLivequery actionIds liveQueryBuilder) -> do

server/src-lib/Hasura/GraphQL/Transport/HTTP.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,9 @@ runGQ ::
318318
[HTTP.Header] ->
319319
E.GraphQLQueryType ->
320320
GQLReqUnparsed ->
321+
ResponseInternalErrorsConfig ->
321322
m (GQLQueryOperationSuccessLog, HttpResponse (Maybe GQResponse, EncJSON))
322-
runGQ env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHeaders queryType reqUnparsed = do
323+
runGQ env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHeaders queryType reqUnparsed responseErrorsConfig = do
323324
getModelInfoLogStatus' <- runGetModelInfoLogStatus
324325
modelInfoLogStatus <- liftIO getModelInfoLogStatus'
325326
let gqlMetrics = pmGraphQLRequestMetrics prometheusMetrics
@@ -360,6 +361,7 @@ runGQ env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicen
360361
queryParts
361362
maybeOperationName
362363
reqId
364+
responseErrorsConfig
363365

364366
-- 4. Execute the execution plan producing a 'AnnotatedResponse'.
365367
(response, queryCachedStatus, modelInfoFromExecution) <- executePlan reqParsed runLimits execPlan
@@ -755,7 +757,7 @@ runGQBatched ::
755757
runGQBatched env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId responseErrorsConfig userInfo ipAddress reqHdrs queryType query =
756758
case query of
757759
GQLSingleRequest req -> do
758-
(gqlQueryOperationLog, httpResp) <- runGQ env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHdrs queryType req
760+
(gqlQueryOperationLog, httpResp) <- runGQ env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHdrs queryType req responseErrorsConfig
759761
let httpLoggingGQInfo = (CommonHttpLogMetadata L.RequestModeSingle (Just (GQLSingleRequest (GQLQueryOperationSuccess gqlQueryOperationLog))), (PQHSetSingleton (gqolParameterizedQueryHash gqlQueryOperationLog)))
760762
pure (httpLoggingGQInfo, snd <$> httpResp)
761763
GQLBatchedReqs reqs -> do
@@ -768,7 +770,7 @@ runGQBatched env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger age
768770
flip HttpResponse []
769771
. encJFromList
770772
. map (either (encJFromJEncoding . encodeGQErr includeInternal) _hrBody)
771-
responses <- for reqs \req -> fmap (req,) $ try $ (fmap . fmap . fmap) snd $ runGQ env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHdrs queryType req
773+
responses <- for reqs \req -> fmap (req,) $ try $ (fmap . fmap . fmap) snd $ runGQ env sqlGenCtx sc enableAL readOnlyMode prometheusMetrics logger agentLicenseKey reqId userInfo ipAddress reqHdrs queryType req responseErrorsConfig
772774
let requestsOperationLogs = map fst $ rights $ map snd responses
773775
batchOperationLogs =
774776
map

server/src-lib/Hasura/GraphQL/Transport/WSServerApp.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,10 @@ createWSServerApp enabledLogTypes serverEnv connInitTimeout licenseKeyCache = \
9696
liftIO $ incWebsocketConnections $ pmConnections prometheusMetrics
9797
flip runReaderT serverEnv $ onConn rid rh ip (wsActions sp)
9898

99-
onMessageHandler conn bs sp =
99+
onMessageHandler conn bs sp = do
100+
responseErrorsConfig <- liftIO $ acResponseInternalErrorsConfig <$> getAppContext (_wseAppStateRef serverEnv)
100101
mask_
101-
$ onMessage enabledLogTypes getAuthMode serverEnv conn bs (wsActions sp) licenseKeyCache
102+
$ onMessage enabledLogTypes getAuthMode serverEnv conn bs (wsActions sp) licenseKeyCache responseErrorsConfig
102103

103104
onCloseHandler conn = mask_ do
104105
granularPrometheusMetricsState <- runGetPrometheusMetricsGranularity

server/src-lib/Hasura/GraphQL/Transport/WebSocket.hs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ import Hasura.Server.Auth
9191
resolveUserInfo,
9292
)
9393
import Hasura.Server.Cors
94-
import Hasura.Server.Init.Config (KeepAliveDelay (..))
94+
import Hasura.Server.Init.Config (KeepAliveDelay (..), ResponseInternalErrorsConfig)
9595
import Hasura.Server.Limits
9696
( HasResourceLimits (..),
9797
ResourceLimits (..),
@@ -445,8 +445,9 @@ onStart ::
445445
ShouldCaptureQueryVariables ->
446446
StartMsg ->
447447
WS.WSActions WSConnData ->
448+
ResponseInternalErrorsConfig ->
448449
m ()
449-
onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables (StartMsg opId q) onMessageActions = catchAndIgnore $ do
450+
onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables (StartMsg opId q) onMessageActions responseErrorsConfig = catchAndIgnore $ do
450451
modelInfoLogStatus' <- runGetModelInfoLogStatus
451452
modelInfoLogStatus <- liftIO modelInfoLogStatus'
452453
timerTot <- startTimer
@@ -513,6 +514,7 @@ onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables
513514
queryParts
514515
maybeOperationName
515516
requestId
517+
responseErrorsConfig
516518

517519
(parameterizedQueryHash, execPlan, modelInfoList) <- onLeft execPlanE (withComplete . preExecErr requestId (Just gqlOpType))
518520

@@ -1090,8 +1092,9 @@ onMessage ::
10901092
LBS.ByteString ->
10911093
WS.WSActions WSConnData ->
10921094
Maybe (CredentialCache AgentLicenseKey) ->
1095+
ResponseInternalErrorsConfig ->
10931096
m ()
1094-
onMessage enabledLogTypes authMode serverEnv wsConn msgRaw onMessageActions agentLicenseKey =
1097+
onMessage enabledLogTypes authMode serverEnv wsConn msgRaw onMessageActions agentLicenseKey responseErrorsConfig = do
10951098
Tracing.newTrace (_wseTraceSamplingPolicy serverEnv) "websocket" do
10961099
case J.eitherDecode msgRaw of
10971100
Left e -> do
@@ -1115,7 +1118,7 @@ onMessage enabledLogTypes authMode serverEnv wsConn msgRaw onMessageActions agen
11151118
if _mcAnalyzeQueryVariables (scMetricsConfig schemaCache)
11161119
then CaptureQueryVariables
11171120
else DoNotCaptureQueryVariables
1118-
onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables startMsg onMessageActions
1121+
onStart enabledLogTypes agentLicenseKey serverEnv wsConn shouldCaptureVariables startMsg onMessageActions responseErrorsConfig
11191122
CMStop stopMsg -> do
11201123
granularPrometheusMetricsState <- runGetPrometheusMetricsGranularity
11211124
onStop serverEnv wsConn stopMsg granularPrometheusMetricsState

server/src-lib/Hasura/Server/App.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,9 +648,10 @@ gqlExplainHandler query = do
648648
onlyAdmin
649649
schemaCache <- asks hcSchemaCache
650650
reqHeaders <- asks hcReqHeaders
651+
responseErrorsConfig <- asks (acResponseInternalErrorsConfig . hcAppContext)
651652
licenseKeyCache <- asks hcLicenseKeyCache
652653
nullInNonNullableVariables <- asks (nullInNonNullableVariables . acSQLGenCtx . hcAppContext)
653-
res <- GE.explainGQLQuery nullInNonNullableVariables (lastBuiltSchemaCache schemaCache) licenseKeyCache reqHeaders query
654+
res <- GE.explainGQLQuery nullInNonNullableVariables (lastBuiltSchemaCache schemaCache) licenseKeyCache reqHeaders query responseErrorsConfig
654655
return $ HttpResponse res []
655656

656657
v1Alpha1PGDumpHandler :: (MonadIO m, MonadError QErr m, MonadReader HandlerCtx m) => PGD.PGDumpReqBody -> m APIResp
@@ -930,6 +931,7 @@ httpApp setupHook appStateRef AppEnv {..} consoleType ekgStore closeWebsocketsOn
930931
setHeader jsonHeader
931932
Spock.lazyBytes $ encode $ object $ ["version" .= currentVersion] <> extraData
932933

934+
responseErrorsConfig <- liftIO $ acResponseInternalErrorsConfig <$> getAppContext appStateRef
933935
let customEndpointHandler ::
934936
RestRequest Spock.SpockMethod ->
935937
Handler m (HttpLogGraphQLInfo, APIResp)
@@ -952,7 +954,7 @@ httpApp setupHook appStateRef AppEnv {..} consoleType ekgStore closeWebsocketsOn
952954
Spock.PATCH -> pure EP.PATCH
953955
other -> throw400 BadRequest $ "Method " <> tshow other <> " not supported."
954956
_ -> throw400 BadRequest $ "Nonstandard method not allowed for REST endpoints"
955-
fmap JSONResp <$> runCustomEndpoint acEnvironment acSQLGenCtx schemaCache acEnableAllowlist appEnvEnableReadOnlyMode appEnvPrometheusMetrics (_lsLogger appEnvLoggers) appEnvLicenseKeyCache requestId userInfo reqHeaders ipAddress req endpoints
957+
fmap JSONResp <$> runCustomEndpoint acEnvironment acSQLGenCtx schemaCache acEnableAllowlist appEnvEnableReadOnlyMode appEnvPrometheusMetrics (_lsLogger appEnvLoggers) appEnvLicenseKeyCache requestId userInfo reqHeaders ipAddress req endpoints responseErrorsConfig
956958

957959
-- See Issue #291 for discussion around restified feature
958960
Spock.hookRouteAll ("api" <//> "rest" <//> Spock.wildcard) $ \wildcard -> do

0 commit comments

Comments
 (0)