From fdca23e4b777eab6f1d390fe11424c9154d5d8d7 Mon Sep 17 00:00:00 2001 From: Olexiy Zamkoviy Date: Sun, 23 Feb 2014 19:02:48 +0200 Subject: [PATCH 1/2] Added facebook support --- examples/facebook-auth-example.lisp | 36 +++++++++++++++++++++++++++++ oauth2.lisp | 36 ++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 examples/facebook-auth-example.lisp diff --git a/examples/facebook-auth-example.lisp b/examples/facebook-auth-example.lisp new file mode 100644 index 0000000..b97b8ba --- /dev/null +++ b/examples/facebook-auth-example.lisp @@ -0,0 +1,36 @@ +(defpackage oauth2.test.facebook-login + (:use cl oauth2)) + +(in-package oauth2.test.facebook-login) + +(defparameter *app-id* NIL + "Facebook app ID.") + +(defparameter *app-secret* NIL + "6094834c1ef28e5fb73cf786ba4e807f" + "Facebook app secret") + +(defparameter *redirect-uri* + NIL + ) + +(defparameter *redirect* + (request-code + "https://www.facebook.com/dialog/oauth" + *app-id* + :other `(("redirect_uri" . ,*redirect-uri*)))) + +(format t "Go to ~A and come back with the code: " *redirect*) +(defparameter *code* (read-line)) + +(defparameter *token* + (request-token + "https://graph.facebook.com/oauth/access_token" + *code* + :redirect-uri *redirect-uri* + :method :post + :other `(("client_id" . ,*app-id*) + ("client_secret" . ,*app-secret*)) + :token-parser 'oauth2:facebook-token->alist)) + +(format t "I got a token:~%~A~%" *token*) diff --git a/oauth2.lisp b/oauth2.lisp index c6098a8..a8a4630 100644 --- a/oauth2.lisp +++ b/oauth2.lisp @@ -3,7 +3,7 @@ (:export :request-code :request-token :request-resource :refresh-token :authorization-error :error-code :error-body :token-string :token-type :token-expires-in - :token-refresh-token :token-scope :token-from-string) + :token-refresh-token :token-scope :token-from-string :facebook-token->alist) (:documentation "This package contains a fairly low-level implementation of the OAUTH2 protocol. It currently only supports \"Authorization Code Grant\" (section 4.1 if the draft) @@ -108,7 +108,20 @@ it will be one of the following: (make-token :string string :type "Bearer" :expires-in expires-in :refresh-token refresh-token :scope scope)) -(defmacro with-handle-token (token) +(defun facebook-token->alist (str) + (list* + (cons :token--type "Bearer") + (loop for i in (ppcre:split "&" str) + collect (let ((data (ppcre:split "=" i))) + (cons + (cond + ((string= (car data) "access_token" ) :access--token) + ((string= (car data) "expires") :expires--in)) + (if (string= (car data) "expires") + (parse-integer (second data)) + (second data))))))) + +(defmacro with-handle-token (token &optional token-parser) "Handle the return value you get from a request for a token. Used by request-token and refresh-token." `(multiple-value-bind (body code) ,token (case code @@ -119,17 +132,17 @@ it will be one of the following: :uri (assoc1 :error--uri data) :description (assoc1 :error--description data))))) (200 - (let ((data (parse-json body))) + (let ((data (funcall ,(or token-parser #'parse-json) body))) (make-token - :string (assoc1 :access--token data) - :type (assoc1 :token--type data) - :expires-in (assoc1 :expires--in data) - :refresh-token (assoc1 :refresh--token data) - :scope (assoc1 :scope data)))) + :string (assoc1 :access--token data) + :type (assoc1 :token--type data) + :expires-in (assoc1 :expires--in data) + :refresh-token (assoc1 :refresh--token data) + :scope (assoc1 :scope data)))) (t (error "Got an invalid response from server. Code: ~A" code))))) -(defun request-token (authorizer code &key redirect-uri (method :get) other) +(defun request-token (authorizer code &key redirect-uri (method :get) other (token-parser 'parse-json)) "Request a token from the authorizer. CODE has to be authorization code. You can get it from calling REQUEST-CODE. @@ -151,7 +164,8 @@ Returns a TOKEN." (http-request authorizer :method method :parameters data - :redirect nil)))) + :redirect nil) + token-parser))) (defun plist-remove (key list) "Returns a copy of list with the key-value pair identified by KEY removed." @@ -195,4 +209,4 @@ The return value is like the one of DRAKMA:HTTP-REQUEST." (apply 'http-request url :additional-headers `(("Authorization" . ,(format nil "Bearer ~A" (token-string token))) ,@headers) - other))) \ No newline at end of file + other))) From a09f4ba0dc5de4b7b465fa09bf0945f0c95fe69f Mon Sep 17 00:00:00 2001 From: Olexiy Zamkoviy Date: Sun, 23 Feb 2014 20:06:00 +0200 Subject: [PATCH 2/2] Removed messy code from facebook auth example --- examples/facebook-auth-example.lisp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/facebook-auth-example.lisp b/examples/facebook-auth-example.lisp index b97b8ba..6b81a11 100644 --- a/examples/facebook-auth-example.lisp +++ b/examples/facebook-auth-example.lisp @@ -7,7 +7,6 @@ "Facebook app ID.") (defparameter *app-secret* NIL - "6094834c1ef28e5fb73cf786ba4e807f" "Facebook app secret") (defparameter *redirect-uri*