;; webid-oidc, implementation of the Solid specification
;; Copyright (C) 2020, 2021 Vivien Kraus
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU Affero General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU Affero General Public License for more details.
;; You should have received a copy of the GNU Affero General Public License
;; along with this program. If not, see .
(define-module (vkraus services webid-oidc)
#:use-module (gnu services)
#:use-module (gnu services shepherd)
#:use-module (gnu services admin)
#:use-module (gnu system shadow)
#:use-module (gnu packages admin)
#:use-module (vkraus packages webid-oidc)
#:use-module (guix gexp)
#:use-module (guix modules)
#:use-module (guix records)
#:use-module (ice-9 match)
#:use-module (ice-9 optargs))
(define-record-type*
webid-oidc-issuer-configuration
make-webid-oidc-issuer-configuration
webid-oidc-issuer-configuration?
(webid-oidc webid-oidc-issuer-configuration-webid-oidc
(default webid-oidc))
(complete-corresponding-source
webid-oidc-issuer-configuration-complete-corresponding-source)
(issuer webid-oidc-issuer-configuration-issuer)
(key-file webid-oidc-issuer-configuration-key-file
(default "/var/lib/webid-oidc/issuer/key.jwk"))
(subject webid-oidc-issuer-configuration-subject)
(encrypted-password webid-oidc-issuer-configuration-encrypted-password)
(jwks-uri webid-oidc-issuer-configuration-jwks-uri)
(authorization-endpoint-uri
webid-oidc-issuer-configuration-authorization-endpoint-uri)
(token-endpoint-uri
webid-oidc-issuer-configuration-token-endpoint-uri)
(port webid-oidc-issuer-configuration-port (default 8088))
(extra-options
webid-oidc-issuer-configuration-extra-options
(default '())))
(define-record-type*
webid-oidc-reverse-proxy-configuration
make-webid-oidc-reverse-proxy-configuration
webid-oidc-reverse-proxy-configuration?
(webid-oidc webid-oidc-reverse-proxy-configuration-webid-oidc
(default webid-oidc))
(complete-corresponding-source
webid-oidc-reverse-proxy-configuration-complete-corresponding-source)
(port webid-oidc-reverse-proxy-port (default 8090))
(inbound-uri webid-oidc-reverse-proxy-configuration-inbound-uri)
(outbound-uri webid-oidc-reverse-proxy-configuration-outbound-uri)
(header webid-oidc-reverse-proxy-configuration-header
(default "XXX-Agent"))
(extra-options
webid-oidc-reverse-proxy-extra-options
(default '())))
(define-record-type*
webid-oidc-hello-configuration
make-webid-oidc-hello-configuration
webid-oidc-hello-configuration?
(webid-oidc webid-oidc-hello-configuration-webid-oidc
(default webid-oidc))
(complete-corresponding-source
webid-oidc-hello-configuration-complete-corresponding-source)
(port webid-oidc-hello-configuration-port (default 8089))
(extra-options
webid-oidc-hello-configuration-extra-options
(default '())))
(define-record-type*
webid-oidc-client-service-configuration
make-webid-oidc-client-service-configuration
webid-oidc-client-service-configuration?
(webid-oidc webid-oidc-client-service-configuration-webid-oidc
(default webid-oidc))
(complete-corresponding-source
webid-oidc-client-service-configuration-complete-corresponding-source)
(client-id webid-oidc-client-service-configuration-client-id)
(redirect-uri webid-oidc-client-service-configuration-redirect-uri)
(client-name webid-oidc-client-service-configuration-client-name (default "Example Solid App"))
(client-uri webid-oidc-client-service-configuration-client-uri (default "https://webid-oidc.planete-kraus.eu/Running-a-client.html#Running-a-client"))
(port webid-oidc-client-service-configuration-port (default 8088))
(extra-options
webid-oidc-client-service-configuration-extra-options
(default '())))
(define-record-type*
webid-oidc-server-configuration
make-webid-oidc-server-configuration
webid-oidc-server-configuration?
(webid-oidc webid-oidc-server-configuration-webid-oidc
(default webid-oidc))
(complete-corresponding-source
webid-oidc-server-configuration-complete-corresponding-source)
(server-name webid-oidc-server-configuration-server-name)
(key-file webid-oidc-server-configuration-key-file
(default "/var/lib/webid-oidc/server/key.jwk"))
(subject webid-oidc-server-configuration-subject)
(encrypted-password webid-oidc-server-configuration-encrypted-password)
(jwks-uri webid-oidc-server-configuration-jwks-uri)
(authorization-endpoint-uri
webid-oidc-server-configuration-authorization-endpoint-uri)
(token-endpoint-uri
webid-oidc-server-configuration-token-endpoint-uri)
(port webid-oidc-server-configuration-port (default 8088))
(extra-options
webid-oidc-issuer-configuration-extra-options
(default '())))
(export
webid-oidc-issuer-configuration
make-webid-oidc-issuer-configuration
webid-oidc-issuer-configuration?
webid-oidc-issuer-configuration-webid-oidc
webid-oidc-issuer-configuration-complete-corresponding-source
webid-oidc-issuer-configuration-issuer
webid-oidc-issuer-configuration-key-file
webid-oidc-issuer-configuration-subject
webid-oidc-issuer-configuration-encrypted-password
webid-oidc-issuer-configuration-jwks-uri
webid-oidc-issuer-configuration-authorization-endpoint-uri
webid-oidc-issuer-configuration-token-endpoint-uri
webid-oidc-issuer-configuration-port
webid-oidc-issuer-configuration-extra-options
webid-oidc-reverse-proxy-configuration
make-webid-oidc-reverse-proxy-configuration
webid-oidc-reverse-proxy-configuration?
webid-oidc-reverse-proxy-configuration-webid-oidc
webid-oidc-reverse-proxy-configuration-complete-corresponding-source
webid-oidc-reverse-proxy-configuration-port
webid-oidc-reverse-proxy-configuration-inbound-uri
webid-oidc-reverse-proxy-configuration-outbound-uri
webid-oidc-reverse-proxy-configuration-header
webid-oidc-reverse-proxy-configuration-extra-options
webid-oidc-hello-configuration
make-webid-oidc-hello-configuration
webid-oidc-hello-configuration?
webid-oidc-hello-configuration-webid-oidc
webid-oidc-hello-configuration-complete-corresponding-source
webid-oidc-hello-configuration-port
webid-oidc-hello-configuration-extra-options
webid-oidc-client-service-configuration
make-webid-oidc-client-service-configuration
webid-oidc-client-service-configuration?
webid-oidc-client-service-configuration-webid-oidc
webid-oidc-client-service-configuration-complete-corresponding-source
webid-oidc-client-service-configuration-client-id
webid-oidc-client-service-configuration-redirect-uri
webid-oidc-client-service-configuration-client-name
webid-oidc-client-service-configuration-client-uri
webid-oidc-client-service-configuration-port
webid-oidc-client-service-configuration-extra-options
webid-oidc-server-configuration
make-webid-oidc-server-configuration
webid-oidc-server-configuration?
webid-oidc-server-configuration-webid-oidc
webid-oidc-server-configuration-complete-corresponding-source
webid-oidc-server-configuration-server-name
webid-oidc-server-configuration-key-file
webid-oidc-server-configuration-subject
webid-oidc-server-configuration-encrypted-password
webid-oidc-server-configuration-jwks-uri
webid-oidc-server-configuration-authorization-endpoint-uri
webid-oidc-server-configuration-token-endpoint-uri
webid-oidc-server-configuration-port
webid-oidc-server-configuration-extra-options)
(define webid-oidc-issuer-shepherd-service
(match-lambda
(($
webid-oidc ccs issuer key-file subject encrypted-password jwks-uri
authorization-endpoint-uri token-endpoint-uri port
extra-options)
(with-imported-modules
(source-module-closure
'((gnu build shepherd)
(gnu system file-systems)))
(list (shepherd-service
(provision '(webid-oidc-issuer))
(documentation "Run the Solid identity provider.")
(requirement '(user-processes))
(modules '((gnu build shepherd)
(gnu system file-systems)))
(start
#~(begin
(let* ((user (getpwnam "webid-oidc"))
(prepare-directory
(lambda (dir)
(mkdir-p dir)
(chown dir (passwd:uid user) (passwd:gid user))
(chmod dir #o700))))
(prepare-directory "/var/log/webid-oidc")
(prepare-directory "/var/lib/webid-oidc")
(prepare-directory "/var/cache/webid-oidc"))
(make-forkexec-constructor
(list
(string-append #$webid-oidc "/bin/webid-oidc")
"identity-provider"
"--complete-corresponding-source" #$ccs
"--server-name" #$issuer
"--key-file" #$key-file
"--subject" #$subject
"--encrypted-password" #$encrypted-password
"--jwks-uri" #$jwks-uri
"--authorization-endpoint-uri" #$authorization-endpoint-uri
"--token-endpoint-uri" #$token-endpoint-uri
"--port" (with-output-to-string (lambda () (display #$port)))
"--log-file" "issuer.log"
"--error-file" "issuer.err"
#$@extra-options)
#:user "webid-oidc"
#:group "webid-oidc"
#:directory "/var/log/webid-oidc"
#:environment-variables
`("XDG_DATA_HOME=/var/lib"
"XDG_CACHE_HOME=/var/cache"
"LANG=C"))))
(stop #~(make-kill-destructor))))))))
(define webid-oidc-reverse-proxy-shepherd-service
(match-lambda
(($
webid-oidc ccs port inbound-uri outbound-uri header
extra-options)
(with-imported-modules
(source-module-closure
'((gnu build shepherd)
(gnu system file-systems)))
(list (shepherd-service
(provision '(webid-oidc-reverse-proxy))
(documentation "Run a proxy to authenticate with Solid.")
(requirement '(user-processes))
(modules '((gnu build shepherd)
(gnu system file-systems)))
(start
#~(begin
(let* ((user (getpwnam "webid-oidc"))
(prepare-directory
(lambda (dir)
(mkdir-p dir)
(chown dir (passwd:uid user) (passwd:gid user))
(chmod dir #o700))))
(prepare-directory "/var/log/webid-oidc")
(prepare-directory "/var/lib/webid-oidc")
(prepare-directory "/var/cache/webid-oidc"))
(make-forkexec-constructor
(list
(string-append #$webid-oidc "/bin/webid-oidc")
"reverse-proxy"
"--complete-corresponding-source" #$ccs
"--port" (with-output-to-string (lambda () (display #$port)))
"--server-name" #$inbound-uri
"--backend-uri" #$outbound-uri
"--header" #$header
"--log-file" "reverse-proxy.log"
"--error-file" "reverse-proxy.err"
#$@extra-options)
#:user "webid-oidc"
#:group "webid-oidc"
#:directory "/var/log/webid-oidc"
#:environment-variables
`("XDG_DATA_HOME=/var/lib"
"XDG_CACHE_HOME=/var/cache"
"LANG=C"))))
(stop #~(make-kill-destructor))))))))
(define webid-oidc-hello-shepherd-service
(match-lambda
(($
webid-oidc ccs port extra-options)
(with-imported-modules
(source-module-closure
'((gnu build shepherd)
(gnu system file-systems)))
(list (shepherd-service
(provision '(webid-oidc-hello))
(documentation "Run a demonstration Solid server.")
(requirement '(user-processes))
(modules '((gnu build shepherd)
(gnu system file-systems)))
(start
#~(begin
(let* ((user (getpwnam "webid-oidc"))
(prepare-directory
(lambda (dir)
(mkdir-p dir)
(chown dir (passwd:uid user) (passwd:gid user))
(chmod dir #o700))))
(prepare-directory "/var/log/webid-oidc")
(prepare-directory "/var/lib/webid-oidc")
(prepare-directory "/var/cache/webid-oidc"))
(make-forkexec-constructor
(list
(string-append #$webid-oidc "/bin/webid-oidc-hello")
"--complete-corresponding-source" #$ccs
"--port" (with-output-to-string (lambda () (display #$port)))
"--log-file" "hello.log"
"--error-file" "hello.err"
#$@extra-options)
#:user "webid-oidc"
#:group "webid-oidc"
#:directory "/var/log/webid-oidc"
#:environment-variables
`("XDG_DATA_HOME=/var/lib"
"XDG_CACHE_HOME=/var/cache"
"LANG=C"))))
(stop #~(make-kill-destructor))))))))
(define webid-oidc-client-service-shepherd-service
(match-lambda
(($
webid-oidc ccs client-id redirect-uri client-name client-uri port
extra-options)
(with-imported-modules
(source-module-closure
'((gnu build shepherd)
(gnu system file-systems)))
(list (shepherd-service
(provision '(webid-oidc-client-service))
(documentation "Run a server for a Solid application.")
(requirement '(user-processes))
(modules '((gnu build shepherd)
(gnu system file-systems)))
(start
#~(begin
(let* ((user (getpwnam "webid-oidc"))
(prepare-directory
(lambda (dir)
(mkdir-p dir)
(chown dir (passwd:uid user) (passwd:gid user))
(chmod dir #o700))))
(prepare-directory "/var/log/webid-oidc"))
(make-forkexec-constructor
(list
(string-append #$webid-oidc "/bin/webid-oidc")
"client-service"
"--complete-corresponding-source" #$ccs
"--client-id" #$client-id
"--redirect-uri" #$redirect-uri
"--client-name" #$client-name
"--client-uri" #$client-uri
"--port" (with-output-to-string (lambda () (display #$port)))
"--log-file" "client-service.log"
"--error-file" "client-service.err"
#$@extra-options)
#:user "webid-oidc"
#:group "webid-oidc"
#:directory "/var/log/webid-oidc"
#:environment-variables
`("LANG=C"))))
(stop #~(make-kill-destructor))))))))
(define webid-oidc-server-shepherd-service
(match-lambda
(($
webid-oidc ccs server-name key-file subject encrypted-password jwks-uri
authorization-endpoint-uri token-endpoint-uri port
extra-options)
(with-imported-modules
(source-module-closure
'((gnu build shepherd)
(gnu system file-systems)))
(list (shepherd-service
(provision '(webid-oidc-server))
(documentation "Run the full Solid server.")
(requirement '(user-processes))
(modules '((gnu build shepherd)
(gnu system file-systems)))
(start
#~(begin
(let* ((user (getpwnam "webid-oidc"))
(prepare-directory
(lambda (dir)
(mkdir-p dir)
(chown dir (passwd:uid user) (passwd:gid user))
(chmod dir #o700))))
(prepare-directory "/var/log/webid-oidc")
(prepare-directory "/var/lib/webid-oidc")
(prepare-directory "/var/cache/webid-oidc"))
(make-forkexec-constructor
(list
(string-append #$webid-oidc "/bin/webid-oidc")
"server"
"--complete-corresponding-source" #$ccs
"--server-name" #$server-name
"--key-file" #$key-file
"--subject" #$subject
"--encrypted-password" #$encrypted-password
"--jwks-uri" #$jwks-uri
"--authorization-endpoint-uri" #$authorization-endpoint-uri
"--token-endpoint-uri" #$token-endpoint-uri
"--port" (with-output-to-string (lambda () (display #$port)))
"--log-file" "server.log"
"--error-file" "server.err"
#$@extra-options)
#:user "webid-oidc"
#:group "webid-oidc"
#:directory "/var/log/webid-oidc"
#:environment-variables
`("XDG_DATA_HOME=/var/lib"
"XDG_CACHE_HOME=/var/cache"
"LANG=C"))))
(stop #~(make-kill-destructor))))))))
(define %webid-oidc-accounts
(list (user-group (name "webid-oidc")
(system? #t))
(user-account
(name "webid-oidc")
(group "webid-oidc")
(system? #t)
(comment "The user that runs the webid-oidc issuer and resource server.")
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))))
(define (%webid-oidc-log-rotation file)
(list (log-rotation
(frequency 'daily)
(files
(map (lambda (ext) (string-append "/var/log/webid-oidc/" file "." ext))
'("log" "err"))))))
(define-public webid-oidc-issuer-service-type
(service-type
(name 'webid-oidc-issuer)
(extensions
(list
(service-extension account-service-type
(const %webid-oidc-accounts))
(service-extension rottlog-service-type
(const (%webid-oidc-log-rotation "issuer")))
(service-extension
shepherd-root-service-type
webid-oidc-issuer-shepherd-service)))))
(define-public webid-oidc-reverse-proxy-service-type
(service-type
(name 'webid-oidc-reverse-proxy)
(extensions
(list
(service-extension account-service-type
(const %webid-oidc-accounts))
(service-extension rottlog-service-type
(const (%webid-oidc-log-rotation "reverse-proxy")))
(service-extension
shepherd-root-service-type
webid-oidc-reverse-proxy-shepherd-service)))))
(define-public webid-oidc-hello-service-type
(service-type
(name 'webid-oidc-hello)
(extensions
(list
(service-extension account-service-type
(const %webid-oidc-accounts))
(service-extension rottlog-service-type
(const (%webid-oidc-log-rotation "hello")))
(service-extension
shepherd-root-service-type
webid-oidc-hello-shepherd-service)))))
(define-public webid-oidc-client-service-service-type
(service-type
(name 'webid-oidc-client-service)
(extensions
(list
(service-extension account-service-type
(const %webid-oidc-accounts))
(service-extension rottlog-service-type
(const (%webid-oidc-log-rotation "client-service")))
(service-extension
shepherd-root-service-type
webid-oidc-client-service-shepherd-service)))))
(define-public webid-oidc-server-service-type
(service-type
(name 'webid-oidc-server)
(extensions
(list
(service-extension account-service-type
(const %webid-oidc-accounts))
(service-extension rottlog-service-type
(const (%webid-oidc-log-rotation "server")))
(service-extension
shepherd-root-service-type
webid-oidc-server-shepherd-service)))))