This commit is contained in:
simon 2017-09-01 22:19:49 +01:00
parent 4d205a4042
commit 3e686e9c5b
11 changed files with 44 additions and 33 deletions

View file

@ -16,6 +16,7 @@
[com.taoensso/encore "2.91.1"] [com.taoensso/encore "2.91.1"]
[lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]] [lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]]
[com.cemerick/url "0.1.1"] [com.cemerick/url "0.1.1"]
[ring/ring-anti-forgery "1.1.0"]
[ring-server "0.4.0"] [ring-server "0.4.0"]
[selmer "1.10.9"] [selmer "1.10.9"]
[org.clojure/tools.logging "0.4.0"] [org.clojure/tools.logging "0.4.0"]

View file

@ -2,6 +2,7 @@
{% block content %} {% block content %}
<div id="content" class="auth"> <div id="content" class="auth">
<form action="{{servlet-context}}/auth" method="POST"> <form action="{{servlet-context}}/auth" method="POST">
{% csrf-field %}
<input type="hidden" name="redirect-to" value="{{redirect-to}}"/> <input type="hidden" name="redirect-to" value="{{redirect-to}}"/>
{% if user %} {% if user %}
<p class="widget"> <p class="widget">

View file

@ -3,6 +3,7 @@
{% block content %} {% block content %}
<div id="content" class="edit"> <div id="content" class="edit">
<form action="{{servlet-context}}/edit-css" method="POST"> <form action="{{servlet-context}}/edit-css" method="POST">
{% csrf-field %}
<input type="hidden" name="page" value="{{page}}"/> <input type="hidden" name="page" value="{{page}}"/>
<textarea name="src" id="src" rows="25" cols="80">{{content}}</textarea> <textarea name="src" id="src" rows="25" cols="80">{{content}}</textarea>
<p class="widget"> <p class="widget">

View file

@ -3,6 +3,7 @@
{% block content %} {% block content %}
<div id="content" class="edit"> <div id="content" class="edit">
<form action="{{servlet-context}}/edit-user" method="POST"> <form action="{{servlet-context}}/edit-user" method="POST">
{% csrf-field %}
<p class="widget"> <p class="widget">
<label for="target">{{config.username-prompt}}</label> <label for="target">{{config.username-prompt}}</label>
<input type="text" name="target" id="target" value="{{target}}" required {% ifunequal target "" %}disabled{% endifunequal %}/> <input type="text" name="target" id="target" value="{{target}}" required {% ifunequal target "" %}disabled{% endifunequal %}/>

View file

@ -7,6 +7,7 @@
{% block content %} {% block content %}
<div id="content" class="edit"> <div id="content" class="edit">
<form action="{{servlet-context}}/edit" method="POST"> <form action="{{servlet-context}}/edit" method="POST">
{% csrf-field %}
<input type="hidden" name="page" value="{{page}}"/> <input type="hidden" name="page" value="{{page}}"/>
<textarea name="src" id="src" rows="25" cols="80">{{content}}</textarea> <textarea name="src" id="src" rows="25" cols="80">{{content}}</textarea>
<p class="widget"> <p class="widget">

View file

@ -2,6 +2,7 @@
{% block content %} {% block content %}
<div id="content" class="auth"> <div id="content" class="auth">
<form action="{{servlet-context}}/passwd" method="POST"> <form action="{{servlet-context}}/passwd" method="POST">
{% csrf-field %}
<p class="widget"> <p class="widget">
<label for="oldpass">{{config.old-pass-prompt}}</label> <label for="oldpass">{{config.old-pass-prompt}}</label>
<input name="oldpass" id="oldpass" type="password" required/> <input name="oldpass" id="oldpass" type="password" required/>

View file

