Skip to content

Commit

Permalink
Merge pull request #452 from victorgama/CORS
Browse files Browse the repository at this point in the history
Add CORS header to public resources (Fix #242)
  • Loading branch information
tobias committed Jan 9, 2016
2 parents 77c82b7 + 1fcc700 commit b357243
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 23 deletions.
27 changes: 27 additions & 0 deletions src/clojars/http_utils.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
(ns clojars.http-utils
(:require [ring.middleware
[session :refer [wrap-session]]]))

(defn wrap-cors-headers [handler]
(fn [req]
(let [response (handler req)]
(if (= 200 (:status response))
(update-in response [:headers] assoc "Access-Control-Allow-Origin" "*")
response
))))

(defn wrap-x-frame-options [f]
(fn [req] (update-in (f req) [:headers] assoc "X-Frame-Options" "DENY")))

(defn https-request? [req]
(or (= (:scheme req) :https)
(= (get-in req [:headers "x-forwarded-proto"]) "https")))

(defn wrap-secure-session [f]
(let [secure-session (wrap-session f {:cookie-attrs {:secure true
:http-only true}})
regular-session (wrap-session f {:cookie-attrs {:http-only true}})]
(fn [req]
(if (https-request? req)
(secure-session req)
(regular-session req)))))
4 changes: 3 additions & 1 deletion src/clojars/routes/api.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
(ns clojars.routes.api
(:require [clojars
[db :as db]
[stats :as stats]]
[stats :as stats]
[http-utils :refer [wrap-cors-headers]]]
[compojure
[core :as compojure :refer [ANY context GET]]
[route :refer [not-found]]]
Expand Down Expand Up @@ -47,4 +48,5 @@

(defn routes [db stats]
(-> (handler db stats)
(wrap-cors-headers)
(wrap-restful-response :formats [:json :edn :yaml :transit-json])))
6 changes: 4 additions & 2 deletions src/clojars/routes/artifact.clj
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@
(cond
(= file-format "json") (-> (response/response (view/make-latest-version-json db group-id artifact-id))
(response/header "Cache-Control" "no-cache")
(response/content-type "application/json; charset=UTF-8"))
(response/content-type "application/json; charset=UTF-8")
(response/header "Access-Control-Allow-Origin" "*"))
(= file-format "svg") (-> (response/response (view/make-latest-version-svg db group-id artifact-id))
(response/header "Cache-Control" "no-cache")
(response/content-type "image/svg+xml")))))
(response/content-type "image/svg+xml")
(response/header "Access-Control-Allow-Origin" "*")))))

(defn routes [db reporter stats]
(compojure/routes
Expand Down
19 changes: 2 additions & 17 deletions src/clojars/web.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
[auth :refer [try-account]]
[config :refer [config]]
[db :as db]
[errors :refer [wrap-exceptions]]]
[errors :refer [wrap-exceptions]]
[http-utils :refer [wrap-x-frame-options wrap-secure-session]]]
[clojars.friend.registration :as registration]
[clojars.routes
[api :as api]
Expand Down Expand Up @@ -99,22 +100,6 @@
(swap! attempts bad-attempt username)
nil)))))

(defn wrap-x-frame-options [f]
(fn [req] (update-in (f req) [:headers] assoc "X-Frame-Options" "DENY")))

(defn https-request? [req]
(or (= (:scheme req) :https)
(= (get-in req [:headers "x-forwarded-proto"]) "https")))

(defn wrap-secure-session [f]
(let [secure-session (wrap-session f {:cookie-attrs {:secure true
:http-only true}})
regular-session (wrap-session f {:cookie-attrs {:http-only true}})]
(fn [req]
(if (https-request? req)
(secure-session req)
(regular-session req)))))

(defn clojars-app [db reporter stats search mailer]
(routes
(context "/repo" _
Expand Down
3 changes: 2 additions & 1 deletion src/clojars/web/search.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

(defn json-search [search query]
(let [response {:status 200
:headers {"Content-Type" "application/json; charset=UTF-8"}}]
:headers {"Content-Type" "application/json; charset=UTF-8"
"Access-Control-Allow-Origin" "*"}}]
(try
(assoc response
:body (let [results (search/search search query 1)]
Expand Down
7 changes: 5 additions & 2 deletions test/clojars/test/integration/api.clj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
[cheshire.core :as json]))

(use-fixtures :each
help/default-fixture
help/run-test-app)
help/default-fixture
help/run-test-app)

(defn get-api [parts & [opts]]
(-> (str "http://localhost:" help/test-port "/api/"
Expand Down Expand Up @@ -46,6 +46,9 @@
(testing "default format is json"
(is (= "application/json" (help/get-content-type (get-api [:groups "fake"])))))

(testing "api endpoints uses permissive cors settings"
(is (help/assert-cors-header (get-api [:groups "fake"]))))

(testing "list group artifacts"
(let [resp (get-api [:groups "fake"] {:accept :json})
body (json/parse-string (:body resp) true)]
Expand Down
23 changes: 23 additions & 0 deletions test/clojars/test/integration/artifact.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
(ns clojars.test.integration.artifact
(:require [clojure.test :refer :all]
[clojars.test.test-helper :as help]
[clojure.string :as str]
[clj-http.lite.client :as client]
[kerodon.core :refer [session]]
[clojars.test.integration.steps :refer [register-as inject-artifacts-into-repo!]]
[cheshire.core :as json]))

(use-fixtures :each
help/using-test-config
help/default-fixture
help/with-clean-database
help/run-test-app)

(defn get-artifact [parts & [opts]]
(-> (str "http://localhost:" help/test-port "/"
(str/join "/" (map name parts)))
(client/get opts)))

(deftest artifacts-test
(testing "latest-version.json should have permissive cors headers"
(is (help/assert-cors-header (get-artifact ["test" "latest-version.json"])))))
3 changes: 3 additions & 0 deletions test/clojars/test/integration/search.clj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
(is (= 200 (:status resp)))
(is (= "application/json" (help/get-content-type resp)))))

(testing "json request uses permissive cors headers"
(is (help/assert-cors-header (do-search :json "test"))))

(testing "default request returns html"
(let [resp (do-search "" "test")]
(is (= 200 (:status resp)))
Expand Down
5 changes: 5 additions & 0 deletions test/clojars/test/test_helper.clj
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,8 @@

(defn get-content-type [resp]
(some-> resp :headers (get "content-type") (string/split #";") first))

(defn assert-cors-header [resp]
(some-> resp :headers
(get "access-control-allow-origin")
(= "*")))

0 comments on commit b357243

Please sign in to comment.