Skip to content

Commit

Permalink
Merge pull request #792 from bcgov/feat/untp-vc
Browse files Browse the repository at this point in the history
feat: W3C credential support
  • Loading branch information
WadeBarnes authored Sep 4, 2024
2 parents 75b878a + a3287ed commit bd5b0eb
Show file tree
Hide file tree
Showing 65 changed files with 2,617 additions and 456 deletions.
11 changes: 11 additions & 0 deletions docker/docker-compose-debug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: '3'
services:
vcr-api:
command: ["sh", "-c", "pip install debugpy -t /tmp && python ./manage.py migrate && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 ./manage.py runserver 0.0.0.0:8080"]
volumes:
- ../server/vcr-server/vcr_server:/opt/app-root/src/vcr_server
- ../server/vcr-server/subscriptions:/opt/app-root/src/subscriptions
- ../server/vcr-server/agent_webhooks:/opt/app-root/src/agent_webhooks
- ../server/vcr-server/api:/opt/app-root/src/api
ports:
- 5678:5678
21 changes: 0 additions & 21 deletions docker/docker-compose.dev.yml

This file was deleted.

22 changes: 5 additions & 17 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ services:
- DEMO_SITE=${DEMO_SITE}
- SQL_DEBUG=${SQL_DEBUG}
- DJANGO_SECRET_KEY=${DJANGO_SECRET_KEY}
- DJANGO_DEBUG=${DJANGO_DEBUG}
- DJANGO_LOG_LEVEL=${DJANGO_LOG_LEVEL}
- OPTIMIZE_TABLE_ROW_COUNTS=${OPTIMIZE_TABLE_ROW_COUNTS}
- SOLR_SERVICE_NAME=${SOLR_SERVICE_NAME}
Expand Down Expand Up @@ -82,10 +81,10 @@ services:
- PAGE_SIZE=${PAGE_SIZE}
- MAX_PAGE_SIZE=${MAX_PAGE_SIZE}
volumes:
- ../server/vcr-server/subscriptions:/home/indy/subscriptions
- ../server/vcr-server/agent_webhooks:/home/indy/agent_webhooks
- ../server/vcr-server/api:/home/indy/api
- vcr-wallet:/home/indy/.indy_client/wallet
- ../server/vcr-server/vcr_server:/opt/app-root/src/vcr_server
- ../server/vcr-server/subscriptions:/opt/app-root/src/subscriptions
- ../server/vcr-server/agent_webhooks:/opt/app-root/src/agent_webhooks
- ../server/vcr-server/api:/opt/app-root/src/api
networks:
- vcr
# when running "./manage scale" comment out or remove these port mappings:
Expand All @@ -97,17 +96,7 @@ services:
- wallet-db
- vcr-solr
- vcr-agent
command: >
/bin/bash -c "
echo waiting for solr ...;
sleep 15;
if [ $DEBUG ] && [ "$DEBUG" == "true" ]; then
python manage.py migrate && \
python manage.py update_index --max-retries=5 --batch-size=500;
python manage.py runserver 0.0.0.0:8080;
else
${STI_SCRIPTS_PATH}/run;
fi"
command: ["/bin/bash -c", "echo waiting for solr ...", "sleep 15", "${STI_SCRIPTS_PATH}/run"]

