summaryrefslogtreecommitdiff
path: root/src/scm/webid-oidc/identity-provider.scm
diff options
context:
space:
mode:
Diffstat (limited to 'src/scm/webid-oidc/identity-provider.scm')
-rw-r--r--src/scm/webid-oidc/identity-provider.scm150
1 files changed, 70 insertions, 80 deletions
diff --git a/src/scm/webid-oidc/identity-provider.scm b/src/scm/webid-oidc/identity-provider.scm
index de56228..5970574 100644
--- a/src/scm/webid-oidc/identity-provider.scm
+++ b/src/scm/webid-oidc/identity-provider.scm
@@ -18,6 +18,8 @@
#:use-module (webid-oidc errors)
#:use-module (webid-oidc authorization-endpoint)
#:use-module (webid-oidc token-endpoint)
+ #:use-module (webid-oidc server endpoint)
+ #:use-module (webid-oidc server endpoint identity-provider)
#:use-module (webid-oidc oidc-configuration)
#:use-module (webid-oidc jwk)
#:use-module ((webid-oidc config) #:prefix cfg:)
@@ -39,6 +41,7 @@
#:use-module (sxml simple)
#:use-module (sxml match)
#:use-module (srfi srfi-19)
+ #:use-module (srfi srfi-26)
#:use-module (rnrs bytevectors)
#:use-module (oop goops)
#:duplicates (merge-generics)
@@ -50,9 +53,16 @@
))
-(define* (same-uri? a b #:key (skip-query #f))
- (and (equal? (uri-path a) (uri-path b))
- (or skip-query (equal? (uri-query a) (uri-query b)))))
+(define-class <default> (<endpoint>))
+
+(define-method (handle (endpoint <default>) request request-body)
+ (raise-exception
+ (make-exception
+ (make-web-exception 404 (W_ "reason-phrase|Not Found"))
+ (make-user-message
+ (call-with-input-string
+ (format #f (W_ "<p>Your request cannot be handled by the identity provider.</p>"))
+ xml->sxml)))))
(define* (make-identity-provider
issuer
@@ -62,84 +72,64 @@
jwks-uri
authorization-endpoint-uri
token-endpoint-uri)
- (let ((key
- (catch #t
- (lambda ()
- (call-with-input-file key-file
- (lambda (port)
- (jwk->key
- (stubs:json->scm port)))))
- (lambda error
- (format (current-error-port)
- (G_ "Warning: generating a new key pair."))
- (let ((k (generate-key #:n-size 2048)))
- (stubs:call-with-output-file*
- key-file
- (lambda (port)
- (stubs:scm->json (key->jwk k) port #:pretty #t)))
- k)))))
- (let ((authorization-endpoint
- (make-authorization-endpoint subject encrypted-password key))
- (token-endpoint
- (make-token-endpoint token-endpoint-uri issuer key))
- (openid-configuration
+ (let ((discovery
+ (make <oidc-discovery>
+ #:path "/.well-known/openid-configuration"
+ #:configuration
(make <oidc-configuration>
#:jwks-uri jwks-uri
#:authorization-endpoint authorization-endpoint-uri
- #:token-endpoint token-endpoint-uri))
- (openid-configuration-uri
- (build-uri 'https
- #:host (uri-host issuer)
- #:path "/.well-known/openid-configuration")))
+ #:token-endpoint token-endpoint-uri)))
+ (authz
+ (make <authorization-endpoint>
+ #:subject subject
+ #:encrypted-password encrypted-password
+ #:key-file key-file
+ #:path (uri-path authorization-endpoint-uri)))
+ (token
+ (make <token-endpoint>
+ #:path (uri-path token-endpoint-uri)
+ #:issuer issuer
+ #:key-file key-file))
+ (jwks
+ (make <jwks-endpoint>
+ #:path (uri-path jwks-uri)
+ #:key-file key-file)))
+ (let ((idp (make <identity-provider>
+ #:oidc-discovery discovery
+ #:authorization-endpoint authz
+ #:token-endpoint token
+ #:jwks-endpoint jwks
+ #:default (make <default>))))
(lambda (request request-body)
- (let ((uri (request-uri request))
- (current-time ((p:current-date))))
- (parameterize ((web-locale request))
- (cond ((same-uri? uri openid-configuration-uri)
- (let* ((current-sec (time-second (date->time-utc current-time)))
- (exp-sec (+ current-sec 3600))
- (exp (time-utc->date
- (make-time time-utc 0 exp-sec))))
- (serve openid-configuration exp)))
- ((same-uri? uri jwks-uri)
- (let* ((current-sec (time-second (date->time-utc current-time)))
- (exp-sec (+ current-sec 3600))
- (exp (time-utc->date
- (make-time time-utc 0 exp-sec))))
- (serve (make <jwks> #:keys (list key)) exp)))
- ((same-uri? uri authorization-endpoint-uri #:skip-query #t)
- (authorization-endpoint request request-body))
- ((same-uri? uri token-endpoint-uri)
- (token-endpoint request request-body))
- ((same-uri? uri subject)
- (values
- (build-response #:headers '((content-type text/turtle))
- #:port #f)
- (format #f
- "@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<#~a> a foaf:Person ;
- rdfs:comment \"It works. Now you should use another service to serve that resource.\" .
-"
- (uri-fragment subject))))
- (else
- (values
- (build-response #:code 404
- #:reason-phrase (W_ "reason-phrase|Not Found")
- #:headers '((content-type application/xhtml+xml)))
- (with-output-to-string
- (lambda ()
- (sxml->xml
- `(*TOP* (*PI* xml "version=\"1.0\" encoding=\"utf-8\"")
- (html (@ (xmlns "http://www.w3.org/1999/xhtml")
- (xml:lang ,(W_ "xml-lang|en")))
- (body
- ,(sxml-match
- (xml->sxml
- (W_ (format #f "<h1>Resource not found</h1>")))
- ((*TOP* ,title) title))
- ,(sxml-match
- (xml->sxml
- (W_ (format #f "<p>This OpenID Connect identity provider does not know the resource you are requesting.</p>")))
- ((*TOP* ,p) p)))))))))))))))))
+ (parameterize ((web-locale request))
+ (with-exception-handler
+ (lambda (exn)
+ (unless (web-exception? exn)
+ (raise-exception exn))
+ (values
+ (build-response
+ #:code (web-exception-code exn)
+ #:reason-phrase (web-exception-reason-phrase exn)
+ #:headers `((content-type application/xhtml+xml)))
+ (call-with-output-string
+ (cute sxml->xml
+ `(*TOP*
+ (*PI* xml "version=\"1.0\" encoding=\"utf-8\"")
+ (html (@ (xmlns "http://www.w3.org/1999/xhtml")
+ (xml:lang ,(W_ "xml-lang|en")))
+ (body
+ ,(call-with-input-string
+ (format #f (W_ "<h1>The identity provider request failed</h1>"))
+ xml->sxml)
+ ,(if (user-message? exn)
+ (user-message-sxml exn)
+ (call-with-input-string
+ (format #f (W_ "<p>No more information.</p>"))
+ xml->sxml)))))
+ <>))))
+ (lambda ()
+ (receive (response response-body response-meta)
+ (handle idp request request-body)
+ (values response response-body)))
+ #:unwind? #t))))))