diff --git a/src/keria/app/credentialing.py b/src/keria/app/credentialing.py index f70d0e0c..eb816226 100644 --- a/src/keria/app/credentialing.py +++ b/src/keria/app/credentialing.py @@ -14,6 +14,8 @@ from keri.app.habbing import SignifyGroupHab from keri.core import coring, scheming, serdering from keri.db import dbing +from keri.db.dbing import dgKey +from keri.vdr import viring from keria.core import httping, longrunning @@ -233,6 +235,70 @@ def on_get(req, rep, name, registryName): rep.content_type = "application/json" rep.data = json.dumps(rd).encode("utf-8") + @staticmethod + def on_put(req, rep, name, registryName): + """ Registry Resource PUT endpoint + + Parameters: + req: falcon.Request HTTP request + rep: falcon.Response HTTP response + name (str): human readable name for AID + registryName(str): human readable name for registry or its SAID + + --- + summary: Get a single credential issuance and revocation registy + description: Get a single credential issuance and revocation registy + tags: + - Registries + responses: + 200: + description: credential issuance and revocation registy + + """ + agent = req.context.agent + + hab = agent.hby.habByName(name) + if hab is None: + raise falcon.HTTPNotFound(description=f"{name} is not a valid reference to an identifier") + + body = req.get_media() + if 'name' not in body: + raise falcon.HTTPBadRequest(description="'name' is required in body") + + name = body['name'] + if agent.rgy.registryByName(name) is not None: + raise falcon.HTTPBadRequest(description=f"{name} is already in use for a registry") + + registry = agent.rgy.registryByName(registryName) + if registry is None: + if registryName in agent.rgy.regs: # Check to see if the registryName parameter is a SAID + registry = agent.rgy.regs[registryName] + else: + regk = registryName + key = dgKey(regk, regk) + raw = agent.rgy.reger.getTvt(key=key) + if raw is None: + raise falcon.HTTPNotFound( + description=f"{registryName} is not a valid reference to a credential registry") + + regser = serdering.SerderKERI(raw=bytes(raw)) + registry = agent.rgy.makeSignifyRegistry(name, hab.pre, regser) + + regord = viring.RegistryRecord(registryKey=registry.regk, prefix=hab.pre) + agent.rgy.reger.regs.pin(keys=(name,), val=regord) + agent.rgy.reger.regs.rem(keys=(registryName,)) + registry.name = name + + rd = dict( + name=registry.name, + regk=registry.regk, + pre=registry.hab.pre, + state=asdict(registry.tever.state()) + ) + rep.status = falcon.HTTP_200 + rep.content_type = "application/json" + rep.data = json.dumps(rd).encode("utf-8") + class SchemaResourceEnd: diff --git a/tests/app/test_credentialing.py b/tests/app/test_credentialing.py index b015f308..342542a8 100644 --- a/tests/app/test_credentialing.py +++ b/tests/app/test_credentialing.py @@ -94,6 +94,8 @@ def test_registry_end(helpers, seeder): idResEnd = aiding.IdentifierResourceEnd() registryEnd = credentialing.RegistryCollectionEnd(idResEnd) app.add_route("/identifiers/{name}/registries", registryEnd) + registryResEnd = credentialing.RegistryResourceEnd() + app.add_route("/identifiers/{name}/registries/{registryName}", registryResEnd) opEnd = longrunning.OperationResourceEnd() app.add_route("/operations/{name}", opEnd) @@ -160,6 +162,38 @@ def test_registry_end(helpers, seeder): assert result.json == {'description': 'alias is not a valid reference to an identifier', 'title': '404 Not Found'} + # Try with bad identifier name + body = b'{"name": "new-name"}' + result = client.simulate_put(path="/identifiers/test-bad/registries/test", body=body) + assert result.status == falcon.HTTP_404 + assert result.json == {'description': 'test-bad is not a valid reference to an identifier', + 'title': '404 Not Found'} + + result = client.simulate_put(path="/identifiers/test/registries/test", body=body) + assert result.status == falcon.HTTP_200 + regk = result.json['regk'] + + # Try to rename a the now used name + result = client.simulate_put(path="/identifiers/test/registries/new-name", body=b'{}') + assert result.status == falcon.HTTP_400 + assert result.json == {'description': "'name' is required in body", 'title': '400 Bad Request'} + + # Try to rename a the now used name + result = client.simulate_put(path="/identifiers/test/registries/test", body=body) + assert result.status == falcon.HTTP_400 + assert result.json == {'description': 'new-name is already in use for a registry', + 'title': '400 Bad Request'} + + # Try to rename a now non-existant registry + body = b'{"name": "newnew-name"}' + result = client.simulate_put(path="/identifiers/test/registries/test", body=body) + assert result.status == falcon.HTTP_404 + assert result.json == {'description': 'test is not a valid reference to a credential registry', + 'title': '404 Not Found'} + # Rename registry by SAID + body = b'{"name": "newnew-name"}' + result = client.simulate_put(path=f"/identifiers/test/registries/{regk}", body=body) + assert result.status == falcon.HTTP_200 result = client.simulate_get(path="/identifiers/not_test/registries") assert result.status == falcon.HTTP_404