From d67b468bbeb600b894f06537c6ebe4844bc2c0d9 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/manual.html | 6 + guix/vkraus/packages/webid-oidc.scm | 2 +- man/Makefile.am | 4 + po/POTFILES.in | 1 + po/fr.po | 236 ++++++++++++++++++++---------------- po/webid-oidc.pot | 109 +++++++++++++++++ src/Makefile.am | 2 +- src/scm/webid-oidc/Makefile.am | 6 +- src/scm/webid-oidc/example-app.scm | 212 ++++++++++++++++++++++++++++++++ src/webid-oidc-example-app | 7 ++ 11 files changed, 477 insertions(+), 110 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 7beb367..07f8c35 100755 --- a/bootstrap +++ b/bootstrap @@ -12,7 +12,7 @@ mkdir -p .native || exit 1 cd .native || exit 1 bash ../configure SHELL=$(which sh) || exit 1 -for file in ../src/webid-oidc-issuer ../src/webid-oidc-reverse-proxy ../src/webid-oidc-client-service +for file in ../src/webid-oidc-issuer ../src/webid-oidc-reverse-proxy ../src/webid-oidc-client-service ../src/webid-oidc-example-app do sed -i "s|/usr/local/bin/guile|$(which guile)|g" $file || exit 1 done diff --git a/doc/manual.html b/doc/manual.html index 610bc02..20a6bc0 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -1244,6 +1244,12 @@ returns the time. It is used to issue DPoP proofs.

+

