Skip to content

Commit

Permalink
feat: more code
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Burdett <[email protected]>
  • Loading branch information
burdettadam committed Nov 2, 2023
1 parent a952e12 commit f49a6da
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 23 deletions.
3 changes: 1 addition & 2 deletions oid4vci/demo/frontend/src/QRCodePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ const QRCodePage = () => {
axios.defaults.withCredentials = true; // Enable credentials (cookies, etc.)
axios.defaults.headers.common['Access-Control-Allow-Origin'] = 'http://localhost:3001'; // Adjust the origin as needed

// api call to controller, `POST /exchange/submit`
axios
.get(`http://localhost:3001/exchange/status/${exchange_id}`, {})
.get(`http://localhost:3001/oid4vci/exchange/records/${exchange_id}`, {})
.then((response) => {
console.log(response.data);
if(response.data === "completed"){
Expand Down
2 changes: 2 additions & 0 deletions oid4vci/oid4vci/v1_0/models/cred_ex_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def __init__(
credential_subject: Optional[Dict[str, Any]] = None,
nonce=None,
pin=None,
code=None,
token=None,
**kwargs,
):
Expand All @@ -34,6 +35,7 @@ def __init__(
self.credential_subject = credential_subject # (received from submit)
self.nonce = nonce # in offer
self.pin = pin # (when relevant)
self.code = code
self.token = token

@property
Expand Down
10 changes: 5 additions & 5 deletions oid4vci/oid4vci/v1_0/models/cred_sup_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ class Meta:
schema_class = "CredSupRecordSchema"

RECORD_ID_NAME = "oid4vci_id"
RECORD_TYPE = "oid4vci"
RECORD_TYPE = "oid4vci_exchange"
EVENT_NAMESPACE = "oid4vci"
TAG_NAMES = {"credential_definition_id", "types", "scope"}
TAG_NAMES = {"credential_supported_id", "types", "scope"}

def __init__(
self,
*,
credential_definition_id,
credential_supported_id,
format,
types,
cryptographic_binding_methods_supported,
Expand All @@ -29,7 +29,7 @@ def __init__(
state="init",
**kwargs,
)
self.credential_definition_id = credential_definition_id
self.credential_supported_id = credential_supported_id
self.format = format
self.types = types
self.cryptographic_binding_methods_supported = (
Expand All @@ -53,7 +53,7 @@ class CredSupRecordSchema(BaseRecordSchema):
class Meta:
model_class = OID4VCICredentialSupported

credential_definition_id = fields.Str(
credential_supported_id = fields.Str(
required=True, metadata={"example": "UniversityDegree_JWT"}
)
format = fields.Str(required=True, metadata={"example": "jwt_vc_json"})
Expand Down
75 changes: 59 additions & 16 deletions oid4vci/oid4vci/v1_0/routes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Basic Messages Storage API Routes."""
import json
import logging
from typing import Mapping
import secrets
Expand All @@ -14,6 +15,9 @@
from aries_cloudagent.core.profile import Profile
from aries_cloudagent.messaging.models.openapi import OpenAPISchema
from aries_cloudagent.protocols.basicmessage.v1_0.message_types import SPEC_URI
from aries_cloudagent.storage.base import BaseStorage
from aries_cloudagent.messaging.models.base import BaseModelError
from aries_cloudagent.storage.error import StorageError, StorageNotFoundError
from marshmallow import fields
from .models.cred_sup_record import OID4VCICredentialSupported
from .models.cred_ex_record import OID4VCICredentialExchangeRecord
Expand All @@ -25,9 +29,9 @@
class CredExRecordListQueryStringSchema(OpenAPISchema):
"""Parameters and validators for credential exchange record list query."""

thread_id = fields.UUID(
exchange_id = fields.UUID(
required=False,
metadata={"description": "Thread identifier"},
metadata={"description": "exchange identifier"},
)
filter = fields.List(
fields.Str(
Expand Down Expand Up @@ -151,7 +155,25 @@ async def credential_exchange_list(request: web.BaseRequest):
The connection list response
"""
pass
context = request["context"]
if exchange_id := request.query.get("exchange_id"):
try:
async with context.profile.session() as session:
record = await OID4VCICredentialExchangeRecord.retrieve_by_id(
session=session, exchange_id=exchange_id
)
# There should only be one record for a id
results = [record.serialize()]
except (StorageError, BaseModelError, StorageNotFoundError) as err:
raise web.HTTPBadRequest(reason=err.roll_up) from err
else:
try:
async with context.profile.session() as session:
records = await OID4VCICredentialExchangeRecord.query(session=session)
results = [record.serialize() for record in records]
except (StorageError, BaseModelError) as err:
raise web.HTTPBadRequest(reason=err.roll_up) from err
return web.json_response({"results": results})


@docs(
Expand Down Expand Up @@ -230,25 +252,46 @@ async def get_cred_offer(request: web.BaseRequest):
"""Endpoint to retrieve an OIDC4VCI compliant offer, that
can f.e. be used in QR-Code presented to a compliant wallet.
"""
request.query["credentials"]
request.query["credential_issuer"]
request["context"].profile
creds = request.query["credentials"]
issuer_url = request.query["credential_issuer"]
profile = request["context"].profile

# TODO: check that the credential_issuer_url is associated with an issuer DID
# TODO: check that the credential requested is offered by the issuer

"".join(
# Generate secure code
code = "".join(
secrets.choice(string.ascii_uppercase + string.digits) for _ in range(code_size)
)
# Retrieve the exchange record
oid4vci_ex_id = request.query["exchange_id"]

try:
async with profile.session() as session:
storage = session.inject(BaseStorage)
record: OID4VCICredentialExchangeRecord = await storage.find_record(
OID4VCICredentialExchangeRecord.RECORD_TYPE,
{OID4VCICredentialExchangeRecord.RECORD_ID_NAME: oid4vci_ex_id},
)
record.code = code
# Save the code to the exchange record
await record.save(session, reason="New cred offer code")
except (StorageError, BaseModelError) as err:
raise web.HTTPBadRequest(reason=err.roll_up) from err
# Create offer object
offer = {
"credential_issuer": issuer_url,
"credentials": creds,
"grants": {
"urn:ietf:params:oauth:grant-type:pre-authorized_code": {
"pre-authorized_code": code,
"user_pin_required": False, # TODO: put as a parameter
}
},
}
# Return it

# TODO:
# - Retrieve the exchange record
# - Generate code
# - Save the code to the exchange record
# - Create offer object
# - Return it

return web.json_response({})
return web.json_response(offer)


@docs(tags=["oid4vci"], summary="Register a Oid4vci credential")
Expand All @@ -271,7 +314,7 @@ async def credential_supported_create(request: web.BaseRequest):
scope = body.get("scope")

record = OID4VCICredentialSupported(
credential_definition_id=credential_definition_id,
credential_supported_id=credential_definition_id,
format=format,
types=types,
cryptographic_binding_methods_supported=cryptographic_binding_methods_supported,
Expand Down

0 comments on commit f49a6da

Please sign in to comment.