/
settings.clj
107 lines (101 loc) · 5.03 KB
/
settings.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
(ns foreclojure.settings
(:require [noir.session :as session]
[ring.util.response :as response])
(:import [org.jasypt.util.password StrongPasswordEncryptor])
(:use [hiccup.form :only [form-to label text-field password-field check-box]]
[foreclojure.utils :only [from-mongo flash-error flash-msg with-user form-row assuming send-email login-url plausible-email?]]
[foreclojure.template :only [def-page content-page]]
[foreclojure.users :only [disable-codebox? hide-solutions? gravatar-img]]
[foreclojure.messages :only [err-msg]]
[compojure.core :only [defroutes GET POST]]
[useful.map :only [keyed]]
[clojail.core :only [thunk-timeout]]
[clojure.stacktrace :only [print-cause-trace]]
[somnium.congomongo :only [update! fetch-one]]))
(defn account-settings-box [user email]
(list
[:p "Leave new and reset password fields blank if you do not wish to change your password."]
[:table
(map form-row
[[text-field :new-username "Username" user]
[password-field :old-pwd "Current password"]
[password-field :pwd "New password"]
[password-field :repeat-pwd "Repeat password"]
[text-field :email "Email" email]])]))
(defn js-settings-box [user-obj]
(list
[:p "Selecting this will disable the JavaScript code entry box and just give you plain text entry"]
(check-box :disable-codebox
(disable-codebox? user-obj))
[:label {:for "disable-codebox"}
"Disable JavaScript in code entry box"]
[:br]))
(defn hide-settings-box [user-obj]
(list
[:p "When you solve a problem, we allow any user who has solved a problem to view your solutions to that problem. Check this box to keep your solutions private."]
(check-box :hide-solutions
(hide-solutions? user-obj))
[:label {:for "hide-solutions"}
"Hide my solutions"]
[:br]))
(def-page settings-page []
(with-user [{:keys [user email] :as user-obj}]
{:title "Account settings"
:content
(content-page
{:main
(form-to [:post "/settings"]
(list
[:h2 "Change settings for " user]
[:div#account-settings (account-settings-box user email)]
[:hr]
[:h3 "Disable JavaScript Code Box"]
[:div#settings-codebox (js-settings-box user-obj)]
[:hr]
[:h3 "Hide My Solutions"]
[:div#settings-follow (hide-settings-box user-obj)]
[:hr]
[:h3 "Profile Image"]
[:div (gravatar-img {:email email :size 64})]
[:p "To change your profile image, visit <a href='http://gravatar.com' target='_blank'>Gravatar</a> and edit the image for '" email "'."]
[:div#button-div
[:button {:type "submit"} "Submit"]]))})}))
(defn do-update-settings! [new-username old-pwd new-pwd repeat-pwd email disable-codebox hide-solutions]
(with-user [{:keys [user pwd]}]
(let [encryptor (StrongPasswordEncryptor.)
new-pwd-hash (.encryptPassword encryptor new-pwd)
new-lower-user (.toLowerCase new-username)]
(assuming [(or (= new-lower-user user) (nil? (fetch-one :users :where {:user new-lower-user})))
(err-msg "settings.user-exists"),
(< 3 (.length new-lower-user) 14)
(err-msg "settings.uname-size"),
(= new-lower-user
(first (re-seq #"[A-Za-z0-9_]+" new-lower-user)))
(err-msg "settings.uname-alphanum")
(or (empty? new-pwd) (< 6 (.length new-pwd)))
(err-msg "settings.npwd-size"),
(= new-pwd repeat-pwd)
(err-msg "settings.npwd-match")
(or (empty? new-pwd)
(.checkPassword encryptor old-pwd pwd))
(err-msg "settings.pwd-incorrect")
(plausible-email? email)
(err-msg "settings.email-invalid")
(nil? (fetch-one :users :where {:email email :user {:$ne user}}))
(err-msg "settings.email-exists")]
(do
(update! :users {:user user}
{:$set {:pwd (if (seq new-pwd) new-pwd-hash pwd)
:user new-lower-user
:email email
:disable-code-box (boolean disable-codebox)
:hide-solutions (boolean hide-solutions)}}
:upsert false)
(session/put! :user new-lower-user)
(flash-msg "/problems"
(str "Account for " new-lower-user " updated successfully")))
(flash-error "/settings" why)))))
(defroutes settings-routes
(GET "/settings" [] (settings-page))
(POST "/settings" {{:strs [new-username old-pwd pwd repeat-pwd email disable-codebox hide-solutions]} :form-params}
(do-update-settings! new-username old-pwd pwd repeat-pwd email disable-codebox hide-solutions)))