(ns auto-ap.routes.auth (:require [auto-ap.datomic.users :as users] [buddy.sign.jwt :as jwt] [clj-http.client :as http] [clj-time.core :as time] [clojure.tools.logging :as log] [config.core :refer [env]] [com.brunobonacci.mulog :as mu])) (def google-client-id "264081895820-0nndcfo3pbtqf30sro82vgq5r27h8736.apps.googleusercontent.com") (def google-client-secret "OC-WemHurPXYpuIw5cT-B90g") #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} (defn make-api-token [] (jwt/sign {:user "API" :exp (time/plus (time/now) (time/days 1000)) :user/role "admin" :user/name "API"} (:jwt-secret env) {:alg :hs512})) (defn oauth [{{:strs [code state]} :query-params {:strs [host]} :headers :as request}] (try (let [auth (-> "https://accounts.google.com/o/oauth2/token" (http/post {:form-params {"client_id" google-client-id "client_secret" google-client-secret "code" code "redirect_uri" (str (:scheme env) "://" host "/api/oauth") "grant_type" "authorization_code"} :as :json}) :body) token (:access_token auth) profile (-> (http/get "https://www.googleapis.com/oauth2/v1/userinfo" {:headers {"Authorization" (str "Bearer " token)} :as :json}) :body) _ (mu/log ::got-profile :profile profile) user (users/find-or-insert! {:user/provider "google" :user/provider-id (:id profile) :user/email (:email profile) :user/profile-image-url (:picture profile) :user/name (:name profile)}) auth {:user (:name profile) :exp (time/plus (time/now) (time/days 30)) :db/id (:db/id user) :user/clients (map (fn [c] (select-keys c [:client/code :db/id :client/locations])) (:user/clients user)) :user/role (name (:user/role user)) :user/name (:name profile)} _ (mu/log ::logged-in-as :auth auth)] ;; TODO - these namespaces are not being transmitted/deserialized properly (if (and token user) (let [jwt (jwt/sign auth (:jwt-secret env) {:alg :hs512})] {:status 301 :headers {"Location" (str (or (not-empty state) "/") "?jwt=" jwt)} :session {:identity (dissoc auth :exp)}}) {:status 401 :body "Couldn't authenticate"})) (catch Exception e (log/warn e) {:status 401 :body (str "Couldn't authenticate " (.toString e))}))) (def routes {"api" {"/oauth" :oauth}}) (def match->handler {:oauth oauth})