Skip to content

Commit 31e10a2

Browse files
authored
Merge branch 'main' into fix/dif-claim-format-designation
2 parents 54e6464 + a28441a commit 31e10a2

44 files changed

Lines changed: 1562 additions & 192 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Nightly Tests
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
workflow_dispatch:
7+
8+
jobs:
9+
tests:
10+
name: Tests
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
os: ["ubuntu-latest"]
15+
python-version: ["3.7", "3.8", "3.9", "3.10"]
16+
include:
17+
- os: "ubuntu-20.04"
18+
python-version: "3.6"
19+
uses: ./.github/workflows/tests.yml
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
os: ${{ matrix.os }}
23+
24+
tests-indy:
25+
name: Tests (Indy)
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
os: ["ubuntu-latest"]
30+
python-version: ["3.7", "3.8", "3.9", "3.10"]
31+
include:
32+
- os: "ubuntu-20.04"
33+
python-version: "3.6"
34+
35+
uses: ./.github/workflows/tests-indy.yml
36+
with:
37+
python-version: ${{ matrix.python-version }}
38+
os: ${{ matrix.os }}
39+
indy-version: "1.16.0"

.github/workflows/pr-tests.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: PR Tests
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
tests:
8+
name: Tests
9+
uses: ./.github/workflows/tests.yml
10+
with:
11+
python-version: "3.6"
12+
os: "ubuntu-20.04"
13+
14+
tests-indy:
15+
name: Tests (Indy)
16+
uses: ./.github/workflows/tests-indy.yml
17+
with:
18+
python-version: "3.6"
19+
indy-version: "1.16.0"
20+
os: "ubuntu-20.04"

.github/workflows/tests-indy.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Tests (Indy)
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
python-version:
7+
required: true
8+
type: string
9+
indy-version:
10+
required: true
11+
type: string
12+
os:
13+
required: true
14+
type: string
15+
16+
jobs:
17+
tests:
18+
name: Test Python ${{ inputs.python-version }} on Indy ${{ inputs.indy-version }}
19+
runs-on: ${{ inputs.os }}
20+
steps:
21+
- uses: actions/checkout@v3
22+
23+
- name: Cache image layers
24+
uses: actions/cache@v3
25+
with:
26+
path: /tmp/.buildx-cache-test
27+
key: ${{ runner.os }}-buildx-test-${{ github.sha }}
28+
restore-keys: |
29+
${{ runner.os }}-buildx-test-
30+
31+
- name: Set up Docker Buildx
32+
uses: docker/setup-buildx-action@v1
33+
34+
- name: Build test image
35+
uses: docker/build-push-action@v3
36+
with:
37+
load: true
38+
context: .
39+
file: docker/Dockerfile.indy
40+
target: acapy-test
41+
tags: acapy-test:latest
42+
build-args: |
43+
python_version=${{ inputs.python-version }}
44+
indy_version=${{ inputs.indy-version }}
45+
cache-from: type=local,src=/tmp/.buildx-cache-test
46+
cache-to: type=local,dest=/tmp/.buildx-cache-test-new,mode=max
47+
48+
# Temp fix
49+
# https://github.com/docker/build-push-action/issues/252
50+
# https://github.com/moby/buildkit/issues/1896
51+
- name: Move cache
52+
run: |
53+
rm -rf /tmp/.buildx-cache-test
54+
mv /tmp/.buildx-cache-test-new /tmp/.buildx-cache-test
55+
56+
- name: Run pytest
57+
run: |
58+
docker run --rm acapy-test:latest

.github/workflows/tests.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Tests
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
python-version:
7+
required: true
8+
type: string
9+
os:
10+
required: true
11+
type: string
12+
13+
jobs:
14+
tests:
15+
name: Test Python ${{ inputs.python-version }}
16+
runs-on: ${{ inputs.os }}
17+
steps:
18+
- uses: actions/checkout@v3
19+
- name: Set up Python ${{ inputs.python-version }}
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: ${{ inputs.python-version }}
23+
cache: 'pip'
24+
cache-dependency-path: 'requirements*.txt'
25+
- name: Install dependencies
26+
run: |
27+
python -m pip install --upgrade pip
28+
pip3 install --no-cache-dir \
29+
-r requirements.txt \
30+
-r requirements.askar.txt \
31+
-r requirements.bbs.txt \
32+
-r requirements.dev.txt
33+
- name: Tests
34+
run: |
35+
pytest

