merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit f1f02c3787541ba29b4a1bcbd4255c51c14c84b1
parent 2da3ea21808c036d8c5889774cb7d5c22d21e522
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Thu, 10 Jul 2025 14:14:37 +0200

Add spa scope that is not refreshable by default

Diffstat:
Msrc/backend/taler-merchant-httpd.c | 17+++++++++++------
Msrc/backend/taler-merchant-httpd.h | 7+++++++
Msrc/testing/test_merchant_instance_auth.sh | 59++++++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 70 insertions(+), 13 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -256,13 +256,19 @@ struct ScopePermissionMap scope_permissions[] = { .name = "write", .permissions = "*" }, - /* Full access */ + /* Full access for SPA */ { .as = TMH_AS_ALL, .name = "all", .permissions = "*" }, - /* Read-only access */ + /* Full access for SPA */ + { + .as = TMH_AS_SPA, + .name = "spa", + .permissions = "*" + }, + /* Read-only access */ { .as = TMH_AS_READ_ONLY, .name = "readonly", @@ -360,10 +366,9 @@ permission_in_scope (const char *permission_required, "-read")); } - if (refreshable && - (0 == strcmp ("token-refresh", - permission_required)) ) - return true; + if (0 == strcmp ("token-refresh", + permission_required)) + return refreshable; permissions = GNUNET_strdup (perms_tmp); { const char *perm = strtok (permissions, diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h @@ -451,10 +451,17 @@ enum TMH_AuthScope /** * Full access is granted to everything. + * We want to deprecate and remove this! + * Old scope "write" */ TMH_AS_ALL = 7 | 1 << 30, /** + * Full access is granted to everything. + */ + TMH_AS_SPA = 8, + + /** * /login access to renew the token is OK. * This is actually combined with other scopes * and not (usually) used as a scope itself. diff --git a/src/testing/test_merchant_instance_auth.sh b/src/testing/test_merchant_instance_auth.sh @@ -55,7 +55,7 @@ BASIC_AUTH=$(echo -n admin:new_pw | base64) STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H "Authorization: Basic $BASIC_AUTH" \ http://localhost:9966/private/token \ - -d '{"scope":"write"}' \ + -d '{"scope":"spa"}' \ -w "%{http_code}" -s -o $LAST_RESPONSE) @@ -140,7 +140,7 @@ BASIC_AUTH=$(echo -n "admin:$NEW_SECRET" | base64) STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H "Authorization: Basic $BASIC_AUTH" \ http://localhost:9966/private/token \ - -d '{"scope":"write"}' \ + -d '{"scope":"spa"}' \ -w "%{http_code}" -s -o $LAST_RESPONSE) @@ -246,12 +246,12 @@ TOKEN=$(jq -e -r .access_token < "$LAST_RESPONSE") echo " OK" >&2 -echo -n "Requesting login token... (write)" >&2 +echo -n "Requesting login token... (spa)" >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Basic '"$BASIC_AUTH2" \ http://localhost:9966/instances/second/private/token \ - -d '{"scope":"write","refreshable":true}' \ + -d '{"scope":"spa"}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] @@ -311,12 +311,12 @@ fi echo " OK" >&2 -echo -n "Refreshing login token..." >&2 +echo -n "Refreshing login token... (expected failure)" >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer '"$TOKEN" \ http://localhost:9966/instances/second/private/token \ - -d '{"scope":"write","refreshable":true}' \ + -d '{"scope":"spa","refreshable":true}' \ -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "403" ] @@ -327,6 +327,51 @@ fi echo " OK" >&2 +echo -n "Refreshing login token... (expected failure)" >&2 + +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer '"$RWTOKEN" \ + http://localhost:9966/instances/second/private/token \ + -d '{"scope":"spa","refreshable":true}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "401" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 401, refused to upgrade login token. got: $STATUS" +fi + +echo " OK" >&2 + +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Basic '"$BASIC_AUTH2" \ + http://localhost:9966/instances/second/private/token \ + -d '{"scope":"spa:refreshable"}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, login token created. got: $STATUS" +fi + +RWTOKEN=$(jq -e -r .access_token < "$LAST_RESPONSE") + +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer '"$RWTOKEN" \ + http://localhost:9966/instances/second/private/token \ + -d '{"scope":"spa","refreshable":true}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 200. got: $STATUS" +fi + +echo " OK" >&2 + + echo -n "Requesting another login token... (read)" >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ @@ -367,7 +412,7 @@ echo "Getting 2 login tokens with offset 2." >&2 STATUS=$(curl -H "Content-Type: application/json" \ -H "Authorization: Bearer $RWTOKEN" \ - 'http://localhost:9966/instances/second/private/tokens?limit=2&offset=2' \ + 'http://localhost:9966/instances/second/private/tokens?limit=2&offset=4' \ -w "%{http_code}" -s -o $LAST_RESPONSE) if [ "$STATUS" != "200" ]