summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2020-12-05 11:33:50 +0100
committerVivien Kraus <vivien@planete-kraus.eu>2021-06-05 16:17:13 +0200
commit1e7bd7402f87faf12c0a18b2b7fc9af32f0ca033 (patch)
treefc65d4a3bbd889834960c542a707cf7f2c17b11a
parent08c42c3c5d7a1a15b6c8a0d8283158863fdf020b (diff)
Implement the token endpoint
-rw-r--r--doc/webid-oidc.texi13
-rw-r--r--po/fr.po247
-rw-r--r--po/webid-oidc.pot237
-rw-r--r--src/scm/webid-oidc/ChangeLog7
-rw-r--r--src/scm/webid-oidc/Makefile.am6
-rw-r--r--src/scm/webid-oidc/errors.scm37
-rw-r--r--src/scm/webid-oidc/token-endpoint.scm168
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/token-endpoint-issue.scm103
-rw-r--r--tests/token-endpoint-refresh.scm101
10 files changed, 686 insertions, 237 deletions
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."
@@ -823,16 +836,6 @@ msgstr ""
"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 <vivien@planete-kraus.eu>
+
+ * 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 <vivien@planete-kraus.eu>
* 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")))
((&not-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 1270451..947afc8 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)))))))))