├── .gitignore ├── README.md ├── project.clj └── src └── friend_oauth2_examples ├── appdotnet_handler.clj ├── facebook_handler.clj ├── github_handler.clj └── google_handler.clj /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | pom.xml 6 | *.jar 7 | *.class 8 | .lein-deps-sum 9 | .lein-failures 10 | .lein-plugins 11 | .lein-env 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # friend-oauth2-examples 2 | 3 | The friend-oauth2 examples have been moved into the friend-oauth2 project itself: 4 | * http://clojusc.github.io/friend-oauth2/current/50-examples.html 5 | 6 | 7 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject friend-oauth2-examples "0.0.5" 2 | :description "Friend Oauth2 Workflow examples, includes App.net, Facebook, Github and Google handlers." 3 | 4 | :url "https://github.com/ddellacosta/friend-oauth2-examples" 5 | 6 | :license {:name "MIT License" 7 | :url "http://dd.mit-license.org"} 8 | 9 | :dependencies [[org.clojure/clojure "1.5.1"] 10 | [compojure "1.1.5" :exclusions [ring/ring-core org.clojure/core.incubator]] 11 | [com.cemerick/friend "0.2.0" :exclusions [ring/ring-core]] 12 | [friend-oauth2 "0.1.1" :exclusions [org.apache.httpcomponents/httpcore]] 13 | [cheshire "5.2.0"] 14 | [ring-server "0.3.0" :exclusions [ring]]] 15 | 16 | :profiles {:dev {:plugins [[lein-ring "0.8.5" :exclusions [org.clojure/clojure]]]} 17 | :appdotnet {:ring {:handler friend-oauth2-examples.appdotnet-handler/app}} 18 | :facebook {:ring {:handler friend-oauth2-examples.facebook-handler/app}} 19 | :github {:ring {:handler friend-oauth2-examples.github-handler/app}} 20 | :google {:ring {:handler friend-oauth2-examples.google-handler/app}}} 21 | 22 | :aliases {"facebook" ["with-profile" "dev,facebook" 23 | "do" "ring" "server-headless"] 24 | "appdotnet" ["with-profile" "dev,appdotnet" 25 | "do" "ring" "server-headless"] 26 | "github" ["with-profile" "dev,github" 27 | "do" "ring" "server-headless"] 28 | "google" ["with-profile" "dev,google" 29 | "do" "ring" "server-headless"]}) 30 | -------------------------------------------------------------------------------- /src/friend_oauth2_examples/appdotnet_handler.clj: -------------------------------------------------------------------------------- 1 | (ns friend-oauth2-examples.appdotnet-handler 2 | (:require [compojure.core :refer :all] 3 | [compojure.handler :as handler] 4 | [compojure.route :as route] 5 | [cemerick.friend :as friend] 6 | [friend-oauth2.workflow :as oauth2] 7 | [friend-oauth2.util :refer [format-config-uri]] 8 | [cheshire.core :as j] 9 | (cemerick.friend [workflows :as workflows] 10 | [credentials :as creds]))) 11 | 12 | (defn credential-fn 13 | [token] 14 | ;;lookup token in DB or whatever to fetch appropriate :roles 15 | {:identity token :roles #{::user}}) 16 | 17 | (def client-config 18 | {:client-id "" 19 | :client-secret "" 20 | :callback {:domain "http://example.com" :path "/app.net.callback"}}) 21 | 22 | (def uri-config 23 | {:authentication-uri {:url "https://account.app.net/oauth/authenticate" 24 | :query {:client_id (:client-id client-config) 25 | :response_type "code" 26 | :redirect_uri (format-config-uri client-config) 27 | :scope "stream,email"}} 28 | 29 | :access-token-uri {:url "https://account.app.net/oauth/access_token" 30 | :query {:client_id (:client-id client-config) 31 | :client_secret (:client-secret client-config) 32 | :grant_type "authorization_code" 33 | :redirect_uri (format-config-uri client-config)}}}) 34 | 35 | (defroutes ring-app 36 | (GET "/" request "open.") 37 | (GET "/status" request 38 | (let [count (:count (:session request) 0) 39 | session (assoc (:session request) :count (inc count))] 40 | (-> (ring.util.response/response 41 | (str "
We've hit the session page " (:count session) 42 | " times.
The current session: " session "
")) 43 | (assoc :session session)))) 44 | (GET "/authlink" request 45 | (friend/authorize #{::user} "Authorized page.")) 46 | (GET "/authlink2" request 47 | (friend/authorize #{::user} "Authorized page 2.")) 48 | (GET "/admin" request 49 | (friend/authorize #{::admin} "Only admins can see this page.")) 50 | (friend/logout (ANY "/logout" request (ring.util.response/redirect "/")))) 51 | 52 | (def app 53 | (handler/site 54 | (friend/authenticate 55 | ring-app 56 | {:allow-anon? true 57 | :workflows [(oauth2/workflow 58 | {:client-config client-config 59 | :uri-config uri-config 60 | :credential-fn credential-fn})]}))) 61 | -------------------------------------------------------------------------------- /src/friend_oauth2_examples/facebook_handler.clj: -------------------------------------------------------------------------------- 1 | (ns friend-oauth2-examples.facebook-handler 2 | (:require [compojure.core :refer :all] 3 | [compojure.handler :as handler] 4 | [compojure.route :as route] 5 | [cemerick.friend :as friend] 6 | [friend-oauth2.workflow :as oauth2] 7 | [friend-oauth2.util :refer [format-config-uri get-access-token-from-params]] 8 | (cemerick.friend [workflows :as workflows] 9 | [credentials :as creds]))) 10 | 11 | (defn credential-fn 12 | [token] 13 | ;;lookup token in DB or whatever to fetch appropriate :roles 14 | {:identity token :roles #{::user}}) 15 | 16 | (def client-config 17 | {:client-id "" 18 | :client-secret "" 19 | :callback {:domain "http://example.com" :path "/facebook.callback"}}) 20 | 21 | (def uri-config 22 | {:authentication-uri {:url "https://www.facebook.com/dialog/oauth" 23 | :query {:client_id (:client-id client-config) 24 | :redirect_uri (format-config-uri client-config)}} 25 | 26 | :access-token-uri {:url "https://graph.facebook.com/oauth/access_token" 27 | :query {:client_id (:client-id client-config) 28 | :client_secret (:client-secret client-config) 29 | :redirect_uri (format-config-uri client-config)}}}) 30 | 31 | (defroutes ring-app 32 | (GET "/" request "open.") 33 | (GET "/status" request 34 | (let [count (:count (:session request) 0) 35 | session (assoc (:session request) :count (inc count))] 36 | (-> (ring.util.response/response 37 | (str "We've hit the session page " (:count session) 38 | " times.
The current session: " session "
")) 39 | (assoc :session session)))) 40 | (GET "/authlink" request 41 | (friend/authorize #{::user} "Authorized page.")) 42 | (GET "/authlink2" request 43 | (friend/authorize #{::user} "Authorized page 2.")) 44 | (GET "/admin" request 45 | (friend/authorize #{::admin} "Only admins can see this page.")) 46 | (friend/logout (ANY "/logout" request (ring.util.response/redirect "/")))) 47 | 48 | (def app 49 | (handler/site 50 | (friend/authenticate 51 | ring-app 52 | {:allow-anon? true 53 | :workflows [(oauth2/workflow 54 | {:client-config client-config 55 | :uri-config uri-config 56 | :access-token-parsefn get-access-token-from-params 57 | :credential-fn credential-fn})]}))) 58 | -------------------------------------------------------------------------------- /src/friend_oauth2_examples/github_handler.clj: -------------------------------------------------------------------------------- 1 | (ns friend-oauth2-examples.github-handler 2 | (:require [compojure.core :refer :all] 3 | [compojure.handler :as handler] 4 | [compojure.route :as route] 5 | [cemerick.friend :as friend] 6 | [clj-http.client :as client] 7 | [friend-oauth2.workflow :as oauth2] 8 | [friend-oauth2.util :refer [format-config-uri get-access-token-from-params]] 9 | [cheshire.core :as j] 10 | (cemerick.friend [workflows :as workflows] 11 | [credentials :as creds]))) 12 | 13 | (declare render-status-page) 14 | (declare render-repos-page) 15 | (declare get-github-repos) 16 | 17 | (defn credential-fn 18 | [token] 19 | ;;lookup token in DB or whatever to fetch appropriate :roles 20 | {:identity token :roles #{::user}}) 21 | 22 | (def client-config 23 | {:client-id "" 24 | :client-secret "" 25 | :callback {:domain "http://example.com" :path "/github.callback"}}) 26 | 27 | (def uri-config 28 | {:authentication-uri {:url "https://github.com/login/oauth/authorize" 29 | :query {:client_id (:client-id client-config) 30 | :response_type "code" 31 | :redirect_uri (format-config-uri client-config) 32 | :scope "user"}} 33 | 34 | :access-token-uri {:url "https://github.com/login/oauth/access_token" 35 | :query {:client_id (:client-id client-config) 36 | :client_secret (:client-secret client-config) 37 | :grant_type "authorization_code" 38 | :redirect_uri (format-config-uri client-config)}}}) 39 | 40 | (defroutes ring-app 41 | (GET "/" request "My Github RepositoriesWe've hit the session page " (:count session) 64 | " times.
The current session: " session "
")) 65 | (assoc :session session)))) 66 | 67 | (defn render-repos-page 68 | "Shows a list of the current users github repositories by calling the github api 69 | with the OAuth2 access token that the friend authentication has retrieved." 70 | [request] 71 | (let [authentications (get-in request [:session :cemerick.friend/identity :authentications]) 72 | access-token (:access_token (second (first authentications))) 73 | repos-response (get-github-repos access-token)] 74 | (str (vec (map :name repos-response))))) 75 | 76 | (defn get-github-repos 77 | "Github API call for the current authenticated users repository list." 78 | [access-token] 79 | (let [url (str "https://api.github.com/user/repos?access_token=" access-token) 80 | response (client/get url {:accept :json}) 81 | repos (j/parse-string (:body response) true)] 82 | repos)) 83 | -------------------------------------------------------------------------------- /src/friend_oauth2_examples/google_handler.clj: -------------------------------------------------------------------------------- 1 | (ns friend-oauth2-examples.google-handler 2 | (:require [compojure.core :refer :all] 3 | [compojure.handler :as handler] 4 | [compojure.route :as route] 5 | [cemerick.friend :as friend] 6 | [friend-oauth2.workflow :as oauth2] 7 | [friend-oauth2.util :refer [format-config-uri]] 8 | [cheshire.core :as j] 9 | (cemerick.friend [workflows :as workflows] 10 | [credentials :as creds]))) 11 | 12 | (defn credential-fn 13 | [token] 14 | ;;lookup token in DB or whatever to fetch appropriate :roles 15 | {:identity token :roles #{::user}}) 16 | 17 | (def client-config 18 | {:client-id "" 19 | :client-secret "" 20 | :callback {:domain "http://example.com" :path "/oauth2callback"}}) 21 | 22 | (def uri-config 23 | {:authentication-uri {:url "https://accounts.google.com/o/oauth2/auth" 24 | :query {:client_id (:client-id client-config) 25 | :response_type "code" 26 | :redirect_uri (format-config-uri client-config) 27 | :scope "email"}} 28 | 29 | :access-token-uri {:url "https://accounts.google.com/o/oauth2/token" 30 | :query {:client_id (:client-id client-config) 31 | :client_secret (:client-secret client-config) 32 | :grant_type "authorization_code" 33 | :redirect_uri (format-config-uri client-config)}}}) 34 | 35 | (defroutes ring-app 36 | (GET "/" request "open.") 37 | (GET "/status" request 38 | (let [count (:count (:session request) 0) 39 | session (assoc (:session request) :count (inc count))] 40 | (-> (ring.util.response/response 41 | (str "We've hit the session page " (:count session) 42 | " times.
The current session: " session "
")) 43 | (assoc :session session)))) 44 | (GET "/authlink" request 45 | (friend/authorize #{::user} "Authorized page.")) 46 | (GET "/authlink2" request 47 | (friend/authorize #{::user} "Authorized page 2.")) 48 | (GET "/admin" request 49 | (friend/authorize #{::admin} "Only admins can see this page.")) 50 | (friend/logout (ANY "/logout" request (ring.util.response/redirect "/")))) 51 | 52 | (def app 53 | (handler/site 54 | (friend/authenticate 55 | ring-app 56 | {:allow-anon? true 57 | :workflows [(oauth2/workflow 58 | {:client-config client-config 59 | :uri-config uri-config 60 | :credential-fn credential-fn})]}))) 61 | --------------------------------------------------------------------------------