Skip to content

Commit aedcbd3

Browse files
authored
Merge pull request openwallet-foundation#2071 from rmnre/record-attribute-validation
Improved validation of record attributes
2 parents 4c20dcd + 4236b69 commit aedcbd3

5 files changed

Lines changed: 36 additions & 47 deletions

File tree

aries_cloudagent/connections/models/conn_record.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -677,11 +677,7 @@ class Meta:
677677
required=False,
678678
description="Routing state of connection",
679679
validate=validate.OneOf(
680-
[
681-
getattr(ConnRecord, m)
682-
for m in vars(ConnRecord)
683-
if m.startswith("ROUTING_STATE_")
684-
]
680+
ConnRecord.get_attributes_by_prefix("ROUTING_STATE_", walk_mro=False)
685681
),
686682
example=ConnRecord.ROUTING_STATE_ACTIVE,
687683
)
@@ -690,11 +686,7 @@ class Meta:
690686
description="Connection acceptance: manual or auto",
691687
example=ConnRecord.ACCEPT_AUTO,
692688
validate=validate.OneOf(
693-
[
694-
getattr(ConnRecord, a)
695-
for a in vars(ConnRecord)
696-
if a.startswith("ACCEPT_")
697-
]
689+
ConnRecord.get_attributes_by_prefix("ACCEPT_", walk_mro=False)
698690
),
699691
)
700692
error_msg = fields.Str(
@@ -707,11 +699,7 @@ class Meta:
707699
description="Invitation mode",
708700
example=ConnRecord.INVITATION_MODE_ONCE,
709701
validate=validate.OneOf(
710-
[
711-
getattr(ConnRecord, i)
712-
for i in vars(ConnRecord)
713-
if i.startswith("INVITATION_MODE_")
714-
]
702+
ConnRecord.get_attributes_by_prefix("INVITATION_MODE_", walk_mro=False)
715703
),
716704
)
717705
alias = fields.Str(

aries_cloudagent/messaging/models/base_record.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class Meta:
8181
EVENT_NAMESPACE: str = "acapy::record"
8282
LOG_STATE_FLAG = None
8383
TAG_NAMES = {"state"}
84+
STATE_DELETED = "deleted"
8485

8586
def __init__(
8687
self,
@@ -420,7 +421,7 @@ async def delete_record(self, session: ProfileSession):
420421
storage = session.inject(BaseStorage)
421422
if self.state:
422423
self._previous_state = self.state
423-
self.state = "deleted"
424+
self.state = BaseRecord.STATE_DELETED
424425
await self.emit_event(session, self.serialize())
425426
await storage.delete_record(self.storage_record)
426427

@@ -497,6 +498,24 @@ def __eq__(self, other: Any) -> bool:
497498
return self.value == other.value and self.tags == other.tags
498499
return False
499500

501+
@classmethod
502+
def get_attributes_by_prefix(cls, prefix: str, walk_mro: bool = True):
503+
"""
504+
List all values for attributes with common prefix.
505+
506+
Args:
507+
prefix: Common prefix to look for
508+
walk_mro: Walk MRO to find attributes inherited from superclasses
509+
"""
510+
511+
bases = cls.__mro__ if walk_mro else [cls]
512+
return [
513+
vars(base)[name]
514+
for base in bases
515+
for name in vars(base)
516+
if name.startswith(prefix)
517+
]
518+
500519

501520
class BaseExchangeRecord(BaseRecord):
502521
"""Represents a base record with event tracing capability."""

aries_cloudagent/protocols/issue_credential/v2_0/models/cred_ex_record.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -296,35 +296,23 @@ class Meta:
296296
description="Issue-credential exchange initiator: self or external",
297297
example=V20CredExRecord.INITIATOR_SELF,
298298
validate=validate.OneOf(
299-
[
300-
getattr(V20CredExRecord, m)
301-
for m in vars(V20CredExRecord)
302-
if m.startswith("INITIATOR_")
303-
]
299+
V20CredExRecord.get_attributes_by_prefix("INITIATOR_", walk_mro=False)
304300
),
305301
)
306302
role = fields.Str(
307303
required=False,
308304
description="Issue-credential exchange role: holder or issuer",
309305
example=V20CredExRecord.ROLE_ISSUER,
310306
validate=validate.OneOf(
311-
[
312-
getattr(V20CredExRecord, m)
313-
for m in vars(V20CredExRecord)
314-
if m.startswith("ROLE_")
315-
]
307+
V20CredExRecord.get_attributes_by_prefix("ROLE_", walk_mro=False)
316308
),
317309
)
318310
state = fields.Str(
319311
required=False,
320312
description="Issue-credential exchange state",
321313
example=V20CredExRecord.STATE_DONE,
322314
validate=validate.OneOf(
323-
[
324-
getattr(V20CredExRecord, m)
325-
for m in vars(V20CredExRecord)
326-
if m.startswith("STATE_")
327-
]
315+
V20CredExRecord.get_attributes_by_prefix("STATE_", walk_mro=True)
328316
),
329317
)
330318
cred_preview = fields.Nested(

aries_cloudagent/protocols/out_of_band/v1_0/models/oob_record.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import json
44
from typing import Any, Mapping, Optional, Union
55

6-
from marshmallow import fields
6+
from marshmallow import fields, validate
77

88
from .....connections.models.conn_record import ConnRecord
99
from .....core.profile import ProfileSession
@@ -248,6 +248,9 @@ class Meta:
248248
required=True,
249249
description="Out of band message exchange state",
250250
example=OobRecord.STATE_AWAIT_RESPONSE,
251+
validate=validate.OneOf(
252+
OobRecord.get_attributes_by_prefix("STATE_", walk_mro=True)
253+
),
251254
)
252255
invi_msg_id = fields.Str(
253256
required=True,
@@ -287,4 +290,7 @@ class Meta:
287290
description="OOB Role",
288291
required=False,
289292
example=OobRecord.ROLE_RECEIVER,
293+
validate=validate.OneOf(
294+
OobRecord.get_attributes_by_prefix("ROLE_", walk_mro=False)
295+
),
290296
)

aries_cloudagent/protocols/present_proof/v2_0/models/pres_exchange.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -244,34 +244,22 @@ class Meta:
244244
description="Present-proof exchange initiator: self or external",
245245
example=V20PresExRecord.INITIATOR_SELF,
246246
validate=validate.OneOf(
247-
[
248-
getattr(V20PresExRecord, m)
249-
for m in vars(V20PresExRecord)
250-
if m.startswith("INITIATOR_")
251-
]
247+
V20PresExRecord.get_attributes_by_prefix("INITIATOR_", walk_mro=False)
252248
),
253249
)
254250
role = fields.Str(
255251
required=False,
256252
description="Present-proof exchange role: prover or verifier",
257253
example=V20PresExRecord.ROLE_PROVER,
258254
validate=validate.OneOf(
259-
[
260-
getattr(V20PresExRecord, m)
261-
for m in vars(V20PresExRecord)
262-
if m.startswith("ROLE_")
263-
]
255+
V20PresExRecord.get_attributes_by_prefix("ROLE_", walk_mro=False)
264256
),
265257
)
266258
state = fields.Str(
267259
required=False,
268260
description="Present-proof exchange state",
269261
validate=validate.OneOf(
270-
[
271-
getattr(V20PresExRecord, m)
272-
for m in vars(V20PresExRecord)
273-
if m.startswith("STATE_")
274-
]
262+
V20PresExRecord.get_attributes_by_prefix("STATE_", walk_mro=True)
275263
),
276264
)
277265
pres_proposal = fields.Nested(

0 commit comments

Comments
 (0)