Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f30c77a
Update dockerfile image after release (#3469)
jamshale Jan 27, 2025
745d2c1
fix: ensure profile names are unique
dbluhm Jan 27, 2025
3f80a4d
fix: same fix for anon profile
dbluhm Jan 27, 2025
ef1ab19
Merge pull request #3470 from dbluhm/fix/unique-profile-name
dbluhm Jan 27, 2025
9ba4434
Upgrade askar and did_webvh (#3474)
jamshale Jan 28, 2025
481d3c2
chore(deps): Bump dawidd6/action-download-artifact (#3473)
dependabot[bot] Jan 29, 2025
0b69442
:sparkles: Add ordering options to askar scan and fetch_all methods (…
ff137 Jan 29, 2025
558be60
:art: Deprecate count/start query params and implement limit/offset (…
ff137 Jan 29, 2025
8d2292b
Update aries-askar / Generate poetry.lock with poetry 2.0 (#3478)
jamshale Jan 29, 2025
faec46e
Anoncreds Issuance - Extra options. (#3483)
jamshale Jan 30, 2025
4c026ed
Fixing BaseAnonCredsResolver get_revocation_list abstract method (#3484)
thiagoromanos Jan 31, 2025
ee67fbe
feat: add did management design doc (#3375)
dbluhm Jan 31, 2025
5e69346
chore(deps): Bump mkdocs-material from 9.5.50 to 9.6.1 (#3486)
dependabot[bot] Feb 3, 2025
7c20fab
chore(deps): Bump sphinx-notfound-page from 1.0.4 to 1.1.0 (#3487)
dependabot[bot] Feb 3, 2025
0f3d33a
chore(deps-dev): Bump pytest-asyncio from 0.25.2 to 0.25.3 (#3488)
dependabot[bot] Feb 3, 2025
d53378e
chore(deps-dev): Bump pydevd from 3.2.3 to 3.3.0 (#3489)
dependabot[bot] Feb 3, 2025
7efb414
chore(deps-dev): Bump pydevd-pycharm from 251.17181.23 to 251.18673.3…
dependabot[bot] Feb 3, 2025
457eee0
fix typo in error message of indy credential offer (#3485)
zoblazo Feb 6, 2025
f0c62cb
Fix Class import for AnonCreds Registry routes (#3495)
PatStLouis Feb 6, 2025
96e0747
Upgrade to bookworm (#3498)
jamshale Feb 10, 2025
bb8abb4
chore(deps): Bump mkdocs-material from 9.6.1 to 9.6.3 (#3504)
dependabot[bot] Feb 10, 2025
7a040ba
Grouped upgrades - Week 7, 2025 (#3508)
jamshale Feb 10, 2025
29c4599
Catch and log universal resolver setup error (#3511)
jamshale Feb 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dockerfile": "Dockerfile",
"context": "..",
"args": {
"VARIANT": "3.12-bullseye",
"VARIANT": "3.12-bookworm",
"POETRY_VERSION": "1.7.1"
}
},
Expand Down Expand Up @@ -48,16 +48,16 @@
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
},

// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",

"remoteEnv": {
"RUST_LOG":"aries-askar::log::target=error"
//"PATH": "${containerEnv:PATH}:${workspaceRoot}/.venv/bin"
},

"mounts": [],
"postCreateCommand": "bash ./.devcontainer/post-install.sh"
}

}
4 changes: 2 additions & 2 deletions .github/workflows/sonar-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
with:
fetch-depth: 0
- name: Download PR number artifact
uses: dawidd6/action-download-artifact@v7
uses: dawidd6/action-download-artifact@v8
with:
workflow: Tests
run_id: ${{ github.event.workflow_run.id }}
Expand All @@ -26,7 +26,7 @@ jobs:
with:
path: ./PR_NUMBER
- name: Download Test Coverage
uses: dawidd6/action-download-artifact@v7
uses: dawidd6/action-download-artifact@v8
with:
workflow: Tests
run_id: ${{ github.event.workflow_run.id }}
Expand Down
6 changes: 5 additions & 1 deletion acapy_agent/anoncreds/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ async def get_revocation_registry_definition(

@abstractmethod
async def get_revocation_list(
self, profile: Profile, revocation_registry_id: str, timestamp: int
self,
profile: Profile,
revocation_registry_id: str,
timestamp_from: Optional[int] = 0,
timestamp_to: Optional[int] = None,
) -> GetRevListResult:
"""Get a revocation list from the registry."""

Expand Down
6 changes: 5 additions & 1 deletion acapy_agent/anoncreds/default/did_web/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ async def register_revocation_registry_definition(
raise NotImplementedError()

async def get_revocation_list(
self, profile: Profile, revocation_registry_id: str, timestamp: int
self,
profile: Profile,
revocation_registry_id: str,
timestamp_from: Optional[int] = 0,
timestamp_to: Optional[int] = None,
) -> GetRevListResult:
"""Get a revocation list from the registry."""
raise NotImplementedError()
Expand Down
23 changes: 12 additions & 11 deletions acapy_agent/anoncreds/holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,12 @@ async def store_credential_w3c(

return credential_id

async def get_credentials(self, start: int, count: int, wql: dict):
async def get_credentials(self, *, offset: int, limit: int, wql: dict):
"""Get credentials stored in the wallet.

Args:
start: Starting index
count: Number of records to return
offset: Starting index
limit: Number of records to return
wql: wql query dict

"""
Expand All @@ -388,8 +388,8 @@ async def get_credentials(self, start: int, count: int, wql: dict):
rows = self.profile.store.scan(
category=CATEGORY_CREDENTIAL,
tag_filter=wql,
offset=start,
limit=count,
offset=offset,
limit=limit,
profile=self.profile.settings.get("wallet.askar_profile"),
)
async for row in rows:
Expand All @@ -406,17 +406,18 @@ async def get_credentials_for_presentation_request_by_referent(
self,
presentation_request: dict,
referents: Sequence[str],
start: int,
count: int,
*,
offset: int,
limit: int,
extra_query: Optional[dict] = None,
):
"""Get credentials stored in the wallet.

Args:
presentation_request: Valid presentation request from issuer
referents: Presentation request referents to use to search for creds
start: Starting index
count: Maximum number of records to return
offset: Starting index
limit: Maximum number of records to return
extra_query: wql query dict

"""
Expand Down Expand Up @@ -459,8 +460,8 @@ async def get_credentials_for_presentation_request_by_referent(
rows = self.profile.store.scan(
category=CATEGORY_CREDENTIAL,
tag_filter=tag_filter,
offset=start,
limit=count,
offset=offset,
limit=limit,
profile=self.profile.settings.get("wallet.askar_profile"),
)
async for row in rows:
Expand Down
42 changes: 34 additions & 8 deletions acapy_agent/anoncreds/models/credential_proposal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import re

from marshmallow import fields
from marshmallow import fields, validate

from ...core.profile import Profile
from ...messaging.models.openapi import OpenAPISchema
Expand All @@ -13,12 +13,30 @@
ANONCREDS_DID_VALIDATE,
ANONCREDS_SCHEMA_ID_EXAMPLE,
ANONCREDS_SCHEMA_ID_VALIDATE,
INDY_DID_VALIDATE,
MAJOR_MINOR_VERSION_EXAMPLE,
MAJOR_MINOR_VERSION_VALIDATE,
)


class AnoncredsCredentialDefinitionProposal(OpenAPISchema):
"""Query string parameters for credential definition searches."""

cred_def_id = fields.Str(
required=False,
validate=ANONCREDS_CRED_DEF_ID_VALIDATE,
metadata={
"description": "Credential definition id. This is the only required field.",
"example": ANONCREDS_CRED_DEF_ID_EXAMPLE,
},
)
issuer_id = fields.Str(
required=False,
# TODO: INDY_DID_VALIDATE should be removed when indy sov did's
# are represented by did:sov:{nym} in acapy
validate=validate.NoneOf([ANONCREDS_DID_VALIDATE, INDY_DID_VALIDATE]),
metadata={"description": "Issuer DID", "example": ANONCREDS_DID_EXAMPLE},
)
schema_id = fields.Str(
required=False,
validate=ANONCREDS_SCHEMA_ID_VALIDATE,
Expand All @@ -27,17 +45,25 @@ class AnoncredsCredentialDefinitionProposal(OpenAPISchema):
"example": ANONCREDS_SCHEMA_ID_EXAMPLE,
},
)
issuer_id = fields.Str(
schema_issuer_id = fields.Str(
required=False,
validate=ANONCREDS_DID_VALIDATE,
metadata={"description": "Issuer DID", "example": ANONCREDS_DID_EXAMPLE},
# TODO: INDY_DID_VALIDATE should be removed when indy sov did's
# are represented by did:sov:{nym} in acapy
validate=validate.NoneOf([ANONCREDS_DID_VALIDATE, INDY_DID_VALIDATE]),
metadata={
"description": "Schema identifier",
"example": ANONCREDS_SCHEMA_ID_EXAMPLE,
},
)
cred_def_id = fields.Str(
schema_name = fields.Str(
required=False, metadata={"description": "Schema name", "example": "simple"}
)
schema_version = fields.Str(
required=False,
validate=ANONCREDS_CRED_DEF_ID_VALIDATE,
validate=MAJOR_MINOR_VERSION_VALIDATE,
metadata={
"description": "Credential definition id",
"example": ANONCREDS_CRED_DEF_ID_EXAMPLE,
"description": "Schema version",
"example": MAJOR_MINOR_VERSION_EXAMPLE,
},
)

Expand Down
8 changes: 4 additions & 4 deletions acapy_agent/anoncreds/models/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ async def get_requested_creds_from_proof_request_preview(
credentials = await holder.get_credentials_for_presentation_request_by_referent(
presentation_request=proof_request,
referents=(referent,),
start=0,
count=100,
offset=0,
limit=100,
)
if not credentials:
raise ValueError(_get_value_error_msg(proof_request, referent))
Expand All @@ -61,8 +61,8 @@ async def get_requested_creds_from_proof_request_preview(
credentials = await holder.get_credentials_for_presentation_request_by_referent(
presentation_request=proof_request,
referents=(referent,),
start=0,
count=100,
offset=0,
limit=100,
)
if not credentials:
raise ValueError(_get_value_error_msg(proof_request, referent))
Expand Down
27 changes: 22 additions & 5 deletions acapy_agent/anoncreds/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
ANONCREDS_CRED_DEF_ID_EXAMPLE,
ANONCREDS_DID_EXAMPLE,
ANONCREDS_REV_REG_ID_EXAMPLE,
ANONCREDS_REV_REG_ID_VALIDATE,
ANONCREDS_SCHEMA_ID_EXAMPLE,
UUIDFour,
)
from ..revocation.error import RevocationNotSupportedError
from ..revocation.routes import RevocationModuleResponseSchema, RevRegIdMatchInfoSchema
from ..storage.error import StorageNotFoundError
from ..utils.profiles import is_not_anoncreds_profile_raise_web_exception
from .base import (
Expand Down Expand Up @@ -62,6 +62,23 @@
)


class AnoncredsRevocationModuleResponseSchema(OpenAPISchema):
"""Response schema for Revocation Module."""


class AnonCredsRevRegIdMatchInfoSchema(OpenAPISchema):
"""Path parameters and validators for request taking rev reg id."""

rev_reg_id = fields.Str(
required=True,
validate=ANONCREDS_REV_REG_ID_VALIDATE,
metadata={
"description": "Revocation Registry identifier",
"example": ANONCREDS_REV_REG_ID_EXAMPLE,
},
)


class SchemaIdMatchInfo(OpenAPISchema):
"""Path parameters and validators for request taking schema id."""

Expand Down Expand Up @@ -699,8 +716,8 @@ async def rev_list_post(request: web.BaseRequest):
tags=["anoncreds - revocation"],
summary="Upload local tails file to server",
)
@match_info_schema(RevRegIdMatchInfoSchema())
@response_schema(RevocationModuleResponseSchema(), description="")
@match_info_schema(AnonCredsRevRegIdMatchInfoSchema())
@response_schema(AnoncredsRevocationModuleResponseSchema(), description="")
@tenant_authentication
async def upload_tails_file(request: web.BaseRequest):
"""Request handler to upload local tails file for revocation registry.
Expand Down Expand Up @@ -735,8 +752,8 @@ async def upload_tails_file(request: web.BaseRequest):
tags=["anoncreds - revocation"],
summary="Update the active registry",
)
@match_info_schema(RevRegIdMatchInfoSchema())
@response_schema(RevocationModuleResponseSchema(), description="")
@match_info_schema(AnonCredsRevRegIdMatchInfoSchema())
@response_schema(AnoncredsRevocationModuleResponseSchema(), description="")
@tenant_authentication
async def set_active_registry(request: web.BaseRequest):
"""Request handler to set the active registry.
Expand Down
10 changes: 5 additions & 5 deletions acapy_agent/anoncreds/tests/test_holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ async def test_store_credential_failed_trx(self, *_):
async def test_get_credentials(self, _):
async with self.profile.session() as session:
await session.handle.insert(CATEGORY_CREDENTIAL, json.dumps(MOCK_CRED))
result = await self.holder.get_credentials(0, 10, {})
result = await self.holder.get_credentials(offset=0, limit=10, wql={})
assert isinstance(result, list)
assert len(result) == 1

Expand All @@ -386,9 +386,9 @@ async def test_get_credentials_errors(self):
)

with self.assertRaises(AnonCredsHolderError):
await self.holder.get_credentials(0, 10, {})
await self.holder.get_credentials(offset=0, limit=10, wql={})
with self.assertRaises(AnonCredsHolderError):
await self.holder.get_credentials(0, 10, {})
await self.holder.get_credentials(offset=0, limit=10, wql={})

async def test_get_credentials_for_presentation_request_by_referent(self):
self.profile.store.scan = mock.Mock(
Expand All @@ -408,13 +408,13 @@ async def test_get_credentials_for_presentation_request_by_referent(self):
"restrictions": [{"schema_name": "MYCO Biomarker"}],
}
await self.holder.get_credentials_for_presentation_request_by_referent(
mock_pres_req, None, start=0, count=10
mock_pres_req, None, offset=0, limit=10
)

# non-existent referent
with self.assertRaises(AnonCredsHolderError):
await self.holder.get_credentials_for_presentation_request_by_referent(
mock_pres_req, "not-found-ref", start=0, count=10
mock_pres_req, "not-found-ref", offset=0, limit=10
)

@mock.patch.object(Credential, "load", return_value=MockCredential())
Expand Down
6 changes: 4 additions & 2 deletions acapy_agent/askar/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ def __init__(
profile_id: Optional[str] = None,
):
"""Create a new AskarProfile instance."""
super().__init__(context=context, name=opened.name, created=opened.created)
super().__init__(
context=context, name=profile_id or opened.name, created=opened.created
)
self.opened = opened
self.ledger_pool: Optional[IndyVdrLedgerPool] = None
self.profile_id = profile_id
Expand All @@ -52,7 +54,7 @@ def __init__(
@property
def name(self) -> str:
"""Accessor for the profile name."""
return self.opened.name
return self.profile_id or self.opened.name

@property
def store(self) -> Store:
Expand Down
6 changes: 4 additions & 2 deletions acapy_agent/askar/profile_anon.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ def __init__(
profile_id: Optional[str] = None,
):
"""Create a new AskarProfile instance."""
super().__init__(context=context, name=opened.name, created=opened.created)
super().__init__(
context=context, name=profile_id or opened.name, created=opened.created
)
self.opened = opened
self.ledger_pool: Optional[IndyVdrLedgerPool] = None
self.profile_id = profile_id
Expand All @@ -54,7 +56,7 @@ def __init__(
@property
def name(self) -> str:
"""Accessor for the profile name."""
return self.opened.name
return self.profile_id or self.opened.name

@property
def store(self) -> Store:
Expand Down
Loading