graphql-engine/server/src-lib/Hasura/RQL/DDL/ApiLimit.hs
pranshi06 823fca2d1c multitenant, server: throw a warning if user sets a time limit greater than the system limit
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7315
Co-authored-by: Sean Park-Ross <94021366+seanparkross@users.noreply.github.com>
GitOrigin-RevId: 639a99fc0651b74f187108613be3086bc52e3a65
2023-03-13 11:45:45 +00:00

98 lines
3.6 KiB
Haskell

module Hasura.RQL.DDL.ApiLimit
( runRemoveApiLimits,
runSetApiLimits,
warningMessage,
compareTimeLimitWith,
MonadGetApiTimeLimit (..),
)
where
import Control.Lens ((.~))
import Hasura.Base.Error
import Hasura.EncJSON
import Hasura.Prelude
import Hasura.RQL.DDL.Warnings
import Hasura.RQL.Types.ApiLimit
import Hasura.RQL.Types.Common
import Hasura.RQL.Types.Metadata
import Hasura.RQL.Types.Metadata.Object
import Hasura.RQL.Types.SchemaCache.Build
import Hasura.Tracing (TraceT)
runSetApiLimits ::
(MonadError QErr m, MetadataM m, CacheRWM m, MonadGetApiTimeLimit m) =>
ApiLimit ->
m EncJSON
runSetApiLimits al = do
let userTimeLimitAPILimit = _lGlobal <$> _alTimeLimit al
-- If both user time limit and cloud limit are present then check if the user time limit API limit is greater than the
-- cloud time limit API limit. Otheriwse, apply the API limit configuration (without the warning).
warningResultEither <- compareTimeLimitWith userTimeLimitAPILimit
case warningResultEither of
Left warning -> do
successMsgWithWarning <- successMsgWithWarnings $ warn warning
setApiLimit successMsgWithWarning
Right _ -> setApiLimit successMsg
where
setApiLimit successMessage = do
withNewInconsistentObjsCheck $
buildSchemaCache $
MetadataModifier $
metaApiLimits .~ al
return successMessage
-- This function compares the user time_limit and the cloud time_limit (used in both set_api_limit and replace_metadata
-- APIs). The function returns either a metadata warning or `()`
compareTimeLimitWith :: MonadGetApiTimeLimit m => Maybe MaxTime -> m (Either MetadataWarning ())
compareTimeLimitWith userTimeLimitMaybe = do
cloudApiTimeLimit <- runGetApiTimeLimit
let compareTimeLimitResultEither =
case (userTimeLimitMaybe, cloudApiTimeLimit) of
(Just userTimeLimitAPILimit, Just cloudTimeLimit) -> do
if userTimeLimitAPILimit > cloudTimeLimit
then Left $ warningMessage userTimeLimitAPILimit cloudTimeLimit
else Right ()
_ -> Right ()
pure compareTimeLimitResultEither
-- warning message if the user time limit API limit is greater than the cloud time limit API limit
warningMessage :: MaxTime -> MaxTime -> MetadataWarning
warningMessage userTimeLimit cloudTimeLimit =
MetadataWarning (MOSource defaultSource) $
"the configured time limit: "
<> tshow (seconds $ unMaxTime userTimeLimit)
<> " exceeds the project time limit: "
<> tshow (seconds $ unMaxTime cloudTimeLimit)
<> ". Time limit of "
<> tshow (seconds $ unMaxTime cloudTimeLimit)
<> " will be applied"
runRemoveApiLimits ::
(MonadError QErr m, MetadataM m, CacheRWM m) =>
m EncJSON
runRemoveApiLimits = do
withNewInconsistentObjsCheck $
buildSchemaCache $
MetadataModifier $
metaApiLimits .~ emptyApiLimit
return successMsg
class Monad m => MonadGetApiTimeLimit m where
runGetApiTimeLimit ::
m (Maybe MaxTime)
instance (MonadGetApiTimeLimit m) => MonadGetApiTimeLimit (ReaderT r m) where
runGetApiTimeLimit = lift runGetApiTimeLimit
instance (MonadGetApiTimeLimit m) => MonadGetApiTimeLimit (MetadataT m) where
runGetApiTimeLimit = lift runGetApiTimeLimit
instance (MonadGetApiTimeLimit m) => MonadGetApiTimeLimit (TraceT m) where
runGetApiTimeLimit = lift runGetApiTimeLimit
instance (MonadGetApiTimeLimit m) => MonadGetApiTimeLimit (ExceptT e m) where
runGetApiTimeLimit = lift runGetApiTimeLimit
instance (MonadGetApiTimeLimit m) => MonadGetApiTimeLimit (StateT w m) where
runGetApiTimeLimit = lift runGetApiTimeLimit