From 526ad8f664ee9c44072cdfb70963149911a7e1dd Mon Sep 17 00:00:00 2001 From: Victor Gama Date: Mon, 4 Jan 2016 15:21:48 -0200 Subject: [PATCH 1/6] Implement assert-cors-header to test_helper --- test/clojars/test/test_helper.clj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/clojars/test/test_helper.clj b/test/clojars/test/test_helper.clj index 720ef1ed..369cdb9d 100644 --- a/test/clojars/test/test_helper.clj +++ b/test/clojars/test/test_helper.clj @@ -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") + (= "*"))) From d5d677e0ed9fda96ecf96a68b7234a5a273fae4b Mon Sep 17 00:00:00 2001 From: Victor Gama Date: Mon, 4 Jan 2016 15:22:58 -0200 Subject: [PATCH 2/6] Move http-related wrappers to http-utils --- src/clojars/http_utils.clj | 27 +++++++++++++++++++++++++++ src/clojars/web.clj | 19 ++----------------- 2 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 src/clojars/http_utils.clj diff --git a/src/clojars/http_utils.clj b/src/clojars/http_utils.clj new file mode 100644 index 00000000..a3b89617 --- /dev/null +++ b/src/clojars/http_utils.clj @@ -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))))) diff --git a/src/clojars/web.clj b/src/clojars/web.clj index 5a537abf..01b9f339 100644 --- a/src/clojars/web.clj +++ b/src/clojars/web.clj @@ -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] @@ -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" _ From cbd1ad2efeb8bdfc42e600e6c47a5ce5783e6844 Mon Sep 17 00:00:00 2001 From: Victor Gama Date: Mon, 4 Jan 2016 15:24:12 -0200 Subject: [PATCH 3/6] Add test cases to check CORS conformity --- test/clojars/test/integration/api.clj | 7 +++++-- test/clojars/test/integration/artifact.clj | 23 ++++++++++++++++++++++ test/clojars/test/integration/search.clj | 3 +++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 test/clojars/test/integration/artifact.clj diff --git a/test/clojars/test/integration/api.clj b/test/clojars/test/integration/api.clj index a281a44d..9c954d0a 100644 --- a/test/clojars/test/integration/api.clj +++ b/test/clojars/test/integration/api.clj @@ -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/" @@ -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)] diff --git a/test/clojars/test/integration/artifact.clj b/test/clojars/test/integration/artifact.clj new file mode 100644 index 00000000..4539b19c --- /dev/null +++ b/test/clojars/test/integration/artifact.clj @@ -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"]))))) diff --git a/test/clojars/test/integration/search.clj b/test/clojars/test/integration/search.clj index 1464ad66..203a4062 100644 --- a/test/clojars/test/integration/search.clj +++ b/test/clojars/test/integration/search.clj @@ -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))) From 1f14cd74baea286d0ddcacc0be28dff3607de580 Mon Sep 17 00:00:00 2001 From: Victor Gama Date: Mon, 4 Jan 2016 15:24:37 -0200 Subject: [PATCH 4/6] Ensure CORS conformity on /api --- src/clojars/routes/api.clj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/clojars/routes/api.clj b/src/clojars/routes/api.clj index 32016b63..32d29285 100644 --- a/src/clojars/routes/api.clj +++ b/src/clojars/routes/api.clj @@ -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]]] @@ -47,4 +48,5 @@ (defn routes [db stats] (-> (handler db stats) + (wrap-cors-headers) (wrap-restful-response :formats [:json :edn :yaml :transit-json]))) From 78a8b95a63e080de0cdac1daf875b3874dfda992 Mon Sep 17 00:00:00 2001 From: Victor Gama Date: Mon, 4 Jan 2016 15:25:03 -0200 Subject: [PATCH 5/6] Ensure CORS conformity on artifact endpoints --- src/clojars/routes/artifact.clj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/clojars/routes/artifact.clj b/src/clojars/routes/artifact.clj index c64756b6..00b4fcbb 100644 --- a/src/clojars/routes/artifact.clj +++ b/src/clojars/routes/artifact.clj @@ -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 From 1fcc7001a079535bbe42bdd697605ae90db1c8f9 Mon Sep 17 00:00:00 2001 From: Victor Gama Date: Mon, 4 Jan 2016 15:25:20 -0200 Subject: [PATCH 6/6] Ensure CORS conformity on /search endpoints --- src/clojars/web/search.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/clojars/web/search.clj b/src/clojars/web/search.clj index e2f23699..d7930ef7 100644 --- a/src/clojars/web/search.clj +++ b/src/clojars/web/search.clj @@ -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)]