From b0c963739e155e0f2e4d54ca3d5de6ae44203a1c Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Sat, 5 Dec 2020 11:33:50 +0100 Subject: Implement the token endpoint --- doc/webid-oidc.texi | 13 ++ po/fr.po | 247 +++++++++++++++++----------------- po/webid-oidc.pot | 237 +++++++++++++++++--------------- src/scm/webid-oidc/ChangeLog | 7 + src/scm/webid-oidc/Makefile.am | 6 +- src/scm/webid-oidc/errors.scm | 37 +++++ src/scm/webid-oidc/token-endpoint.scm | 168 +++++++++++++++++++++++ tests/Makefile.am | 4 +- tests/token-endpoint-issue.scm | 103 ++++++++++++++ tests/token-endpoint-refresh.scm | 101 ++++++++++++++ 10 files changed, 686 insertions(+), 237 deletions(-) create mode 100644 src/scm/webid-oidc/token-endpoint.scm create mode 100644 tests/token-endpoint-issue.scm create mode 100644 tests/token-endpoint-refresh.scm diff --git a/doc/webid-oidc.texi b/doc/webid-oidc.texi index 423459d..a33da87 100644 --- a/doc/webid-oidc.texi +++ b/doc/webid-oidc.texi @@ -746,6 +746,19 @@ cannot be set. This exception is always continuable; if the handler returns, then the page will be served in the english locale. @end deftp +@deftp {exception type} &unsupported-grant-type @var{value} +The token request failed to indicate a @var{value} for the grant type, +or indicated an unsupported grant type. +@end deftp + +@deftp {exception type} &no-authorization-code +The token request forgot to put an authorization code. +@end deftp + +@deftp {exception type} &no-refresh-token +The token request forgot to put a refresh token with the request. +@end deftp + @node GNU Free Documentation License @appendix GNU Free Documentation License diff --git a/po/fr.po b/po/fr.po index 96d65b4..ed6fea5 100644 --- a/po/fr.po +++ b/po/fr.po @@ -126,101 +126,101 @@ msgstr "Utilisation : generate-random [NOMBRE D'OCTETS]\n" msgid "Usage: generate-key [NUMBER OF BITS | CURVE]\n" msgstr "Utilisation : generate-key [NOMBRE DE BITS | COURBE]\n" -#: src/scm/webid-oidc/errors.scm:799 +#: src/scm/webid-oidc/errors.scm:829 msgid "that’s how it is" msgstr "c’est comme ça" -#: src/scm/webid-oidc/errors.scm:804 +#: src/scm/webid-oidc/errors.scm:834 #, scheme-format msgid "the value ~s is not a base64 string (because ~a)" msgstr "la valeur ~s n’est pas une chaîne base64 (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:807 +#: src/scm/webid-oidc/errors.scm:837 #, scheme-format msgid "the value ~s is not JSON (because ~a)" msgstr "la valeur ~s n’est pas du JSON (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:810 +#: src/scm/webid-oidc/errors.scm:840 #, scheme-format msgid "the value ~s is not Turtle (because ~a)" msgstr "la valeur ~s n’est pas du Turtle (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:813 +#: src/scm/webid-oidc/errors.scm:843 #, scheme-format msgid "the value ~s does not identify an elleptic curve" msgstr "la valeur ~s n’identifie pas une courbe elliptique" -#: src/scm/webid-oidc/errors.scm:818 +#: src/scm/webid-oidc/errors.scm:848 #, scheme-format msgid "the value ~s does not identify a JWK (because ~a)" msgstr "la valeur ~s n’identifie pas une JWK (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:820 +#: src/scm/webid-oidc/errors.scm:850 #, scheme-format msgid "the value ~s does not identify a JWK" msgstr "la valeur ~s n’identifie pas une JWK" -#: src/scm/webid-oidc/errors.scm:825 +#: src/scm/webid-oidc/errors.scm:855 #, scheme-format msgid "the value ~s does not identify a public JWK (because ~a)" msgstr "la valeur ~s n’identifie pas une JWK publique (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:827 +#: src/scm/webid-oidc/errors.scm:857 #, scheme-format msgid "the value ~s does not identify a public JWK" msgstr "la valeur ~s n’identifie pas une JWK publique" -#: src/scm/webid-oidc/errors.scm:832 +#: src/scm/webid-oidc/errors.scm:862 #, scheme-format msgid "the value ~s does not identify a private JWK (because ~a)" msgstr "la valeur ~s n’identifie pas une JWK privée (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:834 +#: src/scm/webid-oidc/errors.scm:864 #, scheme-format msgid "the value ~s does not identify a private JWK" msgstr "la valeur ~s n’identifie pas une JWK privée" -#: src/scm/webid-oidc/errors.scm:839 +#: src/scm/webid-oidc/errors.scm:869 #, scheme-format msgid "the value ~s does not identify a JWKS (because ~a)" msgstr "la valeur ~s n’identifie pas un JWKS (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:841 +#: src/scm/webid-oidc/errors.scm:871 #, scheme-format msgid "the value ~s does not identify a JWKS" msgstr "la valeur ~s n’identifie pas un JWKS" -#: src/scm/webid-oidc/errors.scm:844 +#: src/scm/webid-oidc/errors.scm:874 #, scheme-format msgid "the value ~s does not identify a hash algorithm" msgstr "la valeur ~s n’identifie pas un algorithme de hachage" -#: src/scm/webid-oidc/errors.scm:847 +#: src/scm/webid-oidc/errors.scm:877 #, scheme-format msgid "the value ~s is not an alist or misses key ~s" msgstr "la valeur ~s n’est pas une alist ou il manque la clé ~s" -#: src/scm/webid-oidc/errors.scm:850 +#: src/scm/webid-oidc/errors.scm:880 #, scheme-format msgid "the value ~s is not a JWS header (because ~a)" msgstr "la valeur ~s n’est pas un header JWS (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:853 +#: src/scm/webid-oidc/errors.scm:883 #, scheme-format msgid "the value ~s is not a JWS payload (because ~a)" msgstr "la valeur ~s n’est pas un contenu JWS (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:856 +#: src/scm/webid-oidc/errors.scm:886 #, scheme-format msgid "the value ~s is not a JWS (because ~a)" msgstr "la valeur ~s n’est pas un JWS (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:859 +#: src/scm/webid-oidc/errors.scm:889 #, scheme-format msgid "the string ~s cannot be split in 3 parts with ~s" msgstr "la chaîne ~s ne peut pas être découpée en 3 parties avec ~s" -#: src/scm/webid-oidc/errors.scm:862 +#: src/scm/webid-oidc/errors.scm:892 #, scheme-format msgid "" "all key candidates failed to verify signature ~s with algorithm ~s and " @@ -229,17 +229,17 @@ msgstr "" "aucune clé candidate n’a pu vérifier la signature ~s avec l’algorithme ~s et " "le contenu ~a (il y en avait ~a : ~s)" -#: src/scm/webid-oidc/errors.scm:865 +#: src/scm/webid-oidc/errors.scm:895 #, scheme-format msgid "I cannot decode JWS ~a (because ~a)" msgstr "je n’ai pas pu décoder le JWS encodé par ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:868 +#: src/scm/webid-oidc/errors.scm:898 #, scheme-format msgid "I cannot encode JWS ~a (because ~a)" msgstr "je n’ai pas pu encoder le JWS ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:871 +#: src/scm/webid-oidc/errors.scm:901 #, scheme-format msgid "" "the server request unexpectedly failed with code ~a and reason phrase ~s" @@ -247,338 +247,338 @@ msgstr "" "la requête au serveur a échoué de façon inattendue avec un code ~a et une " "raison ~s" -#: src/scm/webid-oidc/errors.scm:876 +#: src/scm/webid-oidc/errors.scm:906 #, scheme-format msgid "the header ~a should not have the value ~s" msgstr "l’en-tête ~a ne devrait pas avoir la valeur ~s" -#: src/scm/webid-oidc/errors.scm:878 +#: src/scm/webid-oidc/errors.scm:908 #, scheme-format msgid "the header ~a should be present" msgstr "l’en-tête ~a devrait être présent" -#: src/scm/webid-oidc/errors.scm:881 +#: src/scm/webid-oidc/errors.scm:911 #, scheme-format msgid "the server response wasn't expected: ~s (because ~a)" msgstr "la réponse du serveur est inattendue : ~s (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:887 +#: src/scm/webid-oidc/errors.scm:917 #, scheme-format msgid "the value ~s is not an OIDC configuration (because ~a)" msgstr "la valeur ~s n’est pas une configuration OIDC (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:892 +#: src/scm/webid-oidc/errors.scm:922 #, scheme-format msgid "the webid field is incorrect: ~s" msgstr "le champ webid est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:893 +#: src/scm/webid-oidc/errors.scm:923 msgid "the webid field is missing" msgstr "le champ webid est manquant" -#: src/scm/webid-oidc/errors.scm:897 +#: src/scm/webid-oidc/errors.scm:927 #, scheme-format msgid "the sub field is incorrect: ~s" msgstr "le champ sub est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:898 +#: src/scm/webid-oidc/errors.scm:928 msgid "the sub field is missing" msgstr "le champ sub est manquant" -#: src/scm/webid-oidc/errors.scm:902 +#: src/scm/webid-oidc/errors.scm:932 #, scheme-format msgid "the iss field is incorrect: ~s" msgstr "le champ iss est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:903 +#: src/scm/webid-oidc/errors.scm:933 msgid "the iss field is missing" msgstr "le champ iss est manquant" -#: src/scm/webid-oidc/errors.scm:907 +#: src/scm/webid-oidc/errors.scm:937 #, scheme-format msgid "the aud field is incorrect: ~s" msgstr "le champ aud est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:908 +#: src/scm/webid-oidc/errors.scm:938 msgid "the aud field is missing" msgstr "le champ aud est manquant" -#: src/scm/webid-oidc/errors.scm:912 +#: src/scm/webid-oidc/errors.scm:942 #, scheme-format msgid "the iat field is incorrect: ~s" msgstr "le champ iat est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:913 +#: src/scm/webid-oidc/errors.scm:943 msgid "the iat field is missing" msgstr "le champ iat est manquant" -#: src/scm/webid-oidc/errors.scm:917 +#: src/scm/webid-oidc/errors.scm:947 #, scheme-format msgid "the exp field is incorrect: ~s" msgstr "le champ exp est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:918 +#: src/scm/webid-oidc/errors.scm:948 msgid "the exp field is missing" msgstr "le champ exp est manquant" -#: src/scm/webid-oidc/errors.scm:922 +#: src/scm/webid-oidc/errors.scm:952 #, scheme-format msgid "the cnf/jkt field is incorrect: ~s" msgstr "le champ cnf/jkt est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:923 +#: src/scm/webid-oidc/errors.scm:953 msgid "the cnf/jkt field is missing" msgstr "le champ cnf/jkt est manquant" -#: src/scm/webid-oidc/errors.scm:927 +#: src/scm/webid-oidc/errors.scm:957 #, scheme-format msgid "the client-id field is incorrect: ~s" msgstr "le champ client-id est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:928 +#: src/scm/webid-oidc/errors.scm:958 msgid "the client-id field is missing" msgstr "le champ client-id est manquant" -#: src/scm/webid-oidc/errors.scm:932 +#: src/scm/webid-oidc/errors.scm:962 #: src/scm/webid-oidc/authorization-page-unsafe.scm:133 #, scheme-format msgid "the redirect_uris field is incorrect: ~s" msgstr "le champ redirect_uris est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:933 +#: src/scm/webid-oidc/errors.scm:963 #: src/scm/webid-oidc/authorization-page-unsafe.scm:134 msgid "the redirect_uris field is missing" msgstr "le champ redirect_uris est manquant" -#: src/scm/webid-oidc/errors.scm:937 +#: src/scm/webid-oidc/errors.scm:967 #, scheme-format msgid "the typ field is incorrect: ~s" msgstr "le champ typ est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:938 +#: src/scm/webid-oidc/errors.scm:968 msgid "the typ field is missing" msgstr "le champ typ est manquant" -#: src/scm/webid-oidc/errors.scm:942 +#: src/scm/webid-oidc/errors.scm:972 #, scheme-format msgid "the jwk field is incorrect: ~s (because ~a)" msgstr "le champ jwk est incorrect : ~s (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:944 +#: src/scm/webid-oidc/errors.scm:974 msgid "the jwk field is missing" msgstr "le champ jwk est manquant" -#: src/scm/webid-oidc/errors.scm:948 +#: src/scm/webid-oidc/errors.scm:978 #, scheme-format msgid "the jti field is incorrect: ~s" msgstr "le champ jti est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:949 +#: src/scm/webid-oidc/errors.scm:979 msgid "the jti field is missing" msgstr "le champ jti est manquant" -#: src/scm/webid-oidc/errors.scm:953 +#: src/scm/webid-oidc/errors.scm:983 #, scheme-format msgid "the nonce field is incorrect: ~s" msgstr "le champ nonce est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:954 +#: src/scm/webid-oidc/errors.scm:984 msgid "the nonce field is missing" msgstr "le champ nonce est manquant" -#: src/scm/webid-oidc/errors.scm:958 +#: src/scm/webid-oidc/errors.scm:988 #, scheme-format msgid "the htm field is incorrect: ~s" msgstr "le champ htm est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:959 +#: src/scm/webid-oidc/errors.scm:989 msgid "the htm field is missing" msgstr "le champ htm est manquant" -#: src/scm/webid-oidc/errors.scm:963 +#: src/scm/webid-oidc/errors.scm:993 #, scheme-format msgid "the htu field is incorrect: ~s" msgstr "le champ htu est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:964 +#: src/scm/webid-oidc/errors.scm:994 msgid "the htu field is missing" msgstr "le champ htu est manquant" -#: src/scm/webid-oidc/errors.scm:966 +#: src/scm/webid-oidc/errors.scm:996 #, scheme-format msgid "~s is not an access token (because ~a)" msgstr "~s n’est pas un jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:969 +#: src/scm/webid-oidc/errors.scm:999 #, scheme-format msgid "~s is not an access token header (because ~a)" msgstr "~s n’est pas un en-tête de jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:972 +#: src/scm/webid-oidc/errors.scm:1002 #, scheme-format msgid "~s is not an access token payload (because ~a)" msgstr "~s n’est pas un contenu de jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:975 +#: src/scm/webid-oidc/errors.scm:1005 #, scheme-format msgid "~s is not a DPoP proof (because ~a)" msgstr "~s n’est pas une preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:978 +#: src/scm/webid-oidc/errors.scm:1008 #, scheme-format msgid "~s is not a DPoP proof header (because ~a)" msgstr "~s n’est pas un en-tête de preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:981 +#: src/scm/webid-oidc/errors.scm:1011 #, scheme-format msgid "~s is not a DPoP proof payload (because ~a)" msgstr "~s n’est pas un contenu de preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:984 +#: src/scm/webid-oidc/errors.scm:1014 #, scheme-format msgid "I cannot fetch the issuer configuration of ~a (because ~a)" msgstr "" "je n’ai pas pu récupérer la configuration de l’émetteur ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:991 +#: src/scm/webid-oidc/errors.scm:1021 #, scheme-format msgid "I cannot fetch the JWKS of ~a at ~a (because ~a)" msgstr "je n’ai pas pu récupérer le JWKS de ~a à ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1002 +#: src/scm/webid-oidc/errors.scm:1032 #, scheme-format msgid "the HTTP method is signed for ~s, but ~s was requested" msgstr "la méthode HTTP a été signée pour ~s, mais ~s a été demandé" -#: src/scm/webid-oidc/errors.scm:1005 +#: src/scm/webid-oidc/errors.scm:1035 #, scheme-format msgid "the HTTP uri is signed for ~a, but ~a was requested" msgstr "l’uri HTTP a été signé pour ~a, mais ~a a été demandé" -#: src/scm/webid-oidc/errors.scm:1008 +#: src/scm/webid-oidc/errors.scm:1038 #, scheme-format msgid "the date is ~a, but the DPoP proof is signed in the future at ~a" msgstr "la date est ~a, mais la preuve DPoP a été signée dans le futur à ~a" -#: src/scm/webid-oidc/errors.scm:1012 +#: src/scm/webid-oidc/errors.scm:1042 #, scheme-format msgid "the date is ~a, but the DPoP proof was signed too long ago at ~a" msgstr "" "la date est ~a, mais la preuve DPoP a été signée il y a trop longtemps à ~a" -#: src/scm/webid-oidc/errors.scm:1021 +#: src/scm/webid-oidc/errors.scm:1051 #, scheme-format msgid "the key ~s does not hash to ~a" msgstr "la clé ~s ne donne pas un hash de ~a" -#: src/scm/webid-oidc/errors.scm:1023 +#: src/scm/webid-oidc/errors.scm:1053 #, scheme-format msgid "the key confirmation of ~s failed (because ~a)" msgstr "la confirmation de clé de ~s a échoué (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1025 +#: src/scm/webid-oidc/errors.scm:1055 #, scheme-format msgid "the key confirmation of ~s failed" msgstr "la confirmation de la clé ~s a échoué" -#: src/scm/webid-oidc/errors.scm:1027 +#: src/scm/webid-oidc/errors.scm:1057 #, scheme-format msgid "the jti ~s has already been found (because ~a)" msgstr "le jti ~s a déjà été trouvé (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1030 +#: src/scm/webid-oidc/errors.scm:1060 #, scheme-format msgid "I cannot decode ~s as an access token (because ~a)" msgstr "je n’ai pas pu décoder ~s comme jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1033 +#: src/scm/webid-oidc/errors.scm:1063 #, scheme-format msgid "I cannot encode ~s as an access token with key ~s (because ~a)" msgstr "" "je n’ai pas pu encoder ~s comme un jeton d’accès avec la clé ~s (parce que " "~a)" -#: src/scm/webid-oidc/errors.scm:1036 +#: src/scm/webid-oidc/errors.scm:1066 #, scheme-format msgid "I cannot decode ~s as a DPoP proof (because ~a)" msgstr "je n’ai pas pu décoder ~s comme preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1039 +#: src/scm/webid-oidc/errors.scm:1069 #, scheme-format msgid "I cannot encode ~s as a DPoP proof (because ~a)" msgstr "je n’ai pas pu encoder ~s comme une preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1042 +#: src/scm/webid-oidc/errors.scm:1072 #, scheme-format msgid "I could not fetch a RDF graph at ~a (because ~a)" msgstr "je n’ai pas pu récupérer de graphe RDF à ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1045 +#: src/scm/webid-oidc/errors.scm:1075 #, scheme-format msgid "~s is not a client manifest (because ~a)" msgstr "~s n’est pas un manifeste client (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1048 +#: src/scm/webid-oidc/errors.scm:1078 #, scheme-format msgid "~s does not authorize redirection URI ~a" msgstr "~s n’autorise pas l’URI de redirection ~a" -#: src/scm/webid-oidc/errors.scm:1051 +#: src/scm/webid-oidc/errors.scm:1081 msgid "I cannot serve a public manifest" msgstr "je ne peux pas servir un manifeste public" -#: src/scm/webid-oidc/errors.scm:1053 +#: src/scm/webid-oidc/errors.scm:1083 #, scheme-format msgid "~a does not have a client manifest registration triple" msgstr "~a n’a pas de triplet d’enregistrement de manifeste client" -#: src/scm/webid-oidc/errors.scm:1056 +#: src/scm/webid-oidc/errors.scm:1086 #, scheme-format msgid "the client manifest at ~a is advertised for ~a" msgstr "le manifeste client ~a est publié pour ~a" -#: src/scm/webid-oidc/errors.scm:1059 +#: src/scm/webid-oidc/errors.scm:1089 #, scheme-format msgid "I could not fetch the client manifest of ~a (because ~a)" msgstr "je n’ai pas pu récupérer le manifeste client de ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1062 +#: src/scm/webid-oidc/errors.scm:1092 #, scheme-format msgid "~s is not an authorization code (because ~a)" msgstr "~s n’est pas un code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1065 +#: src/scm/webid-oidc/errors.scm:1095 #, scheme-format msgid "~s is not an authorization code header (because ~a)" msgstr "~s n’est pas un en-tête de code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1068 +#: src/scm/webid-oidc/errors.scm:1098 #, scheme-format msgid "~s is not an authorization code payload (because ~a)" msgstr "~s n’est pas un contenu de code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1071 +#: src/scm/webid-oidc/errors.scm:1101 #, scheme-format msgid "the current time is ~a, and the authorization code expired at ~a" msgstr "" "la date est actuellement ~a, et le code d’autorisation a expiré à la date ~a" -#: src/scm/webid-oidc/errors.scm:1075 +#: src/scm/webid-oidc/errors.scm:1105 #, scheme-format msgid "I cannot decode ~s as an authorization code (because ~a)" msgstr "je n’ai pas pu décoder ~s comme un code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1078 +#: src/scm/webid-oidc/errors.scm:1108 #, scheme-format msgid "I cannot encode ~s as an authorization code (because ~a)" msgstr "je n’ai pas pu encoder ~s comme un code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1081 +#: src/scm/webid-oidc/errors.scm:1111 #, scheme-format msgid "there is no such refresh token as ~s" msgstr "il n’y a pas de jeton de rafraîchissement ~s" -#: src/scm/webid-oidc/errors.scm:1084 +#: src/scm/webid-oidc/errors.scm:1114 #, scheme-format msgid "" "the refresh token is bound to a key confirmed as ~s, but it is used with key " @@ -587,32 +587,45 @@ msgstr "" "Le jeton de rafraîchissement est lié à une clé confirmée par ~s, mais il est " "utilisé avec la clé ~s" -#: src/scm/webid-oidc/errors.scm:1087 +#: src/scm/webid-oidc/errors.scm:1117 #, scheme-format msgid "I cannot decode ~s as an ID token (because ~a)" msgstr "je n’ai pas pu décoder ~s comme jeton d’identité (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1090 +#: src/scm/webid-oidc/errors.scm:1120 #, scheme-format msgid "I cannot encode ~s as an ID token (because ~a)" msgstr "je n’ai pas pu encoder ~s comme un jeton d’identité (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1093 +#: src/scm/webid-oidc/errors.scm:1123 +#, scheme-format +msgid "the grant type ~s is not supported" +msgstr "le type d’octroi ~s n’est pas supporté " + +#: src/scm/webid-oidc/errors.scm:1126 +msgid "there is no authorization code in the request" +msgstr "il n’y a pas de code d’autorisation dans la requête" + +#: src/scm/webid-oidc/errors.scm:1128 +msgid "there is no refresh token in the request" +msgstr "il n’y a pas de jeton de rafraîchissement dans la requête" + +#: src/scm/webid-oidc/errors.scm:1130 #, scheme-format msgid "~s is not an ID token (because ~a)" msgstr "~s n’est pas un jeton d’identité (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1096 +#: src/scm/webid-oidc/errors.scm:1133 #, scheme-format msgid "~s is not an ID token header (because ~a)" msgstr "~s n’est pas un en-tête de jeton d’identité (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1099 +#: src/scm/webid-oidc/errors.scm:1136 #, scheme-format msgid "~s is not an ID token payload (because ~a)" msgstr "~s n’est pas un contenu de jeton d’identité (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1102 +#: src/scm/webid-oidc/errors.scm:1139 #, scheme-format msgid "" "I couldn’t set the locale to ~s as an approximation of the client locale ~s" @@ -620,66 +633,66 @@ msgstr "" "je n’ai pas pu définir la locale à ~s comme approximation de la locale du " "client ~s" -#: src/scm/webid-oidc/errors.scm:1107 +#: src/scm/webid-oidc/errors.scm:1144 msgid "that’s it" msgstr "c’est tout" -#: src/scm/webid-oidc/errors.scm:1111 +#: src/scm/webid-oidc/errors.scm:1148 #, scheme-format msgid "~a and ~a" msgstr "~a et ~a" -#: src/scm/webid-oidc/errors.scm:1114 +#: src/scm/webid-oidc/errors.scm:1151 #, scheme-format msgid "~a, ~a" msgstr "~a, ~a" -#: src/scm/webid-oidc/errors.scm:1118 +#: src/scm/webid-oidc/errors.scm:1155 #, scheme-format msgid "the signature ~a does not match key ~s with payload ~a" msgstr "la signature ~a ne correspond pas à la clé ~s avec le contenu ~a" -#: src/scm/webid-oidc/errors.scm:1121 +#: src/scm/webid-oidc/errors.scm:1158 msgid "there is an undefined variable" msgstr "il y a une variable non définie" -#: src/scm/webid-oidc/errors.scm:1123 +#: src/scm/webid-oidc/errors.scm:1160 #, scheme-format msgid "the origin is ~a" msgstr "l’origine est ~a" -#: src/scm/webid-oidc/errors.scm:1126 +#: src/scm/webid-oidc/errors.scm:1163 #, scheme-format msgid "a message is attached: ~a" msgstr "un message est attaché : ~a" -#: src/scm/webid-oidc/errors.scm:1129 +#: src/scm/webid-oidc/errors.scm:1166 #, scheme-format msgid "the values ~s are problematic" msgstr "les valeurs ~s sont problématiques" -#: src/scm/webid-oidc/errors.scm:1132 +#: src/scm/webid-oidc/errors.scm:1169 msgid "there is a kind and args" msgstr "il y a un type et des arguments" -#: src/scm/webid-oidc/errors.scm:1134 +#: src/scm/webid-oidc/errors.scm:1171 msgid "there is an assertion failure" msgstr "il y a un échec d’assertion" -#: src/scm/webid-oidc/errors.scm:1136 +#: src/scm/webid-oidc/errors.scm:1173 #, scheme-format msgid "the program quits with code ~a" msgstr "le programme quitte avec le code ~a" -#: src/scm/webid-oidc/errors.scm:1139 +#: src/scm/webid-oidc/errors.scm:1176 msgid "the program cannot recover from this exception" msgstr "le programme ne peut pas récupérer après cette exception" -#: src/scm/webid-oidc/errors.scm:1141 +#: src/scm/webid-oidc/errors.scm:1178 msgid "there is an error" msgstr "il y a une erreur" -#: src/scm/webid-oidc/errors.scm:1143 +#: src/scm/webid-oidc/errors.scm:1180 #, scheme-format msgid "Unhandled exception type ~a." msgstr "Type d’exception non pris en charge ~a." @@ -822,16 +835,6 @@ msgstr "" "~a peut maintenant s'identifier en votre nom. Vous devez " "toujours ajuster ses permissions." -#, scheme-format -#~ msgid "the grant type ~s is not supported" -#~ msgstr "le type d’octroi ~s n’est pas supporté " - -#~ msgid "there is no authorization code in the request" -#~ msgstr "il n’y a pas de code d’autorisation dans la requête" - -#~ msgid "there is no refresh token in the request" -#~ msgstr "il n’y a pas de jeton de rafraîchissement dans la requête" - #, scheme-format #~ msgid "~s does not admit ~s as an identity provider" #~ msgstr "~s n’admet pas ~s comme fournisseur d’identité" diff --git a/po/webid-oidc.pot b/po/webid-oidc.pot index c9da413..cf36502 100644 --- a/po/webid-oidc.pot +++ b/po/webid-oidc.pot @@ -122,547 +122,560 @@ msgstr "" msgid "Usage: generate-key [NUMBER OF BITS | CURVE]\n" msgstr "" -#: src/scm/webid-oidc/errors.scm:799 +#: src/scm/webid-oidc/errors.scm:829 msgid "that’s how it is" msgstr "" -#: src/scm/webid-oidc/errors.scm:804 +#: src/scm/webid-oidc/errors.scm:834 #, scheme-format msgid "the value ~s is not a base64 string (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:807 +#: src/scm/webid-oidc/errors.scm:837 #, scheme-format msgid "the value ~s is not JSON (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:810 +#: src/scm/webid-oidc/errors.scm:840 #, scheme-format msgid "the value ~s is not Turtle (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:813 +#: src/scm/webid-oidc/errors.scm:843 #, scheme-format msgid "the value ~s does not identify an elleptic curve" msgstr "" -#: src/scm/webid-oidc/errors.scm:818 +#: src/scm/webid-oidc/errors.scm:848 #, scheme-format msgid "the value ~s does not identify a JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:820 +#: src/scm/webid-oidc/errors.scm:850 #, scheme-format msgid "the value ~s does not identify a JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:825 +#: src/scm/webid-oidc/errors.scm:855 #, scheme-format msgid "the value ~s does not identify a public JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:827 +#: src/scm/webid-oidc/errors.scm:857 #, scheme-format msgid "the value ~s does not identify a public JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:832 +#: src/scm/webid-oidc/errors.scm:862 #, scheme-format msgid "the value ~s does not identify a private JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:834 +#: src/scm/webid-oidc/errors.scm:864 #, scheme-format msgid "the value ~s does not identify a private JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:839 +#: src/scm/webid-oidc/errors.scm:869 #, scheme-format msgid "the value ~s does not identify a JWKS (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:841 +#: src/scm/webid-oidc/errors.scm:871 #, scheme-format msgid "the value ~s does not identify a JWKS" msgstr "" -#: src/scm/webid-oidc/errors.scm:844 +#: src/scm/webid-oidc/errors.scm:874 #, scheme-format msgid "the value ~s does not identify a hash algorithm" msgstr "" -#: src/scm/webid-oidc/errors.scm:847 +#: src/scm/webid-oidc/errors.scm:877 #, scheme-format msgid "the value ~s is not an alist or misses key ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:850 +#: src/scm/webid-oidc/errors.scm:880 #, scheme-format msgid "the value ~s is not a JWS header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:853 +#: src/scm/webid-oidc/errors.scm:883 #, scheme-format msgid "the value ~s is not a JWS payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:856 +#: src/scm/webid-oidc/errors.scm:886 #, scheme-format msgid "the value ~s is not a JWS (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:859 +#: src/scm/webid-oidc/errors.scm:889 #, scheme-format msgid "the string ~s cannot be split in 3 parts with ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:862 +#: src/scm/webid-oidc/errors.scm:892 #, scheme-format msgid "" "all key candidates failed to verify signature ~s with algorithm ~s and " "payload ~a (there were ~a: ~s)" msgstr "" -#: src/scm/webid-oidc/errors.scm:865 +#: src/scm/webid-oidc/errors.scm:895 #, scheme-format msgid "I cannot decode JWS ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:868 +#: src/scm/webid-oidc/errors.scm:898 #, scheme-format msgid "I cannot encode JWS ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:871 +#: src/scm/webid-oidc/errors.scm:901 #, scheme-format msgid "" "the server request unexpectedly failed with code ~a and reason phrase ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:876 +#: src/scm/webid-oidc/errors.scm:906 #, scheme-format msgid "the header ~a should not have the value ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:878 +#: src/scm/webid-oidc/errors.scm:908 #, scheme-format msgid "the header ~a should be present" msgstr "" -#: src/scm/webid-oidc/errors.scm:881 +#: src/scm/webid-oidc/errors.scm:911 #, scheme-format msgid "the server response wasn't expected: ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:887 +#: src/scm/webid-oidc/errors.scm:917 #, scheme-format msgid "the value ~s is not an OIDC configuration (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:892 +#: src/scm/webid-oidc/errors.scm:922 #, scheme-format msgid "the webid field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:893 +#: src/scm/webid-oidc/errors.scm:923 msgid "the webid field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:897 +#: src/scm/webid-oidc/errors.scm:927 #, scheme-format msgid "the sub field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:898 +#: src/scm/webid-oidc/errors.scm:928 msgid "the sub field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:902 +#: src/scm/webid-oidc/errors.scm:932 #, scheme-format msgid "the iss field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:903 +#: src/scm/webid-oidc/errors.scm:933 msgid "the iss field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:907 +#: src/scm/webid-oidc/errors.scm:937 #, scheme-format msgid "the aud field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:908 +#: src/scm/webid-oidc/errors.scm:938 msgid "the aud field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:912 +#: src/scm/webid-oidc/errors.scm:942 #, scheme-format msgid "the iat field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:913 +#: src/scm/webid-oidc/errors.scm:943 msgid "the iat field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:917 +#: src/scm/webid-oidc/errors.scm:947 #, scheme-format msgid "the exp field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:918 +#: src/scm/webid-oidc/errors.scm:948 msgid "the exp field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:922 +#: src/scm/webid-oidc/errors.scm:952 #, scheme-format msgid "the cnf/jkt field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:923 +#: src/scm/webid-oidc/errors.scm:953 msgid "the cnf/jkt field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:927 +#: src/scm/webid-oidc/errors.scm:957 #, scheme-format msgid "the client-id field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:928 +#: src/scm/webid-oidc/errors.scm:958 msgid "the client-id field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:932 +#: src/scm/webid-oidc/errors.scm:962 #: src/scm/webid-oidc/authorization-page-unsafe.scm:133 #, scheme-format msgid "the redirect_uris field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:933 +#: src/scm/webid-oidc/errors.scm:963 #: src/scm/webid-oidc/authorization-page-unsafe.scm:134 msgid "the redirect_uris field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:937 +#: src/scm/webid-oidc/errors.scm:967 #, scheme-format msgid "the typ field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:938 +#: src/scm/webid-oidc/errors.scm:968 msgid "the typ field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:942 +#: src/scm/webid-oidc/errors.scm:972 #, scheme-format msgid "the jwk field is incorrect: ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:944 +#: src/scm/webid-oidc/errors.scm:974 msgid "the jwk field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:948 +#: src/scm/webid-oidc/errors.scm:978 #, scheme-format msgid "the jti field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:949 +#: src/scm/webid-oidc/errors.scm:979 msgid "the jti field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:953 +#: src/scm/webid-oidc/errors.scm:983 #, scheme-format msgid "the nonce field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:954 +#: src/scm/webid-oidc/errors.scm:984 msgid "the nonce field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:958 +#: src/scm/webid-oidc/errors.scm:988 #, scheme-format msgid "the htm field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:959 +#: src/scm/webid-oidc/errors.scm:989 msgid "the htm field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:963 +#: src/scm/webid-oidc/errors.scm:993 #, scheme-format msgid "the htu field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:964 +#: src/scm/webid-oidc/errors.scm:994 msgid "the htu field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:966 +#: src/scm/webid-oidc/errors.scm:996 #, scheme-format msgid "~s is not an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:969 +#: src/scm/webid-oidc/errors.scm:999 #, scheme-format msgid "~s is not an access token header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:972 +#: src/scm/webid-oidc/errors.scm:1002 #, scheme-format msgid "~s is not an access token payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:975 +#: src/scm/webid-oidc/errors.scm:1005 #, scheme-format msgid "~s is not a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:978 +#: src/scm/webid-oidc/errors.scm:1008 #, scheme-format msgid "~s is not a DPoP proof header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:981 +#: src/scm/webid-oidc/errors.scm:1011 #, scheme-format msgid "~s is not a DPoP proof payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:984 +#: src/scm/webid-oidc/errors.scm:1014 #, scheme-format msgid "I cannot fetch the issuer configuration of ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:991 +#: src/scm/webid-oidc/errors.scm:1021 #, scheme-format msgid "I cannot fetch the JWKS of ~a at ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1002 +#: src/scm/webid-oidc/errors.scm:1032 #, scheme-format msgid "the HTTP method is signed for ~s, but ~s was requested" msgstr "" -#: src/scm/webid-oidc/errors.scm:1005 +#: src/scm/webid-oidc/errors.scm:1035 #, scheme-format msgid "the HTTP uri is signed for ~a, but ~a was requested" msgstr "" -#: src/scm/webid-oidc/errors.scm:1008 +#: src/scm/webid-oidc/errors.scm:1038 #, scheme-format msgid "the date is ~a, but the DPoP proof is signed in the future at ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1012 +#: src/scm/webid-oidc/errors.scm:1042 #, scheme-format msgid "the date is ~a, but the DPoP proof was signed too long ago at ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1021 +#: src/scm/webid-oidc/errors.scm:1051 #, scheme-format msgid "the key ~s does not hash to ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1023 +#: src/scm/webid-oidc/errors.scm:1053 #, scheme-format msgid "the key confirmation of ~s failed (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1025 +#: src/scm/webid-oidc/errors.scm:1055 #, scheme-format msgid "the key confirmation of ~s failed" msgstr "" -#: src/scm/webid-oidc/errors.scm:1027 +#: src/scm/webid-oidc/errors.scm:1057 #, scheme-format msgid "the jti ~s has already been found (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1030 +#: src/scm/webid-oidc/errors.scm:1060 #, scheme-format msgid "I cannot decode ~s as an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1033 +#: src/scm/webid-oidc/errors.scm:1063 #, scheme-format msgid "I cannot encode ~s as an access token with key ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1036 +#: src/scm/webid-oidc/errors.scm:1066 #, scheme-format msgid "I cannot decode ~s as a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1039 +#: src/scm/webid-oidc/errors.scm:1069 #, scheme-format msgid "I cannot encode ~s as a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1042 +#: src/scm/webid-oidc/errors.scm:1072 #, scheme-format msgid "I could not fetch a RDF graph at ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1045 +#: src/scm/webid-oidc/errors.scm:1075 #, scheme-format msgid "~s is not a client manifest (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1048 +#: src/scm/webid-oidc/errors.scm:1078 #, scheme-format msgid "~s does not authorize redirection URI ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1051 +#: src/scm/webid-oidc/errors.scm:1081 msgid "I cannot serve a public manifest" msgstr "" -#: src/scm/webid-oidc/errors.scm:1053 +#: src/scm/webid-oidc/errors.scm:1083 #, scheme-format msgid "~a does not have a client manifest registration triple" msgstr "" -#: src/scm/webid-oidc/errors.scm:1056 +#: src/scm/webid-oidc/errors.scm:1086 #, scheme-format msgid "the client manifest at ~a is advertised for ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1059 +#: src/scm/webid-oidc/errors.scm:1089 #, scheme-format msgid "I could not fetch the client manifest of ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1062 +#: src/scm/webid-oidc/errors.scm:1092 #, scheme-format msgid "~s is not an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1065 +#: src/scm/webid-oidc/errors.scm:1095 #, scheme-format msgid "~s is not an authorization code header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1068 +#: src/scm/webid-oidc/errors.scm:1098 #, scheme-format msgid "~s is not an authorization code payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1071 +#: src/scm/webid-oidc/errors.scm:1101 #, scheme-format msgid "the current time is ~a, and the authorization code expired at ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1075 +#: src/scm/webid-oidc/errors.scm:1105 #, scheme-format msgid "I cannot decode ~s as an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1078 +#: src/scm/webid-oidc/errors.scm:1108 #, scheme-format msgid "I cannot encode ~s as an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1081 +#: src/scm/webid-oidc/errors.scm:1111 #, scheme-format msgid "there is no such refresh token as ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1084 +#: src/scm/webid-oidc/errors.scm:1114 #, scheme-format msgid "" "the refresh token is bound to a key confirmed as ~s, but it is used with key " "~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1087 +#: src/scm/webid-oidc/errors.scm:1117 #, scheme-format msgid "I cannot decode ~s as an ID token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1090 +#: src/scm/webid-oidc/errors.scm:1120 #, scheme-format msgid "I cannot encode ~s as an ID token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1093 +#: src/scm/webid-oidc/errors.scm:1123 +#, scheme-format +msgid "the grant type ~s is not supported" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1126 +msgid "there is no authorization code in the request" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1128 +msgid "there is no refresh token in the request" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1130 #, scheme-format msgid "~s is not an ID token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1096 +#: src/scm/webid-oidc/errors.scm:1133 #, scheme-format msgid "~s is not an ID token header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1099 +#: src/scm/webid-oidc/errors.scm:1136 #, scheme-format msgid "~s is not an ID token payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1102 +#: src/scm/webid-oidc/errors.scm:1139 #, scheme-format msgid "" "I couldn’t set the locale to ~s as an approximation of the client locale ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1107 +#: src/scm/webid-oidc/errors.scm:1144 msgid "that’s it" msgstr "" -#: src/scm/webid-oidc/errors.scm:1111 +#: src/scm/webid-oidc/errors.scm:1148 #, scheme-format msgid "~a and ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1114 +#: src/scm/webid-oidc/errors.scm:1151 #, scheme-format msgid "~a, ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1118 +#: src/scm/webid-oidc/errors.scm:1155 #, scheme-format msgid "the signature ~a does not match key ~s with payload ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1121 +#: src/scm/webid-oidc/errors.scm:1158 msgid "there is an undefined variable" msgstr "" -#: src/scm/webid-oidc/errors.scm:1123 +#: src/scm/webid-oidc/errors.scm:1160 #, scheme-format msgid "the origin is ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1126 +#: src/scm/webid-oidc/errors.scm:1163 #, scheme-format msgid "a message is attached: ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1129 +#: src/scm/webid-oidc/errors.scm:1166 #, scheme-format msgid "the values ~s are problematic" msgstr "" -#: src/scm/webid-oidc/errors.scm:1132 +#: src/scm/webid-oidc/errors.scm:1169 msgid "there is a kind and args" msgstr "" -#: src/scm/webid-oidc/errors.scm:1134 +#: src/scm/webid-oidc/errors.scm:1171 msgid "there is an assertion failure" msgstr "" -#: src/scm/webid-oidc/errors.scm:1136 +#: src/scm/webid-oidc/errors.scm:1173 #, scheme-format msgid "the program quits with code ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1139 +#: src/scm/webid-oidc/errors.scm:1176 msgid "the program cannot recover from this exception" msgstr "" -#: src/scm/webid-oidc/errors.scm:1141 +#: src/scm/webid-oidc/errors.scm:1178 msgid "there is an error" msgstr "" -#: src/scm/webid-oidc/errors.scm:1143 +#: src/scm/webid-oidc/errors.scm:1180 #, scheme-format msgid "Unhandled exception type ~a." msgstr "" diff --git a/src/scm/webid-oidc/ChangeLog b/src/scm/webid-oidc/ChangeLog index 1223e69..8ce40eb 100644 --- a/src/scm/webid-oidc/ChangeLog +++ b/src/scm/webid-oidc/ChangeLog @@ -1,3 +1,10 @@ +2021-05-07 Vivien Kraus + + * token-endpoint.scm (make-token-endpoint): The token endpoint + needs to know its public URI, because if it is behind a reverse + proxy we can’t rely on (request-uri request); and it will fail + DPoP validation. + 2021-04-30 Vivien Kraus * reverse-proxy.scm (make-reverse-proxy): Make the auth header diff --git a/src/scm/webid-oidc/Makefile.am b/src/scm/webid-oidc/Makefile.am index 0aea0d9..8436089 100644 --- a/src/scm/webid-oidc/Makefile.am +++ b/src/scm/webid-oidc/Makefile.am @@ -16,7 +16,8 @@ dist_webidoidcmod_DATA += \ %reldir%/oidc-id-token.scm \ %reldir%/authorization-page.scm \ %reldir%/authorization-page-unsafe.scm \ - %reldir%/authorization-endpoint.scm + %reldir%/authorization-endpoint.scm \ + %reldir%/token-endpoint.scm webidoidcgo_DATA += \ %reldir%/errors.go \ @@ -36,6 +37,7 @@ webidoidcgo_DATA += \ %reldir%/oidc-id-token.go \ %reldir%/authorization-page.go \ %reldir%/authorization-page-unsafe.go \ - %reldir%/authorization-endpoint.go + %reldir%/authorization-endpoint.go \ + %reldir%/token-endpoint.go EXTRA_DIST += %reldir%/ChangeLog diff --git a/src/scm/webid-oidc/errors.scm b/src/scm/webid-oidc/errors.scm index 714e0be..4b4ba2d 100644 --- a/src/scm/webid-oidc/errors.scm +++ b/src/scm/webid-oidc/errors.scm @@ -788,6 +788,36 @@ ((record-constructor &unknown-client-locale) web-locale c-locale) #:continuable? #t)) +(define-public &unsupported-grant-type + (make-exception-type + '&unsupported-grant-type + &external-error + '(value))) + +(define-public (raise-unsupported-grant-type value) + (raise-exception + ((record-constructor &unsupported-grant-type) value))) + +(define-public &no-authorization-code + (make-exception-type + '&no-authorization-code + &external-error + '(value))) + +(define-public (raise-no-authorization-code) + (raise-exception + ((record-constructor &no-authorization-code)))) + +(define-public &no-refresh-token + (make-exception-type + '&no-refresh-token + &external-error + '(value))) + +(define-public (raise-no-refresh-token) + (raise-exception + ((record-constructor &no-refresh-token)))) + (define*-public (error->str err #:key (max-depth #f)) (if (record? err) (let* ((type (record-type-descriptor err)) @@ -1089,6 +1119,13 @@ ((&cannot-encode-id-token) (format #f (G_ "I cannot encode ~s as an ID token (because ~a)") (get 'value) (recurse (get 'cause)))) + ((&unsupported-grant-type) + (format #f (G_ "the grant type ~s is not supported") + (get 'value))) + ((&no-authorization-code) + (format #f (G_ "there is no authorization code in the request"))) + ((&no-refresh-token) + (format #f (G_ "there is no refresh token in the request"))) ((¬-an-id-token) (format #f (G_ "~s is not an ID token (because ~a)") (get 'value) (recurse (get 'cause)))) diff --git a/src/scm/webid-oidc/token-endpoint.scm b/src/scm/webid-oidc/token-endpoint.scm new file mode 100644 index 0000000..422bac6 --- /dev/null +++ b/src/scm/webid-oidc/token-endpoint.scm @@ -0,0 +1,168 @@ +(define-module (webid-oidc token-endpoint) + #:use-module (webid-oidc errors) + #:use-module (webid-oidc authorization-code) + #:use-module (webid-oidc dpop-proof) + #:use-module (webid-oidc jws) + #:use-module (webid-oidc jwk) + #:use-module (webid-oidc oidc-id-token) + #:use-module (webid-oidc access-token) + #:use-module ((webid-oidc stubs) #:prefix stubs:) + #:use-module ((webid-oidc refresh-token) #:prefix refresh:) + #:use-module (web client) + #:use-module (web request) + #:use-module (web response) + #:use-module (web uri) + #:use-module (ice-9 optargs) + #:use-module (ice-9 receive) + #:use-module (srfi srfi-19) + #:use-module (rnrs bytevectors)) + +(define (try-handle-web-failure thunk) + (define (error->str err) + (if (record? err) + (let* ((type (record-type-descriptor err)) + (get + (lambda (slot) + ((record-accessor type slot) err))) + (recurse + (lambda (err) + (error->str err)))) + (case (record-type-name type) + ((&cannot-decode-dpop-proof) + (format #f "the DPoP proof is invalid")) + ((&no-authorization-code) + (format #f "there is no authorization code in the request")) + ((&no-refresh-token) + (format #f "there is no refresh token in the request")) + ((&cannot-decode-authorization-code) + (format #f "the authorization code is invalid")) + ((&invalid-refresh-token) + (format #f "the refresh token is invalid")) + ((&invalid-key-for-refresh-token) + (format #f "the refresh token is bound to another key")) + ((&unsupported-grant-type) + (format #f "the grant type ~s is not supported" (get 'value))) + (else + (raise-exception err)))) + (throw err))) + (with-exception-handler + (lambda (error) + (values + (build-response + #:code 400 + #:reason-phrase (string-append "Bad Request: " (error->str error))) + (error->str error))) + thunk + #:unwind? #t)) + +(define*-public (make-token-endpoint token-endpoint-uri iss alg jwk validity jti-list + #:key + (refresh-token-dir refresh:default-dir) + (current-time current-time)) + (lambda* (request request-body) + (try-handle-web-failure + (lambda () + (when (bytevector? request-body) + (set! request-body (utf8->string request-body))) + (let ((current-time + (let ((t current-time)) + (when (thunk? t) + (set! t (t))) + (when (integer? t) + (set! t (make-time time-utc 0 t))) + (when (time? t) + (set! t (time-utc->date t))) + t)) + (form-args + (if (and (request-content-type request) + (eq? (car (request-content-type request)) + 'application/x-www-form-urlencoded)) + (filter + (lambda (x) x) + (map (lambda (kv) + (let ((parsed + (list->vector + (map (lambda (x) + (uri-decode x #:decode-plus-to-space? #t)) + (string-split kv #\=))))) + (if (eq? (vector-length parsed) 2) + `(,(vector-ref parsed 0) . ,(vector-ref parsed 1)) + #f))) + (string-split request-body #\&))) + '())) + (method (request-method request)) + ;; Maybe we’re behind a reverse proxy, so the authority of + ;; (request-uri request) is meaningless. + (uri (build-uri (uri-scheme token-endpoint-uri) + #:userinfo (uri-userinfo token-endpoint-uri) + #:host (uri-host token-endpoint-uri) + #:port (uri-port token-endpoint-uri) + #:path (uri-path (request-uri request)) + #:query (uri-query (request-uri request))))) + (let ((grant-type (assoc-ref form-args "grant_type")) + (dpop (dpop-proof-decode + current-time jti-list method uri + (assq-ref (request-headers request) 'dpop) + (lambda (jkt) #t)))) + (unless (and grant-type (string? grant-type)) + (raise-unsupported-grant-type #f)) + (receive (webid client-id) + (case (string->symbol grant-type) + ((authorization_code) + (let ((code + (let ((str (assoc-ref form-args "code"))) + (unless str + (raise-no-authorization-code)) + (authorization-code-decode + current-time jti-list str jwk)))) + (values (authorization-code-webid code) + (authorization-code-client-id code)))) + ((refresh_token) + (let ((refresh-token (assoc-ref form-args "refresh_token"))) + (unless refresh-token + (raise-no-refresh-token)) + (refresh:with-refresh-token + refresh-token + (dpop-proof-jwk dpop) + values + #:dir refresh-token-dir))) + (else + (raise-unsupported-grant-type grant-type))) + (let* ((iat (time-second (date->time-utc current-time))) + (exp (+ iat validity))) + (let ((id-token + (issue-id-token + jwk + #:alg alg + #:webid (uri->string webid) + #:sub (uri->string webid) + #:iss (uri->string iss) + #:aud (uri->string client-id) + #:exp exp + #:iat iat)) + (access-token + (issue-access-token + jwk + #:alg alg + #:webid (uri->string webid) + #:iss (uri->string iss) + #:exp exp + #:iat iat + #:client-key (dpop-proof-jwk dpop) + #:client-id (uri->string client-id))) + (refresh-token + (if (equal? grant-type "refresh_token") + (assoc-ref form-args "refresh_token") + (refresh:issue-refresh-token webid client-id + (jkt (dpop-proof-jwk dpop)) + #:dir refresh-token-dir)))) + (values + (build-response #:headers '((content-type application/json) + (cache-control (no-cache no-store))) + #:port #f) + (stubs:scm->json-string + `((id_token . ,id-token) + (access_token . ,access-token) + (token_type . "DPoP") + (expires_in . ,validity) + (refresh_token . ,refresh-token))))))))))))) diff --git a/tests/Makefile.am b/tests/Makefile.am index 457d462..3d5e46d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -33,7 +33,9 @@ TESTS = %reldir%/load-library.scm \ %reldir%/unknown-client-locale.scm \ %reldir%/authorization-endpoint-no-args.scm \ %reldir%/authorization-endpoint-get-form.scm \ - %reldir%/authorization-endpoint-submit-form.scm + %reldir%/authorization-endpoint-submit-form.scm \ + %reldir%/token-endpoint-issue.scm \ + %reldir%/token-endpoint-refresh.scm EXTRA_DIST += $(TESTS) %reldir%/ChangeLog diff --git a/tests/token-endpoint-issue.scm b/tests/token-endpoint-issue.scm new file mode 100644 index 0000000..706b908 --- /dev/null +++ b/tests/token-endpoint-issue.scm @@ -0,0 +1,103 @@ +(use-modules (webid-oidc token-endpoint) + (webid-oidc authorization-code) + (webid-oidc dpop-proof) + (webid-oidc jwk) + (webid-oidc jws) + (webid-oidc jti) + (webid-oidc testing) + ((webid-oidc stubs) #:prefix stubs:) + (web uri) + (web request) + (web response) + (srfi srfi-19) + (web response) + (ice-9 optargs) + (ice-9 receive)) + +(with-test-environment + "token-endpoint-issue" + (lambda () + (define alg 'RS256) + (define key (generate-key #:n-size 2048)) + (define client-key (generate-key #:n-size 2048)) + (define subject (string->uri "https://token-endpoint-issue.scm/profile/card#me")) + (define client (string->uri "https://token-endpoint-issue.scm/client/card#app")) + (define issuer (string->uri "https://issuer.token-endpoint-issue.scm")) + (define validity 3600) + (define jti-list (make-jti-list)) + (define authz (issue-authorization-code + alg key + (time-utc->date (make-time time-utc 0 120)) + subject + client)) + (define the-time 0) + (define (current-time) + (make-time time-utc 0 the-time)) + (define endpoint (make-token-endpoint + (string->uri "https://token-endpoint-issue.scm/token") + issuer alg key validity jti-list + #:current-time current-time)) + (receive (response response-body) + ;; The code is fake! + (let ((dpop + (issue-dpop-proof + client-key + #:alg alg + #:htm 'POST + #:htu (string->uri + "https://token-endpoint-issue.scm/token") + #:iat (time-utc->date (make-time time-utc 0 0))))) + (set! the-time 0) + (endpoint + (build-request (string->uri + "http://localhost:8080/token") + #:headers `((content-type application/x-www-form-urlencoded) + (dpop . ,dpop)) + #:method 'POST + #:port #t) + "grant_type=authorization_code&code=fake")) + (unless (eq? (response-code response) 400) + (exit 3)) + (receive (response response-body) + (let ((dpop + (issue-dpop-proof + client-key + #:alg alg + #:htm 'POST + #:htu (string->uri + "https://token-endpoint-issue.scm/token") + #:iat (time-utc->date (make-time time-utc 0 10))))) + (set! the-time 10) + (endpoint + (build-request (string->uri + "http://localhost:8080/token") + #:headers `((content-type application/x-www-form-urlencoded) + (dpop . ,dpop)) + #:method 'POST + #:port #t) + (string-append "grant_type=authorization_code&code=" authz))) + (unless (eq? (response-code response) 200) + (write response) + (exit 4)) + (unless (eq? (car (response-content-type response)) 'application/json) + (exit 5)) + (let ((response (stubs:json-string->scm response-body))) + (let ((access-token-enc (assq-ref response 'access_token)) + (refresh-token-enc (assq-ref response 'refresh_token))) + (unless access-token-enc + (exit 6)) + (unless refresh-token-enc + (exit 7)) + (let ((access-token (jws-decode access-token-enc + (lambda (h) key)))) + (unless access-token + (exit 8)) + (let ((access-token-cnf (assq-ref (jws-payload access-token) + 'cnf))) + (unless access-token-cnf + (exit 9)) + (let ((access-token-cnf/jkt (assq-ref access-token-cnf 'jkt))) + (unless access-token-cnf/jkt + (exit 10)) + (unless (string=? access-token-cnf/jkt (jkt client-key)) + (exit 11))))))))))) diff --git a/tests/token-endpoint-refresh.scm b/tests/token-endpoint-refresh.scm new file mode 100644 index 0000000..293d656 --- /dev/null +++ b/tests/token-endpoint-refresh.scm @@ -0,0 +1,101 @@ +(use-modules (webid-oidc token-endpoint) + (webid-oidc authorization-code) + (webid-oidc refresh-token) + (webid-oidc dpop-proof) + (webid-oidc jwk) + (webid-oidc jws) + (webid-oidc jti) + (webid-oidc testing) + ((webid-oidc stubs) #:prefix stubs:) + (web uri) + (web request) + (web response) + (srfi srfi-19) + (web response) + (ice-9 optargs) + (ice-9 receive)) + +(with-test-environment + "token-endpoint-refresh" + (lambda () + (define alg 'RS256) + (define key (generate-key #:n-size 2048)) + (define client-key (generate-key #:n-size 2048)) + (define subject (string->uri "https://token-endpoint-issue.scm/profile/card#me")) + (define client (string->uri "https://token-endpoint-issue.scm/client/card#app")) + (define issuer (string->uri "https://issuer.token-endpoint-issue.scm")) + (define validity 3600) + (define jti-list (make-jti-list)) + (define refresh-code + (issue-refresh-token subject client (jkt client-key))) + (define the-time 0) + (define (current-time) + (make-time time-utc 0 the-time)) + (define endpoint (make-token-endpoint + (string->uri "https://token-endpoint-issue.scm/token") + issuer alg key validity jti-list + #:current-time current-time)) + (receive (response response-body) + ;; The refresh token is fake! + (let ((dpop + (issue-dpop-proof + client-key + #:alg alg + #:htm 'POST + #:htu (string->uri + "https://token-endpoint-issue.scm/token") + #:iat (time-utc->date (make-time time-utc 0 0))))) + (set! the-time 0) + (endpoint + (build-request (string->uri + "http://localhost:8080/token") + #:headers `((content-type application/x-www-form-urlencoded) + (dpop . ,dpop)) + #:method 'POST + #:port #t) + "refresh_token=fake")) + (unless (eq? (response-code response) 400) + (exit 3)) + (receive (response response-body) + (let ((dpop + (issue-dpop-proof + client-key + #:alg alg + #:htm 'POST + #:htu (string->uri + "https://token-endpoint-issue.scm/token") + #:iat (time-utc->date (make-time time-utc 0 10))))) + (set! the-time 10) + (endpoint + (build-request (string->uri + "http://localhost:8080/token") + #:headers `((content-type application/x-www-form-urlencoded) + (dpop . ,dpop)) + #:method 'POST + #:port #t) + (string-append "grant_type=refresh_token&refresh_token=" refresh-code))) + (unless (eq? (response-code response) 200) + (exit 4)) + (unless (eq? (car (response-content-type response)) 'application/json) + (exit 5)) + (let ((response (stubs:json-string->scm response-body))) + (let ((access-token-enc (assq-ref response 'access_token)) + (refresh-token-enc (assq-ref response 'refresh_token))) + (unless access-token-enc + (exit 6)) + (unless refresh-token-enc + (exit 7)) + (let ((access-token (jws-decode access-token-enc + (lambda (h) key)))) + (unless access-token + (exit 8)) + (let ((access-token-cnf (assq-ref access-token 'cnf))) + (unless access-token-cnf + (exit 9)) + (let ((access-token-cnf/jkt (assq-ref access-token-cnf 'jkt))) + (unless access-token-cnf/jkt + (exit 10)) + (unless (string=? access-token-cnf/jkt (jkt client-key)) + (exit 11)))) + (unless (string=? refresh-token-enc refresh-code) + (exit 12))))))))) -- cgit v1.2.3