<commit_before>(ns org.openforis.ceo.handler
  (:require [clojure.data.json :as json]
            [clojure.edn       :as edn]
            [clojure.string    :as str]
            [ring.middleware.absolute-redirects :refer [wrap-absolute-redirects]]
            [ring.middleware.content-type       :refer [wrap-content-type]]
            [ring.middleware.default-charset    :refer [wrap-default-charset]]
            [ring.middleware.gzip               :refer [wrap-gzip]]
            [ring.middleware.json               :refer [wrap-json-params]]
            [ring.middleware.keyword-params     :refer [wrap-keyword-params]]
            [ring.middleware.nested-params      :refer [wrap-nested-params]]
            [ring.middleware.not-modified       :refer [wrap-not-modified]]
            [ring.middleware.multipart-params   :refer [wrap-multipart-params]]
            [ring.middleware.params             :refer [wrap-params]]
            [ring.middleware.resource           :refer [wrap-resource]]
            [ring.middleware.reload             :refer [wrap-reload]]
            [ring.middleware.session            :refer [wrap-session]]
            [ring.middleware.ssl                :refer [wrap-ssl-redirect]]
            [ring.middleware.x-headers          :refer [wrap-frame-options wrap-content-type-options wrap-xss-protection]]
            [ring.util.codec                    :refer [url-decode]]
            [org.openforis.ceo.logging          :refer [log-str]]
            [org.openforis.ceo.remote-api       :refer [api-handler]]
            [org.openforis.ceo.views            :refer [render-page not-found-page data-response]]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Routing Handler
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; FIXME: Fill these in as you make pages.
(def view-routes #{"/"
                   "/about"
                   "/accout"
                   "/collection"
                   "/create-instituion"
                   "/create-project"
                   "/geo-dash"
                   "/geo-dash/geo-dash-help" ; TODO flatten url structure
                   "/home"
                   "/institution-dashboard"
                   "/login"
                   "/password-request"
                   "/password-reset"
                   "/project-dashboard"
                   "/register"
                   "/review-institution"
                   "/review-project"
                   "/support"
                   "/widget-layout-editor"
                   "/mailing-list"
                   "/unsubscribe-mailing-list"})

(def proxy-routes #{"/get-tile"
                    "/get-securewatch-dates"})

                 ;; Users API
(def api-routes {"/get-all-users"                  :get
                 "/get-institution-users"          :get
                 "/get-user-details"               :get
                 "/get-user-stats"                 :get
                 "/account"                        :post
                 "/login"                          :post
                 "/logout"                         :post
                 "/register"                       :post
                 "/password-reset"                 :post
                 "/password-request"               :post
                 "/update-user-institution-role"   :post
                 "/request-institution-membership" :post
                 "/send-to-mailing-list"           :post
                 "/unsubscribe-mailing-list"       :post
                 ;; Project API
                 "/dump-project-aggregate-data" :get
                 "/dump-project-raw-data"       :get
                 "/get-all-projects"            :get
                 "/get-project-by-id"           :get
                 "/get-project-stats"           :get
                 "/archive-project"             :post
                 "/close-project"               :post
                 "/create-project"              :post
                 "/publish-project"             :post
                 "/update-project"              :post
                 ;; Plots API
                 "/get-next-plot"      :get
                 "/get-plot-by-id"     :get
                 "/get-prev-plot"      :get
                 "/get-project-plots"  :get
                 "/get-proj-plot"      :get
                 "/add-user-samples"   :post
                 "/flag-plot"          :post
                 "/release-plot-locks" :post
                 "/reset-plot-lock"    :post
                 ;; Institutions API
                 "/get-all-institutions"    :get
                 "/get-institution-details" :get
                 "/archive-institution"     :post
                 "/create-institution"      :post
                 "/update-institution"      :post
                 ;; Imagery API
                 "/get-institution-imagery"     :get
                 "/get-project-imagery"         :get
                 "/get-public-imagery"          :get
                 "/add-geodash-imagery"         :post
                 "/add-institution-imagery"     :post
                 "/update-institution-imagery"  :post
                 "/archive-institution-imagery" :post
                 ;; GeoDash API
                 ;; TODO flatten routes
                 "/geo-dash/get-by-projid"   :get
                 "/geo-dash/create-widget"   :post
                 "/geo-dash/delete-widget"   :post
                 "/geo-dash/gateway-request" :post
                 "/geo-dash/update-widget"   :post})

