Improve OICD attrs lookup mechanism

This commit is contained in:
Andrey Antukh 2023-04-25 12:00:03 +02:00
parent 364dadc93f
commit c0ccc4a5c5
3 changed files with 28 additions and 23 deletions

View file

@ -1,4 +1,3 @@
;; Example climit.edn file
;; Required: concurrency ;; Required: concurrency
;; Optional: queue-size, ommited means Integer/MAX_VALUE ;; Optional: queue-size, ommited means Integer/MAX_VALUE
{:update-file {:concurrency 1 :queue-size 3} {:update-file {:concurrency 1 :queue-size 3}

View file

@ -165,8 +165,8 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- retrieve-github-email (defn- retrieve-github-email
[cfg tdata info] [cfg tdata props]
(or (some-> info :email p/resolved) (or (some-> props :github/email p/resolved)
(->> (http/req! cfg (->> (http/req! cfg
{:uri "https://api.github.com/user/emails" {:uri "https://api.github.com/user/emails"
:headers {"Authorization" (dm/str (:type tdata) " " (:token tdata))} :headers {"Authorization" (dm/str (:type tdata) " " (:token tdata))}
@ -246,6 +246,11 @@
;; HANDLERS ;; HANDLERS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- parse-attr-path
[provider path]
(let [[fitem & items] (str/split path "__")]
(into [(keyword (:name provider) fitem)] (map keyword) items)))
(defn- build-redirect-uri (defn- build-redirect-uri
[{:keys [provider] :as cfg}] [{:keys [provider] :as cfg}]
(let [public (u/uri (cf/get :public-uri))] (let [public (u/uri (cf/get :public-uri))]
@ -316,6 +321,7 @@
:headers {"Authorization" (str (:type tdata) " " (:token tdata))} :headers {"Authorization" (str (:type tdata) " " (:token tdata))}
:timeout 6000 :timeout 6000
:method :get})) :method :get}))
(validate-response [response] (validate-response [response]
(l/trace :hint "user info response" (l/trace :hint "user info response"
:status (:status response) :status (:status response)
@ -328,26 +334,30 @@
:http-body (:body response))) :http-body (:body response)))
response) response)
(get-email [info] (get-email [props]
;; Allow providers hook into this for custom email ;; Allow providers hook into this for custom email
;; retrieval method. ;; retrieval method.
(if-let [get-email-fn (:get-email-fn provider)] (if-let [get-email-fn (:get-email-fn provider)]
(get-email-fn tdata info) (get-email-fn tdata props)
(let [attr-kw (cf/get :oidc-email-attr :email)] (let [attr-kw (cf/get :oidc-email-attr "email")
(p/resolved (get info attr-kw))))) attr-ph (parse-attr-path provider attr-kw)]
(p/resolved (get-in props attr-ph)))))
(get-name [info] (get-name [info]
(let [attr-kw (cf/get :oidc-name-attr :name)] (let [attr-kw (cf/get :oidc-name-attr "name")
(get info attr-kw))) attr-ph (parse-attr-path provider attr-kw)]
(get-in info attr-ph)))
(process-response [response] (process-response [response]
(p/let [info (-> response :body json/decode) (p/let [info (-> response :body json/decode)
email (get-email info)] props (qualify-props provider info)
email (get-email props)]
{:backend (:name provider) {:backend (:name provider)
:fullname (or (get-name props) email)
:email email :email email
:fullname (or (get-name info) email) :props props}))
:props (->> (dissoc info :name :email)
(qualify-props provider))}))
(validate-info [info] (validate-info [info]
(l/trace :hint "authentication info" :info info) (l/trace :hint "authentication info" :info info)
@ -377,19 +387,15 @@
(defn get-info (defn get-info
[{:keys [provider] :as cfg} {:keys [params] :as request}] [{:keys [provider] :as cfg} {:keys [params] :as request}]
(letfn [(parse-oidc-attrs-path [path] (letfn [(validate-oidc [{:keys [props] :as info}]
(let [[fitem & items] (str/split path "__")]
(into [(keyword "oidc" fitem)] (map keyword) items)))
(validate-oidc [info]
;; If the provider is OIDC, we can proceed to check ;; If the provider is OIDC, we can proceed to check
;; roles if they are defined. ;; roles if they are defined.
(when (and (= "oidc" (:name provider)) (when (and (= "oidc" (:name provider))
(seq (:roles provider))) (seq (:roles provider)))
(let [expected-roles (into #{} (:roles provider)) (let [expected-roles (into #{} (:roles provider))
current-roles (let [roles (->> (cf/get :oidc-roles-attr "roles") current-roles (let [roles-kw (cf/get :oidc-roles-attr "roles")
(parse-oidc-attrs-path) roles-ph (parse-attr-path provider roles-kw)
(get-in info))] roles (get-in props roles-ph)]
(cond (cond
(string? roles) (into #{} (str/words roles)) (string? roles) (into #{} (str/words roles))
(vector? roles) (into #{} roles) (vector? roles) (into #{} roles)

View file

@ -154,8 +154,8 @@
(s/def ::oidc-scopes ::us/set-of-strings) (s/def ::oidc-scopes ::us/set-of-strings)
(s/def ::oidc-roles ::us/set-of-strings) (s/def ::oidc-roles ::us/set-of-strings)
(s/def ::oidc-roles-attr ::us/string) (s/def ::oidc-roles-attr ::us/string)
(s/def ::oidc-email-attr ::us/keyword) (s/def ::oidc-email-attr ::us/string)
(s/def ::oidc-name-attr ::us/keyword) (s/def ::oidc-name-attr ::us/string)
(s/def ::host ::us/string) (s/def ::host ::us/string)
(s/def ::http-server-port ::us/integer) (s/def ::http-server-port ::us/integer)
(s/def ::http-server-host ::us/string) (s/def ::http-server-host ::us/string)