diff --git a/AsyncOAuth.ConsoleApp/AsyncOAuth.ConsoleApp.csproj b/AsyncOAuth.ConsoleApp/AsyncOAuth.ConsoleApp.csproj index 0212139..adbaa39 100644 --- a/AsyncOAuth.ConsoleApp/AsyncOAuth.ConsoleApp.csproj +++ b/AsyncOAuth.ConsoleApp/AsyncOAuth.ConsoleApp.csproj @@ -1,91 +1,92 @@ - - - - - Debug - AnyCPU - {C8BF0013-AE03-48C0-A11B-6CF9F39257DE} - Exe - Properties - AsyncOAuth.ConsoleApp - AsyncOAuth.ConsoleApp - v4.5 - 512 - ..\ - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.Extensions.dll - - - - - - - ..\packages\Microsoft.Net.Http.2.2.18\lib\net45\System.Net.Http.Extensions.dll - - - ..\packages\Microsoft.Net.Http.2.2.18\lib\net45\System.Net.Http.Primitives.dll - - - - - - - - - - - - - - - - - - - - - - {877842ff-edae-40e7-913b-c871ad5a48cc} - AsyncOAuth - - - - - - - - - + + + + + Debug + AnyCPU + {C8BF0013-AE03-48C0-A11B-6CF9F39257DE} + Exe + Properties + AsyncOAuth.ConsoleApp + AsyncOAuth.ConsoleApp + v4.5 + 512 + ..\ + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.dll + + + ..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.Extensions.dll + + + + + + + ..\packages\Microsoft.Net.Http.2.2.18\lib\net45\System.Net.Http.Extensions.dll + + + ..\packages\Microsoft.Net.Http.2.2.18\lib\net45\System.Net.Http.Primitives.dll + + + + + + + + + + + + + + + + + + + + + + + {877842ff-edae-40e7-913b-c871ad5a48cc} + AsyncOAuth + + + + + + + + + + --> \ No newline at end of file diff --git a/AsyncOAuth.ConsoleApp/ETrade.cs b/AsyncOAuth.ConsoleApp/ETrade.cs new file mode 100644 index 0000000..f73afa7 --- /dev/null +++ b/AsyncOAuth.ConsoleApp/ETrade.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace AsyncOAuth.ConsoleApp +{ + // a sample of ETrade client + public class ETradeClient + { + readonly string consumerKey; + readonly string consumerSecret; + readonly AccessToken accessToken; + + public ETradeClient(string consumerKey, string consumerSecret, AccessToken accessToken) + { + this.consumerKey = consumerKey; + this.consumerSecret = consumerSecret; + this.accessToken = accessToken; + } + + // sample flow for ETrade authroize + public async static Task AuthorizeSample(string consumerKey, string consumerSecret) + { + try + { + // create authorizer + var authorizer = new OAuthAuthorizer(consumerKey, consumerSecret); + + // get request token + List> args = new List>(); + args.Add(new KeyValuePair("oauth_callback", "oob")); + + var tokenResponse = await authorizer.GetRequestToken("https://etws.etrade.com/oauth/request_token",args); + var requestToken = tokenResponse.Token; + + + // var pinRequestUrl = authorizer.BuildAuthorizeUrl("https://us.etrade.com/e/t/etws/authorize", requestToken); + string pinRequestUrl = "https://us.etrade.com/e/t/etws/authorize" + "?key=" + consumerKey + "&token=" + requestToken.Key; + // open browser and get PIN Code + Process.Start(pinRequestUrl); + + // enter pin + Console.WriteLine("ENTER PIN"); + var pinCode = Console.ReadLine(); + + // get access token + + var accessTokenResponse = await authorizer.GetAccessToken("https://etws.etrade.com/oauth/access_token", requestToken, pinCode); + + // save access token. + var accessToken = accessTokenResponse.Token; + Console.WriteLine("Access Granted: "); + Console.WriteLine(" Access Key:" + accessToken.Key); + Console.WriteLine(" Access Secret:" + accessToken.Secret); + Console.WriteLine("==============================================="); + + return accessToken; + } + catch (Exception e) + { + Console.WriteLine("Exception " + e.ToString()); + } + + return null; + } + + public async Task GetQuote() + { + try + { + + + var client = OAuthUtility.CreateOAuthClient(consumerKey, consumerSecret, accessToken); + + var json = await client.GetStringAsync("https://etwssandbox.etrade.com/market/sandbox/rest/quote/GOOG,MSFT.json?detailFlag=FUNDAMENTAL"); + + return json; + } + catch (Exception e ) + { + Console.WriteLine("Exception in GetQuote: " + e.ToString()); + } + + return null; + } + + + } +} \ No newline at end of file diff --git a/AsyncOAuth.ConsoleApp/Program.cs b/AsyncOAuth.ConsoleApp/Program.cs index 1dcc786..8d0c20a 100644 --- a/AsyncOAuth.ConsoleApp/Program.cs +++ b/AsyncOAuth.ConsoleApp/Program.cs @@ -10,28 +10,49 @@ namespace AsyncOAuth.ConsoleApp { class Program - { - // set your token - const string consumerKey = ""; - const string consumerSecret = ""; + { + // set your token + + + const string consumerKey = "yourConsumerKey"; + const string consumerSecret = "yourConsumerToken"; static async Task Run() { // initialize computehash function OAuthUtility.ComputeHash = (key, buffer) => { using (var hmac = new HMACSHA1(key)) { return hmac.ComputeHash(buffer); } }; - // sample, twitter access flow - var accessToken = await TwitterClient.AuthorizeSample(consumerKey, consumerSecret); + // sample, ETrade access flow + Console.WriteLine("ASyncOauth ETrade Sample: "); + System.Threading.Thread.Sleep(1000); - var client = new TwitterClient(consumerKey, consumerSecret, accessToken); + Console.WriteLine("Getting access token"); + var accessToken = await ETradeClient.AuthorizeSample(consumerKey, consumerSecret); - var tl = await client.GetTimeline(10, 1); - Console.WriteLine(tl); + if ( accessToken == null ) + { + Console.WriteLine("Error getting access token"); + return; + } + + // create the client with the access token and consumer key + var client = new ETradeClient(consumerKey, consumerSecret, accessToken); + + // Get Quote: + Console.WriteLine("Getting Quotes from sandbox server: "); + + var quoteResponse = await client.GetQuote(); + + Console.WriteLine(quoteResponse); } static void Main(string[] args) { Run().Wait(); + + // Exit + Console.WriteLine("Press any key to exit."); + Console.ReadKey(); } } } \ No newline at end of file diff --git a/AsyncOAuth/OAuthUtility.cs b/AsyncOAuth/OAuthUtility.cs index e4be4e1..ea2a6b4 100644 --- a/AsyncOAuth/OAuthUtility.cs +++ b/AsyncOAuth/OAuthUtility.cs @@ -76,10 +76,27 @@ public static IEnumerable> BuildBasicParameters(str if (token != null) parameters.Add(new KeyValuePair("oauth_token", token.Key)); if (optionalParameters == null) optionalParameters = Enumerable.Empty>(); + // generate the signature var signature = GenerateSignature(consumerSecret, new Uri(url), method, token, parameters.Concat(optionalParameters)); + // add the signature to the parameters parameters.Add(new KeyValuePair("oauth_signature", signature)); + // TODO - this is a change made to get library to work with ETrade OAuth login + // the token must be URL encoded, but if you URL encode token prior to generate signature, signature is incorrect + // this is brute force solution that worked for me, but there is probably a better way to handle this + try + { + var findToken = parameters.First(x => x.Key == "oauth_token"); + + parameters.Remove(findToken); + parameters.Add(new KeyValuePair(findToken.Key, findToken.Value.UrlEncode())); + } + catch + { + // oauth_token is not in the header, continue + } + return parameters; }