+ An example application is provided as the +

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 372892e..e6d43a1 100644 --- a/guix/vkraus/packages/webid-oidc.scm +++ b/guix/vkraus/packages/webid-oidc.scm @@ -67,7 +67,7 @@ (format #f "~a/bin/webid-oidc-~a" out program) `("GUILE_LOAD_PATH" ":" = ,mod-paths) `("GUILE_LOAD_COMPILED_PATH" ":" = ,go-paths))) - '(issuer reverse-proxy hello client-service)))))))) + '(issuer reverse-proxy hello client-service example-app)))))))) (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 b0938f9..4a1054e 100644 --- a/po/fr.po +++ b/po/fr.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: webid-oidc 0.0.0\n" "Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n" "POT-Creation-Date: 2021-05-10 23:11+0200\n" -"PO-Revision-Date: 2021-05-10 14:31+0200\n" +"PO-Revision-Date: 2021-05-10 23:12+0200\n" "Last-Translator: Vivien Kraus \n" "Language-Team: French \n" "Language: fr\n" @@ -741,11 +741,13 @@ msgstr "Attention : génération d'une nouvelle paire de clé." #: src/scm/webid-oidc/identity-provider.scm:147 #: src/scm/webid-oidc/reverse-proxy.scm:124 #: src/scm/webid-oidc/hello-world.scm:32 src/scm/webid-oidc/client.scm:606 +#: src/scm/webid-oidc/example-app.scm:101 msgid "command-line|version" msgstr "version" #: src/scm/webid-oidc/identity-provider.scm:149 #: src/scm/webid-oidc/hello-world.scm:34 src/scm/webid-oidc/client.scm:608 +#: src/scm/webid-oidc/example-app.scm:103 msgid "comand-line|help" msgstr "aide" @@ -941,6 +943,7 @@ msgstr "" #: src/scm/webid-oidc/identity-provider.scm:262 #: src/scm/webid-oidc/reverse-proxy.scm:207 #: src/scm/webid-oidc/hello-world.scm:60 src/scm/webid-oidc/client.scm:684 +#: src/scm/webid-oidc/example-app.scm:143 #, scheme-format msgid "~a version ~a\n" msgstr "~a version ~a\n" @@ -1428,129 +1431,152 @@ 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:36 #, scheme-format -#~ msgid "~a.\t~a, certified by ~a;\n" -#~ msgstr "~a.\t~a, certifié par ~a ;\n" +msgid "~a.\t~a, certified by ~a;\n" +msgstr "~a.\t~a, certifié par ~a ;\n" +#: src/scm/webid-oidc/example-app.scm:47 #, scheme-format -#~ msgid "~a – ~a\n" -#~ msgstr "~a – ~a\n" +msgid "~a – ~a\n" +msgstr "~a – ~a\n" +#: src/scm/webid-oidc/example-app.scm:66 #, scheme-format -#~ msgid "I’m expecting a number between ~a and ~a.\n" -#~ msgstr "J’attends un nombre entre ~a et ~a.\n" +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:73 +msgid "Please enter an URI to GET: " +msgstr "Veuillez entrer un URI à requêter avec GET :" + +#: src/scm/webid-oidc/example-app.scm:92 #, scheme-format -#~ msgid "" -#~ "Usage: ~a [OPTIONS]...\n" -#~ "\n" -#~ "Demonstrate a webid-oidc application.\n" -#~ "\n" -#~ "Options:\n" -#~ " -h, --help:\n" -#~ " display this help message and exit.\n" -#~ " -v, --version:\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, --aide :\n" -#~ " affiche ce message d’aide et quitte.\n" -#~ " -v, --version :\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 "Sending a request: ~s\n" +msgstr "Envoi d’une requête : ~s\n" + +#: src/scm/webid-oidc/example-app.scm:111 +#, scheme-format +msgid "" +"Usage: ~a [OPTIONS]...\n" +"\n" +"Demonstrate a webid-oidc application.\n" +"\n" +"Options:\n" +" -h, --help:\n" +" display this help message and exit.\n" +" -v, --version:\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, --aide :\n" +" affiche ce message d’aide et quitte.\n" +" -v, --version :\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" +#: 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" -#~ 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:149 +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 : " +#: 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 : " -#~ msgid "Please enter your webid, or identity server: " -#~ msgstr "Veuillez entrer votre webid, ou serveur d’identité : " +#: 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é : " -#~ 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: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" +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 : " +#: 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:188 #, 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" +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:209 #, scheme-format -#~ msgid "There was an error: ~a\n" -#~ msgstr "Il y a eu une erreur : ~a\n" +msgid "There was an error: ~a\n" +msgstr "Il y a eu une erreur : ~a\n" #, scheme-format #~ msgid "" diff --git a/po/webid-oidc.pot b/po/webid-oidc.pot index 63927e0..b974da8 100644 --- a/po/webid-oidc.pot +++ b/po/webid-oidc.pot @@ -722,11 +722,13 @@ msgstr "" #: src/scm/webid-oidc/identity-provider.scm:147 #: src/scm/webid-oidc/reverse-proxy.scm:124 #: src/scm/webid-oidc/hello-world.scm:32 src/scm/webid-oidc/client.scm:606 +#: src/scm/webid-oidc/example-app.scm:101 msgid "command-line|version" msgstr "" #: src/scm/webid-oidc/identity-provider.scm:149 #: src/scm/webid-oidc/hello-world.scm:34 src/scm/webid-oidc/client.scm:608 +#: src/scm/webid-oidc/example-app.scm:103 msgid "comand-line|help" msgstr "" @@ -849,6 +851,7 @@ msgstr "" #: src/scm/webid-oidc/identity-provider.scm:262 #: src/scm/webid-oidc/reverse-proxy.scm:207 #: src/scm/webid-oidc/hello-world.scm:60 src/scm/webid-oidc/client.scm:684 +#: src/scm/webid-oidc/example-app.scm:143 #, scheme-format msgid "~a version ~a\n" msgstr "" @@ -1214,3 +1217,109 @@ msgstr "" #: src/scm/webid-oidc/client.scm:715 msgid "The client URI should be an URI.\n" msgstr "" + +#: src/scm/webid-oidc/example-app.scm:36 +#, scheme-format +msgid "~a.\t~a, certified by ~a;\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:47 +#, scheme-format +msgid "~a – ~a\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:66 +#, scheme-format +msgid "I’m expecting a number between ~a and ~a.\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:73 +msgid "Please enter an URI to GET: " +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:92 +#, scheme-format +msgid "Sending a request: ~s\n" +msgstr "" + +#: src/scm/webid-oidc/example-app.scm:111 +#, scheme-format +msgid "" +"Usage: ~a [OPTIONS]...\n" +"\n" +"Demonstrate a webid-oidc application.\n" +"\n" +"Options:\n" +" -h, --help:\n" +" display this help message and exit.\n" +" -v, --version:\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:188 +#, 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:209 +#, 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..ec92fb9 --- /dev/null +++ b/src/scm/webid-oidc/example-app.scm @@ -0,0 +1,212 @@ +(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, --help: + display this help message and exit. + -v, --version: + 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)) + 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))) + (login webid issuer refresh-token #: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