From 33955c93ae8050778c75c18756585a59103ea86f Mon Sep 17 00:00:00 2001 From: Scott Ostler Date: Sun, 24 Oct 2010 20:46:30 -0400 Subject: Add initial event logic and merge --- src/events.clj | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/site.clj | 33 +++++++++++++++--------------- src/utils.clj | 44 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 120 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/events.clj b/src/events.clj index 6660518..501c231 100644 --- a/src/events.clj +++ b/src/events.clj @@ -1,13 +1,69 @@ (ns events - (use utils)) + (:import java.util.Date + java.net.URL + java.io.ByteArrayInputStream + java.io.ByteArrayOutputStream + javax.imageio.ImageIO) + (:use clojure.contrib.duck-streams + compojure + rooms + utils)) + +; 256bit b64 key +(def event-secret (b64dec "zLSBf28jZ3Q89MLx7u3P/w==\r\n")) + +(def encoder (aes-encoder event-secret)) +(def decoder (aes-decoder event-secret)) (def sample-event {:name "TMZ Maker!" :key "tmz" - :template "http://dump.fm/images/20100629/1277836809689-dumpfm-ryder-tmz_template.png" + :template "/event/proxy?url=http://dump.fm/images/20100629/1277836809689-dumpfm-ryder-tmz_template.png" :author {:nick "ryder" }}) -(defn current-event [session] +(defn event-page [session] (let [st (fetch-template "event" session) event sample-event] (.setAttribute st "event" (stringify-and-escape sample-event)) - (.toString st))) \ No newline at end of file + (.toString st))) + +(defn image-proxy [session params request] + (println "image-proxy for" (:url params)) + [200 (.openStream (URL. (:url params)))]) + +(defn fetch-event [key] + sample-event) + +(defn image-already-submitted? [event img-src] + false) + +(def event-submission-room "dumpfm") + + +(defn build-event-msg [nick evnet url] + {:nick nick + :content url + :created_on (new Date) + :msg-id 1}) + +(defn submit! [session params request] + (let [nick (:nick session) + bytes (b64dec (:image params)) + src (:src params) + event (and nick bytes src (fetch-event (:event params)))] + (cond (not nick) (resp-error "NO_USER") + (not bytes) (resp-error "NO_IMG") + (not event) (resp-error "NO_EVENT") + (not (is-image? src)) (resp-error "BAD_SRC") + (image-already-submitted? + (:key event) src) (resp-error "IMG_SUBMITTED") + :else (let [ts (System/currentTimeMillis) + room (lookup-room event-submission-room) + fname (format "%s-%s.png" ts nick) + dest (open-file ["events" (:key event)] fname) + url (format "/events/%s/%s" (:key event) fname)] + (println "copying" dest) + (copy (ByteArrayInputStream. bytes) dest) + (dosync + (add-message (build-event-msg nick (:key event) url) room)) + (println "copied") + (resp-success "OK"))))) \ No newline at end of file diff --git a/src/site.clj b/src/site.clj index 98fde79..1523c6f 100644 --- a/src/site.clj +++ b/src/site.clj @@ -19,7 +19,6 @@ admin compojure email - events fame utils cookie-login @@ -473,7 +472,7 @@ ORDER BY cnt DESC (defn generic-profile-handler [session nick date msg-id func redirecter unknown] (if-let [user-info (fetch-nick nick)] - ;; If a valid msg-id is provided, the date is ignored. + ;; If a valid msg-id is provided, the date is ignored. ;; This makes urls such as /user/bogus/5 valid. (cond msg-id (if-let [msg-id (maybe-parse-int msg-id)] (func session user-info nil msg-id) @@ -489,12 +488,12 @@ ORDER BY cnt DESC (defn build-mini-profile [user-info] (let [st (fetch-template-fragment "mini_profile") - nick (user-info :nick) - score (lookup-score nick)] + nick (user-info :nick) + score (lookup-score nick)] (doseq [a [:nick :avatar :contact :bio]] (let [v (user-info a)] - (.setAttribute st (name a) - (if (non-empty-string? v) (escape-html v))))) + (.setAttribute st (name a) + (if (non-empty-string? v) (escape-html v))))) (doto st (.setAttribute "score" (comma-format score)) (.setAttribute "score_ent" (score-to-entity score)) @@ -1150,14 +1149,14 @@ WHERE u.user_id = ANY(?)" (str "FILE_TOO_BIG " limit))) (defn invalid-image-dimensions? [f [max-width max-height]] - (try - (let [i (ImageIO/read f) - height (.getHeight i) - width (.getWidth i)] - (if (or (> width max-width) - (> height max-height)) - (str "INVALID_RESOLUTION " max-width " " max-height))) - (catch Exception _ "INVALID_IMAGE"))) + (try + (let [i (ImageIO/read f) + height (.getHeight i) + width (.getWidth i)] + (if (or (> width max-width) + (> height max-height)) + (str "INVALID_RESOLUTION " max-width " " max-height))) + (catch Exception _ "INVALID_IMAGE"))) (defn format-filename [s nick] (let [spaceless (.replace s \space \-) @@ -1165,7 +1164,7 @@ WHERE u.user_id = ANY(?)" subbed (re-gsub #"[^\w.-]" "" spaceless)] (str-join "-" [(System/currentTimeMillis) "dumpfm" nick-clean subbed]))) -(defn image-url-from-file [dir date file] +(defn image-url-from-file [dir date file] (str-join "/" [*server-url* dir date (.getName file)])) (defn validate-upload-file [f room] @@ -1339,7 +1338,9 @@ WHERE u.user_id = ANY(?)" ;; Events - (GET "/event" (current-event session)) +; (GET "/event" (event-page session)) +; (GET "/event/proxy" (image-proxy session params request)) +; (POST "/event/submit" (submit! session params request)) ;; Fullscreen (GET "/fullscreen" (serve-meme session "fullscreen")) diff --git a/src/utils.clj b/src/utils.clj index 9460bbc..08b06ab 100755 --- a/src/utils.clj +++ b/src/utils.clj @@ -6,7 +6,12 @@ java.io.File java.net.URLDecoder javax.sql.DataSource + javax.crypto.Cipher + javax.crypto.spec.SecretKeySpec + javax.crypto.KeyGenerator + javax.crypto.Mac org.postgresql.ds.PGPoolingDataSource + org.apache.commons.codec.binary.Base64 org.apache.commons.codec.digest.DigestUtils org.antlr.stringtemplate.StringTemplateGroup) (:use clojure.contrib.json.write @@ -297,7 +302,44 @@ (doseq [[i o] (map vector (iterate inc 1) objects)] (.setObject stmt i o)) (.executeQuery stmt)))) - + +;; Crypto + +(def b64codec (Base64.)) + +(defn b64enc [bytes] + (.encodeToString b64codec bytes)) + +(defn b64dec [s] + (.decode b64codec s)) + +(defn generate-aes-key [bits] + (let [kgen (doto (KeyGenerator/getInstance "AES") + (.init bits)) + skey (.generateKey kgen)] + (.getEncoded skey))) + +(defn aes-encoder [secret] + (let [spec (SecretKeySpec. secret "AES") + cipher (Cipher/getInstance "AES")] + (.init cipher Cipher/ENCRYPT_MODE spec) + (fn [input] + (.doFinal cipher input)))) + +(defn aes-decoder [secret] + (let [spec (SecretKeySpec. secret "AES") + cipher (Cipher/getInstance "AES")] + (.init cipher Cipher/DECRYPT_MODE spec) + (fn [input] + (.doFinal cipher input)))) + + +(defn make-signer [secret] + (let [algo "HmacSHA1" + spec (SecretKeySpec. (.getBytes secret) algo) + mac (Mac/getInstance algo)] + (.init mac spec) + (fn [input] (.doFinal mac (.getBytes input))))) ;; Parsing -- cgit v1.2.3-70-g09d2