Skip to content

Commit

Permalink
Refactor oauth code
Browse files Browse the repository at this point in the history
  • Loading branch information
aspiring-aster committed Nov 21, 2024
1 parent 15d76e7 commit 13b0243
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 53 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ nimblecache/
htmldocs/
shell.nix
examples/example
examples/myexample*
47 changes: 33 additions & 14 deletions src/twim/utils/oauth1.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import std/[strformat,random,strutils, base64]
import std/[strformat, random, strutils, base64, times]
import ../utils/xapi
import nimcrypto

Expand All @@ -13,25 +13,25 @@ proc percentEncode(s: string): string =
result.add(toHex(ord(c), 2))

# Random string for oauth_nonce
proc OauthNonce*(): string =
proc OauthNonce(): string =
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
result = ""
for _ in 0 .. 10:
result.add(alphabet[rand(alphabet.high)])

proc OauthSignature*(xAPI: XAPI, httpMethod:string, endpoint:string, text: string, oAuthNonce: string, timeStamp: int):string =
proc OauthSignature(xAPI: XAPI, httpMethod: string, endpoint: string,
text: string, oAuthNonce: string, timeStamp: int): string =
# Follow https://developer.x.com/en/docs/authentication/oauth-1-0a/creating-a-signature
#
var outputString:string =
fmt"{httpMethod}&"&
var outputString: string =
fmt"{httpMethod}&" &
&"{percentEncode(endpoint)}&"

var paramString:string =
fmt"oauth_consumer_key={xAPI.consumerKey}&"&
&"oauth_nonce={oAuthNonce}&"&
&"oauth_signature_method=HMAC-SHA1&"&
&"oauth_timestamp={timeStamp}&"&
&"oauth_token={xAPI.accessToken}&"&
var paramString: string =
fmt"oauth_consumer_key={xAPI.consumerKey}&" &
&"oauth_nonce={oAuthNonce}&" &
&"oauth_signature_method=HMAC-SHA1&" &
&"oauth_timestamp={timeStamp}&" &
&"oauth_token={xAPI.accessToken}&" &
&"oauth_version=1.0"

paramString = percentEncode(paramString)
Expand All @@ -40,11 +40,30 @@ proc OauthSignature*(xAPI: XAPI, httpMethod:string, endpoint:string, text: strin


signatureBase = signatureBase.replace("+", "%20")
signatureBase = signatureBase.replace("%7E", "~") # Don't encode ~
signatureBase = signatureBase.replace("%7E", "~") # Don't encode ~


var signingKey:string = fmt"{xAPI.consumerSecret}&{xAPI.tokenSecret}"
var signingKey: string = fmt"{xAPI.consumerSecret}&{xAPI.tokenSecret}"

let hmac = sha1.hmac(signingKey, signatureBase)
result = base64.encode(hmac.data)
result = percentEncode(result)

proc generateOauthAuthString*(xapi: XAPI, endpoint: string,
content: string): string =
var oauthNonce: string = OauthNonce()
var timeStamp: int = toInt(epochTime())
var oauthSignature: string = OauthSignature(xApi, "POST", endpoint, content,
oauthNonce, timeStamp)

result =
&"OAuth oauth_consumer_key=\"{xAPI.consumerKey}\"," &
&"oauth_token=\"{xAPI.accessToken}\"," &
&"oauth_signature_method=\"HMAC-SHA1\"," &
&"oauth_timestamp=\"{timeStamp}\"," &
&"oauth_nonce=\"{oauthNonce}\"," &
&"oauth_version=\"1.0\"," &
&"oauth_signature=\"{oauthSignature}\""



18 changes: 4 additions & 14 deletions src/twim/v1_1/media.nim
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
import std/[httpclient, strformat, json, times, mimetypes]
import std/[httpclient]
import ../utils/[xapi, oauth1]

const MEDIA_ENDPOINT*: string = "https://upload.twitter.com/1.1/media/upload.json"

proc PostMedia*(xAPI: XAPI, fileName: string): string =

var client: HttpClient = newHttpClient()
var oauthNonce: string = OauthNonce()
var timeStamp: int = toInt(epochTime())
var oauthSignature:string = OauthSignature(xApi, "POST", MEDIA_ENDPOINT, fileName, oauthNonce, timeStamp)
var AUTH_STRING: string =
&"OAuth oauth_consumer_key=\"{xAPI.consumerKey}\"," &
&"oauth_token=\"{xAPI.accessToken}\"," &
&"oauth_signature_method=\"HMAC-SHA1\"," &
&"oauth_timestamp=\"{timeStamp}\"," &
&"oauth_nonce=\"{oauthNonce}\"," &
&"oauth_version=\"1.0\"," &
&"oauth_signature=\"{oauthSignature}\""

let authString: string = generateOauthAuthString(xapi, MEDIA_ENDPOINT, fileName)

client.headers = newHttpHeaders({"Content-Type": "multipart/form-data",
"authorization": AUTH_STRING})
"authorization": authString})

