From 3d83db95469600000f4fbc1337bfc6aac9efd9a4 Mon Sep 17 00:00:00 2001 From: Scott Ostler Date: Thu, 11 Mar 2010 08:01:05 -0500 Subject: Added upload limits --- src/site.clj | 131 +++++++++++++++++++++++++++++++++++++++++----------------- src/utils.clj | 7 ++++ 2 files changed, 100 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/site.clj b/src/site.clj index be19830..d05686b 100755 --- a/src/site.clj +++ b/src/site.clj @@ -4,6 +4,7 @@ java.util.Date java.util.TimeZone java.io.File + javax.imageio.ImageIO org.apache.commons.codec.digest.DigestUtils javax.servlet.http.Cookie org.antlr.stringtemplate.StringTemplateGroup) @@ -59,6 +60,7 @@ "http://dump.fm" "http://localhost:8080")) +(def *root-directory* (System/getProperty "user.dir")) (def *image-directory* "images") (def *avatar-directory* "avatars") @@ -74,15 +76,23 @@ (defn swap [f] (fn [& more] (apply f (reverse more)))) +(def YYYYMMDD-format (new SimpleDateFormat "yyyyMMdd")) + +(defn today [] + (.format YYYYMMDD-format (new Date))) + (def formatter (new SimpleDateFormat "h:mm EEE M/d")) (defn non-empty-string? [s] (and s (> (count s) 0))) -(defn rel-join [& more] - (str-join (System/getProperty "file.separator") - (cons (System/getProperty "user.dir") - more))) +(defn open-file [dir-comps filename] + (let [d (str-join (System/getProperty "file.separator") + (cons *root-directory* dir-comps)) + f (str-join (System/getProperty "file.separator") + [d filename])] + (.mkdir (new File d)) + (new File f))) (defn sha1-hash [& more] (DigestUtils/shaHex (apply str more))) @@ -159,10 +169,13 @@ (vals @(room :users))))) (defn updates [room since] - {"users" (prepare-user-list room) - "messages" (map process-message-for-json - (new-messages room since)) - "topic" @(room :topic)}) + (let [m {"users" (prepare-user-list room) + "messages" (map process-message-for-json + (new-messages room since))} + topic @(room :topic)] + (if topic + (assoc m "topic" topic) + m))) (def *dumps-per-page* 20) @@ -392,8 +405,8 @@ (.setAttribute st "users" users) (cond (= offset 0) (.setAttribute st "prev" false) (= offset 1) (.setAttribute st "prev" "") - :else (.setAttribute st "prev" (str "/" (- offset 1)))) - (.setAttribute st "next" (str "/" (+ offset 1))) + :else (.setAttribute st "prev" (str "/" (dec offset)))) + (.setAttribute st "next" (str "/" (inc offset))) (.toString st))) ;; Topics @@ -420,21 +433,34 @@ [404 "UNKNOWN_ROOM"])) (defn set-topic! [room topic deadline maker] - (ref-set (room :topic) - {:topic topic - :deadline deadline - :maker maker})) + (dosync (ref-set (room :topic) + {:topic topic + :deadline deadline + :maker maker}))) + +(defn end-topic! [room] + (dosync (ref-set (room :topic) nil))) (defn validate-set-topic [session params] (let [room (@rooms (params :room)) topic (params :topic) - deadline (params :deadline)] + deadline (params :deadline) + maker (params :maker)] (cond (not (session :is_admin)) (resp-error "NOT_VIP") (not (valid-topic? topic)) (resp-error "INVALID_TOPIC") (not (valid-deadline? deadline)) (resp-error "INVALID_DEADLINE") (not room) (resp-error "INVALID_ROOM") + (not maker) (resp-error "NOT_MAKER") + :else (do + (set-topic! room topic deadline maker) + (resp-success "OK"))))) + +(defn validate-end-topic [session params] + (let [room (@rooms (params :room))] + (cond (not (session :is_admin)) (resp-error "NOT_VIP") + (not room) (resp-error "INVALID_ROOM") :else (do - (dosync (set-topic! room topic deadline (session :nick))) + (end-topic! room) (resp-success "OK"))))) ;; Chat @@ -590,31 +616,60 @@ ;; Upload +(def *max-image-height* 1000) +(def *max-image-width* 1000) +(def *vip-max-file-size* (mbytes 5)) ; don't be nuts guys +(def *max-file-size* (kbytes 250)) +(def *ignore-size-limit-for-vip* true) (def *avatar-dimensions* [50 50]) -(defn is-image-file? [path] - true) - -(defn format-filename [s] +(defn file-size-limit [vip] + (if (and *ignore-size-limit-for-vip* vip) + *vip-max-file-size* + *max-file-size*)) + +(defn is-file-too-big? [f vip] + (let [limit (file-size-limit vip)] + (if (> (.length f) limit) + (str "FILE_TOO_BIG " (limit vip))))) + +(defn is-image-invalid? [f] + (try + (let [i (ImageIO/read f) + height (.getHeight i) + width (.getWidth i)] + (if (or (> width *max-image-width*) + (> height *max-image-height*)) + (str "INVALID_RESOLUTION " *max-image-width* " " *max-image-height*))) + (catch Exception _ "FILE_NOT_IMAGE"))) + +(defn format-filename [s nick] (let [spaceless (.replace s \space \-) + nick-clean (re-gsub #"[^A-Za-z0-9]" "" nick) subbed (re-gsub #"[^\w.-]" "" spaceless)] - (str (System/currentTimeMillis) "-" subbed))) + (str-join "-" [(System/currentTimeMillis) nick-clean subbed]))) -(defn image-url-from-file [d f] - (str-join "/" [*server-url* d (.getName f)])) +(defn image-url-from-file [dir date file] + (str-join "/" [*server-url* dir date (.getName file)])) +(defn validate-upload [f vip] + (or (is-file-too-big? f vip) + (is-image-invalid? f))) (defn do-upload [session image room] - (let [filename (format-filename (:filename image)) - dest (File. (rel-join *image-directory* filename)) - url (image-url-from-file "images" dest) - msg-id (msg-db (session :user_id) (room :room_id) url) - msg (struct message-struct (session :nick) url (new Date) msg-id)] - (do - (dosync - (add-message msg room)) - (copy (:tempfile image) dest) - (resp-success url)))) + (if-let [err (validate-upload (image :tempfile) (session :is_admin))] + (resp-error err) + (let [filename (format-filename (:filename image) (session :nick)) + date (today) + dest (open-file [*image-directory* date] filename) + url (image-url-from-file "images" date dest) + msg-id (msg-db (session :user_id) (room :room_id) url) + msg (struct message-struct (session :nick) url (new Date) msg-id)] + (do + (dosync + (add-message msg room)) + (copy (:tempfile image) dest) + (resp-success url))))) (defn upload [session params] (let [room-key (params :room) @@ -622,7 +677,6 @@ image (params :image)] (cond (not nick) [200 "NOT_LOGGED_IN"] (not image) [200 "INVALID_REQUEST"] - (not (is-image-file? (image :filename))) [200 "INVALID_IMAGE"] (not (validate-room-access room-key session)) [200 "UNKNOWN_ROOM"] :else (do-upload session image (@rooms room-key))))) @@ -632,9 +686,10 @@ ;; N.B. -- Upload responses aren't JSON-evaluated (defn do-upload-avatar [session image] - (let [filename (format-filename (:filename image)) - dest (File. (rel-join *avatar-directory* filename)) - url (image-url-from-file "avatars" dest)] + (let [filename (format-filename (:filename image) (session :nick)) + date (today) + dest (open-file [*avatar-directory* date] filename) + url (image-url-from-file "avatars" date dest)] (do (copy-and-resize (:tempfile image) dest) (update-user-db (session :user_id) "avatar" url) @@ -645,7 +700,6 @@ (let [image (params :image)] (cond (not image) [200 "INVALID_REQUEST"] (not (session :nick)) [200 "NOT_LOGGED_IN"] - (not (is-image-file? (image :filename))) [200 "INVALID_IMAGE"] :else (do-upload-avatar session image)))) ;; 404 @@ -701,6 +755,7 @@ (POST "/update-profile" (update-profile session params)) (GET "/topic-list" (validate-topic-list session)) (POST "/set-topic" (validate-set-topic session params)) + (POST "/end-topic" (validate-end-topic session params)) (GET "/directory" (directory session 0)) (GET "/directory/:offset" (directory session (maybe-parse-int (-> request :route-params :offset) 0))) diff --git a/src/utils.clj b/src/utils.clj index 3180e89..7abed4f 100755 --- a/src/utils.clj +++ b/src/utils.clj @@ -13,6 +13,13 @@ :user "postgres" :password "root"})) + +(defn kbytes [b] + (* b 1024)) + +(defn mbytes [b] + (* b 1024 1024)) + ;; JSON responses (def yyyy-mm-dd-formatter (new SimpleDateFormat "yyyy-MM-dd")) -- cgit v1.2.3-70-g09d2 From b858836e4fae1336eda2eff8f5ad06ce12e95110 Mon Sep 17 00:00:00 2001 From: Scott Ostler Date: Thu, 11 Mar 2010 08:04:51 -0500 Subject: Upped height/width restrictions --- src/site.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/site.clj b/src/site.clj index 9a1ac79..f9a9706 100755 --- a/src/site.clj +++ b/src/site.clj @@ -653,8 +653,8 @@ ;; Upload -(def *max-image-height* 1000) -(def *max-image-width* 1000) +(def *max-image-height* 1500) +(def *max-image-width* 1500) (def *vip-max-file-size* (mbytes 5)) ; don't be nuts guys (def *max-file-size* (kbytes 250)) (def *ignore-size-limit-for-vip* true) -- cgit v1.2.3-70-g09d2 From 9a5aeb4c29b29b79dc289fabb8ed1145b84c391a Mon Sep 17 00:00:00 2001 From: Scott Ostler Date: Thu, 11 Mar 2010 08:07:00 -0500 Subject: Upped height/width restrictions again --- src/site.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/site.clj b/src/site.clj index f9a9706..f1eb8f3 100755 --- a/src/site.clj +++ b/src/site.clj @@ -653,8 +653,8 @@ ;; Upload -(def *max-image-height* 1500) -(def *max-image-width* 1500) +(def *max-image-height* 2000) +(def *max-image-width* 2000) (def *vip-max-file-size* (mbytes 5)) ; don't be nuts guys (def *max-file-size* (kbytes 250)) (def *ignore-size-limit-for-vip* true) -- cgit v1.2.3-70-g09d2 From cc9a731ff8c3bd96453b70027665fd9e952ea015 Mon Sep 17 00:00:00 2001 From: Scott Ostler Date: Thu, 11 Mar 2010 08:10:10 -0500 Subject: add dump.fm to image names --- src/site.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/site.clj b/src/site.clj index f1eb8f3..30cbf45 100755 --- a/src/site.clj +++ b/src/site.clj @@ -684,7 +684,7 @@ (let [spaceless (.replace s \space \-) nick-clean (re-gsub #"[^A-Za-z0-9]" "" nick) subbed (re-gsub #"[^\w.-]" "" spaceless)] - (str-join "-" [(System/currentTimeMillis) nick-clean subbed]))) + (str-join "-" [(System/currentTimeMillis) "dumpfm" nick-clean subbed]))) (defn image-url-from-file [dir date file] (str-join "/" [*server-url* dir date (.getName file)])) -- cgit v1.2.3-70-g09d2 From b9279bb808b9189f103b82358dbb21bd70f15868 Mon Sep 17 00:00:00 2001 From: Scott Ostler Date: Thu, 11 Mar 2010 23:27:42 -0500 Subject: Fixed is-file-too-big? --- src/site.clj | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/site.clj b/src/site.clj index 30cbf45..7925aa1 100755 --- a/src/site.clj +++ b/src/site.clj @@ -605,17 +605,12 @@ (let [room (@rooms "RoomA") now (System/currentTimeMillis) nick (session :nick) - st (fetch-template "browser" session) - message-list (to-array - (map process-message-for-output - ; TODO: remove db query - (reverse (fetch-messages-by-room (room :room_id) false))))] + st (fetch-template "browser" session)] (if nick (dosync (login-user (user-struct-from-session session) room))) (let [user-list (to-array (prepare-user-list room))] (.setAttribute st "users" user-list)) - (.setAttribute st "messages" message-list) (.setAttribute st "roomkey" (room :key)) (.setAttribute st "isadminroom" (room :admin_only)) (.setAttribute st "json_room_key" (json-str (room :key))) @@ -668,7 +663,7 @@ (defn is-file-too-big? [f vip] (let [limit (file-size-limit vip)] (if (> (.length f) limit) - (str "FILE_TOO_BIG " (limit vip))))) + (str "FILE_TOO_BIG " limit)))) (defn is-image-invalid? [f] (try -- cgit v1.2.3-70-g09d2 From 8aa89f36f5aa59a853daaf24571bb2cddc7e9760 Mon Sep 17 00:00:00 2001 From: Scott Ostler Date: Thu, 11 Mar 2010 23:28:43 -0500 Subject: Upped size limits --- src/site.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/site.clj b/src/site.clj index 7925aa1..fe78633 100755 --- a/src/site.clj +++ b/src/site.clj @@ -651,7 +651,7 @@ (def *max-image-height* 2000) (def *max-image-width* 2000) (def *vip-max-file-size* (mbytes 5)) ; don't be nuts guys -(def *max-file-size* (kbytes 250)) +(def *max-file-size* (kbytes 750)) (def *ignore-size-limit-for-vip* true) (def *avatar-dimensions* [50 50]) -- cgit v1.2.3-70-g09d2