commit adbfddb6fba080c242b7d122d252c6ba75231dc9
parent 3c748c658c9f540da28c4d72910bb98aea4fc52d
Author: Henrique Chan Carvalho Machado <henriqueccmachado@tecnico.ulisboa.pt>
Date: Sat, 22 Nov 2025 18:00:39 +0100
documentation: add sequence diagrams for oauth2 gateway api endpoints
Diffstat:
6 files changed, 222 insertions(+), 0 deletions(-)
diff --git a/documentation/sequence_diagrams/authorize_sequence.txt b/documentation/sequence_diagrams/authorize_sequence.txt
@@ -0,0 +1,37 @@
+sequenceDiagram
+ participant Client
+ participant OAuth2 Gateway
+ participant OAuth2 Gateway DB
+ participant Swiyu Verifier
+
+ Client ->> OAuth2 Gateway: GET /authorize?\nresponse_type=code&\nclient_id={client_id}&\nnonce={nonce}
+
+ OAuth2 Gateway ->> OAuth2 Gateway: Validate parameters:\n- response_type == 'code'
+
+ alt Invalid parameters
+ OAuth2 Gateway -->> Client: 400 BAD REQUEST\n{error: 'invalid_request'}
+ else Valid parameters
+ OAuth2 Gateway ->> OAuth2 Gateway DB: UPDATE verification_sessions s \nSET status = s.status \nFROM clients c \nWHERE s.client_id = c.id \nAND s.nonce = $1 AND c.client_id = $2 \nRETURNING s.id, s.status, s.expires_at, \ns.scope, s.verification_url, \ns.request_id, s.verifier_nonce, \nc.verifier_url, c.verifier_management_api_path
+
+ OAuth2 Gateway DB -->> OAuth2 Gateway: Query result
+ end
+
+ alt Session error
+ OAuth2 Gateway -->> Client: Error Response:\n- 404 NOT FOUND (session not found)\n- 410 GONE (expired)\n- 409 CONFLICT (not pending)
+ else Session already authorized (idempotent)
+ OAuth2 Gateway -->> Client: 200 OK \n{verification_id, verification_url}
+ else Session valid and pending - proceed
+ OAuth2 Gateway ->> OAuth2 Gateway: build_presentation_definition(scope)
+
+ OAuth2 Gateway ->> Swiyu Verifier: POST /management/api/verifications \n{presentation_definition, response_mode, ...}
+ Swiyu Verifier -->> OAuth2 Gateway: Response
+
+ alt Error
+ OAuth2 Gateway -->> Client: Error Response:\n- 502 BAD GATEWAY (verifier error)\n- 500 INTERNAL SERVER ERROR (DB error)
+ else Success
+ OAuth2 Gateway ->> OAuth2 Gateway DB: UPDATE verification_sessions \nSET verification_url = $1, request_id = $2, \nverifier_nonce = $3, status = 'authorized', \nauthorized_at = NOW() \nWHERE id = $4 \nRETURNING verification_url, request_id
+
+ OAuth2 Gateway DB -->> OAuth2 Gateway: Updated session
+ OAuth2 Gateway -->> Client: 200 OK \n{verification_id, verification_url}
+ end
+ end
+\ No newline at end of file
diff --git a/documentation/sequence_diagrams/info_sequence.txt b/documentation/sequence_diagrams/info_sequence.txt
@@ -0,0 +1,29 @@
+sequenceDiagram
+ participant Client
+ participant OAuth2 Gateway
+ participant OAuth2 Gateway DB
+
+ Client ->> OAuth2 Gateway: GET /info \nAuthorization: Bearer <token>
+
+ OAuth2 Gateway ->> OAuth2 Gateway: Extract token from \nAuthorization header
+
+ alt Missing or malformed Authorization header
+ OAuth2 Gateway -->> Client: 401 UNAUTHORIZED \n{error: 'invalid_token'}
+ else Valid header format
+ OAuth2 Gateway ->> OAuth2 Gateway DB: UPDATE access_tokens t \nSET revoked = t.revoked \nFROM verification_sessions s \nWHERE t.session_id = s.id \nAND t.token = $1 \nAND t.expires_at > NOW() \nRETURNING t.revoked, s.status, \ns.verifiable_credential
+
+ alt Token not found or expired
+ OAuth2 Gateway DB -->> OAuth2 Gateway: 0 rows
+ OAuth2 Gateway -->> Client: 401 UNAUTHORIZED \n{error: 'invalid_token'}
+ else Token found
+ OAuth2 Gateway DB -->> OAuth2 Gateway: token and session data
+
+ OAuth2 Gateway ->> OAuth2 Gateway: Validate:\n- not revoked\n- status == 'completed'
+
+ alt Invalid token state
+ OAuth2 Gateway -->> Client: 401 UNAUTHORIZED \n{error: 'invalid_token'}
+ else Valid token and VC available
+ OAuth2 Gateway -->> Client: 200 OK \n{verifiable_credential}
+ end
+ end
+ end
+\ No newline at end of file
diff --git a/documentation/sequence_diagrams/notification_sequence.txt b/documentation/sequence_diagrams/notification_sequence.txt
@@ -0,0 +1,40 @@
+sequenceDiagram
+ participant Swiyu Verifier
+ participant OAuth2 Gateway
+ participant OAuth2 Gateway DB
+
+ note over Swiyu Verifier,OAuth2 Gateway DB: Incoming Webhook from Swiyu
+
+ Swiyu Verifier ->> OAuth2 Gateway: POST /notification \n{verification_id, timestamp}
+
+ OAuth2 Gateway ->> OAuth2 Gateway DB: UPDATE verification_sessions s \nSET status = s.status \nFROM clients c \nWHERE s.client_id = c.id \nAND s.request_id = $1 \nRETURNING s.id, s.nonce, s.status, \nc.id AS client_id, c.webhook_url, \nc.verifier_url, c.verifier_management_api_path
+
+ alt DB error or session invalid
+ OAuth2 Gateway DB -->> OAuth2 Gateway: Error / 0 rows
+ OAuth2 Gateway ->> OAuth2 Gateway: Log error\n- DB connection failed\n- Session not found\n- Session not authorized\n- Session already processed
+ OAuth2 Gateway -->> Swiyu Verifier: 200 OK
+ else Session found
+ OAuth2 Gateway DB -->> OAuth2 Gateway: session + client data
+
+ OAuth2 Gateway ->> OAuth2 Gateway: Validate session (status == 'authorized')
+
+ alt Session invalid
+ OAuth2 Gateway ->> OAuth2 Gateway: Log error\n- Session not authorized\n- Session already processed
+ OAuth2 Gateway -->> Swiyu Verifier: 200 OK
+ else Session valid
+ OAuth2 Gateway ->> Swiyu Verifier: GET verifier_url + verifier_management_api_path + /verification_id
+ Swiyu Verifier -->> OAuth2 Gateway: {status: 'verified'/'failed', ...}
+
+ OAuth2 Gateway ->> OAuth2 Gateway: generate_authorization_code()
+
+ OAuth2 Gateway ->> OAuth2 Gateway DB: WITH updated AS (\n UPDATE verification_sessions \n SET status = $1, verified_at = NOW() \n WHERE id = $2 RETURNING id\n),\ninserted_code AS (\n INSERT INTO authorization_codes \n (session_id, code, expires_at) \n VALUES ($2, $3, NOW() + INTERVAL '10 minutes') \n RETURNING code\n)\nINSERT INTO notification_pending_webhooks \n(session_id, client_id, url, body, next_attempt) \nSELECT $2, $4, $5, $6, 0
+
+ alt Operation failed
+ OAuth2 Gateway ->> OAuth2 Gateway: Log error\n- Verifier fetch failed\n- DB update failed\n- Code generation failed\n- Queue insert failed
+ else Success
+ OAuth2 Gateway DB ->> OAuth2 Gateway DB: TRIGGER\nNotifies Worker Thread\nfor Client Webhooks
+ OAuth2 Gateway DB -->> OAuth2 Gateway: OK
+ end
+ end
+ OAuth2 Gateway -->> Swiyu Verifier: 200 OK
+ end
+\ No newline at end of file
diff --git a/documentation/sequence_diagrams/setup_sequence.txt b/documentation/sequence_diagrams/setup_sequence.txt
@@ -0,0 +1,21 @@
+sequenceDiagram
+ participant Client
+ participant OAuth2 Gateway
+ participant OAuth2 Gateway DB
+
+ Client ->> OAuth2 Gateway: POST /setup/{client_id}\n{scope: "first_name last_name"}
+
+ OAuth2 Gateway ->> OAuth2 Gateway: generate_nonce()\n(256-bit CSPRNG)
+
+ OAuth2 Gateway ->> OAuth2 Gateway DB: INSERT INTO verification_sessions\n(client_id, nonce, scope, expires_at)\nSELECT c.id, $1, $2, NOW() + INTERVAL '15 minutes'\nFROM clients c WHERE c.client_id = $3\nRETURNING id, nonce, expires_at
+
+ alt Client not found
+ OAuth2 Gateway DB -->> OAuth2 Gateway: 0 rows
+ OAuth2 Gateway -->> Client: 404 NOT FOUND\n{error: "client_not_found"}
+ else DB error
+ OAuth2 Gateway DB -->> OAuth2 Gateway: Error
+ OAuth2 Gateway -->> Client: 500 INTERNAL SERVER ERROR
+ else Success
+ OAuth2 Gateway DB -->> OAuth2 Gateway: session {id, nonce, expires_at}
+ OAuth2 Gateway -->> Client: 200 OK {nonce}
+ end
+\ No newline at end of file
diff --git a/documentation/sequence_diagrams/swiyu_taler_sequence_diagram.txt b/documentation/sequence_diagrams/swiyu_taler_sequence_diagram.txt
@@ -0,0 +1,49 @@
+sequenceDiagram
+ title Swiyu-Taler Interaction
+
+ participant Browser
+ participant TalerWallet
+ participant Exchange
+ participant Oauth2Gateway
+ participant SwiyuVerifier
+ participant SwiyuWallet
+
+ TalerWallet ->> Exchange: Initiate KYC-required operation
+ Exchange -->> TalerWallet: Send verification link
+ TalerWallet ->> Browser: Open link
+ Browser ->> Exchange: Select verification method (Swiyu)
+
+ note over Exchange,Oauth2Gateway: Exchange initiates KYC verification process
+ Exchange ->> Oauth2Gateway: POST /setup/$CLIENT_ID
+ Oauth2Gateway -->> Exchange: $NONCE
+ Exchange ->> Browser: Send /authorize endpoint
+
+ Browser ->> Oauth2Gateway: GET /authorize/$NONCE...
+ Oauth2Gateway ->> SwiyuVerifier: POST /management/api/verifications
+ SwiyuVerifier -->> Oauth2Gateway: $VERIFICATION_URL, $REQUEST_ID
+ Oauth2Gateway -->> Browser: Send $VERIFICATION_URL
+
+ Browser ->> Oauth2Gateway: Poll Verification Status
+ Browser ->> SwiyuWallet: Open $VERIFICATION_URL
+ SwiyuWallet ->> SwiyuVerifier: GET /oid4vp/api/request-object/{request_id}
+ SwiyuVerifier -->> SwiyuWallet: OID4VP Request Object (DCQL query)
+ SwiyuWallet ->> SwiyuWallet: Grant Permission
+ SwiyuWallet ->> SwiyuVerifier: POST /oid4vp/api/request-object/{request_id}/response-data (VP Token)
+
+ note over Oauth2Gateway,Exchange: Oauth2Gateway receives webhook and retrieves swiyu wallet response
+ SwiyuVerifier ->> Oauth2Gateway: POST /notification {verification_id, timestamp}
+ Oauth2Gateway ->> SwiyuVerifier: GET /management/api/verifications/{verification_id}
+ SwiyuVerifier -->> Oauth2Gateway: {state: SUCCESS/FAILED, wallet_response}
+ Oauth2Gateway -->> Browser: Notify verification result
+ Oauth2Gateway ->> Exchange: POST /oauth2gw/kyc/notify/$CLIENT_ID {status}
+
+ note over Exchange,Oauth2Gateway: Exchange retrieves the final proof (Verifiable Credential)
+ Exchange ->> Oauth2Gateway: POST /token
+ Oauth2Gateway -->> Exchange: Access token
+ Exchange ->> Oauth2Gateway: GET /info (with access token)
+ Oauth2Gateway ->> SwiyuVerifier: GET /management/api/verifications/{verificationId}
+ SwiyuVerifier -->> Oauth2Gateway: Send proof (Verifiable Credential)
+ Oauth2Gateway -->> Exchange: Send proof (in response body)
+
+ Exchange -->> TalerWallet: Notify success
+ TalerWallet ->> Exchange: Retry original operation
diff --git a/documentation/sequence_diagrams/token_sequence.txt b/documentation/sequence_diagrams/token_sequence.txt
@@ -0,0 +1,41 @@
+sequenceDiagram
+ participant Client
+ participant OAuth2 Gateway
+ participant OAuth2 Gateway DB
+
+ Client ->> OAuth2 Gateway: POST /token \n{code, grant_type}
+
+ OAuth2 Gateway ->> OAuth2 Gateway: Validate grant_type == \n'authorization_code'
+
+ alt Invalid grant type
+ OAuth2 Gateway -->> Client: 400 BAD REQUEST \n{error: 'unsupported_grant_type'}
+ else Valid grant type
+ OAuth2 Gateway ->> OAuth2 Gateway DB: WITH code_data AS (\n SELECT id, used AS was_already_used, session_id\n FROM authorization_codes\n WHERE code = $1 AND expires_at > NOW()\n FOR UPDATE\n),\nupdated_code AS (\n UPDATE authorization_codes ac\n SET used = TRUE,\n used_at = CASE WHEN NOT ac.used THEN NOW() ELSE ac.used_at END\n FROM code_data cd\n WHERE ac.id = cd.id\n RETURNING ac.id, ac.session_id\n)\nSELECT uc.id AS code_id,\n cd.was_already_used,\n uc.session_id,\n vs.status AS session_status,\n at.token AS existing_token,\n at.expires_at AS token_expires_at\nFROM updated_code uc\nJOIN code_data cd ON uc.id = cd.id\nJOIN verification_sessions vs ON vs.id = uc.session_id\nLEFT JOIN access_tokens at\n ON at.session_id = vs.id AND at.revoked = FALSE
+
+ alt No code found or DB error
+ OAuth2 Gateway DB -->> OAuth2 Gateway: 0 rows / Error
+ OAuth2 Gateway -->> Client: Error Response:\n- 400 BAD REQUEST {error: 'invalid_grant'}\n- 500 INTERNAL SERVER ERROR
+ else Code found
+ OAuth2 Gateway DB -->> OAuth2 Gateway: code, session, and token data
+
+ OAuth2 Gateway ->> OAuth2 Gateway: Check state
+
+ alt Token already exists (idempotent)
+ OAuth2 Gateway -->> Client: 200 OK \n{access_token: existing_token, \ntoken_type: 'Bearer', expires_in: 3600}
+ else Invalid state
+ OAuth2 Gateway -->> Client: 400 BAD REQUEST \n{error: 'invalid_grant'}\n- Code already used\n- Session not verified
+ else Valid - create token
+ OAuth2 Gateway ->> OAuth2 Gateway: generate_access_token()
+
+ OAuth2 Gateway ->> OAuth2 Gateway DB: WITH updated AS (\n UPDATE verification_sessions \n SET status = 'completed', completed_at = NOW() \n WHERE id = $1 RETURNING id\n)\nINSERT INTO access_tokens \n(session_id, token, expires_at) \nVALUES ($1, $2, NOW() + INTERVAL '1 hour') \nRETURNING token, expires_at
+
+ alt Error
+ OAuth2 Gateway DB -->> OAuth2 Gateway: Error
+ OAuth2 Gateway -->> Client: 500 INTERNAL SERVER ERROR
+ else Success
+ OAuth2 Gateway DB -->> OAuth2 Gateway: token, expires_at
+ OAuth2 Gateway -->> Client: 200 OK \n{access_token, token_type: 'Bearer', expires_in: 3600}
+ end
+ end
+ end
+ end
+\ No newline at end of file