Woohoo! Users can now change their own passwords. More work on tidying

up stylesheets.
This commit is contained in:
simon 2015-01-16 22:07:41 +00:00
parent 72ed9e5536
commit 1d87595a64
10 changed files with 183 additions and 61 deletions

View file

@ -1,2 +1 @@
{:admin {:password "admin" :email "admin@localhost"}} {:admin {:password "admin", :email "admin@localhost"}}

View file

@ -43,6 +43,10 @@ body {
float: right; float: right;
padding: 0.1em 0.75em; padding: 0.1em 0.75em;
margin: 0; margin: 0;
color: white;
}
#user a {
color: silver; color: silver;
} }
@ -110,13 +114,12 @@ li.nav-item a:active { background: gray; color: white; }
#footer { #footer {
clear: both; clear: both;
font-size: smaller; font-size: smaller;
padding: 0 2em;
text-align: center; text-align: center;
color:white; color:white;
background:rgba(128,128,128,0.95); background:rgba(128,128,128,0.95);
width: 100%; width: 100%;
margin: 0; margin: 0;
padding: 0.1em 10%; /* padding: 0.1em 10%; */
bottom:0; bottom:0;
position:fixed; position:fixed;
z-index:150; z-index:150;
@ -135,6 +138,7 @@ li.nav-item a:active { background: gray; color: white; }
border: thin solid white; border: thin solid white;
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
width: 100%;
} }
.minor-controls { .minor-controls {
@ -144,6 +148,10 @@ li.nav-item a:active { background: gray; color: white; }
font-size: 66%; font-size: 66%;
} }
.message {
border: thin solid red;
}
.wiki { .wiki {
margin: 0; margin: 0;
} }
@ -156,8 +164,12 @@ form {
border: thin solid silver; border: thin solid silver;
} }
div.content, form, p, pre, ul, ol, dl, menu, h1, h2, h3, h4, h5 { div.content, form, p, pre, h1, h2, h3, h4, h5 {
padding: 0.25em 10%; padding: 0.25em 5%;
}
dl, menu, ol, table, ul {
margin: 0.25em 5%;
} }
input { input {
@ -179,7 +191,7 @@ input.required:after {
} }
label { label {
width: 30em; width: 20%;
min-width: 20em; min-width: 20em;
border-right: thin solid gray; border-right: thin solid gray;
} }
@ -192,12 +204,23 @@ menu li::before {
content: "|| "; content: "|| ";
} }
table {
border: 2px solid black;
border-collapse: collapse;
}
table.music-ruled tr:nth-child(odd) { table.music-ruled tr:nth-child(odd) {
background-color: silver; background-color: silver;
} }
th, td { th, td {
text-align: left; text-align: left;
padding: 0 0.25em; vertical-align: top;
padding: 0.15em 1.5em;
border: 1px solid gray;
}
th {
background-color: silver;
} }

View file

@ -126,11 +126,16 @@ h1, h2, h3, h4, h5 {
color: white; color: white;
} }
p, pre, ul, ol, dl, h1, h2, h3, h4, h5 { p, pre, h1, h2, h3, h4, h5 {
width: 100%; width: 100%;
padding: 0.25em 1em; padding: 0.25em 1em;
} }
dl, menu, ol, table, ul {
margin: 0.15em 3%;
}
input { input {
background-color: white; background-color: white;
} }
@ -165,3 +170,24 @@ menu li::before {
content: "|| "; content: "|| ";
} }
table {
border: 2px solid black;
border-collapse: collapse;
}
table.music-ruled tr:nth-child(odd) {
background-color: silver;
}
th, td {
text-align: left;
vertical-align: top;
padding: 0.15em 1.5em;
border: 1px solid gray;
}
th {
background-color: silver;
}

View file

