Skip to content
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

Timezone inclusion [ISO 8601] for W3C VC and Proofs #1373

Merged
merged 2 commits into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""BbsBlsSignature2020 class."""

from datetime import datetime
from datetime import datetime, timezone
from pytz import utc
from typing import List, Union

from ....wallet.util import b64_to_bytes, bytes_to_b64
Expand Down Expand Up @@ -59,7 +60,9 @@ async def create_proof(
# Set created if not already set
if not proof.get("created"):
# Use class date, or now
date = self.date or datetime.now()
date = self.date or datetime.now(timezone.utc)
if not date.tzinfo:
date = utc.localize(date)
proof["created"] = date.isoformat()

# Allow purpose to update the proof; the `proof` is in the
Expand Down
7 changes: 5 additions & 2 deletions aries_cloudagent/vc/ld_proofs/suites/linked_data_signature.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""Linked Data Signature class."""

from abc import abstractmethod, ABCMeta
from datetime import datetime
from datetime import datetime, timezone
from hashlib import sha256
from pytz import utc
from typing import Union

from ..constants import SECURITY_CONTEXT_URL
Expand Down Expand Up @@ -97,7 +98,9 @@ async def create_proof(
# Set created if not already set
if not proof.get("created"):
# Use class date, or now
date = self.date or datetime.now()
date = self.date or datetime.now(timezone.utc)
if not date.tzinfo:
date = utc.localize(date)
proof["created"] = date.isoformat()

# Allow purpose to update the proof; the `proof` is in the
Expand Down
12 changes: 6 additions & 6 deletions aries_cloudagent/vc/ld_proofs/tests/test_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
"image": "https://manu.sporny.org/images/manu.png",
"proof": {
"proofPurpose": "assertionMethod",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..Q6amIrxGiSbM7Ce6DxlfwLCjVcYyclas8fMxaecspXFUcFW9DAAxKzgHx93FWktnlZjM_biitkMgZdStgvivAQ",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..FX3xSAN3BxpHnclqtiCKsHa3f6O1pi_fulEoCNs2YQplYBU7lYSdnIm1BoPo_YCw8AS25pOQo1ufW05mXJlxAw",
},
}

