]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/oauth2/oauth2.el
Clean up copyright notices.
[gnu-emacs-elpa] / packages / oauth2 / oauth2.el
index cdfc666c163dcfa5579c75f84c093c1c09f419e2..c7dc56fb440f670f30b8b4f809b65431c74b24cf 100644 (file)
@@ -1,9 +1,9 @@
 ;;; oauth2.el --- OAuth 2.0 Authorization Protocol
 
-;; Copyright (C) 2011 Free Software Foundation, Inc
+;; Copyright (C) 2011-2012 Free Software Foundation, Inc
 
 ;; Author: Julien Danjou <julien@danjou.info>
-;; Version: 0.2
+;; Version: 0.8
 ;; Keywords: comm
 
 ;; This file is part of GNU Emacs.
 
 ;;; Code:
 
+(require 'cl)
 (require 'plstore)
 (require 'json)
 
-(defun oauth2-request-authorization (auth-url client-id &optional scope state)
+(defun oauth2-request-authorization (auth-url client-id &optional scope state redirect-uri)
   "Request OAuth authorization at AUTH-URL by launching `browse-url'.
 CLIENT-ID is the client id provided by the provider.
 It returns the code provided by the service."
   (browse-url (concat auth-url
                       (if (string-match-p "\?" auth-url) "&" "?")
                       "client_id=" (url-hexify-string client-id)
-                      "&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob"
+                      "&response_type=code"
+                      "&redirect_uri=" (url-hexify-string (or redirect-uri "urn:ietf:wg:oauth:2.0:oob"))
                       (if scope (concat "&scope=" (url-hexify-string scope)) "")
                       (if state (concat "&state=" (url-hexify-string state)) "")))
   (read-string "Enter the code your browser displayed: "))
@@ -74,9 +76,10 @@ It returns the code provided by the service."
   client-secret
   access-token
   refresh-token
-  token-url)
+  token-url
+  access-response)
 
-(defun oauth2-request-access (token-url client-id client-secret code)
+(defun oauth2-request-access (token-url client-id client-secret code &optional redirect-uri)
   "Request OAuth access at TOKEN-URL.
 The CODE should be obtained with `oauth2-request-authorization'.
 Return an `oauth2-token' structure."
@@ -88,25 +91,27 @@ Return an `oauth2-token' structure."
              "client_id=" client-id
              "&client_secret=" client-secret
              "&code=" code
-             "&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code"))))
+             "&redirect_uri=" (url-hexify-string (or redirect-uri "urn:ietf:wg:oauth:2.0:oob"))
+             "&grant_type=authorization_code"))))
       (make-oauth2-token :client-id client-id
                          :client-secret client-secret
-                         :access-token (aget result 'access_token)
-                         :refresh-token (aget result 'refresh_token)
-                         :token-url token-url))))
+                         :access-token (cdr (assoc 'access_token result))
+                         :refresh-token (cdr (assoc 'refresh_token result))
+                         :token-url token-url
+                         :access-response result))))
 
 ;;;###autoload
 (defun oauth2-refresh-access (token)
   "Refresh OAuth access TOKEN.
 TOKEN should be obtained with `oauth2-request-access'."
   (setf (oauth2-token-access-token token)
-        (aget (oauth2-make-access-request
-               (oauth2-token-token-url token)
-               (concat "client_id=" (oauth2-token-client-id token)
-                       "&client_secret=" (oauth2-token-client-secret token)
-                       "&refresh_token=" (oauth2-token-refresh-token token)
-                       "&grant_type=refresh_token"))
-              'access_token))
+        (cdr (assoc 'access_token
+                    (oauth2-make-access-request
+                     (oauth2-token-token-url token)
+                     (concat "client_id=" (oauth2-token-client-id token)
+                             "&client_secret=" (oauth2-token-client-secret token)
+                             "&refresh_token=" (oauth2-token-refresh-token token)
+                             "&grant_type=refresh_token")))))
   ;; If the token has a plstore, update it
   (let ((plstore (oauth2-token-plstore token)))
     (when plstore
@@ -114,19 +119,23 @@ TOKEN should be obtained with `oauth2-request-access'."
                    nil `(:access-token
                          ,(oauth2-token-access-token token)
                          :refresh-token
-                         ,(oauth2-token-refresh-token token)))
+                         ,(oauth2-token-refresh-token token)
+                         :access-response
+                         ,(oauth2-token-access-response token)
+                         ))
       (plstore-save plstore)))
   token)
 
 ;;;###autoload
-(defun oauth2-auth (auth-url token-url client-id client-secret &optional scope state)
+(defun oauth2-auth (auth-url token-url client-id client-secret &optional scope state redirect-uri)
   "Authenticate application via OAuth2."
   (oauth2-request-access
    token-url
    client-id
    client-secret
    (oauth2-request-authorization
-    auth-url client-id scope state)))
+    auth-url client-id scope state redirect-uri)
+   redirect-uri))
 
 (defcustom oauth2-token-file (concat user-emacs-directory "oauth2.plstore")
   "File path where store OAuth tokens."
@@ -139,7 +148,7 @@ This allows to store the token in an unique way."
   (secure-hash 'md5 (concat auth-url token-url resource-url)))
 
 ;;;###autoload
-(defun oauth2-auth-and-store (auth-url token-url resource-url client-id client-secret)
+(defun oauth2-auth-and-store (auth-url token-url resource-url client-id client-secret &optional redirect-uri)
   "Request access to a resource and store it using `plstore'."
   ;; We store a MD5 sum of all URL
   (let* ((plstore (plstore-open oauth2-token-file))
@@ -154,16 +163,19 @@ This allows to store the token in an unique way."
                            :client-secret client-secret
                            :access-token (plist-get plist :access-token)
                            :refresh-token (plist-get plist :refresh-token)
-                           :token-url token-url)
+                           :token-url token-url
+                           :access-response (plist-get plist :access-response))
       (let ((token (oauth2-auth auth-url token-url
-                                client-id client-secret resource-url)))
+                                client-id client-secret resource-url nil redirect-uri)))
         ;; Set the plstore
         (setf (oauth2-token-plstore token) plstore)
         (setf (oauth2-token-plstore-id token) id)
         (plstore-put plstore id nil `(:access-token
                                       ,(oauth2-token-access-token token)
                                       :refresh-token
-                                      ,(oauth2-token-refresh-token token)))
+                                      ,(oauth2-token-refresh-token token)
+                                      :access-response
+                                      ,(oauth2-token-access-response token)))
         (plstore-save plstore)
         token))))
 
@@ -192,9 +204,9 @@ TOKENS can be obtained with `oauth2-auth'."
             (url-request-extra-headers request-extra-headers)
             (url-buffer))
         (setq url-buffer (url-retrieve-synchronously
-                          (oauth2-url-append-access-token token url)))
+                           (oauth2-url-append-access-token token url)))
         (if tokens-need-renew
-              (oauth2-url-retrieve-synchronously (oauth2-refresh-access token) url request-method request-data request-extra-headers)
+            (oauth2-url-retrieve-synchronously (oauth2-refresh-access token) url request-method request-data request-extra-headers)
           url-buffer)))))
 
 (provide 'oauth2)