@ -1,4 +0,0 @@
{% extends "templates/base.html" %}
{% block content %}
<p>this is the story of smeagol... work in progress</p>
{% endblock %}

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">
<input type="hidden" name="redirect-to" value="{{redirect-to}}"/>
{% if user %} {% if user %}
<p class="widget"> <p class="widget">
<label for="submit">To finish editing</label> <label for="submit">To finish editing</label>
@ -10,11 +11,11 @@
{% else %} {% else %}
<p class="widget"> <p class="widget">
<label for="username">Your username</label> <label for="username">Your username</label>
<input name="username" id="username" type="text"/> <input name="username" id="username" type="text" required/>
</p> </p>
<p class="widget"> <p class="widget">
<label for="password">Your password</label> <label for="password">Your password</label>
<input name="password" id="password" type="password"/> <input name="password" id="password" type="password" required/>
</p> </p>
<p class="widget"> <p class="widget">
<label for="submit">To edit this wiki</label> <label for="submit">To edit this wiki</label>

View file

@ -14,7 +14,7 @@
<!-- navbar --> <!-- navbar -->
<div id="nav"> <div id="nav">
{% if user %} {% if user %}
<p class="user" id="user">You are logged in as {{user}}</p> <p class="user" id="user">You are logged in as {{user}} | <a href="passwd">change password</a></p>
{% endif %} {% endif %}
<img id="nav-icon" src="{{servlet-context}}/img/threelines.png" alt="Menu"/> <img id="nav-icon" src="{{servlet-context}}/img/threelines.png" alt="Menu"/>
<ul id="nav-menu" class="nav"> <ul id="nav-menu" class="nav">

View file

@ -7,7 +7,7 @@
<p class="widget"> <p class="widget">
<label for="summary">What have you changed?</label> <label for="summary">What have you changed?</label>
<input name="summary" id="summary" type="text" <input name="summary" id="summary" type="text"
value="{%if exists%}{%else%}New file {{title}}{%endif%}"/> value="{%if exists%}{%else%}New file {{title}}{%endif%}" required/>
</p> </p>
<p class="widget"> <p class="widget">
<label for="submit">When you have finished editing</label> <label for="submit">When you have finished editing</label>

View file

@ -0,0 +1,23 @@
{% extends "templates/base.html" %}
{% block content %}
<div id="content" class="auth">
<form action="{{servlet-context}}/passwd" method="POST">
<p class="widget">
<label for="password">Your password</label>
<input name="oldpass" id="oldpass" type="password" required/>
</p>
<p class="widget">
<label for="password">New password</label>
<input name="pass1" id="pass1" type="password" required/>
</p>
<p class="widget">
<label for="password">And again</label>
<input name="pass2" id="pass2" type="password" required/>
</p>
<p class="widget">
<label for="submit">To edit this wiki</label>
<input name="action" id="action" type="submit" class="action" value="Login!"/>
</p>
</form>
</div>
{% endblock %}

View file

@ -20,6 +20,13 @@
;; along with this program; if not, write to the Free Software ;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; All functions which relate to the passwd file are in this namespace, in order
;; that it can reasonably simply swapped out for a more secure replacement
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn authenticate (defn authenticate
"Return `true` if this `username`/`password` pair match, `false` otherwise" "Return `true` if this `username`/`password` pair match, `false` otherwise"
[username password] [username password]
@ -36,3 +43,25 @@
users (read-string (slurp path)) users (read-string (slurp path))
user ((keyword username) users)] user ((keyword username) users)]
(if user (:email user)))) (if user (:email user))))
(defn change-pass
"Change the password for the user with this `username` and `oldpass` to this `newpass`.
Return `true` if password was successfully changed."
[username oldpass newpass]
(timbre/info (format "Changing password for user %s" username))
(let [path (str (io/resource-path) "../passwd")
users (read-string (slurp path))
keywd (keyword username)
user (if users (keywd users))
email (:email user)]
(try
(cond
(and user (.equals (:password user) oldpass))
(do
(spit path (assoc (dissoc users keywd) keywd {:password newpass :email email}))
true))
(catch Exception any
(timbre/error
(format "Changing password failed for user %s failed: %s (%s)"
username (.getName (.getClass any)) (.getMessage any)))
false))))

