Skip to content
This repository has been archived by the owner on Nov 19, 2023. It is now read-only.

#245 fix validation for additionalProperties #246

Merged

Conversation

idesoto-rover
Copy link
Contributor

Fixes issues described in #245:

  • allows specifying a schema in additionalProperties and validates any extra keys in the response that are not defined in the properties section against this schema
  • additionalProperties can be an empty schema {} and this means any values are allowed in extra keys
  • additionalProperties can be True and this behaves the same as an empty schema (this was already working)

@Goldziher
Copy link
Member

Nice!

Do we need an update to the readme as well?

@sondrelg can you add sonar scanner so coverage is picked?

@sondrelg
Copy link
Member

Looks like the tests are failing on Python 3.10. From what I can tell it's not related to the PR, we just need to add this line to our dev dependencies in master.

@idesoto-rover
Copy link
Contributor Author

Do we need an update to the readme as well?

I took a look and didn't find anything in the README file that would be affected by these changes. What did you have in mind?

I thought I could add a line to the CONTRIBUTING.md file explaining how to run tests, though. I wasn't familiar with poetry and it took me a while to figure it out. Would that be OK?

@sondrelg
Copy link
Member

Go for it 👏

@Goldziher
Copy link
Member

LGTM. Thanks!

@sondrelg
Copy link
Member

I can look over this later tonight and release a patch, unless you're already doing so @Goldziher 👍

@Goldziher
Copy link
Member

I can look over this later tonight and release a patch, unless you're already doing so @Goldziher 👍

Nope, go ahead 😃

Copy link
Member

@sondrelg sondrelg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just have one question!

@@ -295,8 +295,7 @@ def test_openapi_object(
required_keys = [key for key in schema_section.get("required", []) if key not in write_only_properties]
response_keys = data.keys()
additional_properties: Optional[Union[bool, dict]] = schema_section.get("additionalProperties")
if not properties and isinstance(additional_properties, dict):
properties = additional_properties
additional_properties_allowed = additional_properties is not None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we specify

elif isinstance(additional_properties, dict):

we currently won't have any handling for non-bool/non-dict types. What do you think about amending this assignment to this, so all data types are handled?

Suggested change
additional_properties_allowed = additional_properties is not None
additional_properties_allowed = additional_properties is True or isinstance(additional_properties, dict)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

additionalProperties can only be a boolean or an object, so I think those two would be roughly equivalent. The only difference, if the schema is not considered invalid by the schema validation, would be in how we want to handle schemas where additionalProperties is defined as a different type.

So say there's a schema defined like this:

type: object
additionalProperties: 1

Do we want to allow additionalProperties in this case or not? With the is not None check we would allow them but not validate anything about them. With your proposed change we would not allow additionalProperties. I don't mind either option.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can gather, it would be possible for users to specify whatever they want, but anything other than a dict/bool/null would be a violation of the spec - does that seem right? If that's correct, we're deciding whether we think it's within the scope of this library to raise an error for the invalidity of the schema or not.

I can also see both sides, but am probably leaning towards raising an error here. Perhaps instead of the suggestion I made above, we should do something like this?

if not isinstance(additional_properties, (bool, dict, None)):
    raise OpenAPISchemaError('Invalid additional properties type')
additional_properties_allowed = additional_properties is not None

What do you think @Goldziher? 🙂

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, i agree @sondrelg - i think your last suggestion is the cleanest of what has been suggested so far.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the check and a test. Changed it a little bit because None cannot be used as a type in isinstance.

@sonarcloud
Copy link

sonarcloud bot commented Dec 18, 2021

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@Goldziher
Copy link
Member

@idesoto-rover - thanks for your work.

Linting is failing though.

I will let @sondrelg handle it from here.

@sondrelg
Copy link
Member

Nice 👏 Thanks @idesoto-rover!

I'll fix the linting when bumping the version 👍

@sondrelg sondrelg merged commit 3d3b69b into snok:master Dec 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants