Skip to content

Commit

Permalink
Client for new ipex admit API and updated issue-ecr.sh to work with I…
Browse files Browse the repository at this point in the history
…PEX (#93)

* Client for new ipex admit API and updated issue-ecr.sh to work with IPEX

Signed-off-by: pfeairheller <pfeairheller@gmail.com>

* Fix test

Signed-off-by: pfeairheller <pfeairheller@gmail.com>

* Tests for authn.verify

Signed-off-by: pfeairheller <pfeairheller@gmail.com>

* Tests for submitAdmit

Signed-off-by: pfeairheller <pfeairheller@gmail.com>

---------

Signed-off-by: pfeairheller <pfeairheller@gmail.com>
  • Loading branch information
pfeairheller authored Nov 6, 2023
1 parent c48847d commit ba43e15
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 17 deletions.
34 changes: 27 additions & 7 deletions scripts/issue-ecr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,49 @@ kli vc registry incept --name qvi --alias qvi --registry-name vLEI-qvi
kli vc registry incept --name legal-entity --alias legal-entity --registry-name vLEI-legal-entity

# Issue QVI credential vLEI from GLEIF External to QVI
kli vc issue --name external --alias external --registry-name vLEI-external --schema EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao --recipient EHMnCf8_nIemuPx-cUHaDQq8zSnQIFAurdEpwHpNbnvX --data @"${KERI_DEMO_SCRIPT_DIR}"/data/qvi-data.json
kli vc accept --name qvi --alias qvi --poll --auto
kli vc create --name external --alias external --registry-name vLEI-external --schema EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao --recipient EHMnCf8_nIemuPx-cUHaDQq8zSnQIFAurdEpwHpNbnvX --data @"${KERI_DEMO_SCRIPT_DIR}"/data/qvi-data.json
SAID=$(kli vc list --name external --alias external --issued --said --schema EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao)
kli ipex grant --name external --alias external --said "${SAID}" --recipient EHMnCf8_nIemuPx-cUHaDQq8zSnQIFAurdEpwHpNbnvX
GRANT=$(kli ipex list --name qvi --alias qvi --poll --said)
echo "Admitting credential from grant ${GRANT}"
kli ipex admit --name qvi --alias qvi --said "${GRANT}"
kli vc list --name qvi --alias qvi

# Issue LE credential from QVI to Legal Entity - have to create the edges first
QVI_SAID=$(kli vc list --name qvi --alias qvi --said --schema EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao)
echo \"$QVI_SAID\" | jq -f "${KERI_DEMO_SCRIPT_DIR}"/data/legal-entity-edges-filter.jq > /tmp/legal-entity-edges.json
kli saidify --file /tmp/legal-entity-edges.json
kli vc issue --name qvi --alias qvi --registry-name vLEI-qvi --schema ENPXp1vQzRF6JwIuS-mp2U8Uf1MoADoP_GqQ62VsDZWY --recipient EIitNxxiNFXC1HDcPygyfyv3KUlBfS_Zf-ZYOvwjpTuz --data @"${KERI_DEMO_SCRIPT_DIR}"/data/legal-entity-data.json --edges @/tmp/legal-entity-edges.json --rules @"${KERI_DEMO_SCRIPT_DIR}"/data/rules.json
kli vc accept --name legal-entity --alias legal-entity --poll --auto
kli vc create --name qvi --alias qvi --registry-name vLEI-qvi --schema ENPXp1vQzRF6JwIuS-mp2U8Uf1MoADoP_GqQ62VsDZWY --recipient EIitNxxiNFXC1HDcPygyfyv3KUlBfS_Zf-ZYOvwjpTuz --data @"${KERI_DEMO_SCRIPT_DIR}"/data/legal-entity-data.json --edges @/tmp/legal-entity-edges.json --rules @"${KERI_DEMO_SCRIPT_DIR}"/data/rules.json
SAID=$(kli vc list --name qvi --alias qvi --issued --said --schema ENPXp1vQzRF6JwIuS-mp2U8Uf1MoADoP_GqQ62VsDZWY)
kli ipex grant --name qvi --alias qvi --said "${SAID}" --recipient EIitNxxiNFXC1HDcPygyfyv3KUlBfS_Zf-ZYOvwjpTuz
GRANT=$(kli ipex list --name legal-entity --alias legal-entity --poll --said)
echo "Admitting credential from grant ${GRANT}"
kli ipex admit --name legal-entity --alias legal-entity --said "${GRANT}"
kli vc list --name legal-entity --alias legal-entity

# Issue ECR Authorization credential from Legal Entity to QVI - have to create the edges first
LE_SAID=$(kli vc list --name legal-entity --alias legal-entity --said)
echo \"$LE_SAID\" | jq -f "${KERI_DEMO_SCRIPT_DIR}"/data/ecr-auth-edges-filter.jq > /tmp/ecr-auth-edges.json
kli saidify --file /tmp/ecr-auth-edges.json
kli vc issue --name legal-entity --alias legal-entity --registry-name vLEI-legal-entity --schema EH6ekLjSr8V32WyFbGe1zXjTzFs9PkTYmupJ9H65O14g --recipient EHMnCf8_nIemuPx-cUHaDQq8zSnQIFAurdEpwHpNbnvX --data @"${KERI_DEMO_SCRIPT_DIR}"/data/ecr-auth-data.json --edges @/tmp/ecr-auth-edges.json --rules @"${KERI_DEMO_SCRIPT_DIR}"/data/ecr-auth-rules.json
kli vc accept --name qvi --alias qvi --poll --auto
kli vc create --name legal-entity --alias legal-entity --registry-name vLEI-legal-entity --schema EH6ekLjSr8V32WyFbGe1zXjTzFs9PkTYmupJ9H65O14g --recipient EHMnCf8_nIemuPx-cUHaDQq8zSnQIFAurdEpwHpNbnvX --data @"${KERI_DEMO_SCRIPT_DIR}"/data/ecr-auth-data.json --edges @/tmp/ecr-auth-edges.json --rules @"${KERI_DEMO_SCRIPT_DIR}"/data/ecr-auth-rules.json
SAID=$(kli vc list --name legal-entity --alias legal-entity --issued --said --schema EH6ekLjSr8V32WyFbGe1zXjTzFs9PkTYmupJ9H65O14g)
kli ipex grant --name legal-entity --alias legal-entity --said "${SAID}" --recipient EHMnCf8_nIemuPx-cUHaDQq8zSnQIFAurdEpwHpNbnvX
GRANT=$(kli ipex list --name legal-entity --alias legal-entity --sent --type grant --said)
kli ipex list --name qvi --alias qvi --poll
echo "Admitting credential from grant ${GRANT}"
kli ipex admit --name qvi --alias qvi --said "${GRANT}"
kli vc list --name qvi --alias qvi

# Issue ECR credential from QVI to Person
AUTH_SAID=$(kli vc list --name qvi --alias qvi --said --schema EH6ekLjSr8V32WyFbGe1zXjTzFs9PkTYmupJ9H65O14g)
echo "[\"$QVI_SAID\", \"$AUTH_SAID\"]" | jq -f "${KERI_DEMO_SCRIPT_DIR}"/data/ecr-edges-filter.jq > /tmp/ecr-edges.json
kli saidify --file /tmp/ecr-edges.json
kli vc issue --name qvi --alias qvi --private --registry-name vLEI-qvi --schema EEy9PkikFcANV1l7EHukCeXqrzT1hNZjGlUk7wuMO5jw --recipient EBcIURLpxmVwahksgrsGW6_dUw0zBhyEHYFk17eWrZfk --data @"${KERI_DEMO_SCRIPT_DIR}"/data/ecr-data.json --edges @/tmp/ecr-edges.json --rules @"${KERI_DEMO_SCRIPT_DIR}"/data/ecr-rules.json
kli vc create --name qvi --alias qvi --private --registry-name vLEI-qvi --schema EEy9PkikFcANV1l7EHukCeXqrzT1hNZjGlUk7wuMO5jw --recipient EBcIURLpxmVwahksgrsGW6_dUw0zBhyEHYFk17eWrZfk --data @"${KERI_DEMO_SCRIPT_DIR}"/data/ecr-data.json --edges @/tmp/ecr-edges.json --rules @"${KERI_DEMO_SCRIPT_DIR}"/data/ecr-rules.json
SAID=$(kli vc list --name qvi --alias qvi --issued --said --schema EEy9PkikFcANV1l7EHukCeXqrzT1hNZjGlUk7wuMO5jw)
kli ipex grant --name qvi --alias qvi --said "${SAID}" --recipient EBcIURLpxmVwahksgrsGW6_dUw0zBhyEHYFk17eWrZfk

kli ipex list --name qvi --alias qvi
GRANT=$(python "${KERI_SCRIPT_DIR}"/list_ipex.py)
python "${KERI_SCRIPT_DIR}"/send_admit.py "${GRANT}" EHMnCf8_nIemuPx-cUHaDQq8zSnQIFAurdEpwHpNbnvX
kli ipex list --name qvi --alias qvi --poll
python "${KERI_SCRIPT_DIR}"/list_person_credentials.py
32 changes: 32 additions & 0 deletions scripts/list_ipex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# -*- encoding: utf-8 -*-
"""
SIGNIFY
signify.app.clienting module
Testing clienting with integration tests that require a running KERIA Cloud Agent
"""
import sys

from keri.core.coring import Tiers
from keri.vc.proving import Creder

from signify.app.clienting import SignifyClient


def list_ipex():
url = "http://localhost:3901"
bran = b'0123456789abcdefghijk'
tier = Tiers.low

client = SignifyClient(passcode=bran, tier=tier, url=url)
notificatons = client.notifications()

notes = notificatons.list()
for note in notes["notes"]:
a = note['a']
if a['r'].startswith("/exn/ipex/"):
print(a['d'])


if __name__ == "__main__":
list_ipex()
6 changes: 4 additions & 2 deletions scripts/list_person_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from keri.vc.proving import Creder

from signify.app.clienting import SignifyClient
from signify.app.credentialing import CredentialTypes


def list_credentials():
Expand All @@ -21,14 +20,17 @@ def list_credentials():
client = SignifyClient(passcode=bran, tier=tier, url=url)

identifiers = client.identifiers()
aids = identifiers.list()
res = identifiers.list()

aids = res['aids']

assert len(aids) == 1
aid = aids[0]['prefix']
print(aid)
credentials = client.credentials()

creds = credentials.list("BankUser", filtr={'-a-i': aid})
print(creds)
assert len(creds) == 1

creder = Creder(ked=creds[0]['sad'])
Expand Down
36 changes: 36 additions & 0 deletions scripts/send_admit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
"""
SIGNIFY
signify.app.clienting module
Testing clienting with integration tests that require a running KERIA Cloud Agent
"""
import sys

from keri.core.coring import Tiers

from signify.app.clienting import SignifyClient


def send_admit(grant, recp):
url = "http://localhost:3901"
bran = b'0123456789abcdefghijk'
tier = Tiers.low

client = SignifyClient(passcode=bran, tier=tier, url=url)

identifiers = client.identifiers()

hab = identifiers.get("BankUser")
create_admit(client, hab, grant, recp)


def create_admit(client, hab, said, recp, dt=None):
ipex = client.ipex()
admit, sigs, atc = ipex.admit(hab, "", said, dt=dt)

ipex.submitAdmit(hab['name'], exn=admit, sigs=sigs, atc=atc, recp=recp)


if __name__ == "__main__":
send_admit(sys.argv[1], sys.argv[2])
27 changes: 26 additions & 1 deletion src/signify/app/credentialing.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,31 @@ def admit(self, hab, message, grant, dt=None):
)

