post-solve-NONCE.rst (8075B)
1 .. http:post:: /solve/$NONCE 2 3 Used by the user-agent to submit an answer to the challenge. If the answer 4 is correct, the user will be redirected to the client's redirect URI, 5 otherwise the user may be given another chance to complete the process. 6 7 **Request:** 8 9 Body should use the mime-type "application/x-www-form-urlencoded"; 10 ``multipart/form-data`` is accepted as well. 11 The posted form data must contain a "pin" field, whose value must be a 12 decimal unsigned integer. The request body is limited to 1024 bytes. 13 14 **Response:** 15 16 :http:statuscode:`200 OK`: 17 If the request ask for application/json the response is 18 a `ChallengeSolveResponse`. Since protocol **v2**. 19 Note that this status is only used for the *successful* outcome; an 20 incorrect or unusable TAN is reported with 403, 409, 410 or 429 (see 21 below). 22 :http:statuscode:`302 Found`: 23 Only possible if request didn't ask for application/json. Since protocol **v2**. 24 Since protocol **v10**, also returned for a validation that failed 25 permanently, see ``410 Gone`` below. 26 The user is redirected to the redirect URI of the client to pass the 27 grant to the client. The target will be the redirect URI specified 28 by the client (during registration and again upon ``/authorize``), 29 plus a ``code`` argument with the authorization code, and the 30 ``state`` argument from the ``/authorize`` endpoint. The ``state`` 31 argument is omitted entirely if the client did not supply one. The 32 response body is the plain text ``Ok!``. 33 :http:statuscode:`400 Bad Request`: 34 The request does not follow the spec. Since protocol **v1**. 35 Error codes used are: 36 37 * ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` --- the ``$NONCE`` in the URL 38 is not a valid 52-character Crockford-base32 value (``detail`` is 39 ``"nonce"``), the ``Content-Length`` header is not a number 40 (``detail`` is ``"Content-Length"``), or the ``pin`` field is not a 41 decimal number (``detail`` is ``"pin"``). 42 * ``TALER_EC_GENERIC_PARAMETER_MISSING`` --- there is no ``pin`` field in 43 the body (``detail`` is ``"pin"``). 44 :http:statuscode:`403 Forbidden`: 45 The TAN was checked and did not match. 46 The response is `InvalidPinResponse`. Since protocol **v1**. 47 Returned with ``TALER_EC_CHALLENGER_INVALID_PIN``. 48 :http:statuscode:`404 Not found`: 49 The service is unaware of a matching challenge, or the validation 50 has expired. Since protocol **v1**. Returned with 51 ``TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN``. 52 :http:statuscode:`405 Method Not Allowed`: 53 The request used a method other than ``POST`` or ``OPTIONS``. 54 Returned by the request router with an ``Allow`` header and an 55 **empty body**; in particular there is no Taler error code. 56 :http:statuscode:`409 Conflict`: 57 The service had never actually transmitted a TAN, so solving 58 is naturally impossible. Since protocol **v8**. 59 The response is an `InvalidPinResponse` with ``no_challenge`` set to 60 true. Returned with 61 ``TALER_EC_CHALLENGER_NO_CHALLENGE_TRANSMITTED``. 62 :http:statuscode:`410 Gone`: 63 The validation failed permanently: the user exhausted every address 64 change, TAN transmission and TAN attempt (an address the client set 65 as ``read_only`` counts as one that cannot be changed), so it can never 66 succeed. Returned with ``TALER_EC_CHALLENGER_VALIDATION_FAILED``; the 67 response is a `ValidationFailedResponse`. The user-agent must send the 68 user to its ``redirect_url`` so that the client learns about the 69 failure. If the request asked for ``text/html``, the service instead 70 redirects to that URL with a ``302 Found`` right away. 71 Since protocol **v10**. 72 Note that the response *consuming* the very last guess already 73 reports this, rather than ``TALER_EC_CHALLENGER_INVALID_PIN`` with a 74 ``403``: at that point nothing is left to try. 75 Before protocol **v10**, this situation was reported as ``429`` with 76 ``TALER_EC_CHALLENGER_TOO_MANY_ATTEMPTS`` and the client was never 77 told. 78 :http:statuscode:`413 Request entity too large`: 79 The request body exceeds the 1024 byte limit. 80 Returned with ``TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT``. 81 :http:statuscode:`415 Unsupported Media Type`: 82 The ``Content-Type`` is missing or is not one the service can parse. 83 Returned with ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` and ``detail`` 84 set to ``"Content-Type"``. 85 Since protocol **v8**; previously reported as ``400``. 86 :http:statuscode:`429 Too Many Requests`: 87 The user has run out of TAN guesses for the current TAN, but may 88 still request a retransmission or change the address. 89 Since protocol **v2**. The body is an `InvalidPinResponse` with 90 ``exhausted`` set to true, returned with 91 ``TALER_EC_CHALLENGER_NO_PIN_ATTEMPTS_LEFT`` (since protocol **v8**). 92 Once nothing is left to try, the service answers ``410`` instead (since 93 protocol **v10**). 94 :http:statuscode:`500 Internal Server Error`: 95 Server is not able to respond due to internal problems. 96 Since protocol **v1**. Returned with 97 ``TALER_EC_GENERIC_DB_FETCH_FAILED``; ``detail`` is 98 ``"do_solve_challenge"`` when solving failed and ``"get_validation"`` 99 when the subsequent construction of the redirect URL failed. 100 101 .. note:: 102 103 Error responses are always JSON, even when the request asked for 104 ``text/html``; only the success case and a permanently failed 105 validation honour the ``Accept`` header by returning a 302 redirect. 106 107 .. note:: 108 109 Once a challenge has been solved, repeating the request for the same 110 (unexpired) ``$NONCE`` succeeds again regardless of the ``pin`` 111 submitted, re-issuing the redirect and authorization code. 112 113 .. ts:def:: ChallengeSolveResponse 114 115 // Only the "completed" variant occurs with a 200 status; the 116 // "pending" variant (`InvalidPinResponse`) is returned with a 403, 117 // 409 or 429 status, and a failed validation with a 410 118 // (`ValidationFailedResponse`). Since **v8** every unsuccessful /solve uses 119 // that one shape, so a client need only parse `InvalidPinResponse`. 120 type ChallengeSolveResponse = ChallengeRedirect; 121 122 .. ts:def:: ValidationFailedResponse 123 124 // Since protocol **v10**. 125 interface ValidationFailedResponse { 126 // TALER_EC_CHALLENGER_VALIDATION_FAILED 127 code: Integer; 128 129 // human-readable description of the error 130 hint: string; 131 132 // Where the user-agent must send the user: the client's redirect 133 // URI with the RFC 6749 section 4.1.2.1 error response arguments 134 // ``error=access_denied``, an ``error_description`` and the 135 // ``state`` given to ``/authorize`` (omitted if there was none). 136 // Absent if the service does not know a redirect URI for the 137 // validation, which cannot happen once ``/authorize`` succeeded. 138 redirect_url?: string; 139 } 140 141 .. ts:def:: InvalidPinResponse 142 143 interface InvalidPinResponse { 144 // Union discriminator field. 145 type: "pending"; 146 147 // numeric Taler error code, should be shown to indicate the error 148 // compactly for reporting to developers 149 code: Integer; 150 151 // human-readable Taler error code, should be shown for the user to 152 // understand the error 153 hint: string; 154 155 // how many times is the user still allowed to change the address; 156 // if 0, the user should not be shown a link to jump to the 157 // address entry form 158 addresses_left: Integer; 159 160 // how many times might the TAN still be retransmitted 161 pin_transmissions_left: Integer; 162 163 // how many times might the user still try entering the TAN code 164 auth_attempts_left: Integer; 165 166 // if true, the TAN was not even evaluated as the user previously 167 // exhausted the number of attempts 168 exhausted: boolean; 169 170 // if true, the TAN was not even evaluated as no challenge was ever 171 // issued (the user must have skipped the step of providing their 172 // address first!) 173 no_challenge: boolean; 174 }