Skip to content

Commit

Permalink
Update 1.0.0rc4 to 1.0.0 with plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
darshilnb committed Sep 10, 2024
1 parent 8725bea commit 378499c
Show file tree
Hide file tree
Showing 52 changed files with 2,065 additions and 87 deletions.
116 changes: 116 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
ARG python_version=3.12
FROM python:${python_version}-slim-bullseye AS build

WORKDIR /src

ADD . .

RUN pip install --no-cache-dir poetry
RUN poetry build

FROM python:${python_version}-slim-bullseye AS main

ARG uid=1001
ARG user=aries
ARG acapy_name="aries-cloudagent"
ARG acapy_version
ARG acapy_reqs=[askar,didcommv2]

ENV HOME="/home/$user" \
APP_ROOT="$HOME" \
LC_ALL=C.UTF-8 \
LANG=C.UTF-8 \
PIP_NO_CACHE_DIR=off \
PYTHONUNBUFFERED=1 \
PYTHONIOENCODING=UTF-8 \
RUST_LOG=warn \
SHELL=/bin/bash \
SUMMARY="$acapy_name image" \
DESCRIPTION="$acapy_name provides a base image for running Hyperledger Aries agents in Docker. \
This image layers the python implementation of $acapy_name $acapy_version. Based on Debian Buster."

LABEL summary="$SUMMARY" \
description="$DESCRIPTION" \
io.k8s.description="$DESCRIPTION" \
io.k8s.display-name="$acapy_name $acapy_version" \
name=$acapy_name \
acapy.version="$acapy_version" \
maintainer=""

# Add aries user
RUN useradd -U -ms /bin/bash -u $uid $user