Expand Down Expand Up @@ -131,10 +131,10 @@
"image": "https://manu.sporny.org/images/manu.png",
"proof": {
"proofPurpose": "assertionMethod",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..Q6amIrxGiSbM7Ce6DxlfwLCjVcYyclas8fMxaecspXFUcFW9DAAxKzgHx93FWktnlZjM_biitkMgZdStgvivAQ",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..FX3xSAN3BxpHnclqtiCKsHa3f6O1pi_fulEoCNs2YQplYBU7lYSdnIm1BoPo_YCw8AS25pOQo1ufW05mXJlxAw",
},
},
results=[
Expand All @@ -151,10 +151,10 @@
},
],
"proofPurpose": "assertionMethod",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..Q6amIrxGiSbM7Ce6DxlfwLCjVcYyclas8fMxaecspXFUcFW9DAAxKzgHx93FWktnlZjM_biitkMgZdStgvivAQ",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..FX3xSAN3BxpHnclqtiCKsHa3f6O1pi_fulEoCNs2YQplYBU7lYSdnIm1BoPo_YCw8AS25pOQo1ufW05mXJlxAw",
},
purpose_result=PurposeResult(
valid=True,
Expand Down
6 changes: 3 additions & 3 deletions aries_cloudagent/vc/ld_proofs/tests/test_ld_proofs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from datetime import datetime
from datetime import datetime, timezone

from asynctest import TestCase

Expand Down Expand Up @@ -65,7 +65,7 @@ async def test_sign_Ed25519Signature2018(self):
key_type=KeyType.ED25519,
public_key_base58=self.ed25519_key_info.verkey,
),
date=datetime.strptime("2019-12-11T03:50:55Z", "%Y-%m-%dT%H:%M:%SZ"),
date=datetime(2019, 12, 11, 3, 50, 55, 0, timezone.utc),
)
signed = await sign(
document=DOC_TEMPLATE,
Expand Down Expand Up @@ -103,7 +103,7 @@ async def test_sign_BbsBlsSignature2020(self):
key_type=KeyType.BLS12381G2,
public_key_base58=self.bls12381g2_key_info.verkey,
),
date=datetime.strptime("2019-12-11T03:50:55Z", "%Y-%m-%dT%H:%M:%SZ"),
date=datetime(2019, 12, 11, 3, 50, 55, 0),
)
signed = await sign(
document=DOC_TEMPLATE_BBS,
Expand Down
5 changes: 5 additions & 0 deletions aries_cloudagent/vc/vc_ld/models/credential.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Verifiable Credential marshmallow schema classes."""

from datetime import datetime
from pytz import utc
from typing import List, Optional, Union

from marshmallow import INCLUDE, fields, post_dump, ValidationError
Expand Down Expand Up @@ -168,6 +169,8 @@ def issuance_date(self):
def issuance_date(self, date: Union[str, datetime]):
"""Setter for issuance date."""
if isinstance(date, datetime):
if not date.tzinfo:
date = utc.localize(date)
date = date.isoformat()

self._issuance_date = date
Expand All @@ -181,6 +184,8 @@ def expiration_date(self):
def expiration_date(self, date: Union[str, datetime, None]):
"""Setter for expiration date."""
if isinstance(date, datetime):
if not date.tzinfo:
date = utc.localize(date)
date = date.isoformat()

self._expiration_date = date
Expand Down
18 changes: 15 additions & 3 deletions aries_cloudagent/vc/vc_ld/models/tests/test_credential.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from unittest import TestCase

from marshmallow.utils import INCLUDE
Expand Down Expand Up @@ -149,17 +149,29 @@ def test_properties(self):
with self.assertRaises(Exception):
credential.issuer = {"not-id": "not-id"}

date = datetime.now()
date = datetime.now(timezone.utc)
credential.issuance_date = date
assert credential.issuance_date == date.isoformat()
credential.issuance_date = date.isoformat()
assert credential.issuance_date == date.isoformat()
date = datetime(2019, 12, 11, 3, 50, 55, 0)
credential.issuance_date = date
assert (
credential.issuance_date
== datetime(2019, 12, 11, 3, 50, 55, 0, timezone.utc).isoformat()
)

date = datetime.now()
date = datetime.now(timezone.utc)
credential.expiration_date = date
assert credential.expiration_date == date.isoformat()
credential.expiration_date = date.isoformat()
assert credential.expiration_date == date.isoformat()
date = datetime(2019, 12, 11, 3, 50, 55, 0)
credential.expiration_date = date
assert (
credential.expiration_date
== datetime(2019, 12, 11, 3, 50, 55, 0, timezone.utc).isoformat()
)

assert not credential.credential_subject
assert not credential.credential_subject_ids
Expand Down
28 changes: 14 additions & 14 deletions aries_cloudagent/vc/vc_ld/tests/test_credential.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
"proof": {
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..lKJU0Df_keblRKhZAS9Qq6zybm-HqUXNVZ8vgEPNTAjQKBhQDxvXNo7nvtUBb_Eq1Ch6YBKY7UBAjg6iBX5qBQ",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..tELgWSCo0jSOKLpHWLOe2ZWj6WxLFc6FcqBZzgQFdcaawC5mARYmdr0XA37TMUp2Q9jUwriNP4gQm3GFIHV9BQ",
},
}

Expand Down Expand Up @@ -80,9 +80,9 @@
"proof": {
"type": "BbsBlsSignature2020",
"verificationMethod": "did:key:zUC72Q7XD4PE4CrMiDVXuvZng3sBvMmaGgNeTUJuzavH2BS7ThbHL9FhsZM9QYY5fqAQ4MB8M9oudz3tfuaX36Ajr97QRW7LBt6WWmrtESe6Bs5NYzFtLWEmeVtvRYVAgjFcJSa#zUC72Q7XD4PE4CrMiDVXuvZng3sBvMmaGgNeTUJuzavH2BS7ThbHL9FhsZM9QYY5fqAQ4MB8M9oudz3tfuaX36Ajr97QRW7LBt6WWmrtESe6Bs5NYzFtLWEmeVtvRYVAgjFcJSa",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"proofPurpose": "assertionMethod",
"proofValue": "saCdwWlzoYB0Ayo7xthCGK462T4x95lkI7yINra+r/DRY8PH4udviBebYIMA0pHkFX/nW+ilcdipr8jdN+WbHElg2wIrpWEqdvbT/vrjTWM2iXS7MmsMvpQbLfJVohDCBrm4b6BuE6QYO4Va6tYsKw==",
"proofValue": "ke/4UsKMbYyFQP2WAsQs0QGJ0PCfvN3tWMoD8oBjroY3mrgXA7FmUqVy0HaZIoKvFHl1FnE1jqh0OnqErooFBMTu0a4qe3klziRSuRuLdUhgbgzOJeJiWPlrs6Y5/D5d0CRp8ifPj7xZBIy3Iuoz4g==",
},
}

Expand All @@ -107,9 +107,9 @@
"proof": {
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..lKJU0Df_keblRKhZAS9Qq6zybm-HqUXNVZ8vgEPNTAjQKBhQDxvXNo7nvtUBb_Eq1Ch6YBKY7UBAjg6iBX5qBQ",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..tELgWSCo0jSOKLpHWLOe2ZWj6WxLFc6FcqBZzgQFdcaawC5mARYmdr0XA37TMUp2Q9jUwriNP4gQm3GFIHV9BQ",
},
},
results=[
Expand All @@ -122,9 +122,9 @@
],
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..lKJU0Df_keblRKhZAS9Qq6zybm-HqUXNVZ8vgEPNTAjQKBhQDxvXNo7nvtUBb_Eq1Ch6YBKY7UBAjg6iBX5qBQ",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..tELgWSCo0jSOKLpHWLOe2ZWj6WxLFc6FcqBZzgQFdcaawC5mARYmdr0XA37TMUp2Q9jUwriNP4gQm3GFIHV9BQ",
},
purpose_result=PurposeResult(
valid=True,
Expand Down Expand Up @@ -188,9 +188,9 @@
"proof": {
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..lKJU0Df_keblRKhZAS9Qq6zybm-HqUXNVZ8vgEPNTAjQKBhQDxvXNo7nvtUBb_Eq1Ch6YBKY7UBAjg6iBX5qBQ",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..tELgWSCo0jSOKLpHWLOe2ZWj6WxLFc6FcqBZzgQFdcaawC5mARYmdr0XA37TMUp2Q9jUwriNP4gQm3GFIHV9BQ",
},
}
],
Expand Down Expand Up @@ -221,18 +221,18 @@
"proof": {
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"created": "2019-12-11T03:50:55",
"created": "2019-12-11T03:50:55+00:00",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..lKJU0Df_keblRKhZAS9Qq6zybm-HqUXNVZ8vgEPNTAjQKBhQDxvXNo7nvtUBb_Eq1Ch6YBKY7UBAjg6iBX5qBQ",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..tELgWSCo0jSOKLpHWLOe2ZWj6WxLFc6FcqBZzgQFdcaawC5mARYmdr0XA37TMUp2Q9jUwriNP4gQm3GFIHV9BQ",
},
}
],
"proof": {
"type": "Ed25519Signature2018",
"verificationMethod": "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL",
"created": "2020-12-11T03:50:55",
"created": "2020-12-11T03:50:55+00:00",
"proofPurpose": "authentication",
"challenge": "2b1bbff6-e608-4368-bf84-67471b27e41c",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..IOjNkdpk4lF8uU8N7n0OMc3opqU1wtCTu3KbJcdDIKvSt6QLEy-ofRDVgN2xo-21yxzx36mXVjiilWdB6A-dDg",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..vLk6iXrPxdt4xWq_Lwnd85cy17Npol1ALxYoMhZrKpmkaWDOoz_exP1ggurPik7Rhpa7a82AfrT0OnigJnJsAQ",
},
}