Multicredentials.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Multi-Credentials
2+
3+
It is a known fact that multiple AnonCreds can be combined to present a presentation proof with an "and" logical operator: For instance, a verifier can ask for the "name" claim from an eID and the "address" claim from a bank statement to have a single proof that is either valid or invalid. With the Present Proof Protocol v2, it is possible to have "and" and "or" logical operators for AnonCreds and/or W3C Verifiable Credentials.
4+
5+
With the Present Proof Protocol v2, verifiers can ask for a combination of credentials as proof. For instance, a Verifier can ask a claim from an AnonCreds **and** a verifiable presentation from a W3C Verifiable Credential, which would open the possibilities of Aries Cloud Agent Python being used for rather complex presentation proof requests that wouldn't be possible without the support of AnonCreds or W3C Verifiable Credentials.
6+
7+
Moreover, it is possible to make similar presentation proof requests using the or logical operator. For instance, a verifier can ask for either an eID in AnonCreds format or an eID in W3C Verifiable Credential format. This has the potential to solve the interoperability problem of different credential formats and ecosystems from a user point of view by shifting the requirement of holding/accepting different credential formats from identity holders to verifiers. Here again, using Aries Cloud Agent Python as the underlying verifier agent can tackle such complex presentation proof requests since the agent is capable of verifying both type of credential formats and proof types.
8+
9+
In the future, it would be even possible to put mDoc as an attachment with an and or or logical operation, along with AnonCreds and/or W3C Verifiable Credentials. For this to happen, Aca-Py either needs the capabilities to validate mDocs internally or to connect third-party endpoints to validate and get a response.

aries_cloudagent/admin/server.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ async def check_multitenant_authorization(request: web.Request, handler):
370370
and not is_server_path
371371
and not is_unprotected_path(path)
372372
and not base_limited_access_path
373+
and not (request.method == "OPTIONS") # CORS fix
373374
):
374375
raise web.HTTPUnauthorized()
375376

aries_cloudagent/config/argparse.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ def create_argument_parser(*, prog: str = None):
7474

7575

7676
def load_argument_groups(parser: ArgumentParser, *groups: Type[ArgumentGroup]):
77-
"""Log a set of argument groups into a parser.
77+
"""
78+
Log a set of argument groups into a parser.
7879
7980
Returns:
8081
A callable to convert loaded arguments into a settings dictionary
@@ -872,32 +873,56 @@ def get_settings(self, args: Namespace) -> dict:
872873
if args.no_ledger:
873874
settings["ledger.disabled"] = True
874875
else:
875-
configured = False
876+
single_configured = False
877+
multi_configured = False
878+
update_pool_name = False
876879
if args.genesis_url:
877880
settings["ledger.genesis_url"] = args.genesis_url
878-
configured = True
881+
single_configured = True
879882
elif args.genesis_file:
880883
settings["ledger.genesis_file"] = args.genesis_file
881-
configured = True
884+
single_configured = True
882885
elif args.genesis_transactions:
883886
settings["ledger.genesis_transactions"] = args.genesis_transactions
884-
configured = True
887+
single_configured = True
885888
if args.genesis_transactions_list:
886889
with open(args.genesis_transactions_list, "r") as stream:
887890
txn_config_list = yaml.safe_load(stream)
888891
ledger_config_list = []
889892
for txn_config in txn_config_list:
890893
ledger_config_list.append(txn_config)
894+
if "is_write" in txn_config and txn_config["is_write"]:
895+
if "genesis_url" in txn_config:
896+
settings["ledger.genesis_url"] = txn_config[
897+
"genesis_url"
898+
]
899+
elif "genesis_file" in txn_config:
900+
settings["ledger.genesis_file"] = txn_config[
901+
"genesis_file"
902+
]
903+
elif "genesis_transactions" in txn_config:
904+
settings["ledger.genesis_transactions"] = txn_config[
905+
"genesis_transactions"
906+
]
907+
else:
908+
raise ArgsParseError(
909+
"No genesis information provided for write ledger"
910+
)
911+
if "id" in txn_config:
912+
settings["ledger.pool_name"] = txn_config["id"]
913+
update_pool_name = True
891914
settings["ledger.ledger_config_list"] = ledger_config_list
892-
configured = True
893-
if not configured:
915+
multi_configured = True
916+
if not (single_configured or multi_configured):
894917
raise ArgsParseError(
895918
"One of --genesis-url --genesis-file, --genesis-transactions "
896919
"or --genesis-transactions-list must be specified (unless "
897920
"--no-ledger is specified to explicitly configure aca-py to"
898921
" run with no ledger)."
899922
)
900-
if args.ledger_pool_name:
923+
if single_configured and multi_configured:
924+
raise ArgsParseError("Cannot configure both single- and multi-ledger.")
925+
if args.ledger_pool_name and not update_pool_name:
901926
settings["ledger.pool_name"] = args.ledger_pool_name
902927
if args.ledger_keepalive:
903928
settings["ledger.keepalive"] = args.ledger_keepalive

