From 8879c107f3b25cfd51249b75a73cea608a1bf143 Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Tue, 15 Jun 2021 19:02:39 +0200 Subject: Implement WAC --- doc/webid-oidc.texi | 21 ++ po/fr.po | 272 +++++++++++++------------ po/webid-oidc.pot | 263 ++++++++++++------------ src/scm/webid-oidc/errors.scm | 20 ++ src/scm/webid-oidc/server/resource/Makefile.am | 6 +- src/scm/webid-oidc/server/resource/wac.scm | 226 ++++++++++++++++++++ tests/Makefile.am | 3 +- tests/acl-with-group.scm | 11 + tests/acl.scm | 249 ++++++++++++++++++++++ 9 files changed, 806 insertions(+), 265 deletions(-) create mode 100644 src/scm/webid-oidc/server/resource/wac.scm create mode 100644 tests/acl-with-group.scm create mode 100644 tests/acl.scm diff --git a/doc/webid-oidc.texi b/doc/webid-oidc.texi index 60ec866..c1fe781 100644 --- a/doc/webid-oidc.texi +++ b/doc/webid-oidc.texi @@ -631,6 +631,20 @@ then update the parent, then unlock the parent, and finally unlock the child path. @end deffn +The Web Access Control specification defines an RDF vocabulary to +check whether a given user is allowed to perform some operations. The +@code{(webid-oidc server resource wac)} helps you do that. + +@deffn function wac-get-modes @var{server-name} @var{path} @var{user} @var{[#:http-get]} +Return the list of modes that are allowed for @var{user} accessing +@var{path}. The @var{server-name} URI is required to find the relevant +triples in the ACL. If @var{user} is unauthenticated, pass @code{#f}. + +Please note that in any case, the data owner should have all rights +whatsoever, bypassing WAC. Otherwise, it is possible to steal control +away from the data owner. +@end deffn + @node Running a client @chapter Running a client @@ -1229,6 +1243,13 @@ There was a request to delete a non-empty container. There was a request to create a resource in something that is not a container. @end deftp + +@deftp {exception type} &cannot-fetch-group @var{group-uri} @var{cause} +The access control could not fetch the group @var{group-uri} (with a +known @var{cause}). This warning is continuable every time it is +raised. If the handler returns, then the group will be considered +empty. +@end deftp @node GNU Free Documentation License @appendix GNU Free Documentation License diff --git a/po/fr.po b/po/fr.po index 2c499ab..7f0897b 100644 --- a/po/fr.po +++ b/po/fr.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: webid-oidc 0.0.0\n" "Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n" -"POT-Creation-Date: 2021-06-05 16:23+0200\n" -"PO-Revision-Date: 2021-06-05 11:07+0200\n" +"POT-Creation-Date: 2021-06-17 12:23+0200\n" +"PO-Revision-Date: 2021-06-17 12:24+0200\n" "Last-Translator: Vivien Kraus \n" "Language-Team: French \n" "Language: fr\n" @@ -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:931 +#: src/scm/webid-oidc/errors.scm:945 msgid "that’s how it is" msgstr "c’est comme ça" -#: src/scm/webid-oidc/errors.scm:936 +#: src/scm/webid-oidc/errors.scm:950 #, 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:939 +#: src/scm/webid-oidc/errors.scm:953 #, 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:942 +#: src/scm/webid-oidc/errors.scm:956 #, 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:945 +#: src/scm/webid-oidc/errors.scm:959 #, 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:950 +#: src/scm/webid-oidc/errors.scm:964 #, 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:952 +#: src/scm/webid-oidc/errors.scm:966 #, 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:957 +#: src/scm/webid-oidc/errors.scm:971 #, 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:959 +#: src/scm/webid-oidc/errors.scm:973 #, 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:964 +#: src/scm/webid-oidc/errors.scm:978 #, 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:966 +#: src/scm/webid-oidc/errors.scm:980 #, 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:971 +#: src/scm/webid-oidc/errors.scm:985 #, 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:973 +#: src/scm/webid-oidc/errors.scm:987 #, 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:976 +#: src/scm/webid-oidc/errors.scm:990 #, 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:979 +#: src/scm/webid-oidc/errors.scm:993 #, 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:982 +#: src/scm/webid-oidc/errors.scm:996 #, 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:985 +#: src/scm/webid-oidc/errors.scm:999 #, 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:988 +#: src/scm/webid-oidc/errors.scm:1002 #, 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:991 +#: src/scm/webid-oidc/errors.scm:1005 #, 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:994 +#: src/scm/webid-oidc/errors.scm:1008 #, 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:997 +#: src/scm/webid-oidc/errors.scm:1011 #, 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:1000 +#: src/scm/webid-oidc/errors.scm:1014 #, 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:1003 +#: src/scm/webid-oidc/errors.scm:1017 #, 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:1008 +#: src/scm/webid-oidc/errors.scm:1022 #, 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:1010 +#: src/scm/webid-oidc/errors.scm:1024 #, 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:1013 +#: src/scm/webid-oidc/errors.scm:1027 #, 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:1019 +#: src/scm/webid-oidc/errors.scm:1033 #, 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:1024 +#: src/scm/webid-oidc/errors.scm:1038 #, scheme-format msgid "the webid field is incorrect: ~s" msgstr "le champ webid est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1025 +#: src/scm/webid-oidc/errors.scm:1039 msgid "the webid field is missing" msgstr "le champ webid est manquant" -#: src/scm/webid-oidc/errors.scm:1029 +#: src/scm/webid-oidc/errors.scm:1043 #, scheme-format msgid "the sub field is incorrect: ~s" msgstr "le champ sub est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1030 +#: src/scm/webid-oidc/errors.scm:1044 msgid "the sub field is missing" msgstr "le champ sub est manquant" -#: src/scm/webid-oidc/errors.scm:1034 +#: src/scm/webid-oidc/errors.scm:1048 #, scheme-format msgid "the iss field is incorrect: ~s" msgstr "le champ iss est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1035 +#: src/scm/webid-oidc/errors.scm:1049 msgid "the iss field is missing" msgstr "le champ iss est manquant" -#: src/scm/webid-oidc/errors.scm:1039 +#: src/scm/webid-oidc/errors.scm:1053 #, scheme-format msgid "the aud field is incorrect: ~s" msgstr "le champ aud est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1040 +#: src/scm/webid-oidc/errors.scm:1054 msgid "the aud field is missing" msgstr "le champ aud est manquant" -#: src/scm/webid-oidc/errors.scm:1044 +#: src/scm/webid-oidc/errors.scm:1058 #, scheme-format msgid "the iat field is incorrect: ~s" msgstr "le champ iat est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1045 +#: src/scm/webid-oidc/errors.scm:1059 msgid "the iat field is missing" msgstr "le champ iat est manquant" -#: src/scm/webid-oidc/errors.scm:1049 +#: src/scm/webid-oidc/errors.scm:1063 #, scheme-format msgid "the exp field is incorrect: ~s" msgstr "le champ exp est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1050 +#: src/scm/webid-oidc/errors.scm:1064 msgid "the exp field is missing" msgstr "le champ exp est manquant" -#: src/scm/webid-oidc/errors.scm:1054 +#: src/scm/webid-oidc/errors.scm:1068 #, scheme-format msgid "the cnf/jkt field is incorrect: ~s" msgstr "le champ cnf/jkt est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1055 +#: src/scm/webid-oidc/errors.scm:1069 msgid "the cnf/jkt field is missing" msgstr "le champ cnf/jkt est manquant" -#: src/scm/webid-oidc/errors.scm:1059 +#: src/scm/webid-oidc/errors.scm:1073 #, scheme-format msgid "the client-id field is incorrect: ~s" msgstr "le champ client-id est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1060 +#: src/scm/webid-oidc/errors.scm:1074 msgid "the client-id field is missing" msgstr "le champ client-id est manquant" -#: src/scm/webid-oidc/errors.scm:1064 +#: src/scm/webid-oidc/errors.scm:1078 #: 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:1065 +#: src/scm/webid-oidc/errors.scm:1079 #: 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:1069 +#: src/scm/webid-oidc/errors.scm:1083 #, scheme-format msgid "the typ field is incorrect: ~s" msgstr "le champ typ est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1070 +#: src/scm/webid-oidc/errors.scm:1084 msgid "the typ field is missing" msgstr "le champ typ est manquant" -#: src/scm/webid-oidc/errors.scm:1074 +#: src/scm/webid-oidc/errors.scm:1088 #, 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:1076 +#: src/scm/webid-oidc/errors.scm:1090 msgid "the jwk field is missing" msgstr "le champ jwk est manquant" -#: src/scm/webid-oidc/errors.scm:1080 +#: src/scm/webid-oidc/errors.scm:1094 #, scheme-format msgid "the jti field is incorrect: ~s" msgstr "le champ jti est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1081 +#: src/scm/webid-oidc/errors.scm:1095 msgid "the jti field is missing" msgstr "le champ jti est manquant" -#: src/scm/webid-oidc/errors.scm:1085 +#: src/scm/webid-oidc/errors.scm:1099 #, scheme-format msgid "the nonce field is incorrect: ~s" msgstr "le champ nonce est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1086 +#: src/scm/webid-oidc/errors.scm:1100 msgid "the nonce field is missing" msgstr "le champ nonce est manquant" -#: src/scm/webid-oidc/errors.scm:1090 +#: src/scm/webid-oidc/errors.scm:1104 #, scheme-format msgid "the htm field is incorrect: ~s" msgstr "le champ htm est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1091 +#: src/scm/webid-oidc/errors.scm:1105 msgid "the htm field is missing" msgstr "le champ htm est manquant" -#: src/scm/webid-oidc/errors.scm:1095 +#: src/scm/webid-oidc/errors.scm:1109 #, scheme-format msgid "the htu field is incorrect: ~s" msgstr "le champ htu est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:1096 +#: src/scm/webid-oidc/errors.scm:1110 msgid "the htu field is missing" msgstr "le champ htu est manquant" -#: src/scm/webid-oidc/errors.scm:1098 +#: src/scm/webid-oidc/errors.scm:1112 #, 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:1101 +#: src/scm/webid-oidc/errors.scm:1115 #, 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:1104 +#: src/scm/webid-oidc/errors.scm:1118 #, 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:1107 +#: src/scm/webid-oidc/errors.scm:1121 #, 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:1110 +#: src/scm/webid-oidc/errors.scm:1124 #, 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:1113 +#: src/scm/webid-oidc/errors.scm:1127 #, 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:1116 +#: src/scm/webid-oidc/errors.scm:1130 #, 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:1123 +#: src/scm/webid-oidc/errors.scm:1137 #, 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:1134 +#: src/scm/webid-oidc/errors.scm:1148 #, 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:1137 +#: src/scm/webid-oidc/errors.scm:1151 #, 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:1140 +#: src/scm/webid-oidc/errors.scm:1154 #, 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:1144 +#: src/scm/webid-oidc/errors.scm:1158 #, 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:1153 +#: src/scm/webid-oidc/errors.scm:1167 #, 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:1155 +#: src/scm/webid-oidc/errors.scm:1169 #, 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:1157 +#: src/scm/webid-oidc/errors.scm:1171 #, scheme-format msgid "the key confirmation of ~s failed" msgstr "la confirmation de la clé ~s a échoué" -#: src/scm/webid-oidc/errors.scm:1159 +#: src/scm/webid-oidc/errors.scm:1173 #, 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:1162 +#: src/scm/webid-oidc/errors.scm:1176 #, 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:1165 +#: src/scm/webid-oidc/errors.scm:1179 #, 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:1168 +#: src/scm/webid-oidc/errors.scm:1182 #, 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:1171 +#: src/scm/webid-oidc/errors.scm:1185 #, 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:1174 +#: src/scm/webid-oidc/errors.scm:1188 #, 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:1177 +#: src/scm/webid-oidc/errors.scm:1191 #, 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:1180 +#: src/scm/webid-oidc/errors.scm:1194 #, 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:1183 +#: src/scm/webid-oidc/errors.scm:1197 msgid "I cannot serve a public manifest" msgstr "je ne peux pas servir un manifeste public" -#: src/scm/webid-oidc/errors.scm:1185 +#: src/scm/webid-oidc/errors.scm:1199 #, 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:1188 +#: src/scm/webid-oidc/errors.scm:1202 #, 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:1191 +#: src/scm/webid-oidc/errors.scm:1205 #, 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:1194 +#: src/scm/webid-oidc/errors.scm:1208 #, 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:1197 +#: src/scm/webid-oidc/errors.scm:1211 #, 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:1200 +#: src/scm/webid-oidc/errors.scm:1214 #, 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:1203 +#: src/scm/webid-oidc/errors.scm:1217 #, 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:1207 +#: src/scm/webid-oidc/errors.scm:1221 #, 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:1210 +#: src/scm/webid-oidc/errors.scm:1224 #, 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:1213 +#: src/scm/webid-oidc/errors.scm:1227 #, 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:1216 +#: src/scm/webid-oidc/errors.scm:1230 #, scheme-format msgid "" "the refresh token is bound to a key confirmed as ~s, but it is used with key " @@ -587,45 +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:1219 +#: src/scm/webid-oidc/errors.scm:1233 #, 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:1222 +#: src/scm/webid-oidc/errors.scm:1236 #, 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:1225 +#: src/scm/webid-oidc/errors.scm:1239 #, 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:1228 +#: src/scm/webid-oidc/errors.scm:1242 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:1230 +#: src/scm/webid-oidc/errors.scm:1244 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:1232 +#: src/scm/webid-oidc/errors.scm:1246 #, 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:1235 +#: src/scm/webid-oidc/errors.scm:1249 #, 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:1238 +#: src/scm/webid-oidc/errors.scm:1252 #, 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:1241 +#: src/scm/webid-oidc/errors.scm:1255 #, scheme-format msgid "" "I couldn’t set the locale to ~s as an approximation of the client locale ~s" @@ -633,12 +633,12 @@ 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:1244 +#: src/scm/webid-oidc/errors.scm:1258 #, scheme-format msgid "~s does not admit ~s as an identity provider" msgstr "~s n’admet pas ~s comme fournisseur d’identité" -#: src/scm/webid-oidc/errors.scm:1247 +#: src/scm/webid-oidc/errors.scm:1261 #, scheme-format msgid "" "~a is neither an identity provider (because ~a) nor a webid (because ~a)" @@ -646,113 +646,122 @@ msgstr "" "~a n’est ni un fournisseur d’identité (parce que ~a) ni un webid (parce que " "~a)" -#: src/scm/webid-oidc/errors.scm:1252 +#: src/scm/webid-oidc/errors.scm:1266 #, scheme-format msgid "the token request failed (because ~a)" msgstr "la requête de jeton a échoué (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1255 +#: src/scm/webid-oidc/errors.scm:1269 #, scheme-format msgid "you don’t have a refresh token for identity ~a certified by ~a in ~s" msgstr "" "vous n’avez pas de jeton de rafraîchissement pour l’identité ~a certifié par " "~a dans ~s" -#: src/scm/webid-oidc/errors.scm:1260 +#: src/scm/webid-oidc/errors.scm:1274 #, scheme-format msgid "all identity provider candidates for ~a failed: ~a" msgstr "tous les candidats de fournisseurs d’identité pour ~a ont échoué : ~a" -#: src/scm/webid-oidc/errors.scm:1264 +#: src/scm/webid-oidc/errors.scm:1278 #, scheme-format msgid "~s failed (because ~a)" msgstr "~s a échoué (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:1267 +#: src/scm/webid-oidc/errors.scm:1281 msgid ", " msgstr ", " -#: src/scm/webid-oidc/errors.scm:1269 +#: src/scm/webid-oidc/errors.scm:1283 #, scheme-format msgid "no resource has been found to serve URI path ~s" msgstr "aucune ressource n’a été trouvée pour servir le chemin d’URI ~s" -#: src/scm/webid-oidc/errors.scm:1272 +#: src/scm/webid-oidc/errors.scm:1286 #, scheme-format msgid "no resource has been found to serve URI path ~s, but ~s exists" msgstr "" "aucune ressource n’a été trouvée pour servir le chemin d’URI ~s, mais ~s " "existe" -#: src/scm/webid-oidc/errors.scm:1275 +#: src/scm/webid-oidc/errors.scm:1289 msgid "the root storage cannot be deleted" msgstr "le stockage racine ne peut pas être détruit" -#: src/scm/webid-oidc/errors.scm:1277 +#: src/scm/webid-oidc/errors.scm:1291 #, scheme-format msgid "the container ~s should be emptied before being deleted" msgstr "le conteneur ~s doit être vidé avant d’être détruit" -#: src/scm/webid-oidc/errors.scm:1282 +#: src/scm/webid-oidc/errors.scm:1294 +#, scheme-format +msgid "the group ~s cannot be fetched (because ~a)" +msgstr "le groupe ~s n’a pas pu être récupéré (parce que ~a)" + +#: src/scm/webid-oidc/errors.scm:1300 msgid "that’s it" msgstr "c’est tout" -#: src/scm/webid-oidc/errors.scm:1286 +#: src/scm/webid-oidc/errors.scm:1304 #, scheme-format msgid "~a and ~a" msgstr "~a et ~a" -#: src/scm/webid-oidc/errors.scm:1289 +#: src/scm/webid-oidc/errors.scm:1307 #, scheme-format msgid "~a, ~a" msgstr "~a, ~a" -#: src/scm/webid-oidc/errors.scm:1293 +#: src/scm/webid-oidc/errors.scm:1311 #, 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:1296 +#: src/scm/webid-oidc/errors.scm:1314 msgid "there is an undefined variable" msgstr "il y a une variable non définie" -#: src/scm/webid-oidc/errors.scm:1298 +#: src/scm/webid-oidc/errors.scm:1316 #, scheme-format msgid "the origin is ~a" msgstr "l’origine est ~a" -#: src/scm/webid-oidc/errors.scm:1301 +#: src/scm/webid-oidc/errors.scm:1319 #, scheme-format msgid "a message is attached: ~a" msgstr "un message est attaché : ~a" -#: src/scm/webid-oidc/errors.scm:1304 +#: src/scm/webid-oidc/errors.scm:1322 #, scheme-format msgid "the values ~s are problematic" msgstr "les valeurs ~s sont problématiques" -#: src/scm/webid-oidc/errors.scm:1307 +#: src/scm/webid-oidc/errors.scm:1325 msgid "there is a kind and args" msgstr "il y a un type et des arguments" -#: src/scm/webid-oidc/errors.scm:1309 +#: src/scm/webid-oidc/errors.scm:1327 msgid "there is an assertion failure" msgstr "il y a un échec d’assertion" -#: src/scm/webid-oidc/errors.scm:1311 +#: src/scm/webid-oidc/errors.scm:1329 #, scheme-format msgid "the program quits with code ~a" msgstr "le programme quitte avec le code ~a" -#: src/scm/webid-oidc/errors.scm:1314 +#: src/scm/webid-oidc/errors.scm:1332 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:1316 +#: src/scm/webid-oidc/errors.scm:1334 +msgid "there is an external error" +msgstr "il y a une erreur externe" + +#: src/scm/webid-oidc/errors.scm:1336 msgid "there is an error" msgstr "il y a une erreur" -#: src/scm/webid-oidc/errors.scm:1318 +#: src/scm/webid-oidc/errors.scm:1338 #, scheme-format msgid "Unhandled exception type ~a." msgstr "Type d’exception non pris en charge ~a." @@ -1632,13 +1641,6 @@ msgstr "Il y a eu une erreur : ~a\n" #~ msgid "the group ~a is not under the server URI ~a" #~ msgstr "le groupe ~a n’est pas sous l’URI du serveur ~a" -#, scheme-format -#~ msgid "the group ~a cannot be fetched (because ~a)" -#~ msgstr "le groupe ~a n’a pas pu être récupéré (parce que ~a)" - -#~ msgid "there is an external error" -#~ msgstr "il y a une erreur externe" - #, scheme-format #~ msgid "" #~ "The application is not a Solid application because the client ID, " diff --git a/po/webid-oidc.pot b/po/webid-oidc.pot index 7653461..1f9fd31 100644 --- a/po/webid-oidc.pot +++ b/po/webid-oidc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: webid-oidc SNAPSHOT\n" "Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n" -"POT-Creation-Date: 2021-06-05 16:23+0200\n" +"POT-Creation-Date: 2021-06-17 12:23+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -122,614 +122,623 @@ msgstr "" msgid "Usage: generate-key [NUMBER OF BITS | CURVE]\n" msgstr "" -#: src/scm/webid-oidc/errors.scm:931 +#: src/scm/webid-oidc/errors.scm:945 msgid "that’s how it is" msgstr "" -#: src/scm/webid-oidc/errors.scm:936 +#: src/scm/webid-oidc/errors.scm:950 #, scheme-format msgid "the value ~s is not a base64 string (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:939 +#: src/scm/webid-oidc/errors.scm:953 #, scheme-format msgid "the value ~s is not JSON (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:942 +#: src/scm/webid-oidc/errors.scm:956 #, scheme-format msgid "the value ~s is not Turtle (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:945 +#: src/scm/webid-oidc/errors.scm:959 #, scheme-format msgid "the value ~s does not identify an elleptic curve" msgstr "" -#: src/scm/webid-oidc/errors.scm:950 +#: src/scm/webid-oidc/errors.scm:964 #, scheme-format msgid "the value ~s does not identify a JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:952 +#: src/scm/webid-oidc/errors.scm:966 #, scheme-format msgid "the value ~s does not identify a JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:957 +#: src/scm/webid-oidc/errors.scm:971 #, scheme-format msgid "the value ~s does not identify a public JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:959 +#: src/scm/webid-oidc/errors.scm:973 #, scheme-format msgid "the value ~s does not identify a public JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:964 +#: src/scm/webid-oidc/errors.scm:978 #, scheme-format msgid "the value ~s does not identify a private JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:966 +#: src/scm/webid-oidc/errors.scm:980 #, scheme-format msgid "the value ~s does not identify a private JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:971 +#: src/scm/webid-oidc/errors.scm:985 #, scheme-format msgid "the value ~s does not identify a JWKS (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:973 +#: src/scm/webid-oidc/errors.scm:987 #, scheme-format msgid "the value ~s does not identify a JWKS" msgstr "" -#: src/scm/webid-oidc/errors.scm:976 +#: src/scm/webid-oidc/errors.scm:990 #, scheme-format msgid "the value ~s does not identify a hash algorithm" msgstr "" -#: src/scm/webid-oidc/errors.scm:979 +#: src/scm/webid-oidc/errors.scm:993 #, scheme-format msgid "the value ~s is not an alist or misses key ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:982 +#: src/scm/webid-oidc/errors.scm:996 #, scheme-format msgid "the value ~s is not a JWS header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:985 +#: src/scm/webid-oidc/errors.scm:999 #, scheme-format msgid "the value ~s is not a JWS payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:988 +#: src/scm/webid-oidc/errors.scm:1002 #, scheme-format msgid "the value ~s is not a JWS (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:991 +#: src/scm/webid-oidc/errors.scm:1005 #, scheme-format msgid "the string ~s cannot be split in 3 parts with ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:994 +#: src/scm/webid-oidc/errors.scm:1008 #, 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:997 +#: src/scm/webid-oidc/errors.scm:1011 #, scheme-format msgid "I cannot decode JWS ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1000 +#: src/scm/webid-oidc/errors.scm:1014 #, scheme-format msgid "I cannot encode JWS ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1003 +#: src/scm/webid-oidc/errors.scm:1017 #, scheme-format msgid "" "the server request unexpectedly failed with code ~a and reason phrase ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1008 +#: src/scm/webid-oidc/errors.scm:1022 #, scheme-format msgid "the header ~a should not have the value ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1010 +#: src/scm/webid-oidc/errors.scm:1024 #, scheme-format msgid "the header ~a should be present" msgstr "" -#: src/scm/webid-oidc/errors.scm:1013 +#: src/scm/webid-oidc/errors.scm:1027 #, scheme-format msgid "the server response wasn't expected: ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1019 +#: src/scm/webid-oidc/errors.scm:1033 #, scheme-format msgid "the value ~s is not an OIDC configuration (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1024 +#: src/scm/webid-oidc/errors.scm:1038 #, scheme-format msgid "the webid field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1025 +#: src/scm/webid-oidc/errors.scm:1039 msgid "the webid field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1029 +#: src/scm/webid-oidc/errors.scm:1043 #, scheme-format msgid "the sub field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1030 +#: src/scm/webid-oidc/errors.scm:1044 msgid "the sub field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1034 +#: src/scm/webid-oidc/errors.scm:1048 #, scheme-format msgid "the iss field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1035 +#: src/scm/webid-oidc/errors.scm:1049 msgid "the iss field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1039 +#: src/scm/webid-oidc/errors.scm:1053 #, scheme-format msgid "the aud field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1040 +#: src/scm/webid-oidc/errors.scm:1054 msgid "the aud field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1044 +#: src/scm/webid-oidc/errors.scm:1058 #, scheme-format msgid "the iat field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1045 +#: src/scm/webid-oidc/errors.scm:1059 msgid "the iat field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1049 +#: src/scm/webid-oidc/errors.scm:1063 #, scheme-format msgid "the exp field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1050 +#: src/scm/webid-oidc/errors.scm:1064 msgid "the exp field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1054 +#: src/scm/webid-oidc/errors.scm:1068 #, scheme-format msgid "the cnf/jkt field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1055 +#: src/scm/webid-oidc/errors.scm:1069 msgid "the cnf/jkt field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1059 +#: src/scm/webid-oidc/errors.scm:1073 #, scheme-format msgid "the client-id field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1060 +#: src/scm/webid-oidc/errors.scm:1074 msgid "the client-id field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1064 +#: src/scm/webid-oidc/errors.scm:1078 #: 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:1065 +#: src/scm/webid-oidc/errors.scm:1079 #: src/scm/webid-oidc/authorization-page-unsafe.scm:134 msgid "the redirect_uris field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1069 +#: src/scm/webid-oidc/errors.scm:1083 #, scheme-format msgid "the typ field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1070 +#: src/scm/webid-oidc/errors.scm:1084 msgid "the typ field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1074 +#: src/scm/webid-oidc/errors.scm:1088 #, scheme-format msgid "the jwk field is incorrect: ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1076 +#: src/scm/webid-oidc/errors.scm:1090 msgid "the jwk field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1080 +#: src/scm/webid-oidc/errors.scm:1094 #, scheme-format msgid "the jti field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1081 +#: src/scm/webid-oidc/errors.scm:1095 msgid "the jti field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1085 +#: src/scm/webid-oidc/errors.scm:1099 #, scheme-format msgid "the nonce field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1086 +#: src/scm/webid-oidc/errors.scm:1100 msgid "the nonce field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1090 +#: src/scm/webid-oidc/errors.scm:1104 #, scheme-format msgid "the htm field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1091 +#: src/scm/webid-oidc/errors.scm:1105 msgid "the htm field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1095 +#: src/scm/webid-oidc/errors.scm:1109 #, scheme-format msgid "the htu field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1096 +#: src/scm/webid-oidc/errors.scm:1110 msgid "the htu field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:1098 +#: src/scm/webid-oidc/errors.scm:1112 #, scheme-format msgid "~s is not an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1101 +#: src/scm/webid-oidc/errors.scm:1115 #, scheme-format msgid "~s is not an access token header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1104 +#: src/scm/webid-oidc/errors.scm:1118 #, scheme-format msgid "~s is not an access token payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1107 +#: src/scm/webid-oidc/errors.scm:1121 #, scheme-format msgid "~s is not a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1110 +#: src/scm/webid-oidc/errors.scm:1124 #, scheme-format msgid "~s is not a DPoP proof header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1113 +#: src/scm/webid-oidc/errors.scm:1127 #, scheme-format msgid "~s is not a DPoP proof payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1116 +#: src/scm/webid-oidc/errors.scm:1130 #, scheme-format msgid "I cannot fetch the issuer configuration of ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1123 +#: src/scm/webid-oidc/errors.scm:1137 #, scheme-format msgid "I cannot fetch the JWKS of ~a at ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1134 +#: src/scm/webid-oidc/errors.scm:1148 #, scheme-format msgid "the HTTP method is signed for ~s, but ~s was requested" msgstr "" -#: src/scm/webid-oidc/errors.scm:1137 +#: src/scm/webid-oidc/errors.scm:1151 #, scheme-format msgid "the HTTP uri is signed for ~a, but ~a was requested" msgstr "" -#: src/scm/webid-oidc/errors.scm:1140 +#: src/scm/webid-oidc/errors.scm:1154 #, 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:1144 +#: src/scm/webid-oidc/errors.scm:1158 #, 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:1153 +#: src/scm/webid-oidc/errors.scm:1167 #, scheme-format msgid "the key ~s does not hash to ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1155 +#: src/scm/webid-oidc/errors.scm:1169 #, scheme-format msgid "the key confirmation of ~s failed (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1157 +#: src/scm/webid-oidc/errors.scm:1171 #, scheme-format msgid "the key confirmation of ~s failed" msgstr "" -#: src/scm/webid-oidc/errors.scm:1159 +#: src/scm/webid-oidc/errors.scm:1173 #, scheme-format msgid "the jti ~s has already been found (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1162 +#: src/scm/webid-oidc/errors.scm:1176 #, scheme-format msgid "I cannot decode ~s as an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1165 +#: src/scm/webid-oidc/errors.scm:1179 #, scheme-format msgid "I cannot encode ~s as an access token with key ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1168 +#: src/scm/webid-oidc/errors.scm:1182 #, scheme-format msgid "I cannot decode ~s as a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1171 +#: src/scm/webid-oidc/errors.scm:1185 #, scheme-format msgid "I cannot encode ~s as a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1174 +#: src/scm/webid-oidc/errors.scm:1188 #, scheme-format msgid "I could not fetch a RDF graph at ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1177 +#: src/scm/webid-oidc/errors.scm:1191 #, scheme-format msgid "~s is not a client manifest (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1180 +#: src/scm/webid-oidc/errors.scm:1194 #, scheme-format msgid "~s does not authorize redirection URI ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1183 +#: src/scm/webid-oidc/errors.scm:1197 msgid "I cannot serve a public manifest" msgstr "" -#: src/scm/webid-oidc/errors.scm:1185 +#: src/scm/webid-oidc/errors.scm:1199 #, scheme-format msgid "~a does not have a client manifest registration triple" msgstr "" -#: src/scm/webid-oidc/errors.scm:1188 +#: src/scm/webid-oidc/errors.scm:1202 #, scheme-format msgid "the client manifest at ~a is advertised for ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1191 +#: src/scm/webid-oidc/errors.scm:1205 #, scheme-format msgid "I could not fetch the client manifest of ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1194 +#: src/scm/webid-oidc/errors.scm:1208 #, scheme-format msgid "~s is not an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1197 +#: src/scm/webid-oidc/errors.scm:1211 #, scheme-format msgid "~s is not an authorization code header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1200 +#: src/scm/webid-oidc/errors.scm:1214 #, scheme-format msgid "~s is not an authorization code payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1203 +#: src/scm/webid-oidc/errors.scm:1217 #, scheme-format msgid "the current time is ~a, and the authorization code expired at ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1207 +#: src/scm/webid-oidc/errors.scm:1221 #, scheme-format msgid "I cannot decode ~s as an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1210 +#: src/scm/webid-oidc/errors.scm:1224 #, scheme-format msgid "I cannot encode ~s as an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1213 +#: src/scm/webid-oidc/errors.scm:1227 #, scheme-format msgid "there is no such refresh token as ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1216 +#: src/scm/webid-oidc/errors.scm:1230 #, 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:1219 +#: src/scm/webid-oidc/errors.scm:1233 #, scheme-format msgid "I cannot decode ~s as an ID token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1222 +#: src/scm/webid-oidc/errors.scm:1236 #, scheme-format msgid "I cannot encode ~s as an ID token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1225 +#: src/scm/webid-oidc/errors.scm:1239 #, scheme-format msgid "the grant type ~s is not supported" msgstr "" -#: src/scm/webid-oidc/errors.scm:1228 +#: src/scm/webid-oidc/errors.scm:1242 msgid "there is no authorization code in the request" msgstr "" -#: src/scm/webid-oidc/errors.scm:1230 +#: src/scm/webid-oidc/errors.scm:1244 msgid "there is no refresh token in the request" msgstr "" -#: src/scm/webid-oidc/errors.scm:1232 +#: src/scm/webid-oidc/errors.scm:1246 #, scheme-format msgid "~s is not an ID token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1235 +#: src/scm/webid-oidc/errors.scm:1249 #, scheme-format msgid "~s is not an ID token header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1238 +#: src/scm/webid-oidc/errors.scm:1252 #, scheme-format msgid "~s is not an ID token payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1241 +#: src/scm/webid-oidc/errors.scm:1255 #, 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:1244 +#: src/scm/webid-oidc/errors.scm:1258 #, scheme-format msgid "~s does not admit ~s as an identity provider" msgstr "" -#: src/scm/webid-oidc/errors.scm:1247 +#: src/scm/webid-oidc/errors.scm:1261 #, scheme-format msgid "" "~a is neither an identity provider (because ~a) nor a webid (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1252 +#: src/scm/webid-oidc/errors.scm:1266 #, scheme-format msgid "the token request failed (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1255 +#: src/scm/webid-oidc/errors.scm:1269 #, scheme-format msgid "you don’t have a refresh token for identity ~a certified by ~a in ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1260 +#: src/scm/webid-oidc/errors.scm:1274 #, scheme-format msgid "all identity provider candidates for ~a failed: ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1264 +#: src/scm/webid-oidc/errors.scm:1278 #, scheme-format msgid "~s failed (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:1267 +#: src/scm/webid-oidc/errors.scm:1281 msgid ", " msgstr "" -#: src/scm/webid-oidc/errors.scm:1269 +#: src/scm/webid-oidc/errors.scm:1283 #, scheme-format msgid "no resource has been found to serve URI path ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:1272 +#: src/scm/webid-oidc/errors.scm:1286 #, scheme-format msgid "no resource has been found to serve URI path ~s, but ~s exists" msgstr "" -#: src/scm/webid-oidc/errors.scm:1275 +#: src/scm/webid-oidc/errors.scm:1289 msgid "the root storage cannot be deleted" msgstr "" -#: src/scm/webid-oidc/errors.scm:1277 +#: src/scm/webid-oidc/errors.scm:1291 #, scheme-format msgid "the container ~s should be emptied before being deleted" msgstr "" -#: src/scm/webid-oidc/errors.scm:1282 +#: src/scm/webid-oidc/errors.scm:1294 +#, scheme-format +msgid "the group ~s cannot be fetched (because ~a)" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1300 msgid "that’s it" msgstr "" -#: src/scm/webid-oidc/errors.scm:1286 +#: src/scm/webid-oidc/errors.scm:1304 #, scheme-format msgid "~a and ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1289 +#: src/scm/webid-oidc/errors.scm:1307 #, scheme-format msgid "~a, ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1293 +#: src/scm/webid-oidc/errors.scm:1311 #, scheme-format msgid "the signature ~a does not match key ~s with payload ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1296 +#: src/scm/webid-oidc/errors.scm:1314 msgid "there is an undefined variable" msgstr "" -#: src/scm/webid-oidc/errors.scm:1298 +#: src/scm/webid-oidc/errors.scm:1316 #, scheme-format msgid "the origin is ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1301 +#: src/scm/webid-oidc/errors.scm:1319 #, scheme-format msgid "a message is attached: ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1304 +#: src/scm/webid-oidc/errors.scm:1322 #, scheme-format msgid "the values ~s are problematic" msgstr "" -#: src/scm/webid-oidc/errors.scm:1307 +#: src/scm/webid-oidc/errors.scm:1325 msgid "there is a kind and args" msgstr "" -#: src/scm/webid-oidc/errors.scm:1309 +#: src/scm/webid-oidc/errors.scm:1327 msgid "there is an assertion failure" msgstr "" -#: src/scm/webid-oidc/errors.scm:1311 +#: src/scm/webid-oidc/errors.scm:1329 #, scheme-format msgid "the program quits with code ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1314 +#: src/scm/webid-oidc/errors.scm:1332 msgid "the program cannot recover from this exception" msgstr "" -#: src/scm/webid-oidc/errors.scm:1316 +#: src/scm/webid-oidc/errors.scm:1334 +msgid "there is an external error" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1336 msgid "there is an error" msgstr "" -#: src/scm/webid-oidc/errors.scm:1318 +#: src/scm/webid-oidc/errors.scm:1338 #, scheme-format msgid "Unhandled exception type ~a." msgstr "" diff --git a/src/scm/webid-oidc/errors.scm b/src/scm/webid-oidc/errors.scm index 60e45f7..c6802d7 100644 --- a/src/scm/webid-oidc/errors.scm +++ b/src/scm/webid-oidc/errors.scm @@ -920,6 +920,20 @@ container-not-empty? container-not-empty-path) +(define-exception-type + &cannot-fetch-group + &warning + make-cannot-fetch-group + cannot-fetch-group? + (group-uri cannot-fetch-group-group-uri) + (cause cannot-fetch-group-cause)) + +(export &cannot-fetch-group + make-cannot-fetch-group + cannot-fetch-group? + cannot-fetch-group-group-uri + cannot-fetch-group-cause) + (define*-public (error->str err #:key (max-depth #f)) (if (record? err) (let* ((type (record-type-descriptor err)) @@ -1276,6 +1290,10 @@ ((&container-not-empty) (format #f (G_ "the container ~s should be emptied before being deleted") (get 'path))) + ((&cannot-fetch-group) + (format #f (G_ "the group ~s cannot be fetched (because ~a)" + (uri->string (get 'group-uri)) + (recurse (get 'cause))))) ((&compound-exception) (let ((components (get 'components))) (if (null? components) @@ -1312,6 +1330,8 @@ (get 'code))) ((&non-continuable) (format #f (G_ "the program cannot recover from this exception"))) + ((&external-error) + (format #f (G_ "there is an external error"))) ((&error) (format #f (G_ "there is an error"))) (else diff --git a/src/scm/webid-oidc/server/resource/Makefile.am b/src/scm/webid-oidc/server/resource/Makefile.am index 49cc912..efc41ce 100644 --- a/src/scm/webid-oidc/server/resource/Makefile.am +++ b/src/scm/webid-oidc/server/resource/Makefile.am @@ -1,7 +1,9 @@ dist_resourceserverwebidoidcmod_DATA += \ %reldir%/content.scm \ - %reldir%/path.scm + %reldir%/path.scm \ + %reldir%/wac.scm resourceserverwebidoidcgo_DATA += \ %reldir%/content.go \ - %reldir%/path.go + %reldir%/path.go \ + %reldir%/wac.go diff --git a/src/scm/webid-oidc/server/resource/wac.scm b/src/scm/webid-oidc/server/resource/wac.scm new file mode 100644 index 0000000..e482ce4 --- /dev/null +++ b/src/scm/webid-oidc/server/resource/wac.scm @@ -0,0 +1,226 @@ +(define-module (webid-oidc server resource wac) + #:use-module (webid-oidc errors) + #:use-module (webid-oidc server resource path) + #:use-module (webid-oidc server resource content) + #:use-module (webid-oidc cache) + #:use-module (webid-oidc fetch) + #:use-module ((webid-oidc stubs) #:prefix stubs:) + #:use-module (webid-oidc rdf-index) + #:use-module ((webid-oidc refresh-token) #:prefix refresh:) + #:use-module (web uri) + #:use-module (web client) + #:use-module (rdf rdf) + #:use-module (turtle tordf) + #:use-module (rnrs bytevectors) + #:use-module (ice-9 exceptions) + #:use-module (ice-9 receive) + #:use-module (ice-9 optargs) + #:use-module (ice-9 iconv) + #:use-module (ice-9 textual-ports) + #:use-module (ice-9 binary-ports) + #:use-module (ice-9 threads) + #:use-module (rnrs bytevectors) + #:use-module (oop goops) + #:export + ( + + wac-get-modes + + )) + +(define (group-member? http-get group-uri agent) + (when (string? group-uri) + (set! group-uri (string->uri group-uri))) + (when (string? agent) + (set! group-uri (string->uri agent))) + (let ((group-doc-uri + (build-uri (uri-scheme group-uri) + #:userinfo (uri-userinfo group-uri) + #:host (uri-host group-uri) + #:port (uri-port group-uri) + #:path (uri-path group-uri) + #:query (uri-query group-uri)))) + (with-exception-handler + (lambda (error) + (raise-exception + (make-cannot-fetch-group group-uri error) + #:continuable? #t) + #f) + (lambda () + (let ((data (fetch group-doc-uri #:http-get http-get))) + (with-index + data + (lambda (rdf-match) + (not (null? + (rdf-match (uri->string group-uri) + "http://www.w3.org/2006/vcard/ns#hasMember" + (uri->string agent)))))))) + #:unwind? #t + #:unwind-for-type &cannot-fetch-linked-data))) + +(define (with-rdf-source server-name path content-type static-content f) + (with-index + (case content-type + ((text/turtle) + (turtle->rdf (string-append + "# This is not a file name\n" + (utf8->string static-content)) + (uri->string + (build-uri (uri-scheme server-name) + #:userinfo (uri-userinfo server-name) + #:host (uri-host server-name) + #:port (uri-port server-name) + #:path (string-append path ".acl")))))) + f)) + +(define (check-authorization path check-default? server-name final-path http-get user rdf-match id) + ;; The authorization should give accessTo path, + ;; or to a prefix of final-path; and it should + ;; be for agent user, or a group that contains + ;; user. + (let ((access-to-ok + (and + ;; We’re looking for acl:accessTo targetting path + (not + (null? + (rdf-match id "http://www.w3.org/ns/auth/acl#accessTo" + (uri->string + (build-uri (uri-scheme server-name) + #:userinfo (uri-userinfo server-name) + #:host (uri-host server-name) + #:port (uri-port server-name) + #:path path))))) + (or (not check-default?) + ;; We’re also looking for acl:default statement + ;; targetting a prefix of final-path + (let ((defaults + (map rdf-triple-object + (rdf-match id "http://www.w3.org/ns/auth/acl#default" #f)))) + (define (default-ok? uri) + (and (string? uri) + (string->uri uri) + (let ((uri (string->uri uri))) + (and (eq? (uri-scheme uri) + (uri-scheme server-name)) + (equal? (uri-userinfo uri) + (uri-userinfo server-name)) + (equal? (uri-host uri) + (uri-host server-name)) + (equal? (uri-port uri) + (uri-port server-name)) + (let ((final-path-components + (split-and-decode-uri-path final-path)) + (default-components + (split-and-decode-uri-path (uri-path uri)))) + (define (prefix? x y) + (or (null? x) + (and (not (null? y)) + (equal? (car x) (car y)) + (prefix? (cdr x) (cdr y))))) + (prefix? default-components final-path-components)))))) + (not (null? (filter default-ok? defaults))))))) + (agent-ok + (let ((groups + (map rdf-triple-object + (rdf-match id + "http://www.w3.org/ns/auth/acl#agentGroup" + #f))) + (specific-agent-ok? + (and user + (not (null? + (rdf-match id + "http://www.w3.org/ns/auth/acl#agent" + (uri->string user)))))) + (public-access? + (not (null? + (rdf-match id + "http://www.w3.org/ns/auth/acl#agentClass" + "http://xmlns.com/foaf/0.1/Agent")))) + (authenticated-access? + (not (null? + (rdf-match id + "http://www.w3.org/ns/auth/acl#agentClass" + "http://www.w3.org/ns/auth/acl#AuthenticatedAgent"))))) + (or public-access? + (and user authenticated-access?) + specific-agent-ok? + (and user + (not (null? + (filter (lambda (group) + (group-member? http-get group user)) + groups)))))))) + (or + (and access-to-ok + agent-ok + (filter + (lambda (x) x) + (map (lambda (triple) + (let ((mode (rdf-triple-object triple))) + (and (string? mode) + (string->uri mode)))) + (rdf-match id + "http://www.w3.org/ns/auth/acl#mode" + #f)))) + '()))) + +(define (check-authorizations path check-default? server-name final-path http-get user rdf-match + allowed-modes authorizations) + (if (null? authorizations) + (reverse allowed-modes) + (let ((new-modes + (check-authorization path check-default? server-name final-path http-get user rdf-match + (car authorizations)))) + (check-authorizations + path check-default? server-name final-path http-get user rdf-match + (append (reverse new-modes) allowed-modes) + (cdr authorizations))))) + +(define acl-aux (string->uri "http://www.w3.org/ns/auth/acl#accessControl")) + +(define* (wac-get-modes server-name final-path user + #:key + (http-get http-get)) + (with-session + (lambda (content-type contained static-content create delete) + (define (wac-check-recursive path check-default?) + (receive (main-etag auxiliary) (read-path path) + (let ((acl-etag (assoc-ref auxiliary acl-aux))) + (if acl-etag + (with-rdf-source + server-name path (content-type acl-etag) (static-content acl-etag) + (lambda (rdf-match) + (check-authorizations + path check-default? server-name final-path http-get user rdf-match + '() + (map rdf-triple-subject + (rdf-match #f + "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" + "http://www.w3.org/ns/auth/acl#Authorization"))))) + ;; No existing ACL. + (let ((parent-path + (string-append + "/" + (encode-and-join-uri-path + (reverse + (cdr + (reverse + (split-and-decode-uri-path path))))) + "/"))) + (when (equal? parent-path "//") + ;; The parent is the root + (set! parent-path "/")) + (wac-check-recursive parent-path #t)))))) + (let ((all-modes (wac-check-recursive final-path #f))) + (define (accumulate-unique accumulated list) + (cond + ((null? list) + (reverse accumulated)) + ((or (null? accumulated) (not (equal? (car accumulated) (car list)))) + (accumulate-unique (cons (car list) accumulated) (cdr list))) + (else + (accumulate-unique accumulated (cdr list))))) + (accumulate-unique + '() + (sort all-modes + (lambda (a b) + (string< (uri->string a) (uri->string b))))))))) diff --git a/tests/Makefile.am b/tests/Makefile.am index 4d7fda4..34f0964 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -43,7 +43,8 @@ TESTS = %reldir%/load-library.scm \ %reldir%/client-manifest-not-modified.scm \ %reldir%/server-content.scm \ %reldir%/server-path.scm \ - %reldir%/http-link.scm + %reldir%/http-link.scm \ + %reldir%/acl.scm EXTRA_DIST += $(TESTS) %reldir%/ChangeLog diff --git a/tests/acl-with-group.scm b/tests/acl-with-group.scm new file mode 100644 index 0000000..210cc21 --- /dev/null +++ b/tests/acl-with-group.scm @@ -0,0 +1,11 @@ +(define (http-get uri) + (unless (equal? uri + (string->uri "https://group-server.example.com/the#group")) + (exit 1) + (values + (build-response #:headers '((content-type text/turtle))) + "@prefix vcard: . + +<#group> a vcard:Group; + vcard:hasMember . +"))) diff --git a/tests/acl.scm b/tests/acl.scm new file mode 100644 index 0000000..b582b17 --- /dev/null +++ b/tests/acl.scm @@ -0,0 +1,249 @@ +(use-modules (webid-oidc server resource wac) + (webid-oidc server resource content) + (webid-oidc server resource path) + (webid-oidc testing) + (web http) + (web request) + (web response) + (web uri)) + +(define (http-get uri . other-args) + (when (string? uri) + (set! uri (string->uri uri))) + (unless (equal? uri + (string->uri "https://fbi.databox.me/group")) + (format (current-error-port) + "Expected:\n ~s, got:\n ~s\n" uri (string->uri "https://fbi.databox.me/group")) + (exit 1)) + (values + (build-response #:headers '((content-type text/turtle))) + "@prefix vcard: . + +<#spies> a vcard:Group; + vcard:hasMember . +")) + +(with-test-environment + "direct-acl" + (lambda () + (for-each + (lambda (f) + (false-if-exception + (delete-file + (string-append + "tests/direct-acl.home/webid-oidc/server/content/" + f)))) + '("6/8OMG_V5x-KmI6TI" + "X/hqM_2Avn5_egTzs" + "a/68pTwiImTWTpjQl" + "5/n1KPgAd3ng4wSqn" + "D/wxU0ogx5rzRrvu2" + "F/BQKBGrtq6U_M0L7" + "n/U46BXbknEaLWZpH" + "N/gnO8RAS9FpPiO5j" + "A/fkGTJRCHc-jHk-V" + "H/y4S5p1BqTEJi-Jb" + "b/k7RqZevpCHAumba" + "y/29x0MEOMybxUqDU" + "5/KVojpXDg0Aob3_v")) + (with-session + (lambda (content-type contained static-content create delete) + ;; In this little scenario: + ;; / can only be listed by Alice and the FBI + ;; /docs/ can only be updated by Alice and the public can list + ;; /docs/file1 can only be updated by Alice, but public + ;; /docs/file2 same, but authenticated + ;; /private-docs/ private to Alice, no ACL + ;; /private-docs/file1 no ACL (so, readable by the FBI as inherited in /) + ;; /private/docs/file2 no ACL (so, not readable by the FBI) + (let ((/ (create 'text/turtle '("docs" "private-docs") "")) + (/docs/ (create 'text/turtle '("file1" "file2") "")) + (/docs/file1 (create 'text/plain #f "Hello :)")) + (/docs/file2 (create 'text/plain #f "You’re authenticated :)")) + (/private-docs/ (create 'text/turtle '("file1") "")) + (/private-docs/file1 (create 'text/plain #f "Private, but FBI can read!")) + (/private-docs/file2 (create 'text/plain #f "Private!")) + (/.acl (create 'text/turtle #f "@prefix acl: . + +<#default> + a acl:Authorization; + acl:accessTo ; + acl:agent ; + acl:mode acl:Read, acl:Write, acl:Control; + acl:default . + +<#for-the-fbi> + a acl:Authorization; + acl:accessTo ; + acl:agentGroup ; + acl:mode acl:Read, acl:Write; + acl:default . +")) + (/docs/.acl (create 'text/turtle #f "@prefix acl: . +@prefix foaf: . + +<#default> + a acl:Authorization; + acl:accessTo ; + acl:agent ; + acl:mode acl:Read, acl:Write, acl:Control. + +<#anyone-can-list-files> + a acl:Authorization; + acl:accessTo ; + acl:agentClass foaf:Agent; + acl:mode acl:Read. +")) + (/docs/file1.acl (create 'text/turtle #f "@prefix acl: . +@prefix foaf: . + +<#default> + a acl:Authorization; + acl:accessTo ; + acl:agent ; + acl:mode acl:Read, acl:Write, acl:Control. + +<#public> + a acl:Authorization; + acl:accessTo ; + acl:agentClass foaf:Agent; + acl:mode acl:Read. +")) + (/docs/file2.acl (create 'text/turtle #f "@prefix acl: . + +<#default> + a acl:Authorization; + acl:accessTo ; + acl:agent ; + acl:mode acl:Read, acl:Write, acl:Control. + +<#public> + a acl:Authorization; + acl:accessTo ; + acl:agentClass acl:AuthenticatedAgent; + acl:mode acl:Read. +"))) + (update-path + "/" + (lambda (main auxiliary) + (values / + `((,(string->uri "http://www.w3.org/ns/auth/acl#accessControl") + . ,/.acl)))) + content-type contained static-content create delete) + (update-path + "/docs/" + (lambda (main auxiliary) + (values /docs/ + `((,(string->uri "http://www.w3.org/ns/auth/acl#accessControl") + . ,/docs/.acl)))) + content-type contained static-content create delete) + (update-path + "/docs/file1" + (lambda (main auxiliary) + (values /docs/file1 + `((,(string->uri "http://www.w3.org/ns/auth/acl#accessControl") + . ,/docs/file1.acl)))) + content-type contained static-content create delete) + (update-path + "/docs/file2" + (lambda (main auxiliary) + (values /docs/file2 + `((,(string->uri "http://www.w3.org/ns/auth/acl#accessControl") + . ,/docs/file2.acl)))) + content-type contained static-content create delete) + (update-path + "/private-docs/" + (lambda (main auxiliary) + (values /private-docs/ '())) + content-type contained static-content create delete) + (update-path + "/private-docs/file1" + (lambda (main auxiliary) + (values /private-docs/file1 '())) + content-type contained static-content create delete) + (update-path + "/private-docs/file2" + (lambda (main auxiliary) + (values /private-docs/file2 '())) + content-type contained static-content create delete) + (let ((server-name + (string->uri "https://alice.databox.me"))) + ;; Who can access what? + ;; Alice: https://alice.databox.me/profile/card#me + ;; Bob: https://bob.databox.me/profile/card#me (authenticated) + ;; FBI: https://the-spy.databox.me/profile/card#me + ;; Anonymous + ;; + ;; Alice Bob FBI Anonymous + ;; / RWC X RW X + ;; /docs/ RWC R R R + ;; /docs/file1 RWC R R R + ;; /docs/file2 RWC R R X + ;; /private-docs/ RWC X X X + ;; /private-docs/file1 RWC X RW X + ;; /private-docs/file2 RWC X X X + (define (run-test path modes-alice modes-bob modes-fbi modes-anonymous) + (define (uri< a b) + (string< (uri->string a) (uri->string b))) + (let ((alice (wac-get-modes + server-name path + (string->uri "https://alice.databox.me/profile/card#me") + #:http-get http-get)) + (bob (wac-get-modes + server-name path + (string->uri "https://bob.databox.me/profile/card#me") + #:http-get http-get)) + (fbi (wac-get-modes + server-name path + (string->uri "https://the-spy.databox.me/profile/card#me") + #:http-get http-get)) + (anonymous (wac-get-modes + server-name path + #f + #:http-get http-get))) + (unless (equal? alice + modes-alice) + (format (current-error-port) + "Alice’s modes for path ~s:\n expected:\n ~s\n got:\n ~s\n" + path + (map uri->string modes-alice) + (map uri->string alice)) + (exit 2)) + (unless (equal? bob + modes-bob) + (format (current-error-port) + "Bob’s modes for path ~s:\n expected:\n ~s\n got:\n ~s\n" + path + (map uri->string modes-bob) + (map uri->string bob)) + (exit 3)) + (unless (equal? fbi + modes-fbi) + (format (current-error-port) + "Spy’s modes for path ~s:\n expected:\n ~s\n got:\n ~s\n" + path + (map uri->string modes-fbi) + (map uri->string fbi)) + (exit 4)) + (unless (equal? anonymous + modes-anonymous) + (format (current-error-port) + "Anonymous modes for path ~s:\n expected:\n ~s\n got:\n ~s\n" + path + (map uri->string modes-anonymous) + (map uri->string anonymous)) + (exit 5)))) + (let ((read (string->uri "http://www.w3.org/ns/auth/acl#Read")) + (write (string->uri "http://www.w3.org/ns/auth/acl#Write")) + (control (string->uri "http://www.w3.org/ns/auth/acl#Control"))) + (let ((RWC (list control read write)) + (R (list read)) + (RW (list read write)) + (X '())) + (run-test "/" RWC X RW X) + (run-test "/docs/" RWC R R R) + (run-test "/docs/file1" RWC R R R) + (run-test "/docs/file2" RWC R R X) + (run-test "/private-docs/" RWC X X X) + (run-test "/private-docs/file1" RWC X RW X) + (run-test "/private-docs/file2" RWC X X X))))))))) -- cgit v1.2.3