vcr-agent:
image: vcr-agent
Expand Down Expand Up @@ -209,7 +198,6 @@ services:
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
- SQL_DEBUG=${SQL_DEBUG}
- DJANGO_SECRET_KEY=${DJANGO_SECRET_KEY}
- DJANGO_DEBUG=${DJANGO_DEBUG}
- DJANGO_LOG_LEVEL=${DJANGO_LOG_LEVEL}
- SOLR_SERVICE_NAME=${SOLR_SERVICE_NAME}
- SOLR_CORE_NAME=${SOLR_CORE_NAME}
Expand Down
5 changes: 2 additions & 3 deletions docker/manage
Original file line number Diff line number Diff line change
Expand Up @@ -307,15 +307,14 @@ configureEnvironment() {
export APP_CONFIG=${APP_CONFIG:-}
# export APP_MODULE=api_indy.vcr_anchor.boot:init_app
export API_HTTP_PORT=${API_HTTP_PORT:-8080}
export EXPOSED_API_HTTP_PORT=${EXPOSED_API_HTTP_PORT:-8081}
export EXPOSED_API_HTTP_PORT=${EXPOSED_API_HTTP_PORT:-8080}
export DATABASE_SERVICE_NAME="vcr-db"
export DATABASE_ENGINE=${DATABASE_ENGINE-postgresql}
export DATABASE_NAME=${POSTGRESQL_DATABASE}
export DATABASE_USER=${POSTGRESQL_USER}
export DATABASE_PASSWORD=${POSTGRESQL_PASSWORD}
export DEMO_SITE=${DEMO_SITE-True}
export DJANGO_SECRET_KEY=wpn1GZrouOryH2FshRrpVHcEhMfMLtmTWMC2K5Vhx8MAi74H5y
export DJANGO_DEBUG=${DJANGO_DEBUG:-"False"}
export DJANGO_LOG_LEVEL=${DJANGO_LOG_LEVEL-ERROR}
export OPTIMIZE_TABLE_ROW_COUNTS=${OPTIMIZE_TABLE_ROW_COUNTS-}
export INDY_DISABLED=${INDY_DISABLED-}
Expand Down Expand Up @@ -372,7 +371,7 @@ configureEnvironment() {
unset composeOptions
if [ $DEBUG = true ]; then
# Override the vcr-api volume settings; add volume mount to enable hot reloading.
export composeOptions="-f docker-compose.yml -f docker-compose.dev.yml"
export composeOptions="-f docker-compose.yml -f docker-compose-debug.yml"
fi
}

Expand Down
18 changes: 0 additions & 18 deletions server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,6 @@ The API is developed in Django/Python.

`aries-vcr` is configured for debugging while running in its Docker environment using [Visual Studio Code](http://code.visualstudio.com).

To run in debug mode, append DJANGO_DEBUG=True to your run command. For example, `./manage start DJANGO_DEBUG=True`. This will start the debugger software and wait for a remote debugger to be attached before proceeding further.

To add a new debugger session, create a `launch.json` file and add the following configuration:
```
{
"name": "vcr-server",
"type": "python",
"request": "attach",
"pathMappings": [
{
"localRoot": "${workspaceFolder}/server/vcr-server",
"remoteRoot": "/home/indy"
}
],
"port": 3000,
"host": "localhost"
}
```

## Database Migrations

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ class Topic(Schema):
logo_b64 = fields.Str(required=False, allow_none=True)
credential_def_id = fields.Str(required=True)
endpoint = fields.Str(required=False)
visible_fields = fields.List(fields.Str(), required=False)
highlighted_attributes = fields.List(fields.Str(), required=False)
credential_title = fields.Str(required=False)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ class Topic(Schema):
logo_b64 = fields.Str(required=False, allow_none=True)
credential_def_id = fields.Str(required=True)
endpoint = fields.Str(required=False)
visible_fields = fields.List(fields.Str(), required=False)

labels = fields.Dict(required=False)
endpoints = fields.Dict(required=False)
Expand Down
4 changes: 4 additions & 0 deletions server/vcr-server/agent_webhooks/enums/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .format import FormatEnum
from .mapping_type import MappingTypeEnum

__all__ = ["FormatEnum", "MappingTypeEnum"]
8 changes: 8 additions & 0 deletions server/vcr-server/agent_webhooks/enums/format.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from enum import Enum


class FormatEnum(str, Enum):
"""Format enum"""

VC_DI = "vc_di"
ANONCREDS = "anoncreds"
9 changes: 9 additions & 0 deletions server/vcr-server/agent_webhooks/enums/mapping_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from enum import Enum


class MappingTypeEnum(str, Enum):
"""MappingType enum"""

EFFECTIVE_DATE = "effective_date"
EXPIRY_DATE = "expiry_date"
REVOKED_DATE = "revoked_date"
33 changes: 33 additions & 0 deletions server/vcr-server/agent_webhooks/handlers/vc_di_credential.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import logging

from marshmallow import ValidationError

from api.v2.models.Credential import Credential
from api.v4.serializers.rest.credential import CredentialSerializer

from agent_webhooks.enums import FormatEnum
from agent_webhooks.schemas import CredentialDefSchema
from agent_webhooks.utils.vc_di_credential import CredentialManager

LOGGER = logging.getLogger(__name__)

format = FormatEnum.VC_DI.value

def handle_credential(
message: CredentialDefSchema,
) -> Credential:
f"""Webhook message handler for a {format} credential."""

try:
credential_schema = CredentialDefSchema()
credential_schema.load(message)
credential_manager = CredentialManager()

credential = credential_manager.update_credential(message)
return CredentialSerializer(credential).data
except ValidationError as err:
LOGGER.error(f"Invalid {format} credential type definition: {err.messages}")
raise err
except Exception as err:
LOGGER.error(f"Error handling {format} credential type webhook: {err}")
raise err
33 changes: 33 additions & 0 deletions server/vcr-server/agent_webhooks/handlers/vc_di_credential_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import logging

from marshmallow import ValidationError

from agent_webhooks.enums import FormatEnum
from agent_webhooks.schemas import CredentialTypeRegistrationDefSchema

from agent_webhooks.utils.issuer import IssuerManager, IssuerRegistrationResult

LOGGER = logging.getLogger(__name__)

format = FormatEnum.VC_DI.value


def handle_credential_type(
message: CredentialTypeRegistrationDefSchema,
) -> IssuerRegistrationResult:
f"""Webhook message handler for a {format} credential type."""

try:
credential_type_registration_schema = CredentialTypeRegistrationDefSchema()
credential_type_registration_schema.load(message)
issuer_manager = IssuerManager()

# Convert the credential type definition to an issuer registration definition
issuer_registration_def = credential_type_registration_schema.dump(message)
return issuer_manager.register_issuer(issuer_registration_def)
except ValidationError as err:
LOGGER.error(f"Invalid {format} credential type definition: {err.messages}")
raise err
except Exception as err:
LOGGER.error(f"Error handling {format} credential type webhook: {err}")
raise err
29 changes: 29 additions & 0 deletions server/vcr-server/agent_webhooks/handlers/vc_di_issuer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import logging

from marshmallow.exceptions import ValidationError

from agent_webhooks.enums import FormatEnum
from agent_webhooks.schemas import IssuerDefSchema, IssuerRegistrationDefSchema
from agent_webhooks.utils.issuer import IssuerManager, IssuerRegistrationResult

LOGGER = logging.getLogger(__name__)

format = FormatEnum.VC_DI.value


def handle_issuer(message: IssuerDefSchema) -> IssuerRegistrationResult:
f"""Webhook message handler for a {format} issuer."""

try:
IssuerDefSchema().load(message)
issuer_manager = IssuerManager()

# Convert the issuer definition to an issuer registration definition
issuer_registration_def = IssuerRegistrationDefSchema().dump({"issuer": message})
return issuer_manager.register_issuer(issuer_registration_def, issuer_only=True)
except ValidationError as err:
LOGGER.error(f"Invalid {format} issuer definition: {err.messages}")
raise err
except Exception as err:
LOGGER.error(f"Error handling {format} issuer webhook: {err}")
raise err
24 changes: 24 additions & 0 deletions server/vcr-server/agent_webhooks/schemas/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from .base import PathBaseSchema

from .credential_def import CredentialDefSchema
from .credential_mapping_def import CredentialMappingDefSchema
from .issuer_def import IssuerDefSchema
from .mapping_def import MappingDefSchema
from .topic_def import TopicDefSchema

# Import order matters here because of circular dependencies
from .credential_type_def import CredentialTypeDefSchema
from .issuer_registration_def import IssuerRegistrationDefSchema
from .credential_type_registration_def import CredentialTypeRegistrationDefSchema

__all__ = [
"PathBaseSchema",
"CredentialDefSchema",
"CredentialMappingDefSchema",
"CredentialTypeDefSchema",
"CredentialTypeRegistrationDefSchema",
"IssuerDefSchema",
"IssuerRegistrationDefSchema",
"MappingDefSchema",
"TopicDefSchema",
]
3 changes: 3 additions & 0 deletions server/vcr-server/agent_webhooks/schemas/base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .path import PathBaseSchema

__all__ = ["PathBaseSchema"]
6 changes: 6 additions & 0 deletions server/vcr-server/agent_webhooks/schemas/base/path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from marshmallow import Schema, fields


class PathBaseSchema(Schema):

path = fields.String(required=True)
15 changes: 15 additions & 0 deletions server/vcr-server/agent_webhooks/schemas/credential_def.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from marshmallow import Schema, fields

from agent_webhooks.enums import FormatEnum


class CredentialDefSchema(Schema):
format = fields.Enum(FormatEnum, by_value=True, required=True)
schema = fields.String(required=True)
version = fields.String(required=True)
origin_did = fields.String(required=True)
credential_id = fields.String(required=True)
# We don't make any assumptions about the fields in the raw_data dictionary
# since there are different credential formats. Eventually we should define
# schemas for different credential formats.
raw_data = fields.Dict(required=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from marshmallow import fields

from agent_webhooks.schemas import PathBaseSchema


class CredentialMappingDefSchema(PathBaseSchema):
name = fields.String(required=True)
22 changes: 22 additions & 0 deletions server/vcr-server/agent_webhooks/schemas/credential_type_def.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from marshmallow import Schema, fields

from agent_webhooks.enums import FormatEnum, MappingTypeEnum
from agent_webhooks.schemas import (
CredentialMappingDefSchema,
MappingDefSchema,
TopicDefSchema,
)


class CredentialTypeDefSchema(Schema):
format = fields.Enum(FormatEnum, by_value=True, required=True)
schema = fields.String(required=True)
version = fields.String(required=True)
origin_did = fields.String(required=True)
topic = fields.Nested(TopicDefSchema, required=True)
mappings = fields.List(fields.Nested(MappingDefSchema))
credential = fields.Dict(
keys=fields.Enum(MappingTypeEnum, by_value=True),
values=fields.Nested(CredentialMappingDefSchema),
)
raw_data = fields.Dict()
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from marshmallow import fields

from agent_webhooks.schemas import CredentialTypeDefSchema, IssuerRegistrationDefSchema


class CredentialTypeRegistrationDefSchema(IssuerRegistrationDefSchema):
credential_type = fields.Nested(
CredentialTypeDefSchema, required=True, load_only=True
)

def get_issuer_registration(self, obj):
return {
"issuer": obj.get("issuer"),
"credential_types": [obj.get("credential_type")],
}
11 changes: 11 additions & 0 deletions server/vcr-server/agent_webhooks/schemas/issuer_def.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from marshmallow import Schema, fields


class IssuerDefSchema(Schema):
name = fields.String(required=True)
did = fields.String(required=True)
abbreviation = fields.String(required=True)
email = fields.String(required=True)
url = fields.String(required=True)
endpoint = fields.String()
logo_b64 = fields.String()
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from marshmallow import Schema, fields

from agent_webhooks.schemas import IssuerDefSchema


class IssuerRegistrationDefSchema(Schema):
issuer = fields.Nested(IssuerDefSchema, required=True, load_only=True)
issuer_registration = fields.Method("get_issuer_registration")

def get_issuer_registration(self, obj):
return {"issuer": obj.get("issuer")}
Loading

0 comments on commit bd5b0eb

Please sign in to comment.