diff options
Diffstat (limited to 'tests/client-workflow.scm')
-rw-r--r-- | tests/client-workflow.scm | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/tests/client-workflow.scm b/tests/client-workflow.scm new file mode 100644 index 0000000..04a4455 --- /dev/null +++ b/tests/client-workflow.scm @@ -0,0 +1,140 @@ +;; webid-oidc, 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/>. + +(use-modules ((webid-oidc client) #:prefix client:) + ((webid-oidc client accounts) #:prefix client:) + ((webid-oidc jwk) #:prefix jwk:) + (webid-oidc testing) + ((webid-oidc stubs) #:prefix stubs:) + ((webid-oidc refresh-token) #:prefix refresh:) + ((webid-oidc simulation) #:prefix sim:) + ((webid-oidc parameters) #:prefix p:) + (web uri) + (web request) + (web response) + (srfi srfi-19) + (srfi srfi-26) + (ice-9 optargs) + (ice-9 receive) + (ice-9 hash-table) + (ice-9 match)) + +;; In this example, a user firsts requests an account, then logs in +;; with a refresh token, then logs out, but we can still revive per +;; account, then the refresh token gets banned. + +(define (display-log simulation) + (format (current-error-port) "Log:\n") + (for-each + (match-lambda + ((request request-body response response-body) + (format (current-error-port) "~s ~s (~s): ~s ~s\n" + (request-method request) + (uri->string (request-uri request)) + request-body + (response-code response) + (response-reason-phrase response)))) + (sim:simulation-scroll-log! simulation)) + (exit 42)) + +(with-test-environment + "client-workflow" + (lambda () + (let ((simulation (sim:make-simulation))) + (sim:add-server! simulation + (string->uri "https://server@client-workflow.scm") + (string->uri "https://server@client-workflow.scm/alice#me")) + (sim:add-client! simulation + (string->uri "https://client@client-workflow.scm") + (string->uri "https://client@client-workflow.scm/id") + (string->uri "https://client@client-workflow.scm/authorized") + "Client workflow test" + (string->uri "https://client@client-workflow.scm/about")) + (let ((client (client:make-client + (string->uri "https://client@client-workflow.scm/id") + (jwk:generate-key #:n-size 2048) + (string->uri "https://client@client-workflow.scm/authorized")))) + (parameterize ((p:current-date 0) + (client:authorization-process + (lambda* (uri #:key issuer) + (sim:grant-authorization simulation uri)))) + (receive (response response-body) + (let ((handler + (client:request client #f + (string->uri "https://server@client-workflow.scm") + #:http-request (cute sim:request simulation <...>)))) + (handler (build-request (string->uri "https://server@client-workflow.scm/")) + #f)) + (unless (eqv? (response-code response) 200) + ;; Only Alice can read that resource. + (exit 3))) + (match (sim:simulation-scroll-log! simulation) + ;; 1. The client gets the oidc configuration of the + ;; server. + + ;; 2. The browser gets redirected to the authorization + ;; URI and POSTs the authorization form. The server makes + ;; a request to the client ID, which replies first. + + ;; 3. The authorization request completes. + + ;; 4. The client exchanges the authorization code for a + ;; refresh token. + + ;; 5. and 6. The client decodes the ID token and requests + ;; the server keys. + + ;; 7. and 8. While the client is waiting for the final response to + ;; complete, the server checks the access token validity by + ;; querying the identity provider for its key. + + ;; 9. The client sends the signed request to the / URI of + ;; the server. + (((get-oidc-config-request _ get-oidc-config-response _) + (get-client-id-request _ get-client-id-response _) + (authorization-request _ authorization-response _) + (token-request _ token-response _) + _ _ ;; the client gets the key + _ _ ;; the resource server gets the key + (final-request _ final-response _)) + (unless + (and + ;; 1. Get the authorization endpoint. + (equal? (request-uri get-oidc-config-request) + (string->uri "https://server@client-workflow.scm/.well-known/openid-configuration")) + (eqv? (response-code get-oidc-config-response) 200) + ;; 2. The server checks the client ID. + (equal? (request-uri get-client-id-request) + (string->uri "https://client@client-workflow.scm/id")) + (eqv? (response-code get-client-id-response) 200) + ;; 3. The authorization request completes. + (string-prefix? + "https://server@client-workflow.scm/authorize?" + (uri->string (request-uri authorization-request))) + (eq? (request-method authorization-request) 'POST) + (eqv? (response-code authorization-response) 302) + (string-prefix? + "https://client@client-workflow.scm/authorized?" + (uri->string (response-location authorization-response))) + ;; 4. Token negociation. + (equal? (request-uri token-request) + (string->uri "https://server@client-workflow.scm/token")) + (eqv? (response-code token-response) 200) + ;; 5. The final request. + (equal? (request-uri final-request) + (string->uri "https://server@client-workflow.scm/")) + (eqv? (response-code final-response) 200)) + (exit 4))))))))) |