question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add input validation to simple metadata api

See original GitHub issue

Coordinate with validation guidelines https://github.com/theupdateframework/tuf/issues/1130

Description of issue or feature request: Some suggestions:

  • Avoid schema, see secure-systems-lab/securesystemslib#183 (just don’t use it)
  • Make use of type hints for simple type validation
  • Perform additional non-metadata parameter validation at user boundary
  • Provide methods to validate JSON representation at user boundary, i.e. fail on bad json metadata in from_json_file/to_json_file method, but with option to disable check as there might be a justified reason to read or write WIP metadata to json.
  • Be lenient on bad/invalid metadata objects in memory, they might be work in progress. E.g. it might be convenient to create empty metadata and assign attributes later on.
  • Consider using in-toto style ValidationMixin (see the mixin and it’s usage for details).

Current behavior: No input validation

Expected behavior: Add input validation

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:12 (9 by maintainers)

github_iconTop GitHub Comments

4reactions
joshuaglcommented, Dec 3, 2020

The blog also mentions a Python built-in feature, i.e. Descriptors, that as per official docs seems well-suited for attribute validators. Although it looks interesting, I’m unsure if it gives us the flexibility of e.g. initializing empty objects, assigning values, and only then calling validate, which might be a desirable usage pattern (see snippet 2 in #1223 (comment)).

Descriptors look nice, and I’m all for avoid additional dependencies. I believe the pattern of: initialising empty objects, assigning values, and then validating should still work – so long as our empty objects have sane defaults. Based on 5mins experimentation in the Python interpreter:

>>> class MetadataType:
...     def __get__(self, obj, objtype=None):
...         return self.value
...     def __set__(self, obj, value):
...         if value not in ['root', 'timestamp', 'snapshot', 'targets']:
...             raise ValueError('Invalid _type field')
...         self.value = value
...
>>> class Metadata:
...     type = MetadataType()
...     def __init__(self, type):
...         self.type = type
...
>>> class Targets(Metadata):
...     def __init__(self):
...       super().__init__('targets')
...
>>> md = Metadata('badger')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
  File "<stdin>", line 6, in __set__
ValueError: Invalid _type field
>>> md = Metadata('root')
>>> md.type = 'badger'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in __set__
ValueError: Invalid _type field
>>> t = Targets()
>>> t.type
'targets'
3reactions
lukpuehcommented, Dec 3, 2020

Good thinking, @trishankatdatadog. But I agree with @joshuagl that we might not need something as powerful (Django’s validation is really tailored towards web forms and/or ORM, similar is true for WTForms, which I also briefly considered).

I think the in-toto approach is not so bad. It’s also featured in this quite interesting blog post about different instance attribute validation techniques, at least the “individual validation functions” aspect (not the neat self-inspecting mixin part).

The blog also mentions two promising validation libraries, marshmallow and pydantic, which both are actually de/serialization libraries with validation features. Given that we want to minimize dependencies (see #1165), I’m leaning towards rolling our own validation, which doesn’t even have to be that generic (see secure-systems-lab/securesystemslib#183).

The blog also mentions a Python built-in feature, i.e. Descriptors, that as per official docs seems well-suited for attribute validators. Although it looks interesting, I’m unsure if it gives us the flexibility of e.g. initializing empty objects, assigning values, and only then calling validate, which might be a desirable usage pattern (see snippet 2 in https://github.com/theupdateframework/tuf/pull/1223#issuecomment-737188686). Same reservation goes for decorators, which the blog also mentions in conjunction with descriptors. But I can check if there is a solution that involves decorators and/or descriptors that allows for said flexibility.

What I like about both the decorator and descriptor approach(es) is that they make the constraints on the attributes more visible (in the head of the class definition) than vanilla validation methods.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ValidationRule | Metadata API Developer Guide
A validation rule contains a formula or expression that evaluates the data in one or more fields and returns a value of true...
Read more >
Validation using MetaData API - Salesforce Stack Exchange
How to validate a package xml using Metadata API? Similar to what we do with changesets. First we validate, then we deploy.
Read more >
Metadata API Developer Guide
Metadata is data that describes other data. To understand how Salesforce defines metadata, contrast business data with Salesforce metadata.
Read more >
Client-side form validation - Learn web development | MDN
The simplest HTML validation feature is the required attribute. To make an input mandatory, add this attribute to the element.
Read more >
Metadata—ArcGIS Online Help | Documentation
Validate verifies that you have filled in the required fields for the metadata style. You get a message letting you know if your...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found