@ -19,6 +19,7 @@
{% endif %} {% endif %}
{% else %} {% else %}
<form action="{{servlet-context}}/upload" enctype="multipart/form-data" method="POST"> <form action="{{servlet-context}}/upload" enctype="multipart/form-data" method="POST">
{% csrf-field %}
<p class="widget"> <p class="widget">
<label for="upload">{{config.file-upload-prompt}}</label> <label for="upload">{{config.file-upload-prompt}}</label>
<input name="upload" id="upload" type="file" required/> <input name="upload" id="upload" type="file" required/>

View file

@ -4,6 +4,7 @@
smeagol.layout smeagol.layout
(:require [selmer.parser :as parser] (:require [selmer.parser :as parser]
[clojure.string :as s] [clojure.string :as s]
[ring.util.anti-forgery :refer [anti-forgery-field]]
[ring.util.response :refer [content-type response]] [ring.util.response :refer [content-type response]]
[compojure.response :refer [Renderable]] [compojure.response :refer [Renderable]]
[environ.core :refer [env]] [environ.core :refer [env]]
@ -34,6 +35,8 @@
(def template-path "templates/") (def template-path "templates/")
(parser/add-tag! :csrf-field (fn [_ _] (anti-forgery-field)))
(deftype RenderableTemplate [template params] (deftype RenderableTemplate [template params]
Renderable Renderable

View file

@ -5,6 +5,7 @@
[environ.core :refer [env]] [environ.core :refer [env]]
[selmer.middleware :refer [wrap-error-page]] [selmer.middleware :refer [wrap-error-page]]
[prone.middleware :refer [wrap-exceptions]] [prone.middleware :refer [wrap-exceptions]]
[ring.middleware.anti-forgery :refer [wrap-anti-forgery]]
[noir-exception.core :refer [wrap-internal-error]])) [noir-exception.core :refer [wrap-internal-error]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -39,11 +40,13 @@
(def development-middleware (def development-middleware
[wrap-error-page [wrap-error-page
wrap-exceptions]) wrap-exceptions
wrap-anti-forgery])
(def production-middleware (def production-middleware
[#(wrap-internal-error % :log (fn [e] (timbre/error e)))]) [#(wrap-internal-error % :log (fn [e] (timbre/error e)))
wrap-anti-forgery])
(defn load-middleware [] (defn load-middleware []

View file

@ -7,7 +7,6 @@
[cemerick.url :refer (url url-encode url-decode)] [cemerick.url :refer (url url-encode url-decode)]
[compojure.core :refer :all] [compojure.core :refer :all]
[clj-jgit.porcelain :as git] [clj-jgit.porcelain :as git]
[environ.core :refer [env]]
[noir.io :as io] [noir.io :as io]
[noir.response :as response] [noir.response :as response]
[noir.util.route :as route] [noir.util.route :as route]
@ -46,18 +45,10 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def content-dir
(or
(env :smeagol-content-dir)
(cjio/file (io/resource-path) "content")))
(defn get-git-repo (defn get-git-repo
"Get the git repository for my content, creating it if necessary" "Get the git repository for my content, creating it if necessary"
[] []
(hist/load-or-init-repo content-dir)) (hist/load-or-init-repo util/content-dir))
(defn process-source (defn process-source
@ -67,7 +58,7 @@
(let [source-text (:src params) (let [source-text (:src params)
page (:page params) page (:page params)
file-name (str page suffix) file-name (str page suffix)
file-path (cjio/file content-dir file-name) file-path (cjio/file util/content-dir file-name)
exists? (.exists (cjio/as-file file-path)) exists? (.exists (cjio/as-file file-path))
git-repo (get-git-repo) git-repo (get-git-repo)
user (session/get :user) user (session/get :user)
@ -96,7 +87,7 @@
src-text (:src params) src-text (:src params)
page (or (:page params) default) page (or (:page params) default)
file-name (str page suffix) file-name (str page suffix)
file-path (cjio/file content-dir file-name) file-path (cjio/file util/content-dir file-name)
exists? (.exists (cjio/as-file file-path)) exists? (.exists (cjio/as-file file-path))
user (session/get :user)] user (session/get :user)]
(if (not exists?) (if (not exists?)
@ -105,10 +96,10 @@
(cond src-text (process-source params suffix request) (cond src-text (process-source params suffix request)
true true
(layout/render template (layout/render template
(merge (util/standard-params request content-dir) (merge (util/standard-params request)
{:title (str (util/get-message :edit-title-prefix request) " " page) {:title (str (util/get-message :edit-title-prefix request) " " page)
:page page :page page
:side-bar (md->html (slurp (cjio/file content-dir side-bar))) :side-bar (md->html (slurp (cjio/file util/content-dir side-bar)))
:content (if exists? (slurp file-path) "") :content (if exists? (slurp file-path) "")
:exists exists?})))))) :exists exists?}))))))
@ -125,13 +116,13 @@
(let [params (keywordize-keys (:params request)) (let [params (keywordize-keys (:params request))
page (or (:page params) (util/get-message :default-page-title request)) page (or (:page params) (util/get-message :default-page-title request))
file-name (str page ".md") file-name (str page ".md")
file-path (cjio/file content-dir file-name) file-path (cjio/file util/content-dir file-name)
exists? (.exists (clojure.java.io/as-file file-path))] exists? (.exists (clojure.java.io/as-file file-path))]
(cond exists? (cond exists?
(do (do
(timbre/info (format "Showing page '%s' from file '%s'" page file-path)) (timbre/info (format "Showing page '%s' from file '%s'" page file-path))
(layout/render "wiki.html" (layout/render "wiki.html"
(merge (util/standard-params request content-dir) (merge (util/standard-params request)
{:title page {:title page
:page page :page page
:content (md->html (slurp file-path)) :content (md->html (slurp file-path))
@ -146,10 +137,10 @@
(let [params (keywordize-keys (:params request)) (let [params (keywordize-keys (:params request))
page (url-decode (or (:page params) (util/get-message :default-page-title request))) page (url-decode (or (:page params) (util/get-message :default-page-title request)))
file-name (str page ".md") file-name (str page ".md")
repo-path content-dir] repo-path util/content-dir]
(timbre/info (format "Showing history of page '%s'" page)) (timbre/info (format "Showing history of page '%s'" page))
(layout/render "history.html" (layout/render "history.html"
(merge (util/standard-params request content-dir) (merge (util/standard-params request)
{:title (str "History of " page) {:title (str "History of " page)
:page page :page page
:history (hist/find-history repo-path file-name)})))) :history (hist/find-history repo-path file-name)}))))
@ -162,7 +153,7 @@
upload (:upload params) upload (:upload params)
uploaded (if upload (ul/store-upload params))] uploaded (if upload (ul/store-upload params))]
(layout/render "upload.html" (layout/render "upload.html"
(merge (util/standard-params request content-dir) (merge (util/standard-params request)
{:title (util/get-message :file-upload-title request) {:title (util/get-message :file-upload-title request)
:uploaded uploaded :uploaded uploaded
:is-image (and :is-image (and
@ -184,10 +175,10 @@
page (url-decode (or (:page params) (util/get-message :default-page-title request))) page (url-decode (or (:page params) (util/get-message :default-page-title request)))
version (:version params) version (:version params)
file-name (str page ".md") file-name (str page ".md")
content (hist/fetch-version content-dir file-name version)] content (hist/fetch-version util/content-dir file-name version)]
(timbre/info (format "Showing version '%s' of page '%s'" version page)) (timbre/info (format "Showing version '%s' of page '%s'" version page))
(layout/render "wiki.html" (layout/render "wiki.html"
(merge (util/standard-params request content-dir) (merge (util/standard-params request)
{:title (str (util/get-message :vers-col-hdr request) " " version " of " page) {:title (str (util/get-message :vers-col-hdr request) " " version " of " page)
:page page :page page
:content (md->html content)})))) :content (md->html content)}))))
@ -202,10 +193,10 @@
file-name (str page ".md")] file-name (str page ".md")]
(timbre/info (format "Showing diff between version '%s' of page '%s' and current" version page)) (timbre/info (format "Showing diff between version '%s' of page '%s' and current" version page))
(layout/render "wiki.html" (layout/render "wiki.html"
(merge (util/standard-params request content-dir) (merge (util/standard-params request)
{:title (str (util/get-message :diff-title-prefix request)" " version " of " page) {:title (str (util/get-message :diff-title-prefix request)" " version " of " page)
:page page :page page
:content (d2h/diff2html (hist/diff content-dir file-name version))})))) :content (d2h/diff2html (hist/diff util/content-dir file-name version))}))))
(defn auth-page (defn auth-page
@ -229,7 +220,7 @@
(response/redirect redirect-to)) (response/redirect redirect-to))
true true
(layout/render "auth.html" (layout/render "auth.html"
(merge (util/standard-params request content-dir) (merge (util/standard-params request)
{:title (if user (str (util/get-message :logout-link request) " " user) (util/get-message :login-link request)) {:title (if user (str (util/get-message :logout-link request) " " user) (util/get-message :login-link request))
:redirect-to ((:headers request) "referer")}))))) :redirect-to ((:headers request) "referer")})))))
@ -246,7 +237,7 @@
(auth/evaluate-password pass1 pass2) (auth/evaluate-password pass1 pass2)
(auth/change-pass user oldpass pass2))] (auth/change-pass user oldpass pass2))]
(layout/render "passwd.html" (layout/render "passwd.html"
(merge (util/standard-params request content-dir) (merge (util/standard-params request)
{:title (str (util/get-message :chpass-title-prefix request) " " user) {:title (str (util/get-message :chpass-title-prefix request) " " user)
:message (if changed? (util/get-message :chpass-success request)) :message (if changed? (util/get-message :chpass-success request))
:error (cond :error (cond

View file

@ -1,9 +1,10 @@
(ns ^{:doc "Miscellaneous utility functions supporting Smeagol." (ns ^{:doc "Miscellaneous utility functions supporting Smeagol."
:author "Simon Brooke"} :author "Simon Brooke"}
smeagol.util smeagol.util
(:require [noir.session :as session] (:require [clojure.java.io :as cjio]
[clojure.java.io :as cljio] [environ.core :refer [env]]
[noir.io :as io] [noir.io :as io]
[noir.session :as session]
[scot.weft.i18n.core :as i18n] [scot.weft.i18n.core :as i18n]
[smeagol.authenticate :as auth] [smeagol.authenticate :as auth]
[smeagol.configuration :refer [config]] [smeagol.configuration :refer [config]]
@ -33,14 +34,20 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def content-dir
(or
(env :smeagol-content-dir)
(cjio/file (io/resource-path) "content")))
(defn standard-params (defn standard-params
"Return a map of standard parameters to pass to the template renderer." "Return a map of standard parameters to pass to the template renderer."
[request content-dir] [request]
(let [user (session/get :user)] (let [user (session/get :user)]
{:user user {:user user
:admin (auth/get-admin user) :admin (auth/get-admin user)
:side-bar (md->html (slurp (cljio/file content-dir "_side-bar.md"))) :side-bar (md->html (slurp (cjio/file content-dir "_side-bar.md")))
:header (md->html (slurp (cljio/file content-dir "_header.md"))) :header (md->html (slurp (cjio/file content-dir "_header.md")))
:version (System/getProperty "smeagol.version")})) :version (System/getProperty "smeagol.version")}))
@ -51,7 +58,7 @@
(merge (merge
(i18n/get-messages (i18n/get-messages
((:headers request) "accept-language") ((:headers request) "accept-language")
(.getAbsolutePath (cljio/file (io/resource-path) ".." "i18n")) (.getAbsolutePath (cjio/file (io/resource-path) ".." "i18n"))
"en-GB") "en-GB")
config)) config))