summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuchen Pei <id@ypei.org>2024-12-26 10:53:30 +1100
committerYuchen Pei <id@ypei.org>2024-12-26 10:53:30 +1100
commit9e59bd0e850a6042093a9f3fd8341d73d44578ef (patch)
tree7b4e01e3ec459bc0b47235c8002d83afd7eea1a9
parentfffd9a8326a7b676338c339e04aaba15c7da72b3 (diff)
Adding a "test" for request signing
The test is the example from twitter developer document. Also adding references to the document about various steps.
-rw-r--r--exitter.el68
1 files changed, 52 insertions, 16 deletions
diff --git a/exitter.el b/exitter.el
index 70d1996..2d400ca 100644
--- a/exitter.el
+++ b/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