Created
March 6, 2021 04:40
-
-
Save lispnik/a6394ed3c1b971947a97cac6afa3727c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ql:quickload '("clack" "lack" "lack-middleware-mount" "cl-dotenv" "quri" "uuid" "dexador" "jsown")) | |
(defpackage #:example | |
(:use #:common-lisp)) | |
(in-package #:example) | |
(.env:load-env (merge-pathnames ".env")) | |
(defvar *okta-authorize-uri* (quri:uri (uiop:getenv "OKTA_AUTHORIZE_URI"))) | |
(defvar *okta-token-uri* (quri:uri (uiop:getenv "OKTA_TOKEN_URI"))) | |
(defvar *okta-redirect-uri* (quri:uri (uiop:getenv "OKTA_REDIRECT_URI"))) | |
(defvar *okta-client-id* (uiop:getenv "OKTA_CLIENT_ID")) | |
(defvar *okta-client-secret* (uiop:getenv "OKTA_CLIENT_SECRET")) | |
(defvar *app* | |
(lack:builder | |
:session | |
(:mount "/login" 'login) | |
(:mount "/logout" 'logout) | |
(:mount (quri:uri-path *okta-redirect-uri*) 'redirect) | |
'main)) | |
(defun main (env) | |
(list 200 '(:content-type "text/plain") | |
(list "main"))) | |
(defun make-authorize-uri (state) | |
(let ((uri (quri:copy-uri *okta-authorize-uri*))) | |
(setf (quri:uri-query-params uri) | |
`(("client_id" . ,*okta-client-id*) | |
("response_type" . "code") | |
("redirect_uri" . ,(quri:render-uri *okta-redirect-uri*)) | |
("scope" . "openid") | |
("state" . ,state))) | |
uri)) | |
(defun login (env) | |
(let ((state (uuid:make-v4-uuid))) | |
(setf (gethash :app.auth-state (getf env :lack.session)) state) | |
(list 302 `(:location ,(make-authorize-uri state)) nil))) | |
(defun logout (env) | |
(list 200 '(:content-type "text/plain") | |
(list "logout"))) | |
(defun redirect (env) | |
(let ((redirect-state | |
(ignore-errors | |
(uuid:make-uuid-from-string (cdr (assoc "state" (getf env :query-parameters) :test #'string=))))) | |
(session-state | |
(gethash :app.auth-state (getf env :lack.session)))) | |
(if (and redirect-state (uuid:uuid= redirect-state session-state)) | |
(let* ((code (cdr (assoc "code" (getf env :query-parameters) :test #'string=))) | |
(content `(("client_id" . ,*okta-client-id*) | |
("client_secret" . ,*okta-client-secret*) | |
("grant_type" . "authorization_code") | |
("code" . ,code) | |
("redirect_uri" . ,(quri:render-uri *okta-redirect-uri*))))) | |
(multiple-value-bind (body status) | |
(dex:post *okta-token-uri* :content content) | |
(if (= 200 status) | |
(let ((payload (jsown:parse body))) | |
(list 200 '(:content-type "text/plain") | |
(list (format nil "redirect~%~S~%~S" env payload)))) | |
(list 400 nil nil)))) | |
(list 400 nil nil)))) | |
#+nil | |
(progn | |
(clack:clackup *app*)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment