diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs index 7d16e1bb7..b284c822f 100644 --- a/src/PostgREST/App.hs +++ b/src/PostgREST/App.hs @@ -370,9 +370,6 @@ handleUpdate identifier context@(RequestContext _ _ ApiRequest{..} _) = do handleSingleUpsert :: QualifiedIdentifier -> RequestContext-> DbHandler Wai.Response handleSingleUpsert identifier context@(RequestContext _ ctxDbStructure ApiRequest{..} _) = do - when (iTopLevelRange /= RangeQuery.allRange) $ - throwError Error.PutRangeNotAllowedError - let pkCols = maybe mempty tablePKCols $ M.lookup identifier $ dbTables ctxDbStructure WriteQueryResult{..} <- writeQuery MutationSingleUpsert identifier False pkCols context diff --git a/src/PostgREST/Error.hs b/src/PostgREST/Error.hs index d6053f7a8..10a9276be 100644 --- a/src/PostgREST/Error.hs +++ b/src/PostgREST/Error.hs @@ -54,20 +54,21 @@ class (JSON.ToJSON a) => PgrstError a where errorResponseFor err = responseLBS (status err) (headers err) $ errorPayload err instance PgrstError ApiRequestError where - status ActionInappropriate = HTTP.status405 - status AmbiguousRelBetween{} = HTTP.status300 - status AmbiguousRpc{} = HTTP.status300 - status ContentTypeError{} = HTTP.status415 - status InvalidBody{} = HTTP.status400 - status InvalidFilters = HTTP.status405 - status InvalidRange = HTTP.status416 - status NoRelBetween{} = HTTP.status400 - status NoRpc{} = HTTP.status404 - status NotEmbedded{} = HTTP.status400 - status ParseRequestError{} = HTTP.status400 - status QueryParamError{} = HTTP.status400 - status UnacceptableSchema{} = HTTP.status406 - status LimitNoOrderError = HTTP.status400 + status ActionInappropriate = HTTP.status405 + status AmbiguousRelBetween{} = HTTP.status300 + status AmbiguousRpc{} = HTTP.status300 + status ContentTypeError{} = HTTP.status415 + status InvalidBody{} = HTTP.status400 + status InvalidFilters = HTTP.status405 + status InvalidRange = HTTP.status416 + status NoRelBetween{} = HTTP.status400 + status NoRpc{} = HTTP.status404 + status NotEmbedded{} = HTTP.status400 + status ParseRequestError{} = HTTP.status400 + status PutRangeNotAllowedError = HTTP.status400 + status QueryParamError{} = HTTP.status400 + status UnacceptableSchema{} = HTTP.status406 + status LimitNoOrderError = HTTP.status400 headers _ = [ContentType.toHeader CTApplicationJSON] @@ -97,6 +98,11 @@ instance JSON.ToJSON ApiRequestError where "message" .= message, "details" .= details, "hint" .= JSON.Null] + toJSON PutRangeNotAllowedError = JSON.object [ + "code" .= GeneralErrorCode03, + "message" .= ("Range header and limit/offset querystring parameters are not allowed for PUT" :: Text), + "details" .= JSON.Null, + "hint" .= JSON.Null] toJSON InvalidFilters = JSON.object [ "code" .= ApiRequestErrorCode05, "message" .= ("Filters must include all and only primary key columns with 'eq' operators" :: Text), @@ -326,7 +332,6 @@ data Error | OffLimitsChangesError Int64 Integer | PgErr PgError | PutMatchingPkError - | PutRangeNotAllowedError | SingularityError Integer | UnsupportedVerb Text @@ -343,7 +348,6 @@ instance PgrstError Error where status OffLimitsChangesError{} = HTTP.status400 status (PgErr err) = status err status PutMatchingPkError = HTTP.status400 - status PutRangeNotAllowedError = HTTP.status400 status SingularityError{} = HTTP.status406 status UnsupportedVerb{} = HTTP.status405 @@ -393,11 +397,6 @@ instance JSON.ToJSON Error where "details" .= JSON.Null, "hint" .= JSON.Null] - toJSON PutRangeNotAllowedError = JSON.object [ - "code" .= GeneralErrorCode03, - "message" .= ("Range header and limit/offset querystring parameters are not allowed for PUT" :: Text), - "details" .= JSON.Null, - "hint" .= JSON.Null] toJSON PutMatchingPkError = JSON.object [ "code" .= GeneralErrorCode04, "message" .= ("Payload values do not match URL in primary key column(s)" :: Text), diff --git a/src/PostgREST/Request/ApiRequest.hs b/src/PostgREST/Request/ApiRequest.hs index 43e4934e1..85422a1fd 100644 --- a/src/PostgREST/Request/ApiRequest.hs +++ b/src/PostgREST/Request/ApiRequest.hs @@ -186,6 +186,7 @@ apiRequest conf@AppConfig{..} dbStructure req reqBody queryparams@QueryParams{.. | shouldParsePayload && isLeft payload = either (Left . InvalidBody) witness payload | not expectParams && not (L.null qsParams) = Left $ ParseRequestError "Unexpected param or filter missing operator" ("Failed to parse " <> show qsParams) | method `elem` ["PATCH", "DELETE"] && not (null qsRanges) && null qsOrder = Left LimitNoOrderError + | method == "PUT" && topLevelRange /= allRange = Left PutRangeNotAllowedError | otherwise = do acceptContentType <- findAcceptContentType conf action path accepts checkedTarget <- target diff --git a/src/PostgREST/Request/Types.hs b/src/PostgREST/Request/Types.hs index 5f58729ea..2dda47382 100644 --- a/src/PostgREST/Request/Types.hs +++ b/src/PostgREST/Request/Types.hs @@ -70,6 +70,7 @@ data ApiRequestError | NoRpc Text Text [Text] Bool ContentType Bool | NotEmbedded Text | ParseRequestError Text Text + | PutRangeNotAllowedError | QueryParamError QPError | UnacceptableSchema [Text]