summaryrefslogtreecommitdiff
path: root/src/scm/webid-oidc/client/client.scm
blob: c6e24b73e39a429c73c378bc8b9df6ebbfb02655 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
;; disfluid, implementation of the Solid specification
;; Copyright (C) 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 <https://www.gnu.org/licenses/>.

(define-module (webid-oidc client client)
  #:use-module (webid-oidc errors)
  #:use-module (webid-oidc provider-confirmation)
  #:use-module (webid-oidc oidc-id-token)
  #:use-module (webid-oidc dpop-proof)
  #:use-module (webid-oidc web-i18n)
  #:use-module (webid-oidc serializable)
  #:use-module ((webid-oidc jwk) #:prefix jwk:)
  #:use-module ((webid-oidc parameters) #:prefix p:)
  #:use-module ((webid-oidc stubs) #:prefix stubs:)
  #:use-module ((webid-oidc config) #:prefix cfg:)
  #:use-module ((webid-oidc client accounts) #:prefix client:)
  #:use-module (web uri)
  #:use-module (web request)
  #:use-module (web response)
  #:use-module (web server)
  #:use-module (web http)
  #:use-module (ice-9 optargs)
  #:use-module (ice-9 receive)
  #:use-module (ice-9 pretty-print)
  #:use-module (srfi srfi-9)
  #:use-module (srfi srfi-19)
  #:use-module (srfi srfi-26)
  #:use-module (rnrs bytevectors)
  #:use-module (ice-9 i18n)
  #:use-module (ice-9 getopt-long)
  #:use-module (ice-9 suspendable-ports)
  #:use-module (ice-9 match)
  #:use-module (sxml simple)
  #:use-module (oop goops)
  #:export
  (
   <client>
   client-id
   key-pair
   redirect-uri

   client
   )
  #:declarative? #t)

(define <jwk:key-pair> jwk:<key-pair>)

(define-class <client> ()
  (client-id #:init-keyword #:client-id #:getter client-id #:->sxml uri->string)
  (key-pair #:init-keyword #:key-pair #:getter key-pair)
  (redirect-uri #:init-keyword #:redirect-uri #:getter redirect-uri #:->sxml uri->string)
  #:metaclass <plugin-class>
  #:module-name '(webid-oidc client client))

(define-method (initialize (client <client>) initargs)
  (next-method)
  (let-keywords
   initargs #t
   ((client-id #f)
    (key-pair #t) ;; We’ll generate one if not #f
    (redirect-uri #f))
   (let convert-args ((client-id client-id)
                      (key-pair key-pair)
                      (redirect-uri redirect-uri))
     (match `(,client-id ,key-pair ,redirect-uri)
       (((or (? string? (= string->uri (? uri? client-id)))
             (? uri? client-id))
         (? (cute is-a? <> <jwk:key-pair>) client-key)
         (or (? string? (= string->uri (? uri? redirect-uri)))
             (? uri? redirect-uri)))
        (begin
          (slot-set! client 'client-id client-id)
          (slot-set! client 'key-pair client-key)
          (slot-set! client 'redirect-uri redirect-uri)))
       ((_ #t _)
        (convert-args client-id (jwk:generate-key #:n-size 2048) redirect-uri))
       (else
        (scm-error 'wrong-type-arg "make <account>"
                   (G_ "Client ID and redirect URIs should be URIs, and key pair should be a key pair..")
                   '()
                   (list client-id key-pair redirect-uri)))))))

(define client
  (make-parameter #f))

(define-method (display (client <client>) port)
  (format port "<<client> client-id: ~a, key-pair ID: ~a, redirect-uri: ~a>"
          (uri->string (client-id client))
          (jwk:jkt (key-pair client))
          (uri->string (redirect-uri client))))

(define-method (equal? (a <client>) (b <client>))
  (and (equal? (client-id a) (client-id b))
       (equal? (key-pair a) (key-pair b))
       (equal? (redirect-uri a) (redirect-uri b))))