+16
-10
@@ -28,7 +28,8 @@ type RequestBody = BL.ByteString
|
|||||||
data Action = ActionCreate | ActionRead
|
data Action = ActionCreate | ActionRead
|
||||||
| ActionUpdate | ActionDelete
|
| ActionUpdate | ActionDelete
|
||||||
| ActionInfo | ActionInvoke
|
| ActionInfo | ActionInvoke
|
||||||
| ActionUnknown BS.ByteString deriving Eq
|
| ActionInappropriate
|
||||||
|
deriving Eq
|
||||||
-- | The target db object of a user action
|
-- | The target db object of a user action
|
||||||
data Target = TargetIdent QualifiedIdentifier
|
data Target = TargetIdent QualifiedIdentifier
|
||||||
| TargetProc QualifiedIdentifier
|
| TargetProc QualifiedIdentifier
|
||||||
@@ -78,15 +79,20 @@ data ApiRequest = ApiRequest {
|
|||||||
-- | Examines HTTP request and translates it into user intent.
|
-- | Examines HTTP request and translates it into user intent.
|
||||||
userApiRequest :: Schema -> Request -> RequestBody -> ApiRequest
|
userApiRequest :: Schema -> Request -> RequestBody -> ApiRequest
|
||||||
userApiRequest schema req reqBody =
|
userApiRequest schema req reqBody =
|
||||||
let action = case method of
|
let action =
|
||||||
"GET" -> ActionRead
|
if isTargetingProc
|
||||||
"POST" -> if isTargetingProc
|
then
|
||||||
then ActionInvoke
|
if method == "POST"
|
||||||
else ActionCreate
|
then ActionInvoke
|
||||||
"PATCH" -> ActionUpdate
|
else ActionInappropriate
|
||||||
"DELETE" -> ActionDelete
|
else
|
||||||
"OPTIONS" -> ActionInfo
|
case method of
|
||||||
other -> ActionUnknown other
|
"GET" -> ActionRead
|
||||||
|
"POST" -> ActionCreate
|
||||||
|
"PATCH" -> ActionUpdate
|
||||||
|
"DELETE" -> ActionDelete
|
||||||
|
"OPTIONS" -> ActionInfo
|
||||||
|
_ -> ActionInappropriate
|
||||||
target = case path of
|
target = case path of
|
||||||
[] -> TargetRoot
|
[] -> TargetRoot
|
||||||
[table] -> TargetIdent
|
[table] -> TargetIdent
|
||||||
|
|||||||
@@ -179,16 +179,14 @@ app dbStructure conf reqBody req =
|
|||||||
body <- encode <$> H.query schema accessibleTables
|
body <- encode <$> H.query schema accessibleTables
|
||||||
return $ responseLBS status200 [jsonH] $ cs body
|
return $ responseLBS status200 [jsonH] $ cs body
|
||||||
|
|
||||||
(ActionUnknown _, _, _) -> return notFound
|
(ActionInappropriate, _, _) -> return $ responseLBS status405 [] ""
|
||||||
|
|
||||||
(_, TargetProc _, _) -> return $ responseLBS status405 [] ""
|
|
||||||
|
|
||||||
(_, TargetUnknown _, _) -> return notFound
|
|
||||||
|
|
||||||
(_, _, Just (PayloadParseError e)) ->
|
(_, _, Just (PayloadParseError e)) ->
|
||||||
return $ responseLBS status400 [jsonH] $
|
return $ responseLBS status400 [jsonH] $
|
||||||
cs (formatGeneralError "Cannot parse request payload" (cs e))
|
cs (formatGeneralError "Cannot parse request payload" (cs e))
|
||||||
|
|
||||||
|
(_, TargetUnknown _, _) -> return notFound
|
||||||
|
|
||||||
(_, _, _) -> return notFound
|
(_, _, _) -> return notFound
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -386,6 +386,16 @@ spec struct c = around (withApp cfgDefault struct c) $ do
|
|||||||
post "/rpc/sayhello" [json| { "name": "world" } |] `shouldRespondWith`
|
post "/rpc/sayhello" [json| { "name": "world" } |] `shouldRespondWith`
|
||||||
[json| [{"sayhello":"Hello, world"}] |]
|
[json| [{"sayhello":"Hello, world"}] |]
|
||||||
|
|
||||||
|
context "improper input" $ do
|
||||||
|
it "rejects unknown content type even if payload is good" $
|
||||||
|
request methodPost "/rpc/sayhello"
|
||||||
|
(acceptHdrs "audio/mpeg3") [json| { "name": "world" } |]
|
||||||
|
`shouldRespondWith` 415
|
||||||
|
it "rejects malformed json payload" $
|
||||||
|
request methodPost "/rpc/sayhello"
|
||||||
|
(acceptHdrs "application/json") "sdfsdf"
|
||||||
|
`shouldRespondWith` 400
|
||||||
|
|
||||||
context "unsupported verbs" $ do
|
context "unsupported verbs" $ do
|
||||||
it "DELETE fails" $
|
it "DELETE fails" $
|
||||||
request methodDelete "/rpc/sayhello" [] ""
|
request methodDelete "/rpc/sayhello" [] ""
|
||||||
|
|||||||
Reference in New Issue
Block a user