View file

@ -16,7 +16,8 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
(ns smeagol.routes.wiki (ns smeagol.routes.wiki
(:use clojure.walk) (:use clojure.walk
clojure.pprint)
(:require [compojure.core :refer :all] (:require [compojure.core :refer :all]
[clj-jgit.porcelain :as git] [clj-jgit.porcelain :as git]
[markdown.core :as md] [markdown.core :as md]
@ -40,7 +41,7 @@
(defn process-source (defn process-source
"Process `source-text` and save it to the specified `file-path`, committing it "Process `source-text` and save it to the specified `file-path`, committing it
to Git and finally redirecting to wiki-page." to Git and finally redirecting to wiki-page."
[params] [params]
(let [source-text (:src params) (let [source-text (:src params)
page (:page params) page (:page params)
@ -55,8 +56,8 @@
(spit file-path source-text) (spit file-path source-text)
(if (not exists?) (git/git-add git-repo file-name)) (if (not exists?) (git/git-add git-repo file-name))
(git/git-commit git-repo summary {:name user :email email}) (git/git-commit git-repo summary {:name user :email email})
(response/redirect (str "/wiki?" page)) (response/redirect (str "/wiki?page=" page))
)) ))
(defn edit-page (defn edit-page
"Render a page in a text-area for editing. This could have been done in the same function as wiki-page, "Render a page in a text-area for editing. This could have been done in the same function as wiki-page,
@ -70,13 +71,13 @@
(cond src-text (process-source params) (cond src-text (process-source params)
true true
(layout/render "edit.html" (layout/render "edit.html"
{:title (str "Edit " page) {:title (str "Edit " page)
:page page :page page
:left-bar (local-links (util/md->html "/content/_edit-left-bar.md")) :left-bar (local-links (util/md->html "/content/_edit-left-bar.md"))
:header (local-links (util/md->html "/content/_header.md")) :header (local-links (util/md->html "/content/_header.md"))
:content (if exists? (io/slurp-resource (str "/content/" page ".md")) "") :content (if exists? (io/slurp-resource (str "/content/" page ".md")) "")
:user (session/get :user) :user (session/get :user)
:exists exists?})))) :exists exists?}))))
(defn wiki-page (defn wiki-page
"Render the markdown page specified in this `request`, if any. If none found, redirect to edit-page" "Render the markdown page specified in this `request`, if any. If none found, redirect to edit-page"
@ -87,18 +88,18 @@
file-path (str (io/resource-path) file-name) file-path (str (io/resource-path) file-name)
exists? (.exists (clojure.java.io/as-file file-path))] exists? (.exists (clojure.java.io/as-file file-path))]
(cond exists? (cond exists?
(layout/render "wiki.html" (layout/render "wiki.html"
{:title page {:title page
:page page :page page
:left-bar (local-links (util/md->html "/content/_left-bar.md")) :left-bar (local-links (util/md->html "/content/_left-bar.md"))
:header (local-links (util/md->html "/content/_header.md")) :header (local-links (util/md->html "/content/_header.md"))
:content (local-links (util/md->html file-name)) :content (local-links (util/md->html file-name))
:user (session/get :user)}) :user (session/get :user)})
true (response/redirect (str "/edit?page=" page))))) true (response/redirect (str "/edit?page=" page)))))
(defn history-page (defn history-page
"Render the history for the markdown page specified in this `request`, "Render the history for the markdown page specified in this `request`,
if any. If none, error?" if any. If none, error?"
[request] [request]
(let [params (keywordize-keys (:params request)) (let [params (keywordize-keys (:params request))
page (or (:page params) "Introduction") page (or (:page params) "Introduction")
@ -123,13 +124,13 @@
{:title (str "Version " version " of " page) {:title (str "Version " version " of " page)
:page page :page page
:left-bar (local-links :left-bar (local-links
(util/md->html "/content/_left-bar.md")) (util/md->html "/content/_left-bar.md"))
:header (local-links :header (local-links
(util/md->html "/content/_header.md")) (util/md->html "/content/_header.md"))
:content (local-links :content (local-links
(md/md-to-html-string (md/md-to-html-string
(hist/fetch-version (hist/fetch-version
repo-path file-name version))) repo-path file-name version)))
:user (session/get :user)}))) :user (session/get :user)})))
(defn diff-page (defn diff-page
@ -144,39 +145,61 @@
{:title (str "Changes since version " version " of " page) {:title (str "Changes since version " version " of " page)
:page page :page page
:left-bar (local-links :left-bar (local-links
(util/md->html "/content/_left-bar.md")) (util/md->html "/content/_left-bar.md"))
:header (local-links :header (local-links
(util/md->html "/content/_header.md")) (util/md->html "/content/_header.md"))
:content (d2h/diff2html (hist/diff repo-path file-name version)) :content (d2h/diff2html (hist/diff repo-path file-name version))
:user (session/get :user)}))) :user (session/get :user)})))
(defn auth-page (defn auth-page
"Render the auth page" "Render the auth page"
[request] [request]
(pprint request)
(let [params (keywordize-keys (:form-params request)) (let [params (keywordize-keys (:form-params request))
username (:username params) username (:username params)
password (:password params) password (:password params)
action (:action params) action (:action params)
user (session/get :user)] user (session/get :user)
redirect-to (or (:redirect-to params) "/wiki")]
(cond (cond
(= action "Logout!") (= action "Logout!")
(do (do
(timbre/info (str "User " user " logging out")) (timbre/info (str "User " user " logging out"))
(session/remove! :user) (session/remove! :user)
(response/redirect "/wiki")) (response/redirect redirect-to))
(and username password (auth/authenticate username password)) (and username password (auth/authenticate username password))
(do (do
(session/put! :user username) (session/put! :user username)
(response/redirect "/wiki")) (response/redirect redirect-to))
true true
(layout/render "auth.html" (layout/render "auth.html"
{:title (if user (str "Logout " user) "Log in") {:title (if user (str "Logout " user) "Log in")
:redirect-to ((:headers request) "referer")
:left-bar (local-links (util/md->html "/content/_left-bar.md"))
:header (local-links (util/md->html "/content/_header.md"))
:user user}))))
(defn passwd-page
"Render a page to change the user password"
[request]
(let [params (keywordize-keys (:form-params request))
oldpass (:oldpass params)
pass1 (:pass1 params)
pass2 (:pass2 params)
user (session/get :user)
length (if pass1 (count pass1) 0)
message (cond
(nil? oldpass) nil
(and pass1 (>= length 8) (.equals pass1 pass2) (auth/change-pass user oldpass pass2))
"Your password was changed"
(< length 8) "You proposed password wasn't long enough: 8 characters required"
(not (= pass1 pass2)) "Your proposed passwords don't match"
true "Your password was not changed")] ;; but I don't know why...
(layout/render "passwd.html"
{:title (str "Change passord for " user)
:left-bar (local-links (util/md->html "/content/_left-bar.md")) :left-bar (local-links (util/md->html "/content/_left-bar.md"))
:header (local-links (util/md->html "/content/_header.md")) :header (local-links (util/md->html "/content/_header.md"))
:user user})))) :message message})))
(defn about-page []
(layout/render "about.html"))
(defroutes wiki-routes (defroutes wiki-routes
(GET "/wiki" request (wiki-page request)) (GET "/wiki" request (wiki-page request))
@ -188,4 +211,6 @@
(GET "/changes" request (diff-page request)) (GET "/changes" request (diff-page request))
(GET "/auth" request (auth-page request)) (GET "/auth" request (auth-page request))
(POST "/auth" request (auth-page request)) (POST "/auth" request (auth-page request))
(GET "/about" [] (about-page))) (GET "/passwd" request (passwd-page request))
(POST "/passwd" request (passwd-page request))
)