From 50fe27d1fbe624ec9d3d7d5b236a6a8abc8e282c Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Fri, 7 May 2021 14:37:34 +0200 Subject: Add a demonstration program --- bootstrap | 2 +- doc/webid-oidc.texi | 5 + guix/vkraus/packages/webid-oidc.scm | 2 +- man/Makefile.am | 4 + po/POTFILES.in | 1 + po/fr.po | 283 +++++++++++++++++++----------------- po/webid-oidc.pot | 111 +++++++++++++- src/Makefile.am | 2 +- src/scm/webid-oidc/Makefile.am | 6 +- src/scm/webid-oidc/example-app.scm | 214 +++++++++++++++++++++++++++ src/webid-oidc-example-app | 7 + 11 files changed, 499 insertions(+), 138 deletions(-) create mode 100644 src/scm/webid-oidc/example-app.scm create mode 100755 src/webid-oidc-example-app diff --git a/bootstrap b/bootstrap index 9bb00e8..aa4e6db 100755 --- a/bootstrap +++ b/bootstrap @@ -4,7 +4,7 @@ autoreconf -vif || exit 1 sed -i 's|SHELL = /bin/sh|SHELL = @SHELL@|g' po/Makefile.in.in || exit 1 ## Prepare the man pages -SCRIPTS_THAT_GET_EXECUTED="../src/webid-oidc-issuer ../src/webid-oidc-reverse-proxy ../src/webid-oidc-client-service" +SCRIPTS_THAT_GET_EXECUTED="../src/webid-oidc-issuer ../src/webid-oidc-reverse-proxy ../src/webid-oidc-client-service ../src/webid-oidc-example-app" mkdir -p .native || exit 1 cd .native || exit 1 diff --git a/doc/webid-oidc.texi b/doc/webid-oidc.texi index b9c9f65..fb8bf63 100644 --- a/doc/webid-oidc.texi +++ b/doc/webid-oidc.texi @@ -614,6 +614,11 @@ requests. used to issue DPoP proofs. @end deffn +An example application is provided as the +@code{webid-oidc-example-app} program. It demonstrates how +authentication is done. It should help you understand how webid-oidc +works. + The identity provider needs to call the application on the web. So, your client should have a public endpoint on the web. diff --git a/guix/vkraus/packages/webid-oidc.scm b/guix/vkraus/packages/webid-oidc.scm index 8d80cb5..b4d0aa2 100644 --- a/guix/vkraus/packages/webid-oidc.scm +++ b/guix/vkraus/packages/webid-oidc.scm @@ -79,7 +79,7 @@ (format #f "~a/bin/webid-oidc-~a" out program) `("GUILE_LOAD_PATH" ":" = ,mod-paths) `("GUILE_LOAD_COMPILED_PATH" ":" = ,go-paths))) - '(client-service hello issuer reverse-proxy)))))))) + '(client-service example-app hello issuer reverse-proxy)))))))) (native-inputs `(("pkg-config" ,pkg-config) ("guile" ,guile-3.0) diff --git a/man/Makefile.am b/man/Makefile.am index 5a80f50..54e5e15 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -13,3 +13,7 @@ webid-oidc-reverse-proxy.man: ../src/scm/webid-oidc/reverse-proxy.scm ../configu webid-oidc-client-service.man: ../src/scm/webid-oidc/client.scm ../configure.ac $(AM_V_GEN) ../pre-inst-env ./reset-env $(HELP2MAN) $(srcdir)/../src/webid-oidc-client-service > $@-t mv $@-t $(srcdir)/$@ + +webid-oidc-example-app.man: ../src/scm/webid-oidc/example-app.scm ../configure.ac + $(AM_V_GEN) ../pre-inst-env ./reset-env $(HELP2MAN) $(srcdir)/../src/webid-oidc-example-app > $@-t + mv $@-t $(srcdir)/$@ diff --git a/po/POTFILES.in b/po/POTFILES.in index dffc889..1dd9e41 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -13,3 +13,4 @@ src/scm/webid-oidc/resource-server.scm src/scm/webid-oidc/reverse-proxy.scm src/scm/webid-oidc/hello-world.scm src/scm/webid-oidc/client.scm +src/scm/webid-oidc/example-app.scm diff --git a/po/fr.po b/po/fr.po index a3cd5cc..3af1d8e 100644 --- a/po/fr.po +++ b/po/fr.po @@ -2,7 +2,7 @@ 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:21+0200\n" +"POT-Creation-Date: 2021-06-05 16:22+0200\n" "PO-Revision-Date: 2021-06-05 11:07+0200\n" "Last-Translator: Vivien Kraus \n" "Language-Team: French \n" @@ -743,11 +743,13 @@ msgstr "Attention : génération d'une nouvelle paire de clé." #: src/scm/webid-oidc/identity-provider.scm:148 #: src/scm/webid-oidc/reverse-proxy.scm:124 #: src/scm/webid-oidc/hello-world.scm:31 src/scm/webid-oidc/client.scm:618 +#: src/scm/webid-oidc/example-app.scm:100 msgid "command-line|version" msgstr "version" #: src/scm/webid-oidc/identity-provider.scm:150 #: src/scm/webid-oidc/hello-world.scm:33 src/scm/webid-oidc/client.scm:620 +#: src/scm/webid-oidc/example-app.scm:102 msgid "comand-line|help" msgstr "aide" @@ -943,6 +945,7 @@ msgstr "" #: src/scm/webid-oidc/identity-provider.scm:267 #: src/scm/webid-oidc/reverse-proxy.scm:210 #: src/scm/webid-oidc/hello-world.scm:61 src/scm/webid-oidc/client.scm:699 +#: src/scm/webid-oidc/example-app.scm:143 #, scheme-format msgid "~a version ~a\n" msgstr "~a version ~a\n" @@ -1431,6 +1434,153 @@ msgstr "Vous devez définir l'URI de redirection.\n" msgid "The client URI should be an URI.\n" msgstr "L’URI du client doit être un URI.\n" +#: src/scm/webid-oidc/example-app.scm:35 +#, scheme-format +msgid "~a.\t~a, certified by ~a;\n" +msgstr "~a.\t~a, certifié par ~a ;\n" + +#: src/scm/webid-oidc/example-app.scm:46 +#, scheme-format +msgid "~a – ~a\n" +msgstr "~a – ~a\n" + +#: src/scm/webid-oidc/example-app.scm:65 +#, scheme-format +msgid "I’m expecting a number between ~a and ~a.\n" +msgstr "J’attends un nombre entre ~a et ~a.\n" + +#: src/scm/webid-oidc/example-app.scm:72 +msgid "Please enter an URI to GET: " +msgstr "Veuillez entrer un URI à requêter avec GET :" + +#: src/scm/webid-oidc/example-app.scm:91 +#, scheme-format +msgid "Sending a request: ~s\n" +msgstr "Envoi d’une requête : ~s\n" + +#: src/scm/webid-oidc/example-app.scm:110 +#, scheme-format +msgid "" +"Usage: ~a [OPTIONS]...\n" +"\n" +"Demonstrate a webid-oidc application.\n" +"\n" +"Options:\n" +" -h, --~a:\n" +" display this help message and exit.\n" +" -v, --~a:\n" +" display the version information (~a) and exit.\n" +"\n" +"Environment variables:\n" +"\n" +" LANG: set the locale. Currently ~a.\n" +"\n" +" XDG_CACHE_HOME: where the seed for the key generator is\n" +"stored. Currently ~a.\n" +"\n" +" XDG_DATA_HOME: where the login credentials are stored. Currently ~a.\n" +"\n" +" HOME: to compute a default value for XDG_CACHE_HOME and\n" +"XDG_DATA_HOME, if missing. Currently ~a.\n" +"\n" +"If you find a bug, send a report to ~a.\n" +msgstr "" +"Utilisation : ~a [OPTIONS]...\n" +"\n" +"Fait démonstration d’une application webid-oidc.\n" +"\n" +"Options :\n" +" -h, --~a :\n" +" affiche ce message d’aide et quitte.\n" +" -v, --~a :\n" +" affiche le numéro de version (~a) et quitte.\n" +"\n" +"Variables d’environnement :\n" +"\n" +" LANG : définit la locale. Actuellement ~a.\n" +"\n" +" XDG_CACHE_HOME : où stocker la graine aléatoire du générateur de\n" +"clé. Actuellement ~a.\n" +"\n" +" XDG_DATA_HOME : où les données d’authentification sont\n" +"stockées. Actuellement ~a.\n" +"\n" +" HOME : pour calculer une valeur par défaut de XDG_CACHE_HOME et\n" +"XDG_DATA_HOME, si manquant. Actuellement ~a.\n" +"\n" +"Si vous trouvez une erreur dans le programme, envoyez-en un rapport à\n" +"~a.\n" + +#: src/scm/webid-oidc/example-app.scm:147 +msgid "First, let’s log in. Here are your options:\n" +msgstr "En premier lieu, authentifions-nous. Voici vos options :\n" + +#: src/scm/webid-oidc/example-app.scm:149 +msgid "0.\tLog in with a different identity.\n" +msgstr "0.\tS’authentifier avec une identité différente.\n" + +#: src/scm/webid-oidc/example-app.scm:154 +#: src/scm/webid-oidc/example-app.scm:173 +msgid "Please indicate your choice number: " +msgstr "Veuillez indiquer votre choix de numéro : " + +#: src/scm/webid-oidc/example-app.scm:159 +msgid "Please enter your webid, or identity server: " +msgstr "Veuillez entrer votre webid, ou serveur d’identité : " + +#: src/scm/webid-oidc/example-app.scm:169 +msgid "There are different possible identity providers for your webid:\n" +msgstr "" +"Il y a différents fournisseurs d’identité possibles pour votre\n" +"webid :\n" + +#: src/scm/webid-oidc/example-app.scm:176 +#, scheme-format +msgid "" +"Please visit the following URI with a web browser:\n" +"~a\n" +msgstr "" +"Veuillez accéder à cet URI avec un navigateur web :\n" +"~a\n" + +#: src/scm/webid-oidc/example-app.scm:178 +msgid "Please paste your authorization code: " +msgstr "Veuillez coller votre code d’autorisation : " + +#: src/scm/webid-oidc/example-app.scm:189 +#, scheme-format +msgid "" +"Log in success. Keep this identity token for yourself:\n" +"\n" +"~a\n" +"\n" +"Now, you can do authenticated request by presenting the following access " +"token:\n" +"\n" +"~a\n" +"\n" +"and signing DPoP proofs with the following key:\n" +"\n" +"~a\n" +msgstr "" +"Authentification réussie. Gardez ce jeton d’identité pour vous :\n" +"\n" +"~a\n" +"\n" +"À partir de maintenant, vous pouvez effectuer des requêtes\n" +"authentifiées en présentant le jeton d’accès suivant :\n" +"\n" +"~a\n" +"\n" +"et en signant les preuves DPoP avec la clé suivante :\n" +"\n" +"~a\n" + +#: src/scm/webid-oidc/example-app.scm:210 +#, scheme-format +msgid "There was an error: ~a\n" +msgstr "Il y a eu une erreur : ~a\n" + #, scheme-format #~ msgid "the resource ~s could not be found (because ~a)" #~ msgstr "la ressource ~s n’a pas été trouvée (parce que ~a)" @@ -1485,137 +1635,6 @@ msgstr "L’URI du client doit être un URI.\n" #~ msgid "there is an external error" #~ msgstr "il y a une erreur externe" -#, scheme-format -#~ msgid "~a.\t~a, certified by ~a;\n" -#~ msgstr "~a.\t~a, certifié par ~a ;\n" - -#, scheme-format -#~ msgid "~a – ~a\n" -#~ msgstr "~a – ~a\n" - -#, scheme-format -#~ msgid "I’m expecting a number between ~a and ~a.\n" -#~ msgstr "J’attends un nombre entre ~a et ~a.\n" - -#~ msgid "Please enter an URI to GET: " -#~ msgstr "Veuillez entrer un URI à requêter avec GET :" - -#, scheme-format -#~ msgid "Sending a request: ~s\n" -#~ msgstr "Envoi d’une requête : ~s\n" - -#, scheme-format -#~ msgid "" -#~ "Usage: ~a [OPTIONS]...\n" -#~ "\n" -#~ "Demonstrate a webid-oidc application.\n" -#~ "\n" -#~ "Options:\n" -#~ " -h, --~a:\n" -#~ " display this help message and exit.\n" -#~ " -v, --~a:\n" -#~ " display the version information (~a) and exit.\n" -#~ "\n" -#~ "Environment variables:\n" -#~ "\n" -#~ " LANG: set the locale. Currently ~a.\n" -#~ "\n" -#~ " XDG_CACHE_HOME: where the seed for the key generator is\n" -#~ "stored. Currently ~a.\n" -#~ "\n" -#~ " XDG_DATA_HOME: where the login credentials are stored. Currently ~a.\n" -#~ "\n" -#~ " HOME: to compute a default value for XDG_CACHE_HOME and\n" -#~ "XDG_DATA_HOME, if missing. Currently ~a.\n" -#~ "\n" -#~ "If you find a bug, send a report to ~a.\n" -#~ msgstr "" -#~ "Utilisation : ~a [OPTIONS]...\n" -#~ "\n" -#~ "Fait démonstration d’une application webid-oidc.\n" -#~ "\n" -#~ "Options :\n" -#~ " -h, --~a :\n" -#~ " affiche ce message d’aide et quitte.\n" -#~ " -v, --~a :\n" -#~ " affiche le numéro de version (~a) et quitte.\n" -#~ "\n" -#~ "Variables d’environnement :\n" -#~ "\n" -#~ " LANG : définit la locale. Actuellement ~a.\n" -#~ "\n" -#~ " XDG_CACHE_HOME : où stocker la graine aléatoire du générateur de\n" -#~ "clé. Actuellement ~a.\n" -#~ "\n" -#~ " XDG_DATA_HOME : où les données d’authentification sont\n" -#~ "stockées. Actuellement ~a.\n" -#~ "\n" -#~ " HOME : pour calculer une valeur par défaut de XDG_CACHE_HOME et\n" -#~ "XDG_DATA_HOME, si manquant. Actuellement ~a.\n" -#~ "\n" -#~ "Si vous trouvez une erreur dans le programme, envoyez-en un rapport à\n" -#~ "~a.\n" - -#~ msgid "First, let’s log in. Here are your options:\n" -#~ msgstr "En premier lieu, authentifions-nous. Voici vos options :\n" - -#~ msgid "0.\tLog in with a different identity.\n" -#~ msgstr "0.\tS’authentifier avec une identité différente.\n" - -#~ msgid "Please indicate your choice number: " -#~ msgstr "Veuillez indiquer votre choix de numéro : " - -#~ msgid "Please enter your webid, or identity server: " -#~ msgstr "Veuillez entrer votre webid, ou serveur d’identité : " - -#~ msgid "There are different possible identity providers for your webid:\n" -#~ msgstr "" -#~ "Il y a différents fournisseurs d’identité possibles pour votre\n" -#~ "webid :\n" - -#, scheme-format -#~ msgid "" -#~ "Please visit the following URI with a web browser:\n" -#~ "~a\n" -#~ msgstr "" -#~ "Veuillez accéder à cet URI avec un navigateur web :\n" -#~ "~a\n" - -#~ msgid "Please paste your authorization code: " -#~ msgstr "Veuillez coller votre code d’autorisation : " - -#, scheme-format -#~ msgid "" -#~ "Log in success. Keep this identity token for yourself:\n" -#~ "\n" -#~ "~a\n" -#~ "\n" -#~ "Now, you can do authenticated request by presenting the following access " -#~ "token:\n" -#~ "\n" -#~ "~a\n" -#~ "\n" -#~ "and signing DPoP proofs with the following key:\n" -#~ "\n" -#~ "~a\n" -#~ msgstr "" -#~ "Authentification réussie. Gardez ce jeton d’identité pour vous :\n" -#~ "\n" -#~ "~a\n" -#~ "\n" -#~ "À partir de maintenant, vous pouvez effectuer des requêtes\n" -#~ "authentifiées en présentant le jeton d’accès suivant :\n" -#~ "\n" -#~ "~a\n" -#~ "\n" -#~ "et en signant les preuves DPoP avec la clé suivante :\n" -#~ "\n" -#~ "~a\n" - -#, scheme-format -#~ msgid "There was an error: ~a\n" -#~ msgstr "Il y a eu une erreur : ~a\n" - #, 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 306f186..fdfad63 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:21+0200\n" +"POT-Creation-Date: 2021-06-05 16:22+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -722,11 +722,13 @@ msgstr "" #: src/scm/webid-oidc/identity-provider.scm:148 #: src/scm/webid-oidc/reverse-proxy.scm:124 #: src/scm/webid-oidc/hello-world.scm:31 src/scm/webid-oidc/client.scm:618 +#: src/scm/webid-oidc/example-app.scm:100 msgid "command-line|version" msgstr "" #: src/scm/webid-oidc/identity-provider.scm:150 #: src/scm/webid-oidc/hello-world.scm:33 src/scm/webid-oidc/client.scm:620 +#: src/scm/webid-oidc/example-app.scm:102 msgid "comand-line|help" msgstr "" @@ -849,6 +851,7 @@ msgstr "" #: src/scm/webid-oidc/identity-provider.scm:267 #: src/scm/webid-oidc/reverse-proxy.scm:210 #: src/scm/webid-oidc/hello-world.scm:61 src/scm/webid-oidc/client.scm:699 +#: src/scm/webid-oidc/example-app.scm:143 #, scheme-format msgid "~a version ~a\n" msgstr "" @@ -1215,3 +1218,109 @@ msgstr "" #: src/scm/webid-oidc/client.scm:730 msgid "The client URI should be an URI.\n" msgstr "" + +#: src/scm/webid-oidc/example-app.scm:35 +#, scheme-format +msgid "~a.\t~a, certified by ~a;\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:46 +#, scheme-format +msgid "~a – ~a\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:65 +#, scheme-format +msgid "I’m expecting a number between ~a and ~a.\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:72 +msgid "Please enter an URI to GET: " +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:91 +#, scheme-format +msgid "Sending a request: ~s\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:110 +#, scheme-format +msgid "" +"Usage: ~a [OPTIONS]...\n" +"\n" +"Demonstrate a webid-oidc application.\n" +"\n" +"Options:\n" +" -h, --~a:\n" +" display this help message and exit.\n" +" -v, --~a:\n" +" display the version information (~a) and exit.\n" +"\n" +"Environment variables:\n" +"\n" +" LANG: set the locale. Currently ~a.\n" +"\n" +" XDG_CACHE_HOME: where the seed for the key generator is\n" +"stored. Currently ~a.\n" +"\n" +" XDG_DATA_HOME: where the login credentials are stored. Currently ~a.\n" +"\n" +" HOME: to compute a default value for XDG_CACHE_HOME and\n" +"XDG_DATA_HOME, if missing. Currently ~a.\n" +"\n" +"If you find a bug, send a report to ~a.\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:147 +msgid "First, let’s log in. Here are your options:\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:149 +msgid "0.\tLog in with a different identity.\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:154 +#: src/scm/webid-oidc/example-app.scm:173 +msgid "Please indicate your choice number: " +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:159 +msgid "Please enter your webid, or identity server: " +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:169 +msgid "There are different possible identity providers for your webid:\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:176 +#, scheme-format +msgid "" +"Please visit the following URI with a web browser:\n" +"~a\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:178 +msgid "Please paste your authorization code: " +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:189 +#, scheme-format +msgid "" +"Log in success. Keep this identity token for yourself:\n" +"\n" +"~a\n" +"\n" +"Now, you can do authenticated request by presenting the following access " +"token:\n" +"\n" +"~a\n" +"\n" +"and signing DPoP proofs with the following key:\n" +"\n" +"~a\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:210 +#, scheme-format +msgid "There was an error: ~a\n" +msgstr "" diff --git a/src/Makefile.am b/src/Makefile.am index 527f201..3dd6822 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ lib_LTLIBRARIES += %reldir%/libwebidoidc.la -dist_bin_SCRIPTS += %reldir%/webid-oidc-issuer %reldir%/webid-oidc-reverse-proxy %reldir%/webid-oidc-hello %reldir%/webid-oidc-client-service +dist_bin_SCRIPTS += %reldir%/webid-oidc-issuer %reldir%/webid-oidc-reverse-proxy %reldir%/webid-oidc-hello %reldir%/webid-oidc-client-service %reldir%/webid-oidc-example-app AM_CPPFLAGS += -I %reldir% -I $(srcdir)/%reldir% diff --git a/src/scm/webid-oidc/Makefile.am b/src/scm/webid-oidc/Makefile.am index 1f9cb5d..6aeadfc 100644 --- a/src/scm/webid-oidc/Makefile.am +++ b/src/scm/webid-oidc/Makefile.am @@ -23,7 +23,8 @@ dist_webidoidcmod_DATA += \ %reldir%/resource-server.scm \ %reldir%/hello-world.scm \ %reldir%/reverse-proxy.scm \ - %reldir%/client.scm + %reldir%/client.scm \ + %reldir%/example-app.scm webidoidcgo_DATA += \ %reldir%/errors.go \ @@ -50,6 +51,7 @@ webidoidcgo_DATA += \ %reldir%/resource-server.go \ %reldir%/hello-world.go \ %reldir%/reverse-proxy.go \ - %reldir%/client.go + %reldir%/client.go \ + %reldir%/example-app.go EXTRA_DIST += %reldir%/ChangeLog diff --git a/src/scm/webid-oidc/example-app.scm b/src/scm/webid-oidc/example-app.scm new file mode 100644 index 0000000..bb2faa6 --- /dev/null +++ b/src/scm/webid-oidc/example-app.scm @@ -0,0 +1,214 @@ +(define-module (webid-oidc example-app) + #:use-module (webid-oidc client) + #:use-module (webid-oidc errors) + #:use-module ((webid-oidc cache) #:prefix cache:) + #:use-module (webid-oidc dpop-proof) + #:use-module ((webid-oidc stubs) #:prefix stubs:) + #:use-module ((webid-oidc refresh-token) #:prefix refresh:) + #:use-module ((webid-oidc config) #:prefix cfg:) + #:use-module (web uri) + #:use-module (web client) + #:use-module (web response) + #:use-module (web server) + #:use-module (ice-9 optargs) + #:use-module (ice-9 receive) + #:use-module (srfi srfi-19) + #:use-module (ice-9 i18n) + #:use-module (ice-9 getopt-long) + #:use-module (ice-9 suspendable-ports) + #:use-module (ice-9 textual-ports) + #:use-module (ice-9 rdelim) + #:use-module (sxml simple) + #:use-module (rnrs bytevectors)) + +(define (G_ text) + (let ((out (gettext text))) + (if (string=? out text) + ;; No translation, disambiguate + (car (reverse (string-split text #\|))) + out))) + +(define (enumerate-profiles profiles) + (define (aux i) + (when (< i (vector-length profiles)) + (let ((prof (vector-ref profiles i))) + (format #t (G_ "~a.\t~a, certified by ~a;\n") + (+ i 1) + (uri->string (car prof)) + (uri->string (cadr prof)))) + (aux (+ i 1)))) + (aux 0)) + +(define (enumerate-providers providers) + (define (aux i) + (when (< i (vector-length providers)) + (let ((prov (vector-ref providers i))) + (format #t (G_ "~a – ~a\n") + (+ i 1) + (prov))) + (aux (+ i 1)))) + (aux 0)) + +(define (select-choice mini maxi question) + (format #t "~a" question) + (let* ((line + (read-line (current-input-port) 'trim)) + (number (false-if-exception (string->number line)))) + (cond + ((eof-object? line) + (exit 0)) + ((and (integer? number) + (>= number mini) + (<= number maxi)) + number) + (else + (format #t (G_ "I’m expecting a number between ~a and ~a.\n") + mini maxi) + (select-choice mini maxi question))))) + +(define cache-http-get (cache:with-cache)) + +(define (inner-main-loop http-request) + (format #t (G_ "Please enter an URI to GET: ")) + (let ((line (read-line (current-input-port) 'trim))) + (unless (eof-object? line) + (let ((uri (string->uri line))) + (receive (response response-body) + (http-request uri) + (let ((write-body + (write-response response (current-output-port)))) + (when (string? response-body) + (set! response-body (string->utf8 response-body))) + (when response-body + (write-response-body write-body response-body))))) + (inner-main-loop http-request)))) + +(define (main-loop id-token access-token key) + (let ((my-http-request + (make-client id-token access-token key + #:http-request + (lambda args + (format (current-error-port) (G_ "Sending a request: ~s\n") args) + (apply http-request args))))) + (inner-main-loop my-http-request))) + +(define-public (inner-main) + (setlocale LC_ALL "") + (bindtextdomain cfg:package cfg:localedir) + (textdomain cfg:package) + (let ((version-sym + (string->symbol (G_ "command-line|version"))) + (help-sym + (string->symbol (G_ "comand-line|help")))) + (let ((options + (let ((option-spec + `((,version-sym (single-char #\v) (value #f)) + (,help-sym (single-char #\h) (value #f))))) + (getopt-long (command-line) option-spec)))) + (cond + ((option-ref options help-sym #f) + (format #t (G_ "Usage: ~a [OPTIONS]... + +Demonstrate a webid-oidc application. + +Options: + -h, --~a: + display this help message and exit. + -v, --~a: + display the version information (~a) and exit. + +Environment variables: + + LANG: set the locale. Currently ~a. + + XDG_CACHE_HOME: where the seed for the key generator is +stored. Currently ~a. + + XDG_DATA_HOME: where the login credentials are stored. Currently ~a. + + HOME: to compute a default value for XDG_CACHE_HOME and +XDG_DATA_HOME, if missing. Currently ~a. + +If you find a bug, send a report to ~a. +") + (car (command-line)) + help-sym version-sym + cfg:version + (or (getenv "LANG") "") + (or (getenv "XDG_CACHE_HOME") "") + (or (getenv "XDG_DATA_HOME") "") + (or (getenv "HOME") "") + cfg:package-bugreport)) + ((option-ref options version-sym #f) + (format #t (G_ "~a version ~a\n") + cfg:package cfg:version)) + (else + (let ((profiles (list->vector (list-profiles)))) + (format #t (G_ "First, let’s log in. Here are your options:\n")) + (enumerate-profiles profiles) + (format #t (G_ "0.\tLog in with a different identity.\n")) + (let ((i-profile + (select-choice + 0 + (vector-length profiles) + (G_ "Please indicate your choice number: ")))) + (receive (id-token access-token key) + (if (eqv? i-profile 0) + (setup + (lambda () + (format #t (G_ "Please enter your webid, or identity server: ")) + (read-line (current-input-port) 'trim)) + (lambda (providers) + (cond + ((null? providers) + (error "No, this cannot happen.")) + ((null? (cdr providers)) + (car providers)) + (else + (set! providers (list->vector providers)) + (format #t (G_ "There are different possible identity providers for your webid:\n")) + (enumerate-providers providers) + (let ((i-provider + (select-choice 1 (- (vector-length providers) 1) + (G_ "Please indicate your choice number: ")))) + (vector-ref providers i-provider))))) + (lambda (uri) + (format #t (G_ "Please visit the following URI with a web browser:\n~a\n") + (uri->string uri)) + (format #t (G_ "Please paste your authorization code: ")) + (read-line (current-input-port) 'trim)) + #:client-id "https://webid-oidc-demo.planete-kraus.eu/example-application#id" + #:redirect-uri "https://webid-oidc-demo.planete-kraus.eu/authorized" + #:http-get cache-http-get) + (let ((profile (vector-ref profiles (- i-profile 1)))) + (let ((webid (car profile)) + (issuer (cadr profile)) + (refresh-token (caddr profile)) + (key (cadddr profile))) + (login webid issuer refresh-token key #:http-get cache-http-get)))) + (format #t (G_ "Log in success. Keep this identity token for yourself: + +~a + +Now, you can do authenticated request by presenting the following access token: + +~a + +and signing DPoP proofs with the following key: + +~a +") + (stubs:scm->json-string id-token #:pretty #t) + access-token + (stubs:scm->json-string key #:pretty #t)) + (main-loop id-token access-token key))))))))) + +(define-public (main) + (with-exception-handler + (lambda (error) + (format (current-error-port) + (G_ "There was an error: ~a\n") + (error->str error))) + (lambda () + (inner-main)) + #:unwind? #t)) diff --git a/src/webid-oidc-example-app b/src/webid-oidc-example-app new file mode 100755 index 0000000..ebf2da8 --- /dev/null +++ b/src/webid-oidc-example-app @@ -0,0 +1,7 @@ +#!/usr/local/bin/guile \ +--no-auto-compile -s +!# + +(use-modules (webid-oidc example-app)) + +(main) -- cgit v1.2.3