0 people like it.
Like the snippet!
Twitter OAuth
Generates the value string for the "Authorization:" header given Twitter application/user keys and tokens and the parameters for the request being authorized.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
|
#if INTERACTIVE
#else
module TwitterAuth
#endif
open System
open System.Text
open System.Net
let percentEncode (sb:StringBuilder) (ch:char) =
if '0' <= ch && ch <= '9' then sb.Append(ch)
elif 'a' <= ch && ch <= 'z' then sb.Append(ch)
elif 'A' <= ch && ch <= 'Z' then sb.Append(ch)
else
match ch with
| '-' | '.' | '_' | '~' -> sb.Append(ch)
| _ ->
sb.Append('%') |> ignore
sb.AppendFormat("{0:X2}",int(ch))
let (+=) (sb:StringBuilder) (a:string) = sb.Append(a)
let (!*) (s:string) =
let sb = StringBuilder()
for i in 0..s.Length-1 do
let ch = s.[i]
percentEncode sb ch |> ignore
sb.ToString()
let rnd = System.Random()
let nonce() =
let bytes = Array.create 16 0uy
rnd.NextBytes(bytes)
BitConverter.ToString(bytes).Replace("-","")
let epoch = DateTime(1970,1,1)
let timeStamp() =
let dt = (DateTime.UtcNow - epoch).TotalSeconds |> int
dt.ToString()
let toUpper (s:string) = s.ToUpper()
let signingKey (consumerSecret:string) tokenSecret =
consumerSecret + "&" + tokenSecret
|> Encoding.ASCII.GetBytes
let parameterString parameters =
let amp = "&"
let eq = "="
let sb = (new StringBuilder(), parameters) ||> Map.fold (fun sb k v -> sb += k += eq += v += amp)
sb.Remove(sb.Length-amp.Length,amp.Length).ToString()
let sigBase httpMethod baseUrl parmDataStr =
(httpMethod |> toUpper) + "&" + !* baseUrl + "&" + !* parmDataStr
let hmacSha1Sig signKey dataString =
let data = (dataString:string) |> Encoding.ASCII.GetBytes
use alg = new System.Security.Cryptography.HMACSHA1(signKey)
alg.ComputeHash(data) |> Convert.ToBase64String
let buildAuthHdr headerParameters =
assert (headerParameters |> Map.toSeq |> Seq.length = 7)
let sb = StringBuilder()
sb.Append("OAuth ") |> ignore
let sb = (sb,headerParameters) ||> Map.fold (fun sb k v -> sb += k += "=" += "\"" += v += "\"" += ", ")
sb.Remove(sb.Length - 2, 2) |> ignore
let header = sb.ToString()
header
///Generate the Authorization header string based on the request parameters and keys and tokens
//The process is defined here: https://dev.twitter.com/docs/auth/authorizing-request
let authHeader
signKey
consumerKey
token
httpMethod
baseUrl
reqParams =
let secParams =
[
"oauth_consumer_key", !*consumerKey
"oauth_signature_method" , "HMAC-SHA1"
"oauth_timestamp", timeStamp()
"oauth_token", !*token
"oauth_version", "1.0"
"oauth_nonce", nonce()
] |> Map.ofList
let parameters = (secParams,reqParams) ||> Map.fold(fun acc k v -> acc|>Map.add !*k !*v)
let parmStr = parameters |> parameterString
let data2Sign = sigBase httpMethod baseUrl parmStr
let sigData = hmacSha1Sig signKey data2Sign
let headerParameters = secParams |> Map.add "oauth_signature" !*sigData
buildAuthHdr headerParameters
//test parameters are from here
//https://dev.twitter.com/docs/auth/creating-signature
let testSig() =
let parameters =
[
"status", "Hello Ladies + Gentlemen, a signed OAuth request!"
"include_entities", "true"
"oauth_consumer_key", "xvz1evFS4wEEPTGEFPHBog"
"oauth_nonce", "88643f5b760c4780814a7101ef796851"
"oauth_signature_method" , "HMAC-SHA1"
"oauth_timestamp", "1318622958"
"oauth_token", "370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb"
"oauth_version", "1.0"
]
|> List.map (fun (k,v) -> !*k,!*v)
|> Map.ofList
let consumerSecret = "kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw"
let tokenSecret = "LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE"
let signKey = signingKey consumerSecret tokenSecret
let httpMethod = "post"
let baseUrl = "https://api.twitter.com/1/statuses/update.json"
let parmStr = parameters |> parameterString
let data = sigBase httpMethod baseUrl parmStr
let mySig = hmacSha1Sig signKey data
mySig
let toParmString parms =
let sb = (StringBuilder(),parms) ||> Map.fold (fun sb k v -> sb += !*k += "=" += !*v += "&")
sb.Remove(sb.Length-1,1).ToString()
let download (url:string) hdr =
use wc = new WebClient()
wc.Headers.Add(HttpRequestHeader.Authorization,hdr)
wc.DownloadString(url)
//substitute where you see '****' with appropriate values, to test your keys and tokens
let myExample() =
let consumerKey = "<****my consumer key"
let consumerSecret = "<****my consumer secret>"
let token = "<****my access token>"
let tokenSecret = "<****my token secret>"
let signKey = signingKey consumerSecret tokenSecret
let baseUrl = "https://api.twitter.com/1.1/statuses/user_timeline.json"
let httpMethod = "get"
let requestQuery = ["user_id", "<****my userid>"] |> Map.ofList
let authHeader = authHeader signKey consumerKey token httpMethod baseUrl requestQuery
let url = baseUrl + "?" + (requestQuery |> toParmString)
download url authHeader
|
namespace System
namespace System.Text
namespace System.Net
val percentEncode : sb:StringBuilder -> ch:char -> StringBuilder
Full name: Script.percentEncode
val sb : StringBuilder
Multiple items
type StringBuilder =
new : unit -> StringBuilder + 5 overloads
member Append : value:string -> StringBuilder + 18 overloads
member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads
member AppendLine : unit -> StringBuilder + 1 overload
member Capacity : int with get, set
member Chars : int -> char with get, set
member Clear : unit -> StringBuilder
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EnsureCapacity : capacity:int -> int
member Equals : sb:StringBuilder -> bool
...
Full name: System.Text.StringBuilder
--------------------
StringBuilder() : unit
StringBuilder(capacity: int) : unit
StringBuilder(value: string) : unit
StringBuilder(value: string, capacity: int) : unit
StringBuilder(capacity: int, maxCapacity: int) : unit
StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit
val ch : char
Multiple items
val char : value:'T -> char (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.char
--------------------
type char = Char
Full name: Microsoft.FSharp.Core.char
StringBuilder.Append(value: char []) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: obj) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: uint64) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: uint32) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: uint16) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: decimal) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: float) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: float32) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: int64) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: int) : StringBuilder
(+0 other overloads)
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
StringBuilder.AppendFormat(format: string, [<ParamArray>] args: obj []) : StringBuilder
StringBuilder.AppendFormat(format: string, arg0: obj) : StringBuilder
StringBuilder.AppendFormat(provider: IFormatProvider, format: string, [<ParamArray>] args: obj []) : StringBuilder
StringBuilder.AppendFormat(format: string, arg0: obj, arg1: obj) : StringBuilder
StringBuilder.AppendFormat(format: string, arg0: obj, arg1: obj, arg2: obj) : StringBuilder
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val a : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
val s : string
val i : int32
property String.Length: int
StringBuilder.ToString() : string
StringBuilder.ToString(startIndex: int, length: int) : string
val rnd : Random
Full name: Script.rnd
Multiple items
type Random =
new : unit -> Random + 1 overload
member Next : unit -> int + 2 overloads
member NextBytes : buffer:byte[] -> unit
member NextDouble : unit -> float
Full name: System.Random
--------------------
Random() : unit
Random(Seed: int) : unit
val nonce : unit -> string
Full name: Script.nonce
val bytes : byte []
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...
Full name: System.Array
val create : count:int -> value:'T -> 'T []
Full name: Microsoft.FSharp.Collections.Array.create
Random.NextBytes(buffer: byte []) : unit
type BitConverter =
static val IsLittleEndian : bool
static member DoubleToInt64Bits : value:float -> int64
static member GetBytes : value:bool -> byte[] + 9 overloads
static member Int64BitsToDouble : value:int64 -> float
static member ToBoolean : value:byte[] * startIndex:int -> bool
static member ToChar : value:byte[] * startIndex:int -> char
static member ToDouble : value:byte[] * startIndex:int -> float
static member ToInt16 : value:byte[] * startIndex:int -> int16
static member ToInt32 : value:byte[] * startIndex:int -> int
static member ToInt64 : value:byte[] * startIndex:int -> int64
...
Full name: System.BitConverter
BitConverter.ToString(value: byte []) : string
BitConverter.ToString(value: byte [], startIndex: int) : string
BitConverter.ToString(value: byte [], startIndex: int, length: int) : string
val epoch : DateTime
Full name: Script.epoch
Multiple items
type DateTime =
struct
new : ticks:int64 -> DateTime + 10 overloads
member Add : value:TimeSpan -> DateTime
member AddDays : value:float -> DateTime
member AddHours : value:float -> DateTime
member AddMilliseconds : value:float -> DateTime
member AddMinutes : value:float -> DateTime
member AddMonths : months:int -> DateTime
member AddSeconds : value:float -> DateTime
member AddTicks : value:int64 -> DateTime
member AddYears : value:int -> DateTime
...
end
Full name: System.DateTime
--------------------
DateTime()
(+0 other overloads)
DateTime(ticks: int64) : unit
(+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
(+0 other overloads)
val timeStamp : unit -> string
Full name: Script.timeStamp
val dt : int
property DateTime.UtcNow: DateTime
Int32.ToString() : string
Int32.ToString(provider: IFormatProvider) : string
Int32.ToString(format: string) : string
Int32.ToString(format: string, provider: IFormatProvider) : string
val toUpper : s:string -> string
Full name: Script.toUpper
String.ToUpper() : string
String.ToUpper(culture: Globalization.CultureInfo) : string
val signingKey : consumerSecret:string -> tokenSecret:string -> byte []
Full name: Script.signingKey
val consumerSecret : string
val tokenSecret : string
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...
Full name: System.Text.Encoding
property Encoding.ASCII: Encoding
Encoding.GetBytes(s: string) : byte []
Encoding.GetBytes(chars: char []) : byte []
Encoding.GetBytes(chars: char [], index: int, count: int) : byte []
Encoding.GetBytes(chars: nativeptr<char>, charCount: int, bytes: nativeptr<byte>, byteCount: int) : int
Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
val parameterString : parameters:Map<string,string> -> string
Full name: Script.parameterString
val parameters : Map<string,string>
val amp : string
val eq : string
Multiple items
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...
Full name: Microsoft.FSharp.Collections.Map<_,_>
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val fold : folder:('State -> 'Key -> 'T -> 'State) -> state:'State -> table:Map<'Key,'T> -> 'State (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.fold
val k : string
val v : string
StringBuilder.Remove(startIndex: int, length: int) : StringBuilder
property StringBuilder.Length: int
val sigBase : httpMethod:string -> baseUrl:string -> parmDataStr:string -> string
Full name: Script.sigBase
val httpMethod : string
val baseUrl : string
val parmDataStr : string
val hmacSha1Sig : signKey:byte [] -> dataString:string -> string
Full name: Script.hmacSha1Sig
val signKey : byte []
val dataString : string
val data : byte []
val alg : Security.Cryptography.HMACSHA1
namespace System.Security
namespace System.Security.Cryptography
Multiple items
type HMACSHA1 =
inherit HMAC
new : unit -> HMACSHA1 + 2 overloads
Full name: System.Security.Cryptography.HMACSHA1
--------------------
Security.Cryptography.HMACSHA1() : unit
Security.Cryptography.HMACSHA1(key: byte []) : unit
Security.Cryptography.HMACSHA1(key: byte [], useManagedSha1: bool) : unit
Security.Cryptography.HashAlgorithm.ComputeHash(buffer: byte []) : byte []
Security.Cryptography.HashAlgorithm.ComputeHash(inputStream: IO.Stream) : byte []
Security.Cryptography.HashAlgorithm.ComputeHash(buffer: byte [], offset: int, count: int) : byte []
type Convert =
static val DBNull : obj
static member ChangeType : value:obj * typeCode:TypeCode -> obj + 3 overloads
static member FromBase64CharArray : inArray:char[] * offset:int * length:int -> byte[]
static member FromBase64String : s:string -> byte[]
static member GetTypeCode : value:obj -> TypeCode
static member IsDBNull : value:obj -> bool
static member ToBase64CharArray : inArray:byte[] * offsetIn:int * length:int * outArray:char[] * offsetOut:int -> int + 1 overload
static member ToBase64String : inArray:byte[] -> string + 3 overloads
static member ToBoolean : value:obj -> bool + 17 overloads
static member ToByte : value:obj -> byte + 18 overloads
...
Full name: System.Convert
Convert.ToBase64String(inArray: byte []) : string
Convert.ToBase64String(inArray: byte [], options: Base64FormattingOptions) : string
Convert.ToBase64String(inArray: byte [], offset: int, length: int) : string
Convert.ToBase64String(inArray: byte [], offset: int, length: int, options: Base64FormattingOptions) : string
val buildAuthHdr : headerParameters:Map<string,string> -> string
Full name: Script.buildAuthHdr
val headerParameters : Map<string,string>
val toSeq : table:Map<'Key,'T> -> seq<'Key * 'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.toSeq
module Seq
from Microsoft.FSharp.Collections
val length : source:seq<'T> -> int
Full name: Microsoft.FSharp.Collections.Seq.length
val header : string
val authHeader : signKey:byte [] -> consumerKey:string -> token:string -> httpMethod:string -> baseUrl:string -> reqParams:Map<string,string> -> string
Full name: Script.authHeader
Generate the Authorization header string based on the request parameters and keys and tokens
val consumerKey : string
val token : string
val reqParams : Map<string,string>
val secParams : Map<string,string>
val ofList : elements:('Key * 'T) list -> Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.ofList
val acc : Map<string,string>
val add : key:'Key -> value:'T -> table:Map<'Key,'T> -> Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.add
val parmStr : string
val data2Sign : string
val sigData : string
val testSig : unit -> string
Full name: Script.testSig
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.map
val data : string
val mySig : string
val toParmString : parms:Map<string,string> -> string
Full name: Script.toParmString
val parms : Map<string,string>
val download : url:string -> hdr:string -> string
Full name: Script.download
val url : string
val hdr : string
val wc : WebClient
Multiple items
type WebClient =
inherit Component
new : unit -> WebClient
member BaseAddress : string with get, set
member CachePolicy : RequestCachePolicy with get, set
member CancelAsync : unit -> unit
member Credentials : ICredentials with get, set
member DownloadData : address:string -> byte[] + 1 overload
member DownloadDataAsync : address:Uri -> unit + 1 overload
member DownloadFile : address:string * fileName:string -> unit + 1 overload
member DownloadFileAsync : address:Uri * fileName:string -> unit + 1 overload
member DownloadString : address:string -> string + 1 overload
...
Full name: System.Net.WebClient
--------------------
WebClient() : unit
property WebClient.Headers: WebHeaderCollection
Collections.Specialized.NameValueCollection.Add(c: Collections.Specialized.NameValueCollection) : unit
WebHeaderCollection.Add(header: string) : unit
WebHeaderCollection.Add(name: string, value: string) : unit
WebHeaderCollection.Add(header: HttpResponseHeader, value: string) : unit
WebHeaderCollection.Add(header: HttpRequestHeader, value: string) : unit
type HttpRequestHeader =
| CacheControl = 0
| Connection = 1
| Date = 2
| KeepAlive = 3
| Pragma = 4
| Trailer = 5
| TransferEncoding = 6
| Upgrade = 7
| Via = 8
| Warning = 9
...
Full name: System.Net.HttpRequestHeader
field HttpRequestHeader.Authorization = 24
WebClient.DownloadString(address: Uri) : string
WebClient.DownloadString(address: string) : string
val myExample : unit -> string
Full name: Script.myExample
val requestQuery : Map<string,string>
val authHeader : string
More information