Skip to content

Commit

Permalink
feat: fix schemas on cred_abstract and cred_request, improve on vc_di…
Browse files Browse the repository at this point in the history
… support on alice-faber demo

Signed-off-by: tra371 <[email protected]>
  • Loading branch information
tra371 committed Feb 28, 2024
1 parent a4de923 commit dcb3b0d
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 117 deletions.
107 changes: 51 additions & 56 deletions aries_cloudagent/anoncreds/issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,9 +551,7 @@ async def create_credential_offer(self, credential_definition_id: str) -> str:
CATEGORY_CRED_DEF_KEY_PROOF, credential_definition_id
)
except AskarError as err:
raise AnonCredsIssuerError(
"Error retrieving credential definition"
) from err
raise AnonCredsIssuerError("Error retrieving credential definition") from err
if not cred_def or not key_proof:
raise AnonCredsIssuerError(
"Credential definition not found for credential offer"
Expand Down Expand Up @@ -594,9 +592,7 @@ async def create_credential(
CATEGORY_CRED_DEF_PRIVATE, cred_def_id
)
except AskarError as err:
raise AnonCredsIssuerError(
"Error retrieving credential definition"
) from err
raise AnonCredsIssuerError("Error retrieving credential definition") from err

if not cred_def or not cred_def_private:
raise AnonCredsIssuerError(
Expand Down Expand Up @@ -633,60 +629,59 @@ async def create_credential(

return credential.to_json()

async def create_credential_vc_di(
self,
credential_offer: dict,
credential_request: dict,
credential_values: dict,
) -> str:
"""Create Credential."""
anoncreds_registry = self.profile.inject(AnonCredsRegistry)
schema_id = credential_offer["schema_id"]
schema_result = await anoncreds_registry.get_schema(self.profile, schema_id)
cred_def_id = credential_offer["cred_def_id"]
schema_attributes = schema_result.schema_value.attr_names

async def create_credential_vc_di(
self,
credential_offer: dict,
credential_request: dict,
credential_values: dict,
) -> str:
"""Create Credential."""
anoncreds_registry = self.profile.inject(AnonCredsRegistry)
schema_id = credential_offer["schema_id"]
schema_result = await anoncreds_registry.get_schema(self.profile, schema_id)
cred_def_id = credential_offer["cred_def_id"]
schema_attributes = schema_result.schema_value.attr_names

try:
async with self.profile.session() as session:
cred_def = await session.handle.fetch(CATEGORY_CRED_DEF, cred_def_id)
cred_def_private = await session.handle.fetch(
CATEGORY_CRED_DEF_PRIVATE, cred_def_id
)
except AskarError as err:
raise AnonCredsIssuerError("Error retrieving credential definition") from err

if not cred_def or not cred_def_private:
raise AnonCredsIssuerError(
"Credential definition not found for credential issuance"
)

raw_values = {}
for attribute in schema_attributes:
# Ensure every attribute present in schema to be set.
# Extraneous attribute names are ignored.
try:
credential_value = credential_values[attribute]
except KeyError:
async with self.profile.session() as session:
cred_def = await session.handle.fetch(CATEGORY_CRED_DEF, cred_def_id)
cred_def_private = await session.handle.fetch(
CATEGORY_CRED_DEF_PRIVATE, cred_def_id
)
except AskarError as err:
raise AnonCredsIssuerError("Error retrieving credential definition") from err

if not cred_def or not cred_def_private:
raise AnonCredsIssuerError(
"Provided credential values are missing a value "
f"for the schema attribute '{attribute}'"
"Credential definition not found for credential issuance"
)

raw_values[attribute] = str(credential_value)
raw_values = {}
for attribute in schema_attributes:
# Ensure every attribute present in schema to be set.
# Extraneous attribute names are ignored.
try:
credential_value = credential_values[attribute]
except KeyError:
raise AnonCredsIssuerError(
"Provided credential values are missing a value "
f"for the schema attribute '{attribute}'"
)

try:
credential = await asyncio.get_event_loop().run_in_executor(
None,
lambda: Credential.create(
cred_def.raw_value,
cred_def_private.raw_value,
credential_offer,
credential_request,
raw_values,
),
)
except AnoncredsError as err:
raise AnonCredsIssuerError("Error creating credential") from err
raw_values[attribute] = str(credential_value)

return credential.to_json()
try:
credential = await asyncio.get_event_loop().run_in_executor(
None,
lambda: Credential.create(
cred_def.raw_value,
cred_def_private.raw_value,
credential_offer,
credential_request,
raw_values,
),
)
except AnoncredsError as err:
raise AnonCredsIssuerError("Error creating credential") from err

return credential.to_json()
46 changes: 43 additions & 3 deletions aries_cloudagent/indy/models/cred_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ def __init__(
class AnoncredsLinkSecretSchema(BaseModelSchema):
"""Anoncreds Link Secret Schema."""

class Meta:
"""AnoncredsLinkSecret schema metadata."""

model_class = AnoncredsLinkSecret
unknown = EXCLUDE

nonce = fields.Str(
required=True,
validate=NUM_STR_WHOLE_VALIDATE,
Expand Down Expand Up @@ -230,6 +236,12 @@ def __init__(
class DidcommSignedAttachmentSchema(BaseModelSchema):
"""Didcomm Signed Attachment Schema."""

class Meta:
"""Didcomm signed attachment schema metadata."""

model_class = DidcommSignedAttachment
unknown = EXCLUDE

algs_supported = fields.List(fields.Str(), required=True)

did_methods_supported = fields.List(fields.Str(), required=True)
Expand All @@ -244,9 +256,35 @@ class DidcommSignedAttachmentSchema(BaseModelSchema):
)


class BindingMethod(BaseModel):
"""Binding Method Model."""

class Meta:
"""Binding method metadata."""

schema_class = "BindingMethodSchema"

def __init__(
self,
anoncreds_link_secret: Union[dict, AnoncredsLinkSecret] = None,
didcomm_signed_attachment: Union[dict, DidcommSignedAttachment] = None,
**kwargs,
):
"""Initialize values for DidcommSignedAttachment."""
super().__init__(**kwargs)
self.anoncreds_link_secret = anoncreds_link_secret
self.didcomm_signed_attachment = didcomm_signed_attachment


class BindingMethodSchema(BaseModelSchema):
"""VCDI Binding Method Schema."""

class Meta:
"""VCDI binding method schema metadata."""

model_class = BindingMethod
unknown = EXCLUDE

anoncreds_link_secret = fields.Nested(AnoncredsLinkSecretSchema, required=False)
didcomm_signed_attachment = fields.Nested(
DidcommSignedAttachmentSchema, required=True
Expand All @@ -263,7 +301,7 @@ class Meta:

def __init__(
self,
data_model_versions_supported: str = None,
data_model_versions_supported: Sequence[str] = None,
binding_required: str = None,
binding_methods: str = None,
credential: Union[dict, VerifiableCredential] = None,
Expand Down Expand Up @@ -294,7 +332,7 @@ class Meta:
unknown = EXCLUDE

data_model_versions_supported = fields.List(
required=True, validate="", metadata={"description": "", "example": ""}
fields.Str(), required=True, metadata={"description": "", "example": ""}
)

binding_required = fields.Bool(
Expand All @@ -308,5 +346,7 @@ class Meta:
)

credential = fields.Nested(
CredentialSchema(), required=True, metadata={"description": "", "example": ""}
CredentialSchema(),
required=True,
metadata={"description": "", "example": ""},
)
11 changes: 5 additions & 6 deletions aries_cloudagent/indy/models/cred_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from ...messaging.valid import (
INDY_CRED_DEF_ID_EXAMPLE,
INDY_CRED_DEF_ID_VALIDATE,
INDY_DID_EXAMPLE,
INDY_DID_VALIDATE,
UUID4_EXAMPLE,
NUM_STR_WHOLE_EXAMPLE,
NUM_STR_WHOLE_VALIDATE,
Expand Down Expand Up @@ -88,7 +90,6 @@ class Meta:
"""VCDI credential request schema metadata."""

schema_class = "BindingProofSchema"
unknown = EXCLUDE

def __init__(
self,
Expand Down Expand Up @@ -154,7 +155,6 @@ class Meta:
"""Didcomm signed attachment metadata."""

schema_class = "DidcommSignedAttachmentSchema"
unknown = EXCLUDE

def __init__(self, attachment_id: str = None, **kwargs):
"""Initialize DidcommSignedAttachment."""
Expand All @@ -169,10 +169,9 @@ class Meta:
"""Didcomm Signed Attachment schema metadata."""

model_class = DidcommSignedAttachment
unknown = EXCLUDE

attachment_id = fields.str(
required=True, metadata={"description": "", "example": ""}
)
attachment_id = fields.Str(required=True, metadata={"description": "", "example": ""})


class BindingProof(BaseModel):
Expand All @@ -182,7 +181,6 @@ class Meta:
"""Binding proof metadata."""

schema_class = "BindingProofSchema"
unknown = EXCLUDE

def __init__(
self,
Expand All @@ -203,6 +201,7 @@ class Meta:
"""Binding proof schema metadata."""

model_class = BindingProof
unknown = EXCLUDE

anoncreds_link_secret = fields.Nested(
AnoncredsLinkSecretSchema(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ async def _match_sent_cred_def_id(self, tag_query: Mapping[str, str]) -> str:
async def create_proposal(
self, cred_ex_record: V20CredExRecord, proposal_data: Mapping[str, str]
) -> Tuple[V20CredFormat, AttachDecorator]:
"""Create indy credential proposal."""
"""Create vc_di credential proposal."""
if proposal_data is None:
proposal_data = {}

Expand Down Expand Up @@ -260,15 +260,15 @@ async def _create():
async def receive_offer(
self, cred_ex_record: V20CredExRecord, cred_offer_message: V20CredOffer
) -> None:
"""Receive indy credential offer."""
"""Receive vcdi credential offer."""

async def create_request(
self, cred_ex_record: V20CredExRecord, request_data: Mapping = None
) -> CredFormatAttachment:
"""Create indy credential request."""
"""Create vcdi credential request."""
if cred_ex_record.state != V20CredExRecord.STATE_OFFER_RECEIVED:
raise V20CredFormatError(
"Indy issue credential format cannot start from credential request"
"vcdi issue credential format cannot start from credential request"
)

await self._check_uniqueness(cred_ex_record.cred_ex_id)
Expand All @@ -285,9 +285,7 @@ async def create_request(
)

nonce = cred_offer["binding_method"]["anoncreds_link_secret"]["nonce"]
cred_def_id = cred_offer["binding_method"]["anoncreds_link_secret"][
"cred_def_id"
]
cred_def_id = cred_offer["binding_method"]["anoncreds_link_secret"]["cred_def_id"]

async def _create():
anoncreds_registry = self.profile.inject(AnonCredsRegistry)
Expand Down Expand Up @@ -332,16 +330,16 @@ async def _create():
async def receive_request(
self, cred_ex_record: V20CredExRecord, cred_request_message: V20CredRequest
) -> None:
"""Receive indy credential request."""
"""Receive vcdi credential request."""
if not cred_ex_record.cred_offer:
raise V20CredFormatError(
"Indy issue credential format cannot start from credential request"
"vcdi issue credential format cannot start from credential request"
)

async def issue_credential(
self, cred_ex_record: V20CredExRecord, retries: int = 5
) -> CredFormatAttachment:
"""Issue indy credential."""
"""Issue vcdi credential."""
await self._check_uniqueness(cred_ex_record.cred_ex_id)

attached_credential = cred_ex_record.cred_offer.attachment(
Expand Down Expand Up @@ -402,15 +400,15 @@ async def issue_credential(
async def receive_credential(
self, cred_ex_record: V20CredExRecord, cred_issue_message: V20CredIssue
) -> None:
"""Receive indy credential.
"""Receive vcdi credential.
Validation is done in the store credential step.
"""

async def store_credential(
self, cred_ex_record: V20CredExRecord, cred_id: str = None
) -> None:
"""Store indy credential."""
"""Store vcdi credential."""
cred = cred_ex_record.cred_issue.attachment(VCDICredFormatHandler.format)

rev_reg_def = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

MESSAGE_TYPES = DIDCommPrefix.qualify_all(
{
CRED_20_PROPOSAL: (f"{PROTOCOL_PACKAGE}.messages.cred_proposal.V20CredProposal"),
CRED_20_PROPOSAL: (
f"{PROTOCOL_PACKAGE}.messages.cred_proposal.V20CredProposal"
),
CRED_20_OFFER: f"{PROTOCOL_PACKAGE}.messages.cred_offer.V20CredOffer",
CRED_20_REQUEST: f"{PROTOCOL_PACKAGE}.messages.cred_request.V20CredRequest",
CRED_20_ISSUE: f"{PROTOCOL_PACKAGE}.messages.cred_issue.V20CredIssue",
Expand Down
Loading

0 comments on commit dcb3b0d

Please sign in to comment.