001  (ns ring.middleware.okta
002    "Ring middleware for Okta Single Sign-on"
003    (:require [clojure.java.io :as io]
004              [compojure.core :refer [POST defroutes]]
005              [ring.ring-okta.predicates :as p]
006              [ring.ring-okta.session :as okta-session]
007              [ring.util.response :as ring-response]))
008  
009  (defroutes okta-routes
010    "The compojure routes for Okta
011  
012     POST /login
013     POST /logout"
014  
015    {:added "0.1.0"}
016  
017    (POST "/login" request
018          (okta-session/login request))
019  
020    (POST "/logout" request
021          (okta-session/logout request)
022          (merge (ring-response/redirect (:redirect-after-logout request) (ring-response/redirect-status-codes :see-other)))))
023  
024  (defn wrap-okta
025    "Ring middleware for Okta Single Sign-on
026  
027    Arguments:
028  
029    handler                - the ring handler function
030  
031    okta-home              - the URL to be redirected to for Okta login
032                             e.g. https://company.okta.com
033  
034    Accepts the following options:
035  
036    :okta-config           - the location of the Okta configuration file
037                             (defaults to \"resources/okta-config.xml\")
038  
039    :redirect-after-logout - the destination URL to be redirected to after a `POST /logout`
040                             (defaults to \"/\")
041  
042    :skip-routes           - a list of routes as a string or regex to skip Okta authentication
043                             e.g. [:get \"/about\" :any \"/contact\" :get \"/home/\\S+\"]
044  
045    :force-user            - a default user to be used for development"
046  
047    {:arglists '([handler okta-home] [handler okta-home options]) :added "0.1.0"}
048  
049    ([handler okta-home] (wrap-okta handler okta-home {}))
050  
051    ([handler okta-home {:keys [okta-config redirect-after-logout]
052                         :or {okta-config (io/resource "okta-config.xml")
053                              redirect-after-logout "/"}
054                         :as options}]
055  
056     {:pre [(not-empty okta-home)]}
057  
058     (fn [request]
059       (cond
060         (p/login? request) (handler (assoc request :okta-config-location okta-config))
061         (p/logout? request) (handler (assoc request :redirect-after-logout redirect-after-logout))
062         (p/logged-in? request) (handler request)
063         (p/force-user? (:force-user options)) (handler (assoc-in request [:session :okta/user] (:force-user options)))
064         (p/skip-route? request (:skip-routes options)) (handler request)
065         :else (ring-response/redirect okta-home)))))