Skip to content

Commit

Permalink
Add checks for max length of fields in CIP-0119
Browse files Browse the repository at this point in the history
  • Loading branch information
palas committed Dec 17, 2024
1 parent 0d3807b commit f5b01c4
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 4 deletions.
1 change: 1 addition & 0 deletions cardano-api/cardano-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ library internal
Cardano.Api.Experimental.Tx
Cardano.Api.Feature
Cardano.Api.Fees
Cardano.Api.GeneralParsers
Cardano.Api.Genesis
Cardano.Api.GenesisParameters
Cardano.Api.Governance.Actions.MetadataValidation
Expand Down
9 changes: 5 additions & 4 deletions cardano-api/internal/Cardano/Api/DRepMetadata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Data.ByteString (ByteString)
import Data.Either.Combinators (mapRight, maybeToRight)
import Data.Text (Text)
import GHC.Generics (Generic)
import Cardano.Api.GeneralParsers (textWithMaxLength)

-- ----------------------------------------------------------------------------
-- DRep metadata
Expand Down Expand Up @@ -119,11 +120,11 @@ instance FromJSON Body where
parseJSON = withObject "Body" $ \v ->
Body
<$> v .:? "paymentAddress"
<*> v .: "givenName"
<*> (v .: "givenName" >>= textWithMaxLength "givenName" 80)
<*> v .:? "image"
<*> v .:? "objectives"
<*> v .:? "motivations"
<*> v .:? "qualifications"
<*> (v .:? "objectives" >>= traverse (textWithMaxLength "objectives" 1000))
<*> (v .:? "motivations" >>= traverse (textWithMaxLength "motivations" 1000))
<*> (v .:? "qualifications" >>= traverse (textWithMaxLength "qualifications" 1000))
<*> v .:? "doNotList"
<*> v .:? "references"

Expand Down
22 changes: 22 additions & 0 deletions cardano-api/internal/Cardano/Api/GeneralParsers.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Cardano.Api.GeneralParsers (textWithMaxLength) where

import Data.Aeson.Types (Parser, Value, parseJSON)
import Data.Text (Text)
import qualified Data.Text as T

-- | Parser for 'Text' that validates that the number of characters is
-- under a given maximum. The 'String' parameter is meant to be the name
-- of the field in order to be able to give context in case of error.
textWithMaxLength :: String -> Int -> Value -> Parser Text
textWithMaxLength fieldName maxLen value = do
txt <- parseJSON value
if T.length txt <= maxLen
then pure txt
else
fail $
"key \""
++ fieldName
++ "\" exceeds maximum length of "
++ show maxLen
++ " characters. Got length: "
++ show (T.length txt)
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ tests =
, testProperty
"Negative smoke test for DRep registration anchor data JSON schema"
prop_negative_smoke_test_drep_registration_anchor_data_json_schema
, testProperty
"Given name too long smoke test for DRep registration anchor data JSON schema"
prop_given_name_too_long_smoke_test_drep_registration_anchor_data_json_schema
, testProperty
"Positive smoke test for no confidence anchor data JSON schema"
prop_positive_smoke_test_no_confidence_anchor_data_json_schema
Expand Down Expand Up @@ -62,6 +65,17 @@ prop_negative_smoke_test_drep_registration_anchor_data_json_schema = propertyOnc
value <- H.evalEither eitherValue
validateDRepAnchorData (DRepMetadata value) === Left "Error in $.body: key \"givenName\" not found"

prop_given_name_too_long_smoke_test_drep_registration_anchor_data_json_schema :: Property
prop_given_name_too_long_smoke_test_drep_registration_anchor_data_json_schema = propertyOnce $ do
(eitherValue :: Either (FileError Any) ByteString) <-
readByteStringFile
( File "test/cardano-api-test/files/input/gov-anchor-data/too-long-given-name-drep-metadata.jsonld"
:: File DRepMetadata In
)
value <- H.evalEither eitherValue
validateDRepAnchorData (DRepMetadata value)
=== Left "Error in $.body: key \"givenName\" exceeds maximum length of 80 characters. Got length: 90"

prop_positive_smoke_test_no_confidence_anchor_data_json_schema :: Property
prop_positive_smoke_test_no_confidence_anchor_data_json_schema = propertyOnce $ do
(eitherValue :: Either (FileError Any) ByteString) <-
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"@context": {
"CIP100": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#",
"CIP119": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0119/README.md#",
"hashAlgorithm": "CIP100:hashAlgorithm",
"body": {
"@id": "CIP119:body",
"@context": {
"givenName": "CIP119:givenName"
}
}
},
"hashAlgorithm": "blake2b-256",
"body": {
"givenName": "This name is way too long for it to fit in this field, so it should be rejected by the API"
}
}

0 comments on commit f5b01c4

Please sign in to comment.