diff --git a/keyring_restful.c b/keyring_restful.c index 1b998e18..ba6976f3 100644 --- a/keyring_restful.c +++ b/keyring_restful.c @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. static HTTP_HANDLER restful_keyring_identitylist_json; static HTTP_HANDLER restful_keyring_add; +static HTTP_HANDLER restful_keyring_set; int restful_keyring_(httpd_request *r, const char *remainder) { @@ -41,6 +42,7 @@ int restful_keyring_(httpd_request *r, const char *remainder) const char *verb = HTTP_VERB_GET; http_size_t content_length = CONTENT_LENGTH_UNKNOWN; HTTP_HANDLER *handler = NULL; + const char *end; if (strcmp(remainder, "identities.json") == 0) { handler = restful_keyring_identitylist_json; verb = HTTP_VERB_GET; @@ -51,6 +53,13 @@ int restful_keyring_(httpd_request *r, const char *remainder) verb = HTTP_VERB_GET; remainder = ""; } + else if (parse_sid_t(&r->sid1, remainder, -1, &end) != -1) { + remainder = end; + if (strcmp(remainder, "/set") == 0) { + handler = restful_keyring_set; + remainder = ""; + } + } if (handler == NULL) return 404; if ( content_length != CONTENT_LENGTH_UNKNOWN @@ -200,3 +209,23 @@ static int restful_keyring_add(httpd_request *r, const char *remainder) return http_request_keyring_response(r, 501, "Could not store new identity"); return http_request_keyring_response_identity(r, 200, CONTENT_TYPE_JSON, id); } + +static int restful_keyring_set(httpd_request *r, const char *remainder) +{ + if (*remainder) + return 404; + const char *pin = http_request_get_query_param(&r->http, "pin"); + const char *did = http_request_get_query_param(&r->http, "did"); + const char *name = http_request_get_query_param(&r->http, "name"); + if (pin) + keyring_enter_pin(keyring, pin); + keyring_iterator it; + keyring_iterator_start(keyring, &it); + if (!keyring_find_sid(&it, &r->sid1)) + return http_request_keyring_response(r, 404, NULL); + if (keyring_set_did(it.identity, did ? did : "", name ? name : "") == -1) + return http_request_keyring_response(r, 501, "Could not set identity DID/Name"); + if (keyring_commit(keyring) == -1) + return http_request_keyring_response(r, 501, "Could not store new identity"); + return http_request_keyring_response_identity(r, 200, CONTENT_TYPE_JSON, it.identity); +} diff --git a/tests/keyringrestful b/tests/keyringrestful index f8c24b41..e30d346b 100755 --- a/tests/keyringrestful +++ b/tests/keyringrestful @@ -189,4 +189,89 @@ test_keyringAddPin() { assertJq ids.json 'contains([{"sid": "'$SIDA1'"}])' } +doc_keyringSetDidName="HTTP RESTful set DID and name" +setup_keyringSetDidName() { + IDENTITY_COUNT=2 + setup +} +test_keyringSetDidName() { + executeOk curl \ + --silent --show-error --write-out '%{http_code}' \ + --output set.json \ + --dump-header http.headers \ + --basic --user harry:potter \ + "http://$addr_localhost:$PORTA/restful/keyring/$SIDA1/set?did=987654321&name=Joe%20Bloggs" + tfw_cat http.headers set.json + tfw_preserve set.json + assertStdoutIs '200' + assertJq set.json 'contains({"sid": "'$SIDA1'"})' + assertJq set.json 'contains({"did": "987654321"})' + assertJq set.json 'contains({"name": "Joe Bloggs"})' + executeOk_servald keyring list + assert_keyring_list 2 + assertStdoutGrep --stderr --matches=1 "^$SIDA1:987654321:Joe Bloggs\$" +} + +doc_keyringSetDidNamePin="HTTP RESTful set DID and name with PIN" +setup_keyringSetDidNamePin() { + IDENTITY_COUNT=2 + PINA1=xyzabc + setup +} +test_keyringSetDidNamePin() { + # First try with no PIN, and make sure it fails + executeOk curl \ + --silent --show-error --write-out '%{http_code}' \ + --output set1.json \ + --dump-header http.headers \ + --basic --user harry:potter \ + "http://$addr_localhost:$PORTA/restful/keyring/$SIDA1/set?did=111222333&name=Nobody" + tfw_cat http.headers set1.json + tfw_preserve set1.json + assertStdoutIs '404' + # Enter incorrect PIN, and make sure it fails + executeOk curl \ + --silent --show-error --write-out '%{http_code}' \ + --output set2.json \ + --dump-header http.headers \ + --basic --user harry:potter \ + "http://$addr_localhost:$PORTA/restful/keyring/$SIDA1/set?did=444555666&name=Anybody" + tfw_cat http.headers set2.json + tfw_preserve set2.json + assertStdoutIs '404' + # Then try with correct PIN, and make sure it succeeds + executeOk curl \ + --silent --show-error --write-out '%{http_code}' \ + --output set3.json \ + --dump-header http.headers \ + --basic --user harry:potter \ + "http://$addr_localhost:$PORTA/restful/keyring/$SIDA1/set?did=987654321&name=Joe%20Bloggs&pin=xyzabc" + tfw_cat http.headers set3.json + tfw_preserve set3.json + assertStdoutIs '200' + assertJq set3.json 'contains({"sid": "'$SIDA1'"})' + assertJq set3.json 'contains({"did": "987654321"})' + assertJq set3.json 'contains({"name": "Joe Bloggs"})' + executeOk_servald keyring list --entry-pin=xyzabc + assert_keyring_list 2 + assertStdoutGrep --stderr --matches=1 "^$SIDA1:987654321:Joe Bloggs\$" + # Finally, try again with no PIN, and make sure it succeeds (server has + # internalised the PIN supplied in the last request) + executeOk curl \ + --silent --show-error --write-out '%{http_code}' \ + --output set4.json \ + --dump-header http.headers \ + --basic --user harry:potter \ + "http://$addr_localhost:$PORTA/restful/keyring/$SIDA1/set?did=321321321&name=Fred+Nurks" + tfw_cat http.headers set4.json + tfw_preserve set4.json + assertStdoutIs '200' + assertJq set4.json 'contains({"sid": "'$SIDA1'"})' + assertJq set4.json 'contains({"did": "321321321"})' + assertJq set4.json 'contains({"name": "Fred Nurks"})' + executeOk_servald keyring list --entry-pin=xyzabc + assert_keyring_list 2 + assertStdoutGrep --stderr --matches=1 "^$SIDA1:321321321:Fred Nurks\$" +} + runTests "$@"