;; FIXME: Add any conditions you want for URLs you want to exclude up front.
(defn bad-uri? [uri] (str/includes? (str/lower-case uri) "php"))

(defn forbidden-response [_]
  (data-response "Forbidden" {:status 403}))

(defn routing-handler [{:keys [uri request-method] :as request}]
  (let [next-handler (cond
                       (bad-uri? uri)
                       forbidden-response

                       (= uri "/")
                       (render-page "/home")

                       (and (contains? view-routes uri)
                            (= request-method :get))
                       (render-page uri)

                       (and (contains? api-routes uri)
                            (= request-method (api-routes uri)))
                       (api-handler uri)

                       (and (contains? proxy-routes uri)
                            (= request-method :get))
                       (data-response "")

                       :else
                       not-found-page)]
    (next-handler request)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Custom Middlewares
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn wrap-request-logging [handler]
  (fn [request]
    (let [{:keys [uri request-method params]} request
          param-str (pr-str (dissoc params :password :passwordConfirmation))]
      (log-str "Request(" (name request-method) "): \"" uri "\" " param-str)
      (handler request))))

(defn wrap-response-logging [handler]
  (fn [request]
    (let [{:keys [status headers body] :as response} (handler request)
          content-type (headers "Content-Type")]
      (log-str "Response(" status "): "
               (cond
                 (str/includes? content-type "text/html")
                 "<html>...</html>"

                 (= content-type "application/edn")<commit_msg>Web review changes<commit_after>(ns org.openforis.ceo.handler
  (:require [clojure.data.json :as json]
            [clojure.edn       :as edn]
            [clojure.string    :as str]
            [ring.middleware.absolute-redirects :refer [wrap-absolute-redirects]]
            [ring.middleware.content-type       :refer [wrap-content-type]]
            [ring.middleware.default-charset    :refer [wrap-default-charset]]
            [ring.middleware.gzip               :refer [wrap-gzip]]
            [ring.middleware.json               :refer [wrap-json-params]]
            [ring.middleware.keyword-params     :refer [wrap-keyword-params]]
            [ring.middleware.nested-params      :refer [wrap-nested-params]]
            [ring.middleware.not-modified       :refer [wrap-not-modified]]
            [ring.middleware.multipart-params   :refer [wrap-multipart-params]]
            [ring.middleware.params             :refer [wrap-params]]
            [ring.middleware.resource           :refer [wrap-resource]]
            [ring.middleware.reload             :refer [wrap-reload]]
            [ring.middleware.session            :refer [wrap-session]]
            [ring.middleware.ssl                :refer [wrap-ssl-redirect]]
            [ring.middleware.x-headers          :refer [wrap-frame-options wrap-content-type-options wrap-xss-protection]]
            [ring.util.codec                    :refer [url-decode]]
            [org.openforis.ceo.logging          :refer [log-str]]
            [org.openforis.ceo.remote-api       :refer [api-handler]]
            [org.openforis.ceo.views            :refer [render-page not-found-page data-response]]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Routing Handler
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; FIXME: Fill these in as you make pages.
(def view-routes #{"/"
                   "/about"
                   "/account"
                   "/collection"
                   "/create-institution"
                   "/create-project"
                   "/geo-dash"
                   "/geo-dash/geo-dash-help" ; TODO flatten url structure
                   "/home"
                   "/institution-dashboard"
                   "/login"
                   "/password-request"
                   "/password-reset"
                   "/project-dashboard"
                   "/register"
                   "/review-institution"
                   "/review-project"
                   "/support"
                   "/widget-layout-editor"
                   "/mailing-list"
                   "/unsubscribe-mailing-list"})

(def proxy-routes #{"/get-tile"
                    "/get-securewatch-dates"})

                 ;; Users API
(def api-routes {"/get-all-users"                  :get
                 "/get-institution-users"          :get
                 "/get-user-details"               :get
                 "/get-user-stats"                 :get
                 "/account"                        :post
                 "/login"                          :post
                 "/logout"                         :post
                 "/register"                       :post
                 "/password-reset"                 :post
                 "/password-request"               :post
                 "/update-user-institution-role"   :post
                 "/request-institution-membership" :post
                 "/send-to-mailing-list"           :post
                 "/unsubscribe-mailing-list"       :post
                 ;; Projects API
                 "/dump-project-aggregate-data" :get
                 "/dump-project-raw-data"       :get
                 "/get-all-projects"            :get
                 "/get-project-by-id"           :get
                 "/get-project-stats"           :get
                 "/archive-project"             :post
                 "/close-project"               :post
                 "/create-project"              :post
                 "/publish-project"             :post
                 "/update-project"              :post
                 ;; Plots API
                 "/get-next-plot"      :get
                 "/get-plot-by-id"     :get
                 "/get-prev-plot"      :get
                 "/get-project-plots"  :get
                 "/get-proj-plot"      :get
                 "/add-user-samples"   :post
                 "/flag-plot"          :post
                 "/release-plot-locks" :post
                 "/reset-plot-lock"    :post
                 ;; Institutions API
                 "/get-all-institutions"    :get
                 "/get-institution-details" :get
                 "/archive-institution"     :post
                 "/create-institution"      :post
                 "/update-institution"      :post
                 ;; Imagery API
                 "/get-institution-imagery"     :get
                 "/get-project-imagery"         :get
                 "/get-public-imagery"          :get
                 "/add-geodash-imagery"         :post
                 "/add-institution-imagery"     :post
                 "/update-institution-imagery"  :post
                 "/archive-institution-imagery" :post
                 ;; GeoDash API
                 ;; TODO flatten routes
                 "/geo-dash/get-by-projid"   :get
                 "/geo-dash/create-widget"   :post
                 "/geo-dash/delete-widget"   :post
                 "/geo-dash/gateway-request" :post
                 "/geo-dash/update-widget"   :post})

;; FIXME: Add any conditions you want for URLs you want to exclude up front.
(defn bad-uri? [uri] (str/includes? (str/lower-case uri) "php"))

(defn forbidden-response [_]
  (data-response "Forbidden" {:status 403}))

(defn routing-handler [{:keys [uri request-method] :as request}]
  (let [next-handler (cond
                       (bad-uri? uri)
                       forbidden-response

                       (= uri "/")
                       (render-page "/home")

                       (and (contains? view-routes uri)
                            (= request-method :get))
                       (render-page uri)

                       (= request-method (api-routes uri))
                       (api-handler uri)

                       (and (contains? proxy-routes uri)
                            (= request-method :get))
                       (data-response "") ; FIXME missing proxy implementation

                       :else
                       not-found-page)]
    (next-handler request)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Custom Middlewares
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn wrap-request-logging [handler]
  (fn [request]
    (let [{:keys [uri request-method params]} request
          param-str (pr-str (dissoc params :password :passwordConfirmation))]
      (log-str "Request(" (name request-method) "): \"" uri "\" " param-str)
      (handler request))))

(defn wrap-response-logging [handler]
  (fn [request]
    (let [{:keys [status headers body] :as response} (handler request)
          content-type (headers "Content-Type")]
      (log-str "Response(" status "): "
               (cond
                 (str/includes? content-type "text/html")
                 "<html>...</html>"

                 (= content-type "application/edn")
{'fraction_non_alphanumeric': 0.13877858414350266, 'fraction_numerical': 0.0004107900862659181, 'mean_word_length': 1.157925838380854, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '1066403', 'n_tokens_mistral': 3856, 'n_tokens_neox': 3701, 'n_words': 711}