Skip to content

Commit fb6009a

Browse files
committed
Merge branch 'release-0.1.0-rc.1' into development
2 parents 98a33ae + d39c8f2 commit fb6009a

File tree

12 files changed

+77
-55
lines changed

12 files changed

+77
-55
lines changed

setup.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@
3434

3535
setup(
3636
name='keria',
37-
version='0.0.1', # also change in src/keria/__init__.py
37+
version='0.1.0', # also change in src/keria/__init__.py
3838
license='Apache Software License 2.0',
3939
description='KERIA: KERI Agent in the cloud',
4040
long_description="KERIA: KERI Agent in the cloud.",
41-
author='Samuel M. Smith',
42-
author_email='sam@samuelsmith.org',
41+
author='Philip S. Feairheller',
42+
author_email='pfeairheller@gmail.com',
4343
url='https://github.com/WebOfTrust/keria',
4444
packages=find_packages('src'),
4545
package_dir={'': 'src'},
@@ -76,7 +76,7 @@
7676
python_requires='>=3.10.4',
7777
install_requires=[
7878
'hio>=0.6.9',
79-
'keri @ git+https://git@github.com/WebOfTrust/keripy.git',
79+
'keri>=1.1.0',
8080
'mnemonic>=0.20',
8181
'multicommand>=1.0.0',
8282
'falcon>=3.1.0',

src/keria/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
main package
44
"""
55

6-
__version__ = '0.0.1' # also change in setup.py
6+
__version__ = '0.1.0' # also change in setup.py
77

src/keria/app/agenting.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ def on_post(self, req, rep):
818818

819819
caid = icp.pre
820820

821-
if caid in self.agency.agents:
821+
if self.agency.get(caid=caid) is not None:
822822
raise falcon.HTTPBadRequest(title="agent already exists",
823823
description=f"agent for controller {caid} already exists")
824824

src/keria/app/aiding.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def loadEnds(app, agency, authn):
5252
chaResEnd = ChallengeResourceEnd()
5353
app.add_route("/challenges/{name}", chaResEnd)
5454
chaVerResEnd = ChallengeVerifyResourceEnd()
55-
app.add_route("/challenges/{name}/verify/{source}", chaVerResEnd)
55+
app.add_route("/challenges_verify/{source}", chaVerResEnd)
5656

5757
contactColEnd = ContactCollectionEnd()
5858
app.add_route("/contacts", contactColEnd)
@@ -442,6 +442,9 @@ def on_get(req, rep, name):
442442
name (str): human readable name for Hab to GET
443443
444444
"""
445+
if not name:
446+
raise falcon.HTTPBadRequest(description="name is required")
447+
445448
agent = req.context.agent
446449
hab = agent.hby.habByName(name)
447450
if hab is None:
@@ -630,6 +633,9 @@ def on_get(req, rep, name):
630633
631634
"""
632635
agent = req.context.agent
636+
if not name:
637+
raise falcon.HTTPBadRequest(description="name is required")
638+
633639
hab = agent.hby.habByName(name)
634640
if not hab:
635641
raise falcon.HTTPNotFound(description="invalid alias {name}")
@@ -948,13 +954,12 @@ class ChallengeVerifyResourceEnd:
948954
""" Resource for Challenge/Response Verification Endpoints """
949955

950956
@staticmethod
951-
def on_post(req, rep, name, source):
957+
def on_post(req, rep, source):
952958
""" Challenge POST endpoint
953959
954960
Parameters:
955961
req: falcon.Request HTTP request
956962
rep: falcon.Response HTTP response
957-
name: human readable name of identifier to use to sign the challenge/response
958963
source: qb64 AID of of source of signed response to verify
959964
960965
---
@@ -990,9 +995,6 @@ def on_post(req, rep, name, source):
990995
description: Success submission of signed challenge/response
991996
"""
992997
agent = req.context.agent
993-
hab = agent.hby.habByName(name)
994-
if hab is None:
995-
raise falcon.HTTPNotFound(description="no matching Hab for alias {name}")
996998

997999
body = req.get_media()
9981000
words = httping.getRequiredParam(body, "words")
@@ -1008,13 +1010,12 @@ def on_post(req, rep, name, source):
10081010
rep.status = falcon.HTTP_202
10091011

10101012
@staticmethod
1011-
def on_put(req, rep, name, source):
1013+
def on_put(req, rep, source):
10121014
""" Challenge PUT accept endpoint
10131015
10141016
Parameters:
10151017
req: falcon.Request HTTP request
10161018
rep: falcon.Response HTTP response
1017-
name: human readable name of identifier to use to sign the challenge/response
10181019
source: qb64 AID of of source of signed response to verify
10191020
10201021
---
@@ -1049,10 +1050,6 @@ def on_put(req, rep, name, source):
10491050
description: Success submission of signed challenge/response
10501051
"""
10511052
agent = req.context.agent
1052-
hab = agent.hby.habByName(name)
1053-
if hab is None:
1054-
raise falcon.HTTPNotFound(description="no matching Hab for alias {name}")
1055-
10561053
body = req.get_media()
10571054
if "said" not in body:
10581055
raise falcon.HTTPBadRequest(description="challenge response acceptance requires 'aid' and 'said'")

src/keria/app/credentialing.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ def loadEnds(app, identifierResource):
3333
credentialCollectionEnd = CredentialCollectionEnd(identifierResource)
3434
app.add_route("/identifiers/{name}/credentials", credentialCollectionEnd)
3535

36-
credentialResourceEnd = CredentialResourceEnd(identifierResource)
37-
app.add_route("/identifiers/{name}/credentials/{said}", credentialResourceEnd)
36+
credentialResourceEnd = CredentialResourceEnd()
37+
app.add_route("/credentials/{said}", credentialResourceEnd)
38+
credentialResourceDelEnd = CredentialResourceDeleteEnd(identifierResource)
39+
app.add_route("/identifiers/{name}/credentials/{said}", credentialResourceDelEnd)
3840

3941
queryCollectionEnd = CredentialQueryCollectionEnd()
4042
app.add_route("/credentials/query", queryCollectionEnd)
@@ -506,23 +508,18 @@ def on_post(self, req, rep, name):
506508

507509

508510
class CredentialResourceEnd:
509-
def __init__(self, identifierResource):
511+
def __init__(self):
510512
"""
511513
512-
Parameters:
513-
identifierResource (IdentifierResourceEnd): endpoint class for creating rotation and interaction events
514-
515514
"""
516-
self.identifierResource = identifierResource
517515

518516
@staticmethod
519-
def on_get(req, rep, name, said):
517+
def on_get(req, rep, said):
520518
""" Credentials GET endpoint
521519
522520
Parameters:
523521
req: falcon.Request HTTP request
524522
rep: falcon.Response HTTP response
525-
name (str): human readable alias for AID to use as issuer
526523
said (str): SAID of credential to export
527524
528525
---
@@ -554,11 +551,6 @@ def on_get(req, rep, name, said):
554551
555552
"""
556553
agent = req.context.agent
557-
558-
hab = agent.hby.habByName(name)
559-
if hab is None:
560-
raise falcon.HTTPNotFound(description="name is not a valid reference to an identifier")
561-
562554
accept = req.get_header("accept")
563555
if accept == "application/json+cesr":
564556
rep.content_type = "application/json+cesr"
@@ -623,7 +615,18 @@ def outputCred(hby, rgy, said):
623615
out.extend(signing.serialize(creder, prefixer, seqner, saider))
624616

625617
return out
626-
618+
619+
620+
class CredentialResourceDeleteEnd:
621+
def __init__(self, identifierResource):
622+
"""
623+
624+
Parameters:
625+
identifierResource (IdentifierResourceEnd): endpoint class for creating rotation and interaction events
626+
627+
"""
628+
self.identifierResource = identifierResource
629+
627630
def on_delete(self, req, rep, name, said):
628631
""" Initiate a credential revocation
629632
@@ -655,7 +658,7 @@ def on_delete(self, req, rep, name, said):
655658
regk = rserder.ked['ri']
656659
if regk not in agent.rgy.tevers:
657660
raise falcon.HTTPNotFound(description=f"revocation against invalid registry SAID {regk}")
658-
661+
659662
try:
660663
agent.rgy.reger.cloneCreds([coring.Saider(qb64=said)], db=agent.hby.db)
661664
except:

src/keria/db/basing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ def generateIndexes(self, said):
241241
# Assign single field Schema and ISSUER index and ISSUER/SCHEMA:
242242
self.schIdx.add(keys=(said,), val=SCHEMA_FIELD.qb64b)
243243
self.schIdx.add(keys=(said,), val=ISSUER_FIELD.qb64b)
244+
self.schIdx.add(keys=(said,), val=REGISTRY_FIELD.qb64b)
244245
subkey = f"{ISSUER_FIELD.qb64}.{SCHEMA_FIELD.qb64}"
245246
self.schIdx.add(keys=(said,), val=subkey.encode("UTF-8"))
246247

src/keria/end/ending.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def on_get(self, _, rep, aid=None, role=None, eid=None):
4848
eid: qb64 identifier prefix of participant in role
4949
5050
"""
51-
if aid is None:
51+
if not aid:
5252
if self.default is None:
5353
raise falcon.HTTPNotFound(description="no blind oobi for this node")
5454

tests/app/test_aiding.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,10 @@ def test_identifier_collection_end(helpers):
315315
res = client.simulate_post(path="/identifiers", body=json.dumps(body))
316316
assert res.status_code == 202
317317

318+
res = client.simulate_get(path="/identifiers/")
319+
assert res.status_code == 400
320+
assert res.json == {'description': 'name is required', 'title': '400 Bad Request'}
321+
318322
res = client.simulate_get(path="/identifiers")
319323
assert res.status_code == 200
320324
assert len(res.json) == 2
@@ -852,7 +856,7 @@ def test_challenge_ends(helpers):
852856
chaResEnd = aiding.ChallengeResourceEnd()
853857
app.add_route("/challenges/{name}", chaResEnd)
854858
chaVerResEnd = aiding.ChallengeVerifyResourceEnd()
855-
app.add_route("/challenges/{name}/verify/{source}", chaVerResEnd)
859+
app.add_route("/challenges-verify/{source}", chaVerResEnd)
856860

857861
client = testing.TestClient(app)
858862

@@ -902,16 +906,16 @@ def test_challenge_ends(helpers):
902906
assert result.status == falcon.HTTP_404 # Missing recipient
903907

904908
b = json.dumps(data).encode("utf-8")
905-
result = client.simulate_put(path=f"/challenges/pal/verify/{aid['i']}", body=b)
909+
result = client.simulate_put(path=f"/challenges-verify/{aid['i']}", body=b)
906910
assert result.status == falcon.HTTP_400 # Missing said
907911

908912
data["said"] = exn.said
909913
b = json.dumps(data).encode("utf-8")
910-
result = client.simulate_put(path=f"/challenges/pal/verify/EFt8G8gkCJ71e4amQaRUYss0BDK4pUpzKelEIr3yZ1D0",
914+
result = client.simulate_put(path=f"/challenges-verify/EFt8G8gkCJ71e4amQaRUYss0BDK4pUpzKelEIr3yZ1D0",
911915
body=b)
912916
assert result.status == falcon.HTTP_404 # Missing said
913917

914-
result = client.simulate_put(path=f"/challenges/pal/verify/{aid['i']}", body=b)
918+
result = client.simulate_put(path=f"/challenges-verify/{aid['i']}", body=b)
915919
assert result.status == falcon.HTTP_202
916920

917921
data = dict(
@@ -923,12 +927,12 @@ def test_challenge_ends(helpers):
923927
assert result.status_code == 404
924928

925929
b = json.dumps(data).encode("utf-8")
926-
result = client.simulate_post(path=f"/challenges/pal/verify/EFt8G8gkCJ71e4amQaRUYss0BDK4pUpzKelEIr3yZ1D0",
930+
result = client.simulate_post(path=f"/challenges-verify/EFt8G8gkCJ71e4amQaRUYss0BDK4pUpzKelEIr3yZ1D0",
927931
body=b)
928932
assert result.status_code == 404
929933

930934
b = json.dumps(data).encode("utf-8")
931-
result = client.simulate_post(path=f"/challenges/pal/verify/{aid['i']}", body=b)
935+
result = client.simulate_post(path=f"/challenges-verify/{aid['i']}", body=b)
932936
assert result.status == falcon.HTTP_202
933937
op = result.json
934938
assert op["done"] is False
@@ -937,7 +941,7 @@ def test_challenge_ends(helpers):
937941
agent.hby.db.reps.add(keys=(aid['i'],), val=coring.Saider(qb64=exn.said))
938942
agent.hby.db.exns.pin(keys=(exn.said,), val=exn)
939943

940-
result = client.simulate_post(path=f"/challenges/pal/verify/{aid['i']}", body=b)
944+
result = client.simulate_post(path=f"/challenges-verify/{aid['i']}", body=b)
941945
assert result.status == falcon.HTTP_202
942946
op = result.json
943947
assert op["done"] is True
@@ -1228,6 +1232,11 @@ def test_oobi_ends(helpers):
12281232
iserder = serdering.SerderKERI(sad=op["response"])
12291233
assert iserder.pre == "EHgwVwQT15OJvilVvW57HE4w0-GPs_Stj2OFoAHZSysY"
12301234

1235+
# Test empty
1236+
res = client.simulate_get("/identifiers//oobis?role=agent")
1237+
assert res.status_code == 400
1238+
assert res.json == {'description': 'name is required', 'title': '400 Bad Request'}
1239+
12311240
# Test before endroles are added
12321241
res = client.simulate_get("/identifiers/pal/oobis?role=agent")
12331242
assert res.status_code == 200

tests/app/test_basing.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def test_seeker(helpers, seeder, mockHelpingNowUTC):
3838
# Verify the indexes created for the QVI schema
3939
assert indexes == ['5AABAA-s',
4040
'5AABAA-i',
41+
'4AABA-ri',
4142
'5AABAA-i.5AABAA-s',
4243
'4AAB-a-i',
4344
'4AAB-a-i.5AABAA-s',
@@ -73,6 +74,7 @@ def test_seeker(helpers, seeder, mockHelpingNowUTC):
7374
# Test the indexes assigned to the LE schema
7475
assert indexes == ['5AABAA-s',
7576
'5AABAA-i',
77+
'4AABA-ri',
7678
'5AABAA-i.5AABAA-s',
7779
'4AAB-a-i',
7880
'4AAB-a-i.5AABAA-s',
@@ -122,6 +124,12 @@ def test_seeker(helpers, seeder, mockHelpingNowUTC):
122124
saids = seeker.find({}).limit(50)
123125
assert len(list(saids)) == 50
124126

127+
saids = seeker.find({ '-ri': "EACehJRd0wfteUAJgaTTJjMSaQqWvzeeHqAMMqxuqxU4" })
128+
assert len(list(saids)) == 25
129+
130+
saids = seeker.find({ '-ri': "EAzc9zFLaK22zbrKDGIgKtrpDBNKWKvl8B0FKYAo19z_" })
131+
assert len(list(saids)) == 0
132+
125133
saids = seeker.find({'-d': "EAzc9zFLaK22zbrKDGIgKtrpDBNKWKvl8B0FKYAo19z_"})
126134
assert list(saids) == ['EAzc9zFLaK22zbrKDGIgKtrpDBNKWKvl8B0FKYAo19z_']
127135

tests/app/test_credentialing.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ def test_credentialing_ends(helpers, seeder):
270270
app.add_route("/identifiers/{name}/credentials", credEnd)
271271
credResEnd = credentialing.CredentialQueryCollectionEnd()
272272
app.add_route("/credentials/query", credResEnd)
273-
credResEnd = credentialing.CredentialResourceEnd(idResEnd)
274-
app.add_route("/identifiers/{name}/credentials/{said}", credResEnd)
273+
credResEnd = credentialing.CredentialResourceEnd()
274+
app.add_route("/credentials/{said}", credResEnd)
275275

276276
assert hab.pre == "EIqTaQiZw73plMOq8pqHTi9BDgDrrE7iE9v2XfN2Izze"
277277

@@ -375,22 +375,16 @@ def test_credentialing_ends(helpers, seeder):
375375
assert res.status_code == 200
376376
assert len(res.json) == 4
377377

378-
res = client.simulate_get(f"/identifiers/test/credentials/{saids[0]}")
378+
res = client.simulate_get(f"/credentials/{saids[0]}")
379379
assert res.status_code == 200
380380
assert res.headers['content-type'] == "application/json"
381381
assert res.json['sad']['d'] == saids[0]
382382

383383
headers = {"Accept": "application/json+cesr"}
384-
res = client.simulate_get(f"/identifiers/{hab.name}/credentials/{saids[0]}", headers=headers)
385-
assert res.status_code == 404
386-
387-
res = client.simulate_get(f"/identifiers/test/credentials/{saids[0]}", headers=headers)
384+
res = client.simulate_get(f"/credentials/{saids[0]}", headers=headers)
388385
assert res.status_code == 200
389386
assert res.headers['content-type'] == "application/json+cesr"
390387

391-
res = client.simulate_get(f"/identifiers/bad_test/credentials/{saids[0]}", headers=headers)
392-
assert res.status_code == 404
393-
394388

395389
def test_revoke_credential(helpers, seeder):
396390
with helpers.openKeria() as (agency, agent, app, client):
@@ -406,8 +400,10 @@ def test_revoke_credential(helpers, seeder):
406400
app.add_route("/identifiers", end)
407401
endRolesEnd = aiding.EndRoleCollectionEnd()
408402
app.add_route("/identifiers/{name}/endroles", endRolesEnd)
409-
credResEnd = credentialing.CredentialResourceEnd(idResEnd)
410-
app.add_route("/identifiers/{name}/credentials/{said}", credResEnd)
403+
credResEnd = credentialing.CredentialResourceEnd()
404+
app.add_route("/credentials/{said}", credResEnd)
405+
credResDelEnd = credentialing.CredentialResourceDeleteEnd(idResEnd)
406+
app.add_route("/identifiers/{name}/credentials/{said}", credResDelEnd)
411407
credResEnd = credentialing.CredentialQueryCollectionEnd()
412408
app.add_route("/credentials/query", credResEnd)
413409

0 commit comments

Comments
 (0)