require facebook auth for updating quantities

This commit is contained in:
Bart Akeley 2018-01-27 17:09:59 -06:00
parent bcb7699a7e
commit 50657ef22d
8 changed files with 60 additions and 26 deletions

3
.gitignore vendored
View file

@ -8,4 +8,5 @@ pom.xml.asc
*.class *.class
/.lein-* /.lein-*
/.nrepl-port /.nrepl-port
profiles.clj profiles.clj
.idea

View file

@ -16,6 +16,11 @@ To start a web server for the application, run:
To test a request/response, run: To test a request/response, run:
curl --data @sample-food-item-post.json --header "Content-Type: application/json" http://localhost:3000/fooditems curl --data @sample-food-item-post.json \
--header "Content-Type: application/json" \
http://localhost:3000/fooditems
curl --data @sample-quantity-post.json --header "Content-Type: application/json" http://localhost:3000/quantity curl --data @sample-quantity-post.json \
--header "Content-Type: application/json" \
--header "authorization: facebook-token <paste fb token>" \
http://localhost:3000/quantity

View file

@ -15,7 +15,9 @@
[ring/ring-json "0.4.0"] [ring/ring-json "0.4.0"]
[ring/ring-mock "0.3.1"] [ring/ring-mock "0.3.1"]
[ring/ring-jetty-adapter "1.4.0"] [ring/ring-jetty-adapter "1.4.0"]
[com.layerware/hugsql "0.4.8"]] [com.layerware/hugsql "0.4.8"]
[buddy/buddy-auth "2.1.0"]
[clj-http "3.7.0"]]
:plugins [[lein-ring "0.9.7"] [lein-environ "1.1.0"]] :plugins [[lein-ring "0.9.7"] [lein-environ "1.1.0"]]
:ring {:handler aretherecookies.app/app} :ring {:handler aretherecookies.app/app}
:profiles :profiles

View file