aries_cloudagent/core/conductor.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from ..config.wallet import wallet_config
2929
from ..core.profile import Profile
3030
from ..indy.verifier import IndyVerifier
31-
from ..ledger.base import BaseLedger
31+
3232
from ..ledger.error import LedgerConfigError, LedgerTransactionError
3333
from ..ledger.multiple_ledger.base_manager import (
3434
BaseMultipleLedgerManager,
@@ -144,7 +144,6 @@ async def setup(self):
144144
self.root_profile.BACKEND_NAME == "askar"
145145
and ledger.BACKEND_NAME == "indy-vdr"
146146
):
147-
context.injector.bind_instance(BaseLedger, ledger)
148147
context.injector.bind_provider(
149148
IndyVerifier,
150149
ClassProvider(
@@ -156,7 +155,6 @@ async def setup(self):
156155
self.root_profile.BACKEND_NAME == "indy"
157156
and ledger.BACKEND_NAME == "indy"
158157
):
159-
context.injector.bind_instance(BaseLedger, ledger)
160158
context.injector.bind_provider(
161159
IndyVerifier,
162160
ClassProvider(

aries_cloudagent/indy/models/cred_request.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class Meta:
4444
unknown = EXCLUDE
4545

4646
prover_did = fields.Str(
47-
requred=True,
47+
required=True,
4848
description="Prover DID",
4949
**INDY_DID,
5050
)

aries_cloudagent/ledger/multiple_ledger/indy_manager.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from ...cache.base import BaseCache
1111
from ...core.profile import Profile
12+
from ...ledger.base import BaseLedger
1213
from ...ledger.error import LedgerError
1314
from ...wallet.crypto import did_is_self_certified
1415

@@ -53,7 +54,11 @@ def __init__(
5354

5455
async def get_write_ledger(self) -> Optional[Tuple[str, IndySdkLedger]]:
5556
"""Return the write IndySdkLedger instance."""
56-
return self.write_ledger_info
57+
# return self.write_ledger_info
58+
if self.write_ledger_info:
59+
return (self.write_ledger_info[0], self.profile.inject_or(BaseLedger))
60+
else:
61+
return None
5762

5863
async def get_prod_ledgers(self) -> Mapping:
5964
"""Return production ledgers mapping."""
@@ -83,7 +88,11 @@ async def _get_ledger_by_did(
8388
"""
8489
try:
8590
indy_sdk_ledger = None
86-
if ledger_id in self.production_ledgers:
91+
if self.write_ledger_info and ledger_id == self.write_ledger_info[0]:
92+
indy_sdk_ledger = await self.get_write_ledger()
93+
if indy_sdk_ledger:
94+
indy_sdk_ledger = indy_sdk_ledger[1]
95+
elif ledger_id in self.production_ledgers:
8796
indy_sdk_ledger = self.production_ledgers.get(ledger_id)
8897
else:
8998
indy_sdk_ledger = self.non_production_ledgers.get(ledger_id)
@@ -134,7 +143,9 @@ async def lookup_did_in_configured_ledgers(
134143
cache_key = f"did_ledger_id_resolver::{did}"
135144
if bool(cache_did and self.cache and await self.cache.get(cache_key)):
136145
cached_ledger_id = await self.cache.get(cache_key)
137-
if cached_ledger_id in self.production_ledgers:
146+
if self.write_ledger_info and cached_ledger_id == self.write_ledger_info[0]:
147+
return self.get_write_ledger()
148+
elif cached_ledger_id in self.production_ledgers:
138149
return (cached_ledger_id, self.production_ledgers.get(cached_ledger_id))
139150
elif cached_ledger_id in self.non_production_ledgers:
140151
return (

0 commit comments

Comments
 (0)