Browse Source

Adding a "test" for request signing

The test is the example from twitter developer document.

Also adding references to the document about various steps.
Yuchen Pei 11 tháng trước cách đây
mục cha
commit
9e59bd0e85
1 tập tin đã thay đổi với 52 bổ sung16 xóa
  1. 52 16
      exitter.el

+ 52 - 16
exitter.el

@@ -105,6 +105,8 @@
     (setq request-message-level 'blather)
   (setq request-message-level -1))
 
+;;; Get an oauth2 bearer token
+;;; https://developer.x.com/en/docs/authentication/api-reference/token
 (defun exitter-get-access-token ()
   (let ((oauth-consumer-key-secret
          (base64-encode-string
@@ -128,6 +130,13 @@
                      (message "Got error: %S" error-thrown)))
       )))
 
+;;; Use the twitter frontend flow and the oauth2 bearer token to
+;;; obtain a user oauth token aka user access token.
+
+;;; The official way of doing so is by oauth 1.0a documented at
+;;; https://developer.x.com/en/docs/authentication/oauth-1-0a, but
+;;; here we use the twitter frontend flow, similar to how one logs in
+;;; the twitter web client
 (defun exitter-get-guest-token ()
   (when exitter-debug (message "entering exitter-get-guest-token"))
   (request exitter-url-activate
@@ -299,12 +308,36 @@
                    (message "Got error: %S" error-thrown)))
     ))
 
-(defun exitter-get-sign-oauth (link url-params method)
-  (let* ((oauth-params `(("oauth_consumer_key" . ,exitter-oauth-consumer-key)
-                         ("oauth_nonce" . ,(exitter-nonce))
+;;; Example at
+;;; https://developer.x.com/en/docs/authentication/oauth-1-0a/creating-a-signature
+;;; should produce signature "Ls93hJiZbQ3akF3HF3x1Bz8%2FzU4%3D"
+(defun exitter-example-sign-oauth ()
+  (exitter-get-sign-oauth
+   "https://api.x.com/1.1/statuses/update.json" ;link
+   '(("status" . "Hello Ladies + Gentlemen, a signed OAuth request!")
+     ("include_entities" .	"true"))             ;url-params
+   "POST"                                        ;method
+   "xvz1evFS4wEEPTGEFPHBog"                      ;oauth-consumer-key
+   "kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw" ;oauth-consumer-secret
+   "370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb" ;oauth-token
+   "LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE"  ;oauth-token-secret
+   "kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg" ;oauth-nonce
+   "1318622958"                                 ;oauth-timestamp
+   ))
+
+;;; see
+;;; https://developer.x.com/en/docs/authentication/oauth-1-0a/creating-a-signature
+;;; https://developer.x.com/en/docs/authentication/oauth-1-0a/authorizing-a-request
+(defun exitter-get-sign-oauth (link url-params method &optional
+                                    oauth-consumer-key oauth-consumer-secret
+                                    oauth-token oauth-token-secret
+                                    oauth-nonce oauth-timestamp)
+  (let* ((oauth-params `(("oauth_consumer_key" .
+                          ,(or oauth-consumer-key exitter-oauth-consumer-key))
+                         ("oauth_nonce" . ,(or oauth-nonce (exitter-nonce)))
                          ("oauth_signature_method" . "HMAC-SHA1")
-                         ("oauth_timestamp" . ,(format-time-string "%s" (current-time)))
-                         ("oauth_token" . ,exitter-oauth-token)
+                         ("oauth_timestamp" . ,(or oauth-timestamp (format-time-string "%s" (current-time))))
+                         ("oauth_token" . ,(or oauth-token exitter-oauth-token))
                          ("oauth_version" . "1.0")))
          (all-params (sort (seq-concatenate 'list url-params oauth-params)
                            (lambda (a b) (string< (car a) (car b)))))
@@ -327,18 +360,19 @@
               "\\+" "%20"
               param-to-sign-unencoded)))))
          (to-sign (format "%s&%s&%s" method-up hexed-link param-to-sign))
+         (signing-key (format "%s&%s"
+                              (or oauth-consumer-secret
+                                  exitter-oauth-consumer-secret)
+                              (or oauth-token-secret
+                                  exitter-oauth-token-secret)))
          (signature (url-hexify-string
-                     (base64-encode-string
-                      (hmac-sha1 (encode-coding-string
-                                  (format "%s&%s"
-                                          exitter-oauth-consumer-secret
-                                          exitter-oauth-token-secret)
-                                  'utf-8)
-                                 (encode-coding-string to-sign 'utf-8)))))
+                     (print (base64-encode-string
+                             (exitter-hmac-sha1 (encode-coding-string signing-key 'utf-8)
+                                                (encode-coding-string to-sign 'utf-8))))))
          )
-    (message "PARAM-TO-SIGN-UNENC: %s" (prin1-to-string param-to-sign-unencoded))
-    (message "PARAM-TO-SIGN: %s" (prin1-to-string param-to-sign))
-    (message "TO-SIGN: %s" (prin1-to-string to-sign))
+    ;; (message "PARAM-TO-SIGN-UNENC: %s" (prin1-to-string param-to-sign-unencoded))
+    ;; (message "PARAM-TO-SIGN: %s" (prin1-to-string param-to-sign))
+    ;; (message "TO-SIGN: %s" (prin1-to-string to-sign))
     (format "OAuth realm=\"http://api.twitter.com/\", oauth_signature=\"%s\", %s"
             signature
             (mapconcat
@@ -403,6 +437,7 @@ ONEPLUS A3010 Build/PKQ1.181203.001)")
      `(("variables" . ,variables)
        ("features" . ,exitter-default-features)))))
 
+;;; utilities
 (require 'bindat)
 
 (defun exitter-nonce ()
@@ -417,7 +452,8 @@ ONEPLUS A3010 Build/PKQ1.181203.001)")
 
 (require 'sha1)
 
-(defun hmac-sha1 (key message)
+;;; Source: https://www.emacswiki.org/emacs/HmacShaOne
+(defun exitter-hmac-sha1 (key message)
   "Return an HMAC-SHA1 authentication code for KEY and MESSAGE.
 
 KEY and MESSAGE must be unibyte strings.  The result is a unibyte