@ -1,25 +1,33 @@
(ns aretherecookies.app (ns aretherecookies.app
(:gen-class) (:gen-class)
(:require [aretherecookies.handler :refer [food-items-handler quantity-handler]] (:require [aretherecookies.handler :refer [food-items-handler quantity-handler]]
[aretherecookies.auth :refer [auth-backend]]
[environ.core :refer [env]] [environ.core :refer [env]]
[compojure.handler :refer [site]] [compojure.handler :refer [api]]
[compojure.core :refer :all] [compojure.core :refer :all]
[compojure.route :as route]
[ring.adapter.jetty :as jetty] [ring.adapter.jetty :as jetty]
[ring.middleware.anti-forgery :refer :all] [ring.middleware.anti-forgery :refer :all]
[ring.middleware.json :refer [wrap-json-body]] [ring.middleware.json :refer [wrap-json-body]]
[ring.middleware.defaults :refer [wrap-defaults api-defaults]])) [ring.middleware.defaults :refer [wrap-defaults api-defaults]]
[buddy.auth :refer [throw-unauthorized]]
[buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]))
(defroutes app-routes (defroutes app-routes
(GET "/" [] (str {:csrf-token *anti-forgery-token*})) (GET "/" [] (str {:csrf-token *anti-forgery-token*}))
(POST "/test" req "ok") (POST "/test" [] "ok")
(POST "/fooditems" req (wrap-json-body food-items-handler)) (POST "/fooditems" [] food-items-handler)
(POST "/quantity" req (wrap-json-body quantity-handler))) (POST "/quantity" [] quantity-handler))
(def app-config (assoc-in api-defaults [:security :anti-forgery] false)) (def app-config (assoc-in api-defaults [:security :anti-forgery] false))
(def app (wrap-defaults app-routes app-config)) (def app (wrap-defaults app-routes app-config))
(defn -main [& [port]] (defn -main
[& [port]]
(let [port (Integer. (or port (env :port) 3000))] (let [port (Integer. (or port (env :port) 3000))]
(jetty/run-jetty (site #'app) {:port port :join? false}))) (->
(api #'app)
(wrap-authorization auth-backend)
(wrap-authentication auth-backend)
(wrap-json-body {:keywords? true})
(jetty/run-jetty {:port port :join? false}))))

View file

@ -0,0 +1,15 @@
(ns aretherecookies.auth
(:require [buddy.auth.backends :as backends]
[clj-http.client :as client]))
(defn facebook-me [token]
(client/get (str "https://graph.facebook.com/me?access_token=" token) {:accept :json}))
(defn facebook-me-ok [token]
(= (:status (facebook-me token)) 200))
(defn facebook-token-auth [_ token]
(if (facebook-me-ok token) token))
(def auth-backend
(backends/token {:token-name "facebook-token" :authfn facebook-token-auth}))

View file

@ -35,7 +35,7 @@
(defonce pooled-db (delay (pool db-spec))) (defonce pooled-db (delay (pool db-spec)))
(defn get-orderby [{orderby "orderby"} & args] (defn get-orderby [{orderby :orderby} & args]
(apply (apply
(cond (cond
(= orderby "distance") by-distance (= orderby "distance") by-distance
@ -48,13 +48,13 @@
(str/replace token #"(^|$)" "'")) (str/replace token #"(^|$)" "'"))
(defn get-where [{:keys [:lat :lng :filter]}] (defn get-where [{:keys [:lat :lng :filter]}]
(let [radius (-> (filter "radius") (or 10)) (let [radius (or (:radius filter) 10)
categories (filter "categories")] categories (:categories filter)]
(cond (cond
categories (has-category {:categories (map wrap-in-quotes categories) :lat lat :lng lng :dist radius}) categories (has-category {:categories (map wrap-in-quotes categories) :lat lat :lng lng :dist radius})
:else (within-radius {:lat lat :lng lng :dist radius})))) :else (within-radius {:lat lat :lng lng :dist radius}))))
(defn query-food-items [{lat "lat" lng "lng" filter "filter"}] (defn query-food-items [{lat :lat lng :lng filter :filter}]
(select-food-items (select-food-items
@pooled-db @pooled-db
{:lat lat {:lat lat
@ -62,7 +62,7 @@
:where (get-where {:lat lat :lng lng :filter filter}) :where (get-where {:lat lat :lng lng :filter filter})
:order (get-orderby filter)})) :order (get-orderby filter)}))
(defn insert-quantity [{:keys [foodItemId quantity]}] (defn insert-quantity [{:keys [:foodItemId :quantity]}]
(insert-quantity-query @pooled-db {:food_item_id (wrap-in-quotes foodItemId) :quantity (wrap-in-quotes quantity)})) (insert-quantity-query @pooled-db {:food_item_id (wrap-in-quotes foodItemId) :quantity (wrap-in-quotes quantity)}))
(defn select-latest-quantity [{:keys [:foodItemId]}] (defn select-latest-quantity [{:keys [:foodItemId]}]

View file

@ -3,19 +3,22 @@
[aretherecookies.parsers :refer [food-items-to-json [aretherecookies.parsers :refer [food-items-to-json
parse-special-types]] parse-special-types]]
[clojure.data.json :as json] [clojure.data.json :as json]
[clojure.string :as str])) [clojure.string :as str]
[buddy.auth :refer [authenticated? throw-unauthorized]]))
(defn food-items-handler [req] (defn food-items-handler [req]
(println "req ---->" (:body req)) (println "req ---->" (:body req))
(let [{body :body} req] (let [{body :body} req]
(json/write-str (json/write-str
(hash-map (hash-map
:filter (get body "filter") :filter (get body :filter)
:fooditems (food-items-to-json (query-food-items body))) :fooditems (food-items-to-json (query-food-items body)))
:value-fn parse-special-types))) :value-fn parse-special-types)))
(defn quantity-handler [{{foodItemId "foodItemId" quantity "quantity"} :body}] (defn quantity-handler [req]
(println "req ---->" foodItemId quantity) (let [{{foodItemId :foodItemId quantity :quantity} :body} req]
(json/write-str (if-not (authenticated? req) (throw-unauthorized))
(insert-quantity {:foodItemId foodItemId :quantity quantity}) (println "req ---->" foodItemId quantity)
:value-fn parse-special-types)) (json/write-str
(insert-quantity {:foodItemId foodItemId :quantity quantity})
:value-fn parse-special-types)))

View file

@ -13,9 +13,9 @@
(defn get-coords [item] (defn get-coords [item]
(-> (->
item item
(get :location) (:location)
json/read-str json/read-str
(get "coordinates"))) (:coordinates)))
(defn build-lat-lng [[lng lat]] (defn build-lat-lng [[lng lat]]
(hash-map :longitude lng :latitude lat)) (hash-map :longitude lng :latitude lat))