summaryrefslogtreecommitdiff
path: root/src/user.clj
blob: c516fd2f47051ff514954f51a94cea45ee60100b (plain)
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
(ns user
  (:use clojure.contrib.sql
        compojure
        cache-dot-clj.cache
        utils))

(defstruct user-struct :nick :user_id :avatar :last-seen)

(defn user-struct-from-session [session]
  (struct user-struct (session :nick) (session :user_id) (session :avatar)
          (System/currentTimeMillis)))

(def *nick-regex* #"^[A-Za-z0-9\-_âˆb˚†]*$")

(defn is-invalid-nick? [n]
  (cond
   (< (count n) 3) "NICK_TOO_SHORT"
   (> (count n) 16) "NICK_TOO_LONG"
   (not (re-matches *nick-regex* n)) "NICK_INVALID_CHARS"))

;;; User info cache

(defn-cached fetch-nick-cached
  (lru-cache-strategy 2000)
  "Retrieves user info from database"
  [nick]
  (first (do-select ["SELECT * FROM users WHERE lower(nick) = ? LIMIT 1"
                     (lower-case nick)])))

(def fetch-nick (comp fetch-nick-cached lower-case))

(defn-cached nick-from-user-id
  (lru-cache-strategy 10000)
  "Retrieves nick for user id"
  [uid]
  (:nick (first (do-select ["SELECT nick FROM users WHERE user_id = ? LIMIT 1" uid]))))

(def fetch-user-id
  (comp fetch-nick nick-from-user-id))

(def user-id-from-nick
     (comp :user_id fetch-nick))

;; user login

(defn authorize-nick-hash [nick hash]
  (if-let [db-user (fetch-nick nick)]
    (and (= (db-user :hash) hash) db-user)))

(defn update-nick-hash [nick hash]
  (do-update :users ["nick=?" nick]
             {:hash hash}))

;; user pw reset

(defn reset-token [nick hash ts]
  (sha1-hash nick hash ts))

(defn reset-link [nick token ts]
  (url-params "http://dump.fm/reset" {"nick"  nick
                                      "ts"    ts
                                      "token" token}))

(defn valid-reset-link? [nick token ts]
  (if-let [info (and nick (fetch-nick nick))]
    (and (= token (reset-token (info :nick) (info :hash) ts))
         (>= ts (ms-ago (days 2))))))


;; user db update & cache invalidation

(defn update-user-info! [nick user-id attr val]
  (with-connection *db*
    (update-values "users" ["user_id = ?" user-id] {attr val}))
  (invalidate-cache fetch-nick-cached (lower-case nick)))