taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

post-solve-NONCE.rst (6959B)


      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 or 429 (see below).
     21   :http:statuscode:`302 Found`:
     22     Only possible if request didn't ask for application/json. Since protocol **v2**.
     23     The user is redirected to the redirect URI of the client to pass the
     24     grant to the client.  The target will be the redirect URI specified
     25     by the client (during registration and again upon ``/authorize``),
     26     plus a ``code`` argument with the authorization code, and the
     27     ``state`` argument from the ``/authorize`` endpoint.  The ``state``
     28     argument is omitted entirely if the client did not supply one.  The
     29     response body is the plain text ``Ok!``.
     30   :http:statuscode:`400 Bad Request`:
     31     The request does not follow the spec. Since protocol **v1**.
     32     Error codes used are:
     33 
     34     * ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` --- the ``$NONCE`` in the URL
     35       is not a valid 52-character Crockford-base32 value (``detail`` is
     36       ``"nonce"``), the ``Content-Length`` header is not a number
     37       (``detail`` is ``"Content-Length"``), or the ``pin`` field is not a
     38       decimal number (``detail`` is ``"pin"``).
     39     * ``TALER_EC_GENERIC_PARAMETER_MISSING`` --- there is no ``pin`` field in
     40       the body (``detail`` is ``"pin"``).
     41   :http:statuscode:`403 Forbidden`:
     42     The TAN was checked and did not match.
     43     The response is `InvalidPinResponse`. Since protocol **v1**.
     44     Returned with ``TALER_EC_CHALLENGER_INVALID_PIN``.
     45   :http:statuscode:`404 Not found`:
     46     The service is unaware of a matching challenge, or the validation
     47     has expired. Since protocol **v1**.  Returned with
     48     ``TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN``.
     49   :http:statuscode:`405 Method Not Allowed`:
     50     The request used a method other than ``POST`` or ``OPTIONS``.
     51     Returned by the request router with an ``Allow`` header and an
     52     **empty body**; in particular there is no Taler error code.
     53   :http:statuscode:`409 Conflict`:
     54     The service had never actually transmitted a TAN, so solving
     55     is naturally impossible. Since protocol **v8**.
     56     The response is an `InvalidPinResponse` with ``no_challenge`` set to
     57     true.  Returned with
     58     ``TALER_EC_CHALLENGER_NO_CHALLENGE_TRANSMITTED``.
     59   :http:statuscode:`413 Request entity too large`:
     60     The request body exceeds the 1024 byte limit.
     61     Returned with ``TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT``.
     62   :http:statuscode:`415 Unsupported Media Type`:
     63     The ``Content-Type`` is missing or is not one the service can parse.
     64     Returned with ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` and ``detail``
     65     set to ``"Content-Type"``.
     66     Since protocol **v8**; previously reported as ``400``.
     67   :http:statuscode:`429 Too Many Requests`:
     68     There have been too many attempts to solve the challenge
     69     for this address (and $NONCE). The user-agent should
     70     either try a different address (or wait and (eventually)
     71     request a fresh nonce to be set up by the client).
     72     Since protocol **v2**.  The body is an `InvalidPinResponse` in both of
     73     the cases below, which are told apart by the error code:
     74 
     75     * ``TALER_EC_CHALLENGER_NO_PIN_ATTEMPTS_LEFT`` --- the user has run out
     76       of TAN guesses but may still request a retransmission or change the
     77       address.  ``exhausted`` is true.  Since protocol **v8**.
     78     * ``TALER_EC_CHALLENGER_TOO_MANY_ATTEMPTS`` --- the user has exhausted
     79       address changes, TAN guesses *and* retransmissions, so the situation
     80       is terminal and all three counters are zero.  Since protocol **v8**
     81       this returns an `InvalidPinResponse` as well; it previously returned
     82       a plain error object with only ``code``, ``hint`` and ``detail``.
     83       Note that the response *consuming* the very last guess already
     84       reports this, rather than
     85       ``TALER_EC_CHALLENGER_INVALID_PIN`` with a ``403``: at that point
     86       nothing is left to try, which is the more useful thing to tell the
     87       user.
     88   :http:statuscode:`500 Internal Server Error`:
     89     Server is not able to respond due to internal problems.
     90     Since protocol **v1**.  Returned with
     91     ``TALER_EC_GENERIC_DB_FETCH_FAILED``; ``detail`` is
     92     ``"do_solve_challenge"`` when solving failed and ``"get_validation"``
     93     when the subsequent construction of the redirect URL failed.
     94 
     95   .. note::
     96 
     97     Error responses are always JSON, even when the request asked for
     98     ``text/html``; only the success case honours the ``Accept`` header by
     99     returning a 302 redirect.
    100 
    101   .. note::
    102 
    103     Once a challenge has been solved, repeating the request for the same
    104     (unexpired) ``$NONCE`` succeeds again regardless of the ``pin``
    105     submitted, re-issuing the redirect and authorization code.
    106 
    107   .. ts:def:: ChallengeSolveResponse
    108 
    109     // Only the "completed" variant occurs with a 200 status; the
    110     // "pending" variant (`InvalidPinResponse`) is returned with a 403,
    111     // 409 or 429 status.  Since **v8** every unsuccessful /solve uses
    112     // that one shape, so a client need only parse `InvalidPinResponse`.
    113     type ChallengeSolveResponse = ChallengeRedirect;
    114 
    115   .. ts:def:: InvalidPinResponse
    116 
    117     interface InvalidPinResponse {
    118       // Union discriminator field.
    119       type: "pending";
    120 
    121       // numeric Taler error code, should be shown to indicate the error
    122       // compactly for reporting to developers
    123       code: Integer;
    124 
    125       // human-readable Taler error code, should be shown for the user to
    126       // understand the error
    127       hint: string;
    128 
    129       // how many times is the user still allowed to change the address;
    130       // if 0, the user should not be shown a link to jump to the
    131       // address entry form
    132       addresses_left: Integer;
    133 
    134       // how many times might the TAN still be retransmitted
    135       pin_transmissions_left: Integer;
    136 
    137       // how many times might the user still try entering the TAN code
    138       auth_attempts_left: Integer;
    139 
    140       // if true, the TAN was not even evaluated as the user previously
    141       // exhausted the number of attempts
    142       exhausted: boolean;
    143 
    144       // if true, the TAN was not even evaluated as no challenge was ever
    145       // issued (the user must have skipped the step of providing their
    146       // address first!)
    147       no_challenge: boolean;
    148     }