diff --git a/resources/templates/base.html b/resources/templates/base.html index 99ba1e1..c14f6de 100644 --- a/resources/templates/base.html +++ b/resources/templates/base.html @@ -46,7 +46,7 @@
{{ error }}
- {% if error %} + {% endif %} {% endblock %}
diff --git a/resources/templates/error.html b/resources/templates/error.html index f811553..adc576e 100644 --- a/resources/templates/error.html +++ b/resources/templates/error.html @@ -2,7 +2,6 @@ {% block big-links %} {% endblock %} {% block content %} -
diff --git a/src/clj/youyesyet/oauth.clj b/src/clj/youyesyet/authentication.clj similarity index 95% rename from src/clj/youyesyet/oauth.clj rename to src/clj/youyesyet/authentication.clj index e96c29b..d967ab9 100644 --- a/src/clj/youyesyet/oauth.clj +++ b/src/clj/youyesyet/authentication.clj @@ -1,5 +1,5 @@ (ns ^{:doc "Handle oauth with multiple authenticating authorities." - :author "Simon Brooke"} youyesyet.oauth + :author "Simon Brooke"} youyesyet.authentication (:require [youyesyet.config :refer [env]] [youyesyet.db.core :as db] [oauth.client :as oauth] @@ -8,7 +8,8 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; -;;;; youyesyet.routes.home: routes and pages for unauthenticated users. +;;;; youyesyet.authentication: Handle oauth with multiple authenticating +;;;; authorities. ;;;; ;;;; This program is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU General Public License @@ -49,6 +50,7 @@ :hmac-sha1))) (db/list-authorities db/*db* {})))) + (def authority! ;; Closure to allow authorities map to be created once when the function is first ;; called. The argument `id` should be a string, the id of some authority diff --git a/src/clj/youyesyet/handler.clj b/src/clj/youyesyet/handler.clj index 983df79..8e48796 100644 --- a/src/clj/youyesyet/handler.clj +++ b/src/clj/youyesyet/handler.clj @@ -91,14 +91,18 @@ (-> #'rest-routes (wrap-routes middleware/wrap-formats)) (-> #'service-routes - (wrap-routes middleware/wrap-formats)) ;; TODO: and authentication, but let's not sweat the small stuff. - 'oauth-routes + (wrap-routes middleware/wrap-formats)) + (-> #'oauth-routes + (wrap-routes middleware/wrap-csrf) + (wrap-routes middleware/wrap-formats)) (route/resources "/") (route/not-found + (fn [request] + (log/error "NOT-FOUND: " request) (:body (error-page {:status 404 :title "Page not found" - :message "The page you requested has not yet been implemented"}))))) + :message (str "The page you requested has not yet been implemented: " (:uri request))})))))) (def app (middleware/wrap-base #'app-routes)) diff --git a/src/clj/youyesyet/layout.clj b/src/clj/youyesyet/layout.clj index 06f56f3..03a88d3 100644 --- a/src/clj/youyesyet/layout.clj +++ b/src/clj/youyesyet/layout.clj @@ -112,6 +112,7 @@ returns a response map with the error page as the body and the status specified by the status key" [error-details] + (log/error "ERROR: " error-details) {:status (:status error-details) :headers {"Content-Type" "text/html; charset=utf-8"} - :body (render "error.html" {} error-details)}) + :body (render "error.html" error-details)}) diff --git a/src/clj/youyesyet/routes/home.clj b/src/clj/youyesyet/routes/home.clj index 2f37538..92f3eb4 100644 --- a/src/clj/youyesyet/routes/home.clj +++ b/src/clj/youyesyet/routes/home.clj @@ -11,7 +11,7 @@ [youyesyet.config :refer [env]] [youyesyet.db.core :as db-core] [youyesyet.layout :as layout] - [youyesyet.oauth :as oauth] + [youyesyet.authentication :as auth] [compojure.core :refer [defroutes GET POST]] )) @@ -84,13 +84,13 @@ (str (:servlet-context request) "/roles"))] (cond (:authority params) - (let [auth (oauth/authority! (:authority params))] - (if auth + (let [authority (auth/authority! (:authority params))] + (if authority (do (log/info "Attempting to authorise with authority " (:authority params)) - (oauth/fetch-request-token - (assoc request :session (assoc session :authority auth)) - auth)) + (auth/fetch-request-token + (assoc request :session (assoc session :authority authority)) + authority)) (throw (Exception. (str "No such authority: " (:authority params)))))) ;; this is obviously, ABSURDLY, insecure. I don't want to put just-about-good-enough, ;; it-will-do-for-now security in place; instead, I want this to be test code only diff --git a/src/clj/youyesyet/routes/issue_experts.clj b/src/clj/youyesyet/routes/issue_experts.clj index 3989dca..f4a3060 100644 --- a/src/clj/youyesyet/routes/issue_experts.clj +++ b/src/clj/youyesyet/routes/issue_experts.clj @@ -12,13 +12,12 @@ [youyesyet.config :refer [env]] [youyesyet.db.core :as db] [youyesyet.layout :as layout] - [youyesyet.oauth :as oauth] [compojure.core :refer [defroutes GET POST]] )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; -;;;; youyesyet.routes.home: routes and pages for issue experts. +;;;; youyesyet.routes.issue-experts: routes and pages for issue experts. ;;;; ;;;; This program is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU General Public License diff --git a/src/clj/youyesyet/routes/logged_in.clj b/src/clj/youyesyet/routes/logged_in.clj index cb97171..90db790 100644 --- a/src/clj/youyesyet/routes/logged_in.clj +++ b/src/clj/youyesyet/routes/logged_in.clj @@ -12,7 +12,6 @@ [youyesyet.config :refer [env]] [youyesyet.db.core :as db] [youyesyet.layout :as layout] - [youyesyet.oauth :as oauth] [compojure.core :refer [defroutes GET POST]] )) diff --git a/src/clj/youyesyet/routes/oauth.clj b/src/clj/youyesyet/routes/oauth.clj index 0706672..68b0498 100644 --- a/src/clj/youyesyet/routes/oauth.clj +++ b/src/clj/youyesyet/routes/oauth.clj @@ -1,29 +1,40 @@ (ns ^{:doc "OAuth authentication routes - not finished, does not work yet." :author "Simon Brooke"} youyesyet.routes.oauth - (:require [clojure.tools.logging :as log] + (:require [adl-support.core :refer :all] + [clojure.tools.logging :as log] [compojure.core :refer [defroutes GET]] [ring.util.http-response :refer [ok found]] [clojure.java.io :as io] - [youyesyet.oauth :as oauth])) + [youyesyet.authentication :as auth] + [youyesyet.layout :refer [error-page]])) (defn oauth-init "Initiates the OAuth with the authority implied by this `request`" [request] - (let [authority (or - (:authority (:session request)) - (oauth/authority! (:authority (massage-params :request))))] - (if - authority - (assoc-in - (found - (oauth/auth-redirect-uri - (:request-token - (oauth/fetch-request-token request authority)) - authority)) - [:session :authority] - authority)))) - :session + (let [authority-name (:authority (massage-params request)) + authority (or + (:authority (:session request)) + (auth/authority! authority-name))] + (log/debug "Authenticating with oauth request: " request "; authority: " authority) + (if + authority + (do-or-log-error + (assoc-in + (auth/auth-redirect-uri + (:request-token + (auth/fetch-request-token request authority)) + authority) + [:session :authority] + authority) + :error-return + {:status 500 + :title "Error while seeking authentication" + :message "See server log for more detail"}) + (:body + (error-page {:status 404 + :title (str "No such authority: " authority-name) + :message "The authority you requested is unknown to this system."}))))) (defn oauth-callback @@ -35,12 +46,13 @@ (assoc :flash {:denied true})) ; fetch the request token and do anything else you wanna do if not denied. (let [{:keys [user_id screen_name]} - (oauth/fetch-access-token request_token (:authority session))] + (auth/fetch-access-token request_token (:authority session))] (log/info "successfully authenticated as" user_id screen_name) (-> (found "/") (assoc :session (assoc session :user-id user_id :screen-name screen_name)))))) + (defroutes oauth-routes (GET "/oauth/oauth-init" req (oauth-init req)) (GET "/oauth/oauth-callback" [& req_token :as req] (oauth-callback req_token req))) diff --git a/src/clj/youyesyet/routes/roles.clj b/src/clj/youyesyet/routes/roles.clj index 9a49acc..5bdfca8 100644 --- a/src/clj/youyesyet/routes/roles.clj +++ b/src/clj/youyesyet/routes/roles.clj @@ -11,7 +11,6 @@ [youyesyet.db.core :as db-core] [youyesyet.routes.issue-experts :as expert] [youyesyet.layout :as layout] - [youyesyet.oauth :as oauth] [youyesyet.routes.auto :as auto]))