Skip to content

Commit

Permalink
check function name and argument names for GraphQL compliance
Browse files Browse the repository at this point in the history
  • Loading branch information
rakeshkky committed Jan 22, 2019
1 parent 5027a8c commit 4fae992
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
8 changes: 4 additions & 4 deletions server/src-lib/Hasura/GraphQL/Schema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ type SelField = Either PGColInfo (RelInfo, Bool, AnnBoolExpSQL, Maybe Int, Bool)
qualObjectToName :: (ToTxt a) => QualifiedObject a -> G.Name
qualObjectToName = G.Name . snakeCaseQualObject

isValidTableName :: QualifiedTable -> Bool
isValidTableName = isValidName . qualObjectToName
isValidObjectName :: (ToTxt a) => QualifiedObject a -> Bool
isValidObjectName = isValidName . qualObjectToName

isValidField :: FieldInfo -> Bool
isValidField = \case
Expand All @@ -168,7 +168,7 @@ isValidField = \case
where
isColEligible = isValidName . G.Name . getPGColTxt
isRelEligible rn rt = isValidName (G.Name $ getRelTxt rn)
&& isValidTableName rt
&& isValidObjectName rt

upsertable :: [ConstraintName] -> Bool -> Bool -> Bool
upsertable uniqueOrPrimaryCons isUpsertAllowed view =
Expand Down Expand Up @@ -1903,7 +1903,7 @@ mkGCtxMap tableCache functionCache = do
mkGCtx ty flds insCtxMap
where
tableFltr ti = not (tiSystemDefined ti)
&& isValidTableName (tiName ti)
&& isValidObjectName (tiName ti)


-- mkGCtx :: TyAgg -> RootFlds -> InsCtxMap -> GCtx
Expand Down
39 changes: 28 additions & 11 deletions server/src-lib/Hasura/RQL/DDL/Schema/Function.hs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
module Hasura.RQL.DDL.Schema.Function where

import Hasura.GraphQL.Utils (isValidName, showNames)
import Hasura.Prelude
import Hasura.RQL.Types
import Hasura.SQL.Types

import Data.Aeson
import Data.Aeson.Casing
import Data.Aeson.TH
import Language.Haskell.TH.Syntax (Lift)
import Language.Haskell.TH.Syntax (Lift)

import qualified Hasura.GraphQL.Schema as GS
import qualified Hasura.GraphQL.Schema as GS
import qualified Language.GraphQL.Draft.Syntax as G

import qualified Data.HashMap.Strict as M
import qualified Data.Sequence as Seq
import qualified Data.Text as T
import qualified Database.PG.Query as Q
import qualified Data.HashMap.Strict as M
import qualified Data.Sequence as Seq
import qualified Data.Text as T
import qualified Database.PG.Query as Q


data PGTypType
Expand Down Expand Up @@ -62,6 +64,15 @@ mkFunctionArgs tys argNames =
mkArg "" ty = FunctionArg Nothing ty
mkArg n ty = flip FunctionArg ty $ Just $ FunctionArgName n

validateFuncArgs :: MonadError QErr m => [FunctionArg] -> m ()
validateFuncArgs args =
unless (null invalidArgs) $ throw400 NotSupported $
"arguments: " <> showNames invalidArgs
<> " are not in compliance with GraphQL spec"
where
funcArgsText = mapMaybe (fmap getFuncArgNameTxt . faName) args
invalidArgs = filter (not . isValidName) $ map G.Name funcArgsText

mkFunctionInfo :: QualifiedFunction -> RawFuncInfo -> Q.TxE QErr FunctionInfo
mkFunctionInfo qf rawFuncInfo = do
-- throw error if function has variadic arguments
Expand All @@ -78,10 +89,13 @@ mkFunctionInfo qf rawFuncInfo = do
-- throw error if return type is not a valid table
assertTableExists retTable $ "return type " <> retTable <<> " is not a valid table"

-- inpArgTyps <- mapM fetchTypNameFromOid inpArgTypIds
let funcArgs = Seq.fromList $ mkFunctionArgs inpArgTyps inpArgNames
let funcArgs = mkFunctionArgs inpArgTyps inpArgNames

validateFuncArgs funcArgs

let funcArgsSeq = Seq.fromList funcArgs
dep = SchemaDependency (SOTable retTable) "table"
return $ FunctionInfo qf False funTy funcArgs retTable [dep]
return $ FunctionInfo qf False funTy funcArgsSeq retTable [dep]
where
RawFuncInfo hasVariadic funTy retSn retN retTyTyp retSet inpArgTyps inpArgNames = rawFuncInfo

Expand Down Expand Up @@ -162,9 +176,12 @@ trackFunctionP2 :: (QErrM m, CacheRWM m, MonadTx m)
trackFunctionP2 qf = do
sc <- askSchemaCache
let defGCtx = scDefaultRemoteGCtx sc
funcNameGQL = GS.qualObjectToName qf
-- check function name is in compliance with GraphQL spec
unless (isValidName funcNameGQL) $ throw400 NotSupported $
"function name " <> qf <<> " is not in compliance with GraphQL spec"
-- check for conflicts in remote schema
GS.checkConflictingNode defGCtx $ GS.qualObjectToName qf

GS.checkConflictingNode defGCtx funcNameGQL
trackFunctionP2Setup qf
liftTx $ saveFunctionToCatalog qf False
return successMsg
Expand Down

0 comments on commit 4fae992

Please sign in to comment.