diff --git a/scripts/keri/cf/demo-witness-oobis.json b/scripts/keri/cf/demo-witness-oobis.json index a79c059a..10d91fd0 100755 --- a/scripts/keri/cf/demo-witness-oobis.json +++ b/scripts/keri/cf/demo-witness-oobis.json @@ -5,8 +5,8 @@ "curls": ["http://127.0.0.1:3902/"] }, "iurls": [ - "http://127.0.0.1:5642/oobi/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha/controller", - "http://127.0.0.1:5643/oobi/BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM/controller", - "http://127.0.0.1:5644/oobi/BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX/controller" + "http://127.0.0.1:5642/oobi/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha/controller?name=Wan&tag=witness", + "http://127.0.0.1:5643/oobi/BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM/controller?name=Wes&tag=witness", + "http://127.0.0.1:5644/oobi/BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX/controller?name=Wil&tag=witness" ] } \ No newline at end of file diff --git a/src/keria/app/agenting.py b/src/keria/app/agenting.py index 1868797b..b91fdf6e 100644 --- a/src/keria/app/agenting.py +++ b/src/keria/app/agenting.py @@ -292,6 +292,7 @@ def __init__(self, hby, rgy, agentHab, agency, caid, **opts): self.anchors = decking.Deck() self.witners = decking.Deck() self.queries = decking.Deck() + self.exchanges = decking.Deck() receiptor = agenting.Receiptor(hby=hby) self.postman = forwarding.Poster(hby=hby) @@ -357,6 +358,7 @@ def __init__(self, hby, rgy, agentHab, agency, caid, **opts): ParserDoer(kvy=self.kvy, parser=self.parser), Witnesser(receiptor=receiptor, witners=self.witners), Delegator(agentHab=agentHab, swain=self.swain, anchors=self.anchors), + ExchangeSender(hby=hby, agentHab=agentHab, exc=self.exc, postman=self.postman, exchanges=self.exchanges), GroupRequester(hby=hby, agentHab=agentHab, counselor=self.counselor, groups=self.groups), SeekerDoer(seeker=self.seeker, cues=self.verifier.cues), ExnSeekerDoer(seeker=self.exnseeker, cues=self.exc.cues) @@ -448,6 +450,41 @@ def recur(self, tyme=None): return False +class ExchangeSender(doing.Doer): + + def __init__(self, hby, agentHab, postman, exc, exchanges): + self.hby = hby + self.agentHab = agentHab + self.postman = postman + self.exc = exc + self.exchanges = exchanges + super(ExchangeSender, self).__init__() + + def recur(self, tyme): + if self.exchanges: + msg = self.exchanges.popleft() + said = msg['said'] + if not self.exc.complete(said=said): + self.exchanges.append(msg) + return False + + serder, pathed = exchanging.cloneMessage(self.hby, said) + + pre = msg["pre"] + rec = msg["rec"] + topic = msg['topic'] + hab = self.hby.habs[pre] + if self.exc.lead(hab, said=said): + atc = exchanging.serializeMessage(self.hby, said) + del atc[:serder.size] + for recp in rec: + self.postman.send(hab=self.agentHab, + dest=recp, + topic=topic, + serder=serder, + attachment=atc) + + class SeekerDoer(doing.Doer): def __init__(self, seeker, cues): diff --git a/src/keria/app/aiding.py b/src/keria/app/aiding.py index 1f81a4d3..f4aaffe2 100644 --- a/src/keria/app/aiding.py +++ b/src/keria/app/aiding.py @@ -664,24 +664,46 @@ def on_get(req, rep, name): elif role in (kering.Roles.agent,): # Fetch URL OOBIs for all witnesses roleUrls = hab.fetchRoleUrls(cid=hab.pre, role=kering.Roles.agent, scheme=kering.Schemes.http) or hab.fetchRoleUrls(cid=hab.pre, role=kering.Roles.agent, scheme=kering.Schemes.https) if kering.Roles.agent not in roleUrls: - raise falcon.HTTPNotFound(description=f"unable to query agent roles for {hab.pre}, no http endpoint") - - aoobis = roleUrls[kering.Roles.agent] - - oobis = list() - for agent in set(aoobis.keys()): - murls = aoobis.naball(agent) - for murl in murls: - urls = [] - if kering.Schemes.http in murl: - urls.extend(murl.naball(kering.Schemes.http)) - if kering.Schemes.https in murl: - urls.extend(murl.naball(kering.Schemes.https)) - for url in urls: - up = urlparse(url) - oobis.append(urljoin(up.geturl(), f"/oobi/{hab.pre}/agent/{agent}")) - - res["oobis"] = oobis + res['oobis'] = [] + else: + aoobis = roleUrls[kering.Roles.agent] + + oobis = list() + for agent in set(aoobis.keys()): + murls = aoobis.naball(agent) + for murl in murls: + urls = [] + if kering.Schemes.http in murl: + urls.extend(murl.naball(kering.Schemes.http)) + if kering.Schemes.https in murl: + urls.extend(murl.naball(kering.Schemes.https)) + for url in urls: + up = urlparse(url) + oobis.append(urljoin(up.geturl(), f"/oobi/{hab.pre}/agent/{agent}")) + + res["oobis"] = oobis + elif role in (kering.Roles.mailbox,): # Fetch URL OOBIs for all witnesses + roleUrls = (hab.fetchRoleUrls(cid=hab.pre, role=kering.Roles.mailbox, scheme=kering.Schemes.http) or + hab.fetchRoleUrls(cid=hab.pre, role=kering.Roles.mailbox, scheme=kering.Schemes.https)) + if kering.Roles.mailbox not in roleUrls: + res['oobis'] = [] + else: + aoobis = roleUrls[kering.Roles.mailbox] + + oobis = list() + for mailbox in set(aoobis.keys()): + murls = aoobis.naball(mailbox) + for murl in murls: + urls = [] + if kering.Schemes.http in murl: + urls.extend(murl.naball(kering.Schemes.http)) + if kering.Schemes.https in murl: + urls.extend(murl.naball(kering.Schemes.https)) + for url in urls: + up = urlparse(url) + oobis.append(urljoin(up.geturl(), f"/oobi/{hab.pre}/mailbox/{mailbox}")) + + res["oobis"] = oobis else: raise falcon.HTTPBadRequest(description=f"unsupport role type {role} for oobi request") diff --git a/src/keria/core/authing.py b/src/keria/core/authing.py index 6391cb13..78471f29 100644 --- a/src/keria/core/authing.py +++ b/src/keria/core/authing.py @@ -4,7 +4,7 @@ keria.core.authing module """ - +from urllib.parse import quote, unquote import falcon from hio.help import Hict from keri import kering @@ -167,9 +167,12 @@ def process_request(self, req, resp): if req.path.startswith(path): return + req.path = quote(req.path) + try: # Use Authenticater to verify the signature on the request if self.authn.verify(req): + req.path = unquote(req.path) resource = self.authn.resource(req) agent = self.agency.get(caid=resource) @@ -198,6 +201,7 @@ def process_response(self, req, rep, resource, req_succeeded): """ if hasattr(req.context, "agent"): + req.path = quote(req.path) agent = req.context.agent rep.set_header('Signify-Resource', agent.agentHab.pre) rep.set_header('Signify-Timestamp', helping.nowIso8601()) diff --git a/src/keria/peer/exchanging.py b/src/keria/peer/exchanging.py index c09c5053..fd9a0143 100644 --- a/src/keria/peer/exchanging.py +++ b/src/keria/peer/exchanging.py @@ -75,14 +75,11 @@ def on_post(req, rep, name): # now get rid of the event so we can pass it as atc to send del ims[:serder.size] - for recp in rec: # now let's send it off the all the recipients - agent.postman.send(hab=agent.agentHab, - dest=recp, - topic=topic, - serder=serder, - attachment=ims) + msg = dict(said=serder.said, pre=hab.pre, rec=rec, topic=topic) - rep.status = falcon.HTTP_200 + agent.exchanges.append(msg) + + rep.status = falcon.HTTP_202 rep.data = json.dumps(serder.ked).encode("utf-8") @@ -169,7 +166,7 @@ def on_get(req, rep, name, said): if serder is None: raise falcon.HTTPNotFound(description=f"SAID {said} does not match a verified EXN message") - exn = dict(exn=serder.ked, pathed=pathed) + exn = dict(exn=serder.ked, pathed={k: v.decode("utf-8") for k, v in pathed.items()}) rep.status = falcon.HTTP_200 rep.content_type = "application/json" rep.data = json.dumps(exn).encode("utf-8") diff --git a/tests/app/test_aiding.py b/tests/app/test_aiding.py index 1f0c3daf..cbe107fe 100644 --- a/tests/app/test_aiding.py +++ b/tests/app/test_aiding.py @@ -1230,7 +1230,8 @@ def test_oobi_ends(helpers): # Test before endroles are added res = client.simulate_get("/identifiers/pal/oobis?role=agent") - assert res.status_code == 404 + assert res.status_code == 200 + assert res.json == {'oobis': [], 'role': 'agent'} rpy = helpers.endrole(iserder.pre, agent.agentHab.pre) sigs = helpers.sign(salt, 0, 0, rpy.raw) @@ -1301,6 +1302,27 @@ def test_oobi_ends(helpers): assert oobis[0] == "http://localhost:1234/oobi/EHgwVwQT15OJvilVvW57HE4w0-GPs_Stj2OFoAHZSysY/controller" + rpy = helpers.endrole(iserder.pre, agent.agentHab.pre, role="mailbox") + sigs = helpers.sign(salt, 0, 0, rpy.raw) + body = dict(rpy=rpy.ked, sigs=sigs) + + res = client.simulate_post(path=f"/identifiers/pal/endroles", json=body) + op = res.json + ked = op["response"] + serder = coring.Serder(ked=ked) + assert serder.raw == rpy.raw + + res = client.simulate_get("/identifiers/pal/oobis?role=mailbox") + assert res.status_code == 200 + role = res.json['role'] + oobis = res.json['oobis'] + + assert role == "mailbox" + assert len(oobis) == 1 + assert oobis[0] == "http://127.0.0.1:3902/oobi/EHgwVwQT15OJvilVvW57HE4w0-GPs_Stj2OFoAHZSysY/mailbox/EI7AkI40M11MS7lkTCb10JC9-nDt-tXwQh44OHAFlv_9" + + + def test_rpy_escow_end(helpers): with helpers.openKeria() as (agency, agent, app, client): rpyEscrowEnd = RpyEscrowCollectionEnd() diff --git a/tests/peer/test_exchanging.py b/tests/peer/test_exchanging.py index d9fcd1af..8ea7296e 100644 --- a/tests/peer/test_exchanging.py +++ b/tests/peer/test_exchanging.py @@ -8,6 +8,7 @@ """ import json +from hio.base import doing from keri.core import coring from keri.peer.exchanging import exchange @@ -31,6 +32,12 @@ def test_exchange_end(helpers): with helpers.openKeria() as (agency, agent, app, client): exchanging.loadEnds(app=app) + tock = 0.03125 + limit = 1.0 + doist = doing.Doist(limit=limit, tock=tock, real=True) + + deeds = doist.enter(doers=[agent]) + end = aiding.IdentifierCollectionEnd() app.add_route("/identifiers", end) endRolesEnd = aiding.EndRoleCollectionEnd() @@ -65,9 +72,14 @@ def test_exchange_end(helpers): ) res = client.simulate_post(path="/identifiers/aid1/exchanges", json=body) - assert res.status_code == 200 + assert res.status_code == 202 assert res.json == cexn.ked + assert len(agent.exchanges) == 1 + + doist.recur(deeds=deeds) + assert len(agent.postman.evts) == 1 + assert len(agent.exchanges) == 0 agent.exnseeker.index(cexn.said) QVI_SAID = "EFgnk_c08WmZGgv9_mpldibRuqFMTQN-rAgtD-TCOwbs" @@ -92,9 +104,14 @@ def test_exchange_end(helpers): assert res.status_code == 404 res = client.simulate_post(path="/identifiers/aid1/exchanges", json=body) - assert res.status_code == 200 + assert res.status_code == 202 + assert len(agent.exchanges) == 1 assert res.json == exn.ked - assert len(agent.postman.evts) == 2 + + doist.recur(deeds=deeds) + + assert len(agent.postman.evts) == 1 + assert len(agent.exchanges) == 0 agent.exnseeker.index(exn.said) body = json.dumps({}).encode("utf-8")