Skip to content

Commit 1013145

Browse files
MHHukiewitzPsycojokerhoh
committed
feat: add aleph.sdk.security module
Co-authored-by: Laurent Peuch <[email protected]> Co-authored-by: Hugo Herter <[email protected]>
1 parent 9c5ec6e commit 1013145

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

src/aleph/sdk/security.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from importlib import import_module
2+
from typing import Callable, Dict, Optional, Union
3+
4+
from aleph_message.models import AlephMessage, Chain
5+
6+
from aleph.sdk.chains.common import get_verification_buffer
7+
from aleph.sdk.query.responses import Post
8+
9+
10+
def _try_import_verify_signature(
11+
chain: str,
12+
) -> Optional[
13+
Callable[[Union[bytes, str], Union[bytes, str], Union[bytes, str]], None]
14+
]:
15+
"""Try to import a chain signature validator."""
16+
try:
17+
return import_module(f"aleph.sdk.chains.{chain}").verify_signature
18+
except (ImportError, AttributeError):
19+
return None
20+
21+
22+
# This is a dict containing all currently available signature validators,
23+
# indexed by their Chain abbreviation.
24+
#
25+
# Ex.: validators["SOL"] -> aleph.sdk.chains.solana.verify_signature()
26+
VALIDATORS: Dict[
27+
Chain, Callable[[Union[bytes, str], Union[bytes, str], Union[bytes, str]], None]
28+
] = {
29+
key: _try_import_verify_signature(value)
30+
for key, value in {
31+
# TODO: Add AVAX
32+
Chain.ETH: "ethereum",
33+
Chain.SOL: "sol",
34+
Chain.CSDK: "cosmos",
35+
Chain.DOT: "substrate",
36+
Chain.NULS2: "nuls2",
37+
Chain.TEZOS: "tezos",
38+
}.items()
39+
}
40+
41+
42+
def verify_message_signature(message: Union[AlephMessage, Post]) -> None:
43+
"""Verify the signature of a message, raise an error if invalid or unsupported.
44+
A BadSignatureError is raised when the signature is incorrect.
45+
A ValueError is raised when the chain is not supported or required dependencies are missing.
46+
"""
47+
if message.chain not in VALIDATORS:
48+
raise ValueError(f"Chain {message.chain} is not supported.")
49+
50+
validator = VALIDATORS[message.chain]
51+
if validator is None:
52+
raise ValueError(
53+
f"Chain {message.chain} is not installed. Install it with `aleph-sdk-python[{message.chain}]`."
54+
)
55+
56+
signature = message.signature
57+
public_key = message.sender
58+
message = get_verification_buffer(message.dict())
59+
60+
# to please mypy
61+
assert isinstance(signature, (str, bytes))
62+
63+
validator(signature, public_key, message)

tests/unit/test_security.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
def test_validators_loaded():
2+
import aleph.sdk.security as security
3+
4+
assert any([validator is not None for validator in security.validators.values()])

0 commit comments

Comments
 (0)