var multipart = newMultipartData()
multipart.addFiles({"media": fileName})
Expand All @@ -29,7 +19,7 @@ proc PostMedia*(xAPI: XAPI, fileName: string): string =
var response: Response
try:
response = client.request(MEDIA_ENDPOINT,
httpMethod = HttpPost, multipart=multipart)
httpMethod = HttpPost, multipart = multipart)
result = response.body
finally:
client.close()
30 changes: 5 additions & 25 deletions src/twim/v2/tweets.nim
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import std/[httpclient, strformat, json, times, strutils]
import std/[httpclient, strformat, json]
import ../utils/[xapi, oauth1]

const TWEET_ENDPOINT*: string = "https://api.twitter.com/2/tweets"

proc PostTextTweet*(xAPI: XAPI, text: string): string =
var client: HttpClient = newHttpClient()
var oauthNonce: string = OauthNonce()
var timeStamp: int = toInt(epochTime())
var oauthSignature:string = OauthSignature(xApi, "POST", TWEET_ENDPOINT, text, oauthNonce, timeStamp)
var AUTH_STRING: string =
&"OAuth oauth_consumer_key=\"{xAPI.consumerKey}\"," &
&"oauth_token=\"{xAPI.accessToken}\"," &
&"oauth_signature_method=\"HMAC-SHA1\"," &
&"oauth_timestamp=\"{timeStamp}\"," &
&"oauth_nonce=\"{oauthNonce}\"," &
&"oauth_version=\"1.0\"," &
&"oauth_signature=\"{oauthSignature}\""
let authString: string = generateOauthAuthString(xapi, TWEET_ENDPOINT, text)

client.headers = newHttpHeaders({"Content-Type": "application/json",
"authorization": AUTH_STRING})
"authorization": authString})
let body = %*{
"text": &"{text}"
}
Expand All @@ -35,20 +25,10 @@ proc PostTextTweet*(xAPI: XAPI, text: string): string =
proc PostTextTweet*(xAPI: XAPI, text: string, media_ids: seq[string]): string =

var client: HttpClient = newHttpClient()
var oauthNonce: string = OauthNonce()
var timeStamp: int = toInt(epochTime())
var oauthSignature:string = OauthSignature(xApi, "POST", TWEET_ENDPOINT, text, oauthNonce, timeStamp)
var AUTH_STRING: string =
&"OAuth oauth_consumer_key=\"{xAPI.consumerKey}\"," &
&"oauth_token=\"{xAPI.accessToken}\"," &
&"oauth_signature_method=\"HMAC-SHA1\"," &
&"oauth_timestamp=\"{timeStamp}\"," &
&"oauth_nonce=\"{oauthNonce}\"," &
&"oauth_version=\"1.0\"," &
&"oauth_signature=\"{oauthSignature}\""
let authString: string = generateOauthAuthString(xapi, TWEET_ENDPOINT, text)

client.headers = newHttpHeaders({"Content-Type": "application/json",
"authorization": AUTH_STRING})
"authorization": authString})


let body = %*{
Expand Down

0 comments on commit 13b0243

Please sign in to comment.