Skip to content

Commit

Permalink
Merge branch 'release-0.1.0-rc.1' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
pfeairheller committed Feb 13, 2024
2 parents 98a33ae + d39c8f2 commit fb6009a
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 55 deletions.
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@

setup(
name='keria',
version='0.0.1', # also change in src/keria/__init__.py
version='0.1.0', # also change in src/keria/__init__.py
license='Apache Software License 2.0',
description='KERIA: KERI Agent in the cloud',
long_description="KERIA: KERI Agent in the cloud.",
author='Samuel M. Smith',
author_email='[email protected]',
author='Philip S. Feairheller',
author_email='[email protected]',
url='https://github.com/WebOfTrust/keria',
packages=find_packages('src'),
package_dir={'': 'src'},
Expand Down Expand Up @@ -76,7 +76,7 @@
python_requires='>=3.10.4',
install_requires=[
'hio>=0.6.9',
'keri @ git+https://[email protected]/WebOfTrust/keripy.git',
'keri>=1.1.0',
'mnemonic>=0.20',
'multicommand>=1.0.0',
'falcon>=3.1.0',
Expand Down
2 changes: 1 addition & 1 deletion src/keria/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
main package
"""

__version__ = '0.0.1' # also change in setup.py
__version__ = '0.1.0' # also change in setup.py

2 changes: 1 addition & 1 deletion src/keria/app/agenting.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ def on_post(self, req, rep):

caid = icp.pre

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

Expand Down
21 changes: 9 additions & 12 deletions src/keria/app/aiding.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def loadEnds(app, agency, authn):
chaResEnd = ChallengeResourceEnd()
app.add_route("/challenges/{name}", chaResEnd)
chaVerResEnd = ChallengeVerifyResourceEnd()
app.add_route("/challenges/{name}/verify/{source}", chaVerResEnd)
app.add_route("/challenges_verify/{source}", chaVerResEnd)

contactColEnd = ContactCollectionEnd()
app.add_route("/contacts", contactColEnd)
Expand Down Expand Up @@ -442,6 +442,9 @@ def on_get(req, rep, name):
name (str): human readable name for Hab to GET
"""
if not name:
raise falcon.HTTPBadRequest(description="name is required")

agent = req.context.agent
hab = agent.hby.habByName(name)
if hab is None:
Expand Down Expand Up @@ -630,6 +633,9 @@ def on_get(req, rep, name):
"""
agent = req.context.agent
if not name:
raise falcon.HTTPBadRequest(description="name is required")

hab = agent.hby.habByName(name)
if not hab:
raise falcon.HTTPNotFound(description="invalid alias {name}")
Expand Down Expand Up @@ -948,13 +954,12 @@ class ChallengeVerifyResourceEnd:
""" Resource for Challenge/Response Verification Endpoints """

@staticmethod
def on_post(req, rep, name, source):
def on_post(req, rep, source):
""" Challenge POST endpoint
Parameters:
req: falcon.Request HTTP request
rep: falcon.Response HTTP response
name: human readable name of identifier to use to sign the challenge/response
source: qb64 AID of of source of signed response to verify
---
Expand Down Expand Up @@ -990,9 +995,6 @@ def on_post(req, rep, name, source):
description: Success submission of signed challenge/response
"""
agent = req.context.agent
hab = agent.hby.habByName(name)
if hab is None:
raise falcon.HTTPNotFound(description="no matching Hab for alias {name}")

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

@staticmethod
def on_put(req, rep, name, source):
def on_put(req, rep, source):
""" Challenge PUT accept endpoint
Parameters:
req: falcon.Request HTTP request
rep: falcon.Response HTTP response
name: human readable name of identifier to use to sign the challenge/response
source: qb64 AID of of source of signed response to verify
---
Expand Down Expand Up @@ -1049,10 +1050,6 @@ def on_put(req, rep, name, source):
description: Success submission of signed challenge/response
"""
agent = req.context.agent
hab = agent.hby.habByName(name)
if hab is None:
raise falcon.HTTPNotFound(description="no matching Hab for alias {name}")

body = req.get_media()
if "said" not in body:
raise falcon.HTTPBadRequest(description="challenge response acceptance requires 'aid' and 'said'")
Expand Down
35 changes: 19 additions & 16 deletions src/keria/app/credentialing.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ def loadEnds(app, identifierResource):
credentialCollectionEnd = CredentialCollectionEnd(identifierResource)
app.add_route("/identifiers/{name}/credentials", credentialCollectionEnd)

credentialResourceEnd = CredentialResourceEnd(identifierResource)
app.add_route("/identifiers/{name}/credentials/{said}", credentialResourceEnd)
credentialResourceEnd = CredentialResourceEnd()
app.add_route("/credentials/{said}", credentialResourceEnd)
credentialResourceDelEnd = CredentialResourceDeleteEnd(identifierResource)
app.add_route("/identifiers/{name}/credentials/{said}", credentialResourceDelEnd)

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


class CredentialResourceEnd:
def __init__(self, identifierResource):
def __init__(self):
"""
Parameters:
identifierResource (IdentifierResourceEnd): endpoint class for creating rotation and interaction events
"""
self.identifierResource = identifierResource

@staticmethod
def on_get(req, rep, name, said):
def on_get(req, rep, said):
""" Credentials GET endpoint
Parameters:
req: falcon.Request HTTP request
rep: falcon.Response HTTP response
name (str): human readable alias for AID to use as issuer
said (str): SAID of credential to export
---
Expand Down Expand Up @@ -554,11 +551,6 @@ def on_get(req, rep, name, said):
"""
agent = req.context.agent

hab = agent.hby.habByName(name)
if hab is None:
raise falcon.HTTPNotFound(description="name is not a valid reference to an identifier")

accept = req.get_header("accept")
if accept == "application/json+cesr":
rep.content_type = "application/json+cesr"
Expand Down Expand Up @@ -623,7 +615,18 @@ def outputCred(hby, rgy, said):
out.extend(signing.serialize(creder, prefixer, seqner, saider))

return out



class CredentialResourceDeleteEnd:
def __init__(self, identifierResource):
"""
Parameters:
identifierResource (IdentifierResourceEnd): endpoint class for creating rotation and interaction events
"""
self.identifierResource = identifierResource

def on_delete(self, req, rep, name, said):
""" Initiate a credential revocation
Expand Down Expand Up @@ -655,7 +658,7 @@ def on_delete(self, req, rep, name, said):
regk = rserder.ked['ri']
if regk not in agent.rgy.tevers:
raise falcon.HTTPNotFound(description=f"revocation against invalid registry SAID {regk}")

try:
agent.rgy.reger.cloneCreds([coring.Saider(qb64=said)], db=agent.hby.db)
except:
Expand Down
1 change: 1 addition & 0 deletions src/keria/db/basing.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ def generateIndexes(self, said):
# Assign single field Schema and ISSUER index and ISSUER/SCHEMA:
self.schIdx.add(keys=(said,), val=SCHEMA_FIELD.qb64b)
self.schIdx.add(keys=(said,), val=ISSUER_FIELD.qb64b)
self.schIdx.add(keys=(said,), val=REGISTRY_FIELD.qb64b)
subkey = f"{ISSUER_FIELD.qb64}.{SCHEMA_FIELD.qb64}"
self.schIdx.add(keys=(said,), val=subkey.encode("UTF-8"))

Expand Down
2 changes: 1 addition & 1 deletion src/keria/end/ending.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def on_get(self, _, rep, aid=None, role=None, eid=None):
eid: qb64 identifier prefix of participant in role
"""
if aid is None:
if not aid:
if self.default is None:
raise falcon.HTTPNotFound(description="no blind oobi for this node")

Expand Down
23 changes: 16 additions & 7 deletions tests/app/test_aiding.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ def test_identifier_collection_end(helpers):
res = client.simulate_post(path="/identifiers", body=json.dumps(body))
assert res.status_code == 202

res = client.simulate_get(path="/identifiers/")
assert res.status_code == 400
assert res.json == {'description': 'name is required', 'title': '400 Bad Request'}

res = client.simulate_get(path="/identifiers")
assert res.status_code == 200
assert len(res.json) == 2
Expand Down Expand Up @@ -852,7 +856,7 @@ def test_challenge_ends(helpers):
chaResEnd = aiding.ChallengeResourceEnd()
app.add_route("/challenges/{name}", chaResEnd)
chaVerResEnd = aiding.ChallengeVerifyResourceEnd()
app.add_route("/challenges/{name}/verify/{source}", chaVerResEnd)
app.add_route("/challenges-verify/{source}", chaVerResEnd)

client = testing.TestClient(app)

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

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

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

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

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

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

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

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

# Test empty
res = client.simulate_get("/identifiers//oobis?role=agent")
assert res.status_code == 400
assert res.json == {'description': 'name is required', 'title': '400 Bad Request'}

# Test before endroles are added
res = client.simulate_get("/identifiers/pal/oobis?role=agent")
assert res.status_code == 200
Expand Down
8 changes: 8 additions & 0 deletions tests/app/test_basing.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def test_seeker(helpers, seeder, mockHelpingNowUTC):
# Verify the indexes created for the QVI schema
assert indexes == ['5AABAA-s',
'5AABAA-i',
'4AABA-ri',
'5AABAA-i.5AABAA-s',
'4AAB-a-i',
'4AAB-a-i.5AABAA-s',
Expand Down Expand Up @@ -73,6 +74,7 @@ def test_seeker(helpers, seeder, mockHelpingNowUTC):
# Test the indexes assigned to the LE schema
assert indexes == ['5AABAA-s',
'5AABAA-i',
'4AABA-ri',
'5AABAA-i.5AABAA-s',
'4AAB-a-i',
'4AAB-a-i.5AABAA-s',
Expand Down Expand Up @@ -122,6 +124,12 @@ def test_seeker(helpers, seeder, mockHelpingNowUTC):
saids = seeker.find({}).limit(50)
assert len(list(saids)) == 50

saids = seeker.find({ '-ri': "EACehJRd0wfteUAJgaTTJjMSaQqWvzeeHqAMMqxuqxU4" })
assert len(list(saids)) == 25

saids = seeker.find({ '-ri': "EAzc9zFLaK22zbrKDGIgKtrpDBNKWKvl8B0FKYAo19z_" })
assert len(list(saids)) == 0

saids = seeker.find({'-d': "EAzc9zFLaK22zbrKDGIgKtrpDBNKWKvl8B0FKYAo19z_"})
assert list(saids) == ['EAzc9zFLaK22zbrKDGIgKtrpDBNKWKvl8B0FKYAo19z_']

Expand Down
20 changes: 8 additions & 12 deletions tests/app/test_credentialing.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ def test_credentialing_ends(helpers, seeder):
app.add_route("/identifiers/{name}/credentials", credEnd)
credResEnd = credentialing.CredentialQueryCollectionEnd()
app.add_route("/credentials/query", credResEnd)
credResEnd = credentialing.CredentialResourceEnd(idResEnd)
app.add_route("/identifiers/{name}/credentials/{said}", credResEnd)
credResEnd = credentialing.CredentialResourceEnd()
app.add_route("/credentials/{said}", credResEnd)

assert hab.pre == "EIqTaQiZw73plMOq8pqHTi9BDgDrrE7iE9v2XfN2Izze"

Expand Down Expand Up @@ -375,22 +375,16 @@ def test_credentialing_ends(helpers, seeder):
assert res.status_code == 200
assert len(res.json) == 4

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

headers = {"Accept": "application/json+cesr"}
res = client.simulate_get(f"/identifiers/{hab.name}/credentials/{saids[0]}", headers=headers)
assert res.status_code == 404

res = client.simulate_get(f"/identifiers/test/credentials/{saids[0]}", headers=headers)
res = client.simulate_get(f"/credentials/{saids[0]}", headers=headers)
assert res.status_code == 200
assert res.headers['content-type'] == "application/json+cesr"

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


def test_revoke_credential(helpers, seeder):
with helpers.openKeria() as (agency, agent, app, client):
Expand All @@ -406,8 +400,10 @@ def test_revoke_credential(helpers, seeder):
app.add_route("/identifiers", end)
endRolesEnd = aiding.EndRoleCollectionEnd()
app.add_route("/identifiers/{name}/endroles", endRolesEnd)
credResEnd = credentialing.CredentialResourceEnd(idResEnd)
app.add_route("/identifiers/{name}/credentials/{said}", credResEnd)
credResEnd = credentialing.CredentialResourceEnd()
app.add_route("/credentials/{said}", credResEnd)
credResDelEnd = credentialing.CredentialResourceDeleteEnd(idResEnd)
app.add_route("/identifiers/{name}/credentials/{said}", credResDelEnd)
credResEnd = credentialing.CredentialQueryCollectionEnd()
app.add_route("/credentials/query", credResEnd)

Expand Down
Loading

0 comments on commit fb6009a

Please sign in to comment.