mirror of https://github.com/penpot/penpot.git
85 lines
2.5 KiB
Clojure
85 lines
2.5 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS INC
|
|
|
|
(ns app.http.access-token
|
|
(:require
|
|
[app.common.logging :as l]
|
|
[app.config :as cf]
|
|
[app.db :as db]
|
|
[app.main :as-alias main]
|
|
[app.setup :as-alias setup]
|
|
[app.tokens :as tokens]
|
|
[yetti.request :as yreq]))
|
|
|
|
(def header-re #"^Token\s+(.*)")
|
|
|
|
(defn- get-token
|
|
[request]
|
|
(some->> (yreq/get-header request "authorization")
|
|
(re-matches header-re)
|
|
(second)))
|
|
|
|
(defn- decode-token
|
|
[props token]
|
|
(when token
|
|
(tokens/verify props {:token token :iss "access-token"})))
|
|
|
|
(def sql:get-token-data
|
|
"SELECT perms, profile_id, expires_at
|
|
FROM access_token
|
|
WHERE id = ?
|
|
AND (expires_at IS NULL
|
|
OR (expires_at > now()));")
|
|
|
|
(defn- get-token-data
|
|
[pool token-id]
|
|
(when-not (db/read-only? pool)
|
|
(some-> (db/exec-one! pool [sql:get-token-data token-id])
|
|
(update :perms db/decode-pgarray #{}))))
|
|
|
|
(defn- wrap-soft-auth
|
|
"Soft Authentication, will be executed synchronously on the undertow
|
|
worker thread."
|
|
[handler {:keys [::setup/props]}]
|
|
(letfn [(handle-request [request]
|
|
(try
|
|
(let [token (get-token request)
|
|
claims (decode-token props token)]
|
|
(cond-> request
|
|
(map? claims)
|
|
(assoc ::id (:tid claims))))
|
|
(catch Throwable cause
|
|
(l/trace :hint "exception on decoding malformed token" :cause cause)
|
|
request)))]
|
|
|
|
(fn [request]
|
|
(handler (handle-request request)))))
|
|
|
|
(defn- wrap-authz
|
|
"Authorization middleware, will be executed synchronously on vthread."
|
|
[handler {:keys [::db/pool]}]
|
|
(fn [request]
|
|
(let [{:keys [perms profile-id expires-at]} (some->> (::id request) (get-token-data pool))]
|
|
(handler (cond-> request
|
|
(some? perms)
|
|
(assoc ::perms perms)
|
|
(some? profile-id)
|
|
(assoc ::profile-id profile-id)
|
|
(some? expires-at)
|
|
(assoc ::expires-at expires-at))))))
|
|
|
|
(def soft-auth
|
|
{:name ::soft-auth
|
|
:compile (fn [& _]
|
|
(when (contains? cf/flags :access-tokens)
|
|
wrap-soft-auth))})
|
|
|
|
(def authz
|
|
{:name ::authz
|
|
:compile (fn [& _]
|
|
(when (contains? cf/flags :access-tokens)
|
|
wrap-authz))})
|