-
Notifications
You must be signed in to change notification settings - Fork 515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add vcdm 2.0 model and context #3436
base: main
Are you sure you want to change the base?
Add vcdm 2.0 model and context #3436
Conversation
Signed-off-by: PatStLouis <[email protected]>
… date with vcdm 1.1 Signed-off-by: PatStLouis <[email protected]>
Signed-off-by: PatStLouis <[email protected]>
Signed-off-by: PatStLouis <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some early review comments
@@ -253,13 +289,16 @@ def proof(self, proof: LDProof): | |||
def __eq__(self, o: object) -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can maybe be made more legible with:
def __eq__(self, o: object) -> bool:
"""Check equality."""
if not isinstance(o, VerifiableCredential):
return False
return all(
getattr(self, attr) == getattr(o, attr)
for attr in vars(self)
)
or, if vars(self)
returns extra properties that should be ignored, then define the relevant attributes in a list:
def __eq__(self, o: object) -> bool:
"""Check equality."""
if not isinstance(o, VerifiableCredential):
return False
attributes = [
"context", "id", "type", "issuer", "issuance_date",
"expiration_date", "valid_from", "valid_until",
"credential_subject", "credential_status", "proof", "extra"
]
return all(
getattr(self, attr) == getattr(o, attr)
for attr in attributes
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll look into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's probably more than one place that this pattern is used and can be improved. So, could perhaps change all at once in a separate PR. But I haven't checked where else it's done.
I'm just a fan of making things more readable / maintainable :-)
"""Validate input value.""" | ||
length = len(value) | ||
|
||
if length < 1 or value[0] != CredentialContext.FIRST_CONTEXT: | ||
if length < 1 or value[0] not in CredentialContext.FIRST_CONTEXT: | ||
raise ValidationError( | ||
f"First context must be {CredentialContext.FIRST_CONTEXT}" | ||
f"First context must be one of {CredentialContext.FIRST_CONTEXT}" | ||
) | ||
|
||
return value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If value
is None, there would be a TypeError.
Probably worth asserting that value is of expected type before calling len or [0]
.
(because a dev could try call with a string, and get unclear error message).
Something like:
def __call__(self, value: List[str]) -> List[str]:
"""Validate input value."""
if not isinstance(value, list):
raise ValidationError("Value must be a non-empty list.")
if not value or value[0] not in CredentialContext.FIRST_CONTEXT:
raise ValidationError(
f"First context must be one of {CredentialContext.FIRST_CONTEXT}"
)
return value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can implement this, however this type of validation would of been done at the datamodel version in the class invoking this validation
@@ -875,8 +875,11 @@ def __call__(self, value): | |||
class CredentialContext(Validator): | |||
"""Credential Context.""" | |||
|
|||
FIRST_CONTEXT = "https://www.w3.org/2018/credentials/v1" | |||
EXAMPLE = [FIRST_CONTEXT, "https://www.w3.org/2018/credentials/examples/v1"] | |||
FIRST_CONTEXT = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps rename to a VALID_CONTEXTS
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I agree
@@ -271,6 +274,12 @@ async def prepare_credential( | |||
and SECURITY_CONTEXT_ED25519_2020_URL not in credential.context_urls | |||
): | |||
credential.add_context(SECURITY_CONTEXT_ED25519_2020_URL) | |||
# Limit VCDM 2.0 with Ed25519Signature2020 | |||
elif ( | |||
options.proof_type == Ed25519Signature2018.signature_type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps better to have options.proof_type != Ed25519Signature2020.signature_type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree, maybe I should change the comment. We want to explicitly prevent the 2018 version, other types might be fine down the line. I mentioned 2020 because this is the only other current registered type, but the BLS2020 stuff would be okay as well.
The limitation of 2018 is because it was implicitly included in the vcdm 1.1 context, while 2020 has its own unique context url.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. Soon after I commented, I thought that the best would be for there to be a list of supported signature types, and then the condition would just assert the requested type is in the list. That would allow the error message to indicate "please use one of the supported types: ", and can easily be expanded in the future
Quality Gate failedFailed conditions |
Needs issuanceDate validation for vcdm 1.0 (add a current timestamp if absent)
Needs hooking up with didcomm