Guest User

Untitled

a guest
Oct 20th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.32 KB | None | 0 0
  1. # Code below modified from original. Credit can be found within
  2. # the twitter script itself. All credit goes to it's original authors.
  3. # You and me, know who these are if it includes either of us.
  4. # v1.0alpha - Twitter Oauth - single token use
  5. # * multiple accounts
  6. # * minimal packages required.
  7. # * tcl8.4 friendly.
  8. # * dict/json not required.
  9. # * All packages required provided.
  10. # * works like rss on crack, other rss scripts wont do twitter this can. ;)
  11. # - original credit to horgh/fedex
  12. # - major rewrite done by speechles
  13. # - oauth timestamp fix by thommey
  14.  
  15. # Incorrect signature, other errors pissing you off.
  16. # Get the inside look at every oauth transaction via query
  17. # set your debug nick here
  18. set oauthdebug ""
  19.  
  20. # Use this to set your timezone on your bot. Most people
  21. # should never need to change this. For FreeBSD you most
  22. # likely will need to alter this.
  23. set oauth_time "%Y-%m-%d %H:%M:%S %Z"
  24.  
  25. package provide OAuthSingle 1.0
  26.  
  27. # Multiple account wrapper. Single token use. No pin required.
  28. proc proc:twitter:oauth {url method chan query} {
  29. global twitter
  30. set found [lsearch -glob $twitter(accts) "[string tolower $chan]|*"]
  31. if {$found != -1} {
  32. set s [split [lindex $twitter(accts) $found] |]
  33. set c_tok [lindex $s 2]
  34. set c_sec [lindex $s 3]
  35. set o_tok [lindex $s 4]
  36. set o_sec [lindex $s 5]
  37. if {[string length $::oauthdebug]} { putserv "privmsg $::oauthdebug :oauth:query_api $url $c_tok $c_sec $method $o_tok $o_sec $query" }
  38. if {[catch {set reply [oauth:query_api $url $c_tok $c_sec $method $o_tok $o_sec $query]} error]} { error $error }
  39. return $reply
  40. }
  41. }
  42.  
  43. # single query use. We can proceed directly to api requests.
  44. # query_dict is POST request to twitter as before, key:value pairing (tcl-lists)
  45. # oauth_token, oauth_token_secret from get_access_token
  46. proc oauth:query_api {url consumer_key consumer_secret method oauth_token oauth_token_secret query_dict} {
  47. set params {}
  48. if {[catch {set result [oauth:query_call $url $consumer_key $consumer_secret $method $params $query_dict $oauth_token $oauth_token_secret]} error]} { error $error }
  49. return $result
  50. }
  51.  
  52. # build header & query, call http request and return result
  53. # params stay in oauth header
  54. # sign_params are only used in base string for signing (optional) - tcl-lists
  55. proc oauth:query_call {url consumer_key consumer_secret method params {sign_params {}} {token {}} {token_secret {}}} {
  56. lappend oauth_raw [list oauth_consumer_key $consumer_key]
  57. lappend oauth_raw [list oauth_nonce [oauth:nonce]]
  58. lappend oauth_raw [list oauth_signature_method HMAC-SHA1]
  59. lappend oauth_raw [list oauth_timestamp [clock scan [clock format [clock seconds] -format $::oauth_time] -gmt 1]]
  60. lappend oauth_raw [list oauth_token $token]
  61. lappend oauth_raw [list oauth_version 1.0]
  62.  
  63. # variable number of params
  64. foreach param $params {
  65. lappend oauth_raw [list [lindex $param 0] [lindex $param 1]]
  66. }
  67. if {[string length $::oauthdebug]} { putserv "privmsg $::oauthdebug :oauth_raw $oauth_raw" }
  68. # second oauth_raw holds data to be signed but not placed in header
  69. set oauth_raw_sign $oauth_raw
  70. foreach param $sign_params {
  71. lappend oauth_raw_sign [list [lindex $param 0] [lindex $param 1]]
  72. }
  73. if {[string length $::oauthdebug]} { putserv "privmsg $::oauthdebug :oauth_raw_sign $oauth_raw_sign" }
  74. set signature [oauth:signature $url $consumer_secret $method [lsort $oauth_raw_sign] $token_secret]
  75. if {[string length $::oauthdebug]} { putserv "privmsg $::oauthdebug :signature $signature" }
  76. set oauth_raw [linsert $oauth_raw 2 [list oauth_signature $signature]]
  77. if {[string length $::oauthdebug]} { putserv "privmsg $::oauthdebug :oauth_raw $oauth_raw" }
  78. set oauth_header [oauth:oauth_header [lsort $oauth_raw]]
  79. if {[string length $::oauthdebug]} { putserv "privmsg $::oauthdebug :oauth_header $oauth_header" }
  80. set my_query ""
  81. foreach param [lsort $sign_params] {
  82. append my_query "[lindex $param 0]=[lindex $param 1]&"
  83. }
  84. set my_query [string trimright $my_query &]
  85. if {[string length $::oauthdebug]} { putserv "privmsg $::oauthdebug :my_query $my_query" }
  86. return [oauth:query $url $method $oauth_header $my_query]
  87. }
  88.  
  89. # do http request with oauth header
  90. proc oauth:query {url method oauth_header {query {}}} {
  91. #putserv "privmsg speechles :$url - $method - $oauth_header - $query"
  92. set header [list Authorization [concat "OAuth" $oauth_header]]
  93. if {[string equal -nocase "POST" $method]} {
  94. catch { set token [http::geturl $url -headers $header -query $query -timeout 5000] } error
  95. } else {
  96. if {[string length $query]} {
  97. catch { set token [http::geturl $url?$query -headers $header -timeout 5000] } error
  98. } else {
  99. catch { set token [http::geturl $url -headers $header -timeout 5000] } error
  100. }
  101. }
  102. if {[string match -nocase "::http::*" $error]} {
  103. if {[string equal -nocase [set status [http::status $token]] "reset"]} {
  104. http::cleanup $token
  105. error "OAuth failed: Connection reset..."
  106. }
  107. if {![string length [set ncode [http::ncode $token]]]} { set ncode "???" }
  108. if {[string match "5*" $ncode]} {
  109. error "OAuth fail whale: Wait a bit, or find a Japanese fishing vessel. HARPOON! (code: $ncode)"
  110. }
  111. set data [http::data $token]
  112. http::cleanup $token
  113. if {$ncode != 200} {
  114. set erta [list]
  115. set junk [split [string map -nocase [list \" ""] [join $data]] ,]
  116. foreach name $junk {
  117. lappend erta [string map [list ":" ": " "\\" ""] [string totitle $name]]
  118. }
  119. if {[llength $erta]} {
  120. error "OAuth failed: ($ncode) [join [lsort -dictionary $erta] {; }] ( $status )"
  121. } else {
  122. error "OAuth failed: ($ncode) Unknown problem... No reason given...( $status )"
  123. }
  124. }
  125. } else {
  126. error "OAuth failed: (???) [join [split $error "\n"] {; }] ( internal error )"
  127. }
  128. return $data
  129. }
  130.  
  131. # take a tcl-list of params and create as follows:
  132. # create string as: key="value",...,key2="value2"
  133. proc oauth:oauth_header {params} {
  134. set header {}
  135. foreach param $params {
  136. lappend header [oauth:uri_escape [lindex $param 0]]=\"[oauth:uri_escape [lindex $param 1]]\"
  137. }
  138. return [join $header ","]
  139. }
  140.  
  141. # take tcl-list of params and create as follows
  142. # sort params by key
  143. # create string as key=value&key2=value2...
  144. # TODO: if key matches, sort by value
  145. proc oauth:params_signature {params} {
  146. foreach item [lsort $params] {
  147. lappend lis [lindex $item 0]=[lindex $item 1]
  148. }
  149.  
  150. return [join ${lis} "&"]
  151. }
  152.  
  153. # build signature as in section 9 of oauth spec
  154. # token_secret may be empty
  155. proc oauth:signature {url consumer_secret method params {token_secret {}}} {
  156. # We want base URL for signing (remove ?params=...)
  157. set url [lindex [split $url "?"] 0]
  158. set base_string [oauth:uri_escape ${method}]&[oauth:uri_escape ${url}]&[oauth:uri_escape [oauth:params_signature $params]]
  159. if {[string length $::oauthdebug]} { putserv "privmsg $::oauthdebug :base-string $base_string" }
  160. set key [oauth:uri_escape $consumer_secret]&[oauth:uri_escape $token_secret]
  161. set signature [sha1::hmac -bin -key $key $base_string]
  162. return [base64::encode $signature]
  163. }
  164.  
  165. proc oauth:nonce {} {
  166. set nonce [clock clicks][rand 10000]
  167. return [sha1::sha1 $nonce]
  168. }
  169.  
  170. # wrapper around http::formatQuery which uppercases octet characters
  171. proc oauth:uri_escape {str} {
  172. set str [http::formatQuery $str]
  173. # uppercase all %hex where hex=2 octets
  174. set str [regsub -all -- {%(\w{2})} $str {%[string toupper \1]}]
  175. return [subst $str]
  176. }
Add Comment
Please, Sign In to add comment