# Install environment
RUN apt-get update -y && \
apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
build-essential \
bzip2 \
curl \
git \
less \
libffi-dev \
libgmp10 \
liblzma5 \
libncurses5 \
libncursesw5 \
libsecp256k1-0 \
libzmq5 \
net-tools \
openssl \
sqlite3 \
zlib1g && \
rm -rf /var/lib/apt/lists/* /usr/share/doc/*

WORKDIR $HOME

# Add local binaries and aliases to path
ENV PATH="$HOME/.local/bin:$PATH"

# - In order to drop the root user, we have to make some directories writable
# to the root group as OpenShift default security model is to run the container
# under random UID.
RUN usermod -a -G 0 $user

# Create standard directories to allow volume mounting and set permissions
# Note: PIP_NO_CACHE_DIR environment variable should be cleared to allow caching
RUN mkdir -p \
$HOME/.aries_cloudagent \
$HOME/.cache/pip/http \
$HOME/.indy_client \
$HOME/ledger/sandbox/data \
$HOME/log

# The root group needs access the directories under $HOME/.indy_client and $HOME/.aries_cloudagent for the container to function in OpenShift.
RUN chown -R $user:root $HOME/.indy_client $HOME/.aries_cloudagent && \
chmod -R ug+rw $HOME/log $HOME/ledger $HOME/.aries_cloudagent $HOME/.cache $HOME/.indy_client

# Create /home/indy and symlink .indy_client folder for backwards compatibility with artifacts created on older indy-based images.
RUN mkdir -p /home/indy
RUN ln -s /home/aries/.indy_client /home/indy/.indy_client

# Install ACA-py from the wheel as $user,
# and ensure the permissions on the python 'site-packages' and $HOME/.local folders are set correctly.
USER $user
COPY --from=build /src/dist/aries_cloudagent*.whl .
RUN aries_cloudagent_package=$(find ./ -name "aries_cloudagent*.whl" | head -n 1) && \
echo "Installing ${aries_cloudagent_package} ..." && \
pip install --no-cache-dir --find-links=. ${aries_cloudagent_package}${acapy_reqs} && \
rm aries_cloudagent*.whl && \
chmod +rx $(python -m site --user-site) $HOME/.local

# Clean-up unneccessary build dependencies and reduce final image size
USER root

COPY plugins/ /plugins/

RUN pip install /plugins/did_key_plugin
RUN pip install /plugins/did_sov_plugin
RUN pip install /plugins/did_web_plugin

RUN apt-get purge -y --auto-remove build-essential

USER $user

ENTRYPOINT ["/bin/bash", "-c", "aca-py \"$@\"", "--"]
4 changes: 3 additions & 1 deletion aries_cloudagent/config/ledger.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from ..ledger.error import LedgerError
from ..utils.http import FetchError, fetch
from ..wallet.base import BaseWallet
from ..wallet.did_method import DIDMethods
from .base import ConfigError

LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -150,8 +151,9 @@ async def ledger_config(
endpoint = session.settings.get("default_endpoint")
if public_did:
wallet = session.inject(BaseWallet)
did_methods = session.inject(DIDMethods)
try:
await wallet.set_did_endpoint(public_did, endpoint, ledger)
await wallet.set_did_endpoint(public_did, endpoint, ledger, did_methods)
except LedgerError as x_ledger:
raise ConfigError(x_ledger.message) from x_ledger # e.g., read-only

Expand Down
5 changes: 3 additions & 2 deletions aries_cloudagent/config/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from ..wallet.base import BaseWallet
from ..wallet.crypto import seed_to_did
from ..wallet.did_info import DIDInfo
from ..wallet.did_method import SOV
from ..wallet.did_method import DIDMethods
from ..wallet.key_type import ED25519
from .base import ConfigError
from .injection_context import InjectionContext
Expand All @@ -35,7 +35,8 @@ async def wallet_config(
"""Initialize the root profile."""

mgr = context.inject(ProfileManager)

did_methods = context.inject_or(DIDMethods)
SOV = did_methods.from_method("sov")
settings = context.settings
profile_cfg = {}
for k in CFG_MAP:
Expand Down
4 changes: 3 additions & 1 deletion aries_cloudagent/connections/base_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
from ..wallet.base import BaseWallet
from ..wallet.crypto import create_keypair, seed_to_did
from ..wallet.did_info import INVITATION_REUSE_KEY, DIDInfo, KeyInfo
from ..wallet.did_method import PEER2, PEER4, SOV, DIDMethod
from ..wallet.did_method import PEER2, PEER4, DIDMethod, DIDMethods
from ..wallet.error import WalletNotFoundError
from ..wallet.key_type import ED25519, X25519
from ..wallet.util import b64_to_bytes, bytes_to_b58
Expand Down Expand Up @@ -1110,6 +1110,8 @@ async def create_static_connection(
"""
async with self._profile.session() as session:
wallet = session.inject(BaseWallet)
did_methods = session.inject_or(DIDMethods)
SOV = did_methods.from_method('sov')
# seed and DID optional
my_info = await wallet.create_local_did(SOV, ED25519, my_seed, my_did)

Expand Down
10 changes: 9 additions & 1 deletion aries_cloudagent/protocols/connections/v1_0/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from ....storage.error import StorageNotFoundError
from ....transport.inbound.receipt import MessageReceipt
from ....wallet.base import BaseWallet
from ....wallet.did_method import SOV
from ....wallet.did_method import DIDMethods
from ....wallet.key_type import ED25519
from ...coordinate_mediation.v1_0.manager import MediationManager
from .message_types import ARIES_PROTOCOL as CONN_PROTO
Expand Down Expand Up @@ -384,6 +384,8 @@ async def create_request(
else:
async with self.profile.session() as session:
wallet = session.inject(BaseWallet)
did_methods = session.inject_or(DIDMethods)
SOV = did_methods.from_method("sov")
# Create new DID for connection
my_info = await wallet.create_local_did(SOV, ED25519)
connection.my_did = my_info.did
Expand Down Expand Up @@ -490,6 +492,8 @@ async def receive_request(
if connection.is_multiuse_invitation:
async with self.profile.session() as session:
wallet = session.inject(BaseWallet)
did_methods = session.inject_or(DIDMethods)
SOV = did_methods.from_method("sov")
my_info = await wallet.create_local_did(SOV, ED25519)

new_connection = ConnRecord(
Expand Down Expand Up @@ -548,6 +552,8 @@ async def receive_request(
else: # request from public did
async with self.profile.session() as session:
wallet = session.inject(BaseWallet)
did_methods = session.inject_or(DIDMethods)
SOV = did_methods.from_method("sov")
my_info = await wallet.create_local_did(SOV, ED25519)

async with self.profile.session() as session:
Expand Down Expand Up @@ -635,6 +641,8 @@ async def create_response(
else:
async with self.profile.session() as session:
wallet = session.inject(BaseWallet)
did_methods = session.inject_or(DIDMethods)
SOV = did_methods.from_method("sov")
my_info = await wallet.create_local_did(SOV, ED25519)
connection.my_did = my_info.did

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from ....storage.record import StorageRecord
from ....wallet.base import BaseWallet
from ....wallet.did_info import DIDInfo
from ....wallet.did_method import SOV
from ....wallet.did_method import DIDMethods
from ....wallet.key_type import ED25519
from ...routing.v1_0.manager import RoutingManager, RoutingManagerError
from ...routing.v1_0.models.route_record import RouteRecord
Expand Down Expand Up @@ -108,6 +108,8 @@ async def _create_routing_did(self, session: ProfileSession) -> DIDInfo:
"""
wallet = session.inject(BaseWallet)
storage = session.inject(BaseStorage)
did_methods = session.inject(DIDMethods)
SOV = did_methods.from_method('sov')
info = await wallet.create_local_did(
method=SOV,
key_type=ED25519,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ....storage.error import StorageNotFoundError
from ....wallet.base import BaseWallet
from ....wallet.did_info import DIDInfo
from ....wallet.did_method import SOV
from ....wallet.did_method import DIDMethods
from ....wallet.key_type import ED25519
from ...routing.v1_0.models.route_record import RouteRecord
from .manager import MediationManager
Expand Down Expand Up @@ -50,6 +50,8 @@ async def get_or_create_my_did(
if not conn_record.my_did:
async with profile.session() as session:
wallet = session.inject(BaseWallet)
did_methods = session.inject(DIDMethods)
SOV = did_methods.from_method("sov")
# Create new DID for connection
my_info = await wallet.create_local_did(SOV, ED25519)
conn_record.my_did = my_info.did
Expand Down
4 changes: 3 additions & 1 deletion aries_cloudagent/protocols/didexchange/v1_0/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from ....storage.error import StorageNotFoundError
from ....transport.inbound.receipt import MessageReceipt
from ....wallet.base import BaseWallet
from ....wallet.did_method import SOV
from ....wallet.did_method import DIDMethods
from ....wallet.did_posture import DIDPosture
from ....wallet.error import WalletError
from ....wallet.key_type import ED25519
Expand Down Expand Up @@ -490,6 +490,8 @@ async def _legacy_did_with_attached_doc(
else:
async with self.profile.session() as session:
wallet = session.inject(BaseWallet)
did_methods = session.inject(DIDMethods)
SOV = did_methods.from_method("sov")
my_info = await wallet.create_local_did(
method=SOV,
key_type=ED25519,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ async def _get_issue_suite(
did_info = await self._did_info_for_did(issuer_id)
verkey_id_strategy = self.profile.context.inject(BaseVerificationKeyStrategy)
verification_method = await verkey_id_strategy.get_verification_method_id_for_did(
issuer_id, self.profile, proof_purpose="assertionMethod"
issuer_id,
self.profile,
proof_type=self.proof_type,
proof_purpose="assertionMethod",
)

if verification_method is None:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
"""Presentation request message handler."""

import base64
import json
from aries_cloudagent.resolver.did_resolver import DIDResolver
from aries_cloudagent.wallet.base import BaseWallet
from aries_cloudagent.wallet.key_type import ED25519
from .....anoncreds.holder import AnonCredsHolderError
from .....core.oob_processor import OobMessageProcessor
from .....indy.holder import IndyHolderError
Expand Down Expand Up @@ -61,6 +66,44 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
profile = context.profile
pres_manager = V20PresManager(profile)

pres_request = context.message
if pres_request.verifier_did is not None:
verifier_did = pres_request.verifier_did
async with profile.session() as session:
did_resolver = session.inject(DIDResolver)
wallet = session.inject(BaseWallet)
did_document = await did_resolver.resolve(
profile=profile, did=verifier_did
)
verification_method_list = did_document.get("verificationMethod", [])
request_verified = False
for method in verification_method_list:
verkey = method.get("publicKeyBase58")
key_type = ED25519 # need to change this to support other key types
sr_pres_request = pres_request.serialize()
sr_pres_request.pop("~thread", None)
sr_pres_request.pop("signature", None)
sr_pres_request_bytes = json.dumps(sr_pres_request).encode("utf-8")
if verkey:
try:
request_verified = await wallet.verify_message(
sr_pres_request_bytes,
base64.b64decode(pres_request.signature),
verkey,
key_type,
)
if request_verified:
break
except Exception as e:
self._logger.error(
f"Could not verify signature...Retrying with next verification method: {e}" # noqa: E501
)
continue
if not request_verified:
self._logger.error(
"Presentation request signature verification failed. DID of verifier is not verifed" # noqa: E501
)

# Get pres ex record (holder initiated via proposal)
# or create it (verifier sent request first)
try:
Expand Down Expand Up @@ -93,6 +136,20 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
pres_ex_record
) # mgr only saves record: on exception, saving state err is hopeless

if not request_verified:
if pres_ex_record:
async with profile.session() as session:
await pres_ex_record.save_error_state(
session,
reason="Presentation request signature verification failed",
)
await responder.send_reply(
problem_report_for_record(
pres_ex_record,
ProblemReportReason.ABANDONED.value, # them: be vague
)
)

r_time = trace_event(
context.settings,
context.message,
Expand Down
Loading

0 comments on commit 378499c

Please sign in to comment.