<commit_before>(ns metabase.middleware.auth
  "Middleware for dealing with authentication and session management."
  (:require [korma.core :refer :all]
            [metabase.db :refer [sel]]
            [metabase.api.common :refer [*current-user* *current-user-id*]]
            (metabase.models [session :refer [Session]]
                             [user :refer [User current-user-fields]])))


(def SESSION_COOKIE "metabase.SESSION_ID")
(def SESSION_HEADER "x-metabase-session")


(defn wrap-sessionid
  "Middleware that sets the :metabase-sessionid keyword on the request if a session id can be found.

   We first check the request :cookies for `metabase.SESSION_ID`, then if no cookie is found we look in the
   http headers for `X-METABASE-SESSION`.  If neither is found then then no keyword is bound to the request."
  [handler]
  (fn [{:keys [cookies headers] :as request}]
    (if-let [session-id (or (get-in cookies [SESSION_COOKIE :value]) (headers SESSION_HEADER))]
      ;; alternatively we could always associate the keyword and just let it be nil if there is no value
      (handler (assoc request :metabase-sessionid session-id))
      (handler request))))


(defn enforce-authentication
  "Middleware that enforces authentication of the client, cancelling the request processing if auth fails.

   Authentication is determined by validating the :metabase-sessionid on the request against the db session list.
   If the session is valid then we associate a :metabase-userid on the request and carry on, but if the validation
   fails then we return an HTTP 401 response indicating that the client is not authentic.

   NOTE: we are purposely not associating the full current user object here so that we can be modular."
  [handler]
  (fn [{:keys [metabase-sessionid] :as request}]
    (if-let [session (sel :one Session :id metabase-sessionid)]
      ;; TODO - enforce session expiration
      ;; TODO - validate user is_active?
      (handler (assoc request :metabase-userid (:user_id session)))
      {:status 401 :body "Unauthenticated"})))


(defmacro sel-current-user [current-user-id]
  `(sel :one [User ~@current-user-fields]
     :id ~current-user-id))


(defn bind-current-user<commit_msg>upgrade authentication check middleware to validate that session user `is_active = true` and session age is less than max-session-age<commit_after>(ns metabase.middleware.auth
  "Middleware for dealing with authentication and session management."
  (:require [korma.core :as korma]
            [metabase.config :as config]
            [metabase.db :refer [sel]]
            [metabase.api.common :refer [*current-user* *current-user-id*]]
            (metabase.models [session :refer [Session]]
                             [user :refer [User current-user-fields]])))


(def SESSION_COOKIE "metabase.SESSION_ID")
(def SESSION_HEADER "x-metabase-session")

(def response-unauthentic {:status 401 :body "Unauthenticated"})


(defn wrap-sessionid
  "Middleware that sets the :metabase-sessionid keyword on the request if a session id can be found.

   We first check the request :cookies for `metabase.SESSION_ID`, then if no cookie is found we look in the
   http headers for `X-METABASE-SESSION`.  If neither is found then then no keyword is bound to the request."
  [handler]
  (fn [{:keys [cookies headers] :as request}]
    (if-let [session-id (or (get-in cookies [SESSION_COOKIE :value]) (headers SESSION_HEADER))]
      ;; alternatively we could always associate the keyword and just let it be nil if there is no value
      (handler (assoc request :metabase-sessionid session-id))
      (handler request))))


(defn enforce-authentication
  "Middleware that enforces authentication of the client, cancelling the request processing if auth fails.

   Authentication is determined by validating the :metabase-sessionid on the request against the db session list.
   If the session is valid then we associate a :metabase-userid on the request and carry on, but if the validation
   fails then we return an HTTP 401 response indicating that the client is not authentic.

   NOTE: we are purposely not associating the full current user object here so that we can be modular."
  [handler]
  (fn [{:keys [metabase-sessionid] :as request}]
    ;; TODO - what kind of validations can we do on the sessionid to make sure it's safe to handle?  str?  alphanumeric?
    (let [session (first (korma/select Session
                           ;; NOTE: we join with the User table and ensure user.is_active = true
                           (korma/with User (korma/where {:is_active true}))
                           (korma/fields :created_at)
                           (korma/where {:id metabase-sessionid})))
          session-age (- (System/currentTimeMillis) (.getTime (get session :created_at (java.util.Date. 0))))]
      ;; If the session exists and is not expired (max-session-age > session-age) then validation is good
      (when (and session (> (:max-session-age config/app-defaults) session-age))
        (handler (assoc request :metabase-userid (:user_id session))))
      ;; default response is 401
      response-unauthentic)))


(defmacro sel-current-user [current-user-id]
  `(sel :one [User ~@current-user-fields]
     :id ~current-user-id))


(defn bind-current-user
{'fraction_non_alphanumeric': 0.09357277882797732, 'fraction_numerical': 0.0030245746691871457, 'mean_word_length': 3.322712418300654, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7369635', 'n_tokens_mistral': 1522, 'n_tokens_neox': 1465, 'n_words': 595}