admit, asigs, end = exchanges.createExchangeMessage(sender=hab, route="/ipex/admit",
payload=data, embeds=None, dt=dt, dig=grant.said)
payload=data, embeds=None, dt=dt, dig=grant)

return admit, asigs, end

def submitAdmit(self, name, exn, sigs, atc, recp):
""" Send precreated exn message to recipients
Parameters:
name (str): human readable identifier alias to send from
exn (Serder): peer-to-peer message to send
sigs (list): qb64 signatures over the exn
atc (string|bytes): additional attachments for exn (usually pathed signatures over embeds)
recp (list[string]): qb64 recipient AID
Returns:
dict: operation response from KERIA
"""

body = dict(
exn=exn.ked,
sigs=sigs,
atc=atc,
rec=[recp]
)

res = self.client.post(f"/identifiers/{name}/ipex/admit", json=body)
return res.json()
3 changes: 3 additions & 0 deletions src/signify/core/authing.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ def __init__(self, agent: Agent, ctrl: Controller):

def verify(self, rep, **kwargs):
url = urlparse(rep.request.url)
if "SIGNIFY-RESOURCE" not in rep.headers:
raise kering.AuthNError("No valid signature from agent on response.")

resource = rep.headers["SIGNIFY-RESOURCE"]
if resource != self.agent.pre or not self.verifysig(rep.headers, rep.request.method, url.path):
raise kering.AuthNError("No valid signature from agent on response.")
Expand Down
5 changes: 3 additions & 2 deletions src/signify/peer/exchanging.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(self, client: SignifyClient):
"""
self.client = client

def send(self, name, topic, sender, route, payload, embeds, recipients):
def send(self, name, topic, sender, route, payload, embeds, recipients, dig=None):
""" Send exn message to recipients
Parameters:
Expand All @@ -32,13 +32,14 @@ def send(self, name, topic, sender, route, payload, embeds, recipients):
payload (dict): payload of the exn message
embeds (dict): map of label to bytes of encoded KERI event to embed in exn
recipients (list[string]): list of qb64 recipient AIDs
dig (str): Optional qb64 SAID of exchange message reverse chain
Returns:
dict: operation response from KERIA
"""

exn, sigs, atc = self.createExchangeMessage(sender, route, payload, embeds)
exn, sigs, atc = self.createExchangeMessage(sender, route, payload, embeds, dig=dig)
json = self.sendFromEvents(name, topic, exn=exn, sigs=sigs, atc=atc, recipients=recipients)

return exn, sigs, json
Expand Down
28 changes: 26 additions & 2 deletions tests/app/test_credentialing.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,35 @@ def test_ipex_admit():
mock_gsigs,
mock_end))

ipex = credentialing.Ipex(mock_client) # type: ignore
grant, gsigs, end = ipex.admit(hab=mock_hab, message="this is a test", dt=dt, grant=grant)
ipex = credentialing.Ipex(mock_client) # type: ignore
grant, gsigs, end = ipex.admit(hab=mock_hab, message="this is a test", dt=dt, grant=grant.said)

assert grant == mock_admit
assert gsigs == mock_gsigs
assert end == mock_end

unstub()


def test_submit_admit():
from signify.app.clienting import SignifyClient
mock_client = mock(spec=SignifyClient, strict=True)

from requests import Response
mock_rep = mock(spec=Response, strict=True)

expect(mock_rep).json().thenReturn(dict(b='c'))

mock_admit = mock({'ked': dict(a='b')})
mock_gsigs = []
mock_end = ""
recp = ["ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose"]

ipex = credentialing.Ipex(mock_client) # type: ignore
body = {'exn': {'a': 'b'}, 'sigs': [], 'atc': '', 'rec': [['ELI7pg979AdhmvrjDeam2eAO2SR5niCgnjAJXJHtJose']]}
expect(mock_client, times=1).post(f"/identifiers/aid1/ipex/admit", json=body).thenReturn(mock_rep)
rep = ipex.submitAdmit("aid1", exn=mock_admit, sigs=mock_gsigs, atc=mock_end, recp=recp)

assert rep == dict(b='c')

unstub()
46 changes: 43 additions & 3 deletions tests/core/test_authing.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,43 @@

from mockito import mock, patch, unstub, expect, verifyNoUnwantedInteractions, when
from keri import kering
from mockito import mock, unstub, expect, verifyNoUnwantedInteractions
import pytest


def rt(a, b, c):
return True


def test_verify():
agent = mock({'pre': "EEz01234"})
ctrl = mock()

from signify.core.authing import Authenticater
authn = Authenticater(agent, ctrl)

import requests
mock_request = mock({'method': 'GET', 'url': 'http://example.com/my_path', 'headers': {}, 'body': "a body for len"},
spec=requests.Request, strict=True)
mock_rep = mock({'request': mock_request, 'headers': {}}, spec=requests.Response, strict=True)

with pytest.raises(kering.AuthNError):
authn.verify(rep=mock_rep)

mock_rep = mock({'request': mock_request, 'headers': {"SIGNIFY-RESOURCE": 'EABC'}}, spec=requests.Response,
strict=True)

with pytest.raises(kering.AuthNError):
authn.verify(rep=mock_rep)

# Swap out verifysig so we can test verify
authn.verifysig = rt
mock_rep = mock({'request': mock_request, 'headers': {"SIGNIFY-RESOURCE": 'EEz01234'}}, spec=requests.Response,
strict=True)

authn.verify(rep=mock_rep)
verifyNoUnwantedInteractions()
unstub()


def test_agent():
mock_verfer = mock()
from keri.core import coring
Expand Down Expand Up @@ -71,7 +107,8 @@ def test_controller(bran):
assert ctrl.event()[1].raw == (b'\x8a\xf6\x7f\x9e\xc8%\xc4\xe9\xc1<p\x8as\xd3[\x95k;\xe1\xe1\xce\x84\xcf\xe3'
b'\t\xf9\x7f}\xeeb\xa6c\xe21-t\x17h\xad\x91\x14\xf7\x88L\xdc5\xaf\xc6'
b'\x05\xc0\x01\xd3\x9f}\xbf\xe7\x06\x80\xfb\x80\x14*\x8c\x04')



def test_controller_derive():
from signify.core.authing import Controller
from keri.core.coring import Tiers
Expand Down Expand Up @@ -99,6 +136,7 @@ def test_controller_derive():
assert serder.raw == (b'{"v":"KERI10JSON00006f_","d":"EIM66TjBMfwPnbwK7oZqbZyGz9nOeVmQHeH3NZxrsk8F",'
b'"i":"ABCDEFG","s":"0001","t":"rot"}')


def test_approve_delegation():
from signify.core.authing import Controller
ctrl = Controller(bran="abcdefghijklmnop01234", tier=Tiers.low)
Expand Down Expand Up @@ -132,6 +170,7 @@ def test_approve_delegation():
verifyNoUnwantedInteractions()
unstub()


def test_approve_delegation():
from signify.core.authing import Controller
from keri.core.coring import Tiers
Expand Down Expand Up @@ -173,6 +212,7 @@ def test_approve_delegation():
verifyNoUnwantedInteractions()
unstub()


def test_controller_rotate_salty():
from signify.core.authing import Controller
from keri.core.coring import Tiers
Expand Down

0 comments on commit ba43e15

Please sign in to comment.