# HG changeset patch
# User Nelo@Kenia.neluz.int
# Date 1307147759 10800
# Node ID d1688622fa88dc0e3f4a70ef7e7def85c0a87ec4
# Parent 24e9488ac152b294e4ebbca2662e8e2e6397100a
Autenticando con twitter (falta emprolijar el código, pero autentica!)
diff -r 24e9488ac152 -r d1688622fa88 Agendas/trunk/src/Agendas.Twitter/Agendas.Twitter.csproj
--- a/Agendas/trunk/src/Agendas.Twitter/Agendas.Twitter.csproj Tue May 31 16:31:24 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Twitter/Agendas.Twitter.csproj Fri Jun 03 21:35:59 2011 -0300
@@ -32,7 +32,9 @@
+
+
@@ -40,6 +42,8 @@
+
+
diff -r 24e9488ac152 -r d1688622fa88 Agendas/trunk/src/Agendas.Twitter/oAuth.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.Twitter/oAuth.cs Fri Jun 03 21:35:59 2011 -0300
@@ -0,0 +1,373 @@
+using System;
+using System.Security.Cryptography;
+using System.Collections.Generic;
+using System.Text;
+using System.Web;
+
+namespace AltNetHispano.Agendas.Twitter
+{
+ public class OAuthBase
+ {
+
+ ///
+ /// Provides a predefined set of algorithms that are supported officially by the protocol
+ ///
+ public enum SignatureTypes
+ {
+ HMACSHA1,
+ PLAINTEXT,
+ RSASHA1
+ }
+
+ ///
+ /// Provides an internal structure to sort the query parameter
+ ///
+ protected class QueryParameter
+ {
+ private string name = null;
+ private string value = null;
+
+ public QueryParameter(string name, string value)
+ {
+ this.name = name;
+ this.value = value;
+ }
+
+ public string Name
+ {
+ get { return name; }
+ }
+
+ public string Value
+ {
+ get { return value; }
+ }
+ }
+
+ ///
+ /// Comparer class used to perform the sorting of the query parameters
+ ///
+ protected class QueryParameterComparer : IComparer
+ {
+
+ #region IComparer Members
+
+ public int Compare(QueryParameter x, QueryParameter y)
+ {
+ if (x.Name == y.Name)
+ {
+ return string.Compare(x.Value, y.Value);
+ }
+ else
+ {
+ return string.Compare(x.Name, y.Name);
+ }
+ }
+
+ #endregion
+ }
+
+ protected const string OAuthVersion = "1.0";
+ protected const string OAuthParameterPrefix = "oauth_";
+
+ //
+ // List of know and used oauth parameters' names
+ //
+ protected const string OAuthConsumerKeyKey = "oauth_consumer_key";
+ protected const string OAuthCallbackKey = "oauth_callback";
+ protected const string OAuthVersionKey = "oauth_version";
+ protected const string OAuthSignatureMethodKey = "oauth_signature_method";
+ protected const string OAuthSignatureKey = "oauth_signature";
+ protected const string OAuthTimestampKey = "oauth_timestamp";
+ protected const string OAuthNonceKey = "oauth_nonce";
+ protected const string OAuthTokenKey = "oauth_token";
+ protected const string OAuthTokenSecretKey = "oauth_token_secret";
+ protected const string OAuthVerifierKey = "oauth_verifier";
+
+ protected const string HMACSHA1SignatureType = "HMAC-SHA1";
+ protected const string PlainTextSignatureType = "PLAINTEXT";
+ protected const string RSASHA1SignatureType = "RSA-SHA1";
+
+ protected Random random = new Random();
+
+ protected string unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
+
+ ///
+ /// Helper function to compute a hash value
+ ///
+ /// The hashing algoirhtm used. If that algorithm needs some initialization, like HMAC and its derivatives, they should be initialized prior to passing it to this function
+ /// The data to hash
+ /// a Base64 string of the hash value
+ private string ComputeHash(HashAlgorithm hashAlgorithm, string data)
+ {
+ if (hashAlgorithm == null)
+ {
+ throw new ArgumentNullException("hashAlgorithm");
+ }
+
+ if (string.IsNullOrEmpty(data))
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ byte[] dataBuffer = System.Text.Encoding.ASCII.GetBytes(data);
+ byte[] hashBytes = hashAlgorithm.ComputeHash(dataBuffer);
+
+ return Convert.ToBase64String(hashBytes);
+ }
+
+ ///
+ /// Internal function to cut out all non oauth query string parameters (all parameters not begining with "oauth_")
+ ///
+ /// The query string part of the Url
+ /// A list of QueryParameter each containing the parameter name and value
+ private List GetQueryParameters(string parameters)
+ {
+ if (parameters.StartsWith("?"))
+ {
+ parameters = parameters.Remove(0, 1);
+ }
+
+ List result = new List();
+
+ if (!string.IsNullOrEmpty(parameters))
+ {
+ string[] p = parameters.Split('&');
+ foreach (string s in p)
+ {
+ if (!string.IsNullOrEmpty(s) && !s.StartsWith(OAuthParameterPrefix))
+ {
+ if (s.IndexOf('=') > -1)
+ {
+ string[] temp = s.Split('=');
+ result.Add(new QueryParameter(temp[0], temp[1]));
+ }
+ else
+ {
+ result.Add(new QueryParameter(s, string.Empty));
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ ///
+ /// This is a different Url Encode implementation since the default .NET one outputs the percent encoding in lower case.
+ /// While this is not a problem with the percent encoding spec, it is used in upper case throughout OAuth
+ ///
+ /// The value to Url encode
+ /// Returns a Url encoded string
+ public string UrlEncode(string value)
+ {
+ StringBuilder result = new StringBuilder();
+
+ foreach (char symbol in value)
+ {
+ if (unreservedChars.IndexOf(symbol) != -1)
+ {
+ result.Append(symbol);
+ }
+ else
+ {
+ result.Append('%' + String.Format("{0:X2}", (int)symbol));
+ }
+ }
+
+ return result.ToString();
+ }
+
+ ///
+ /// Normalizes the request parameters according to the spec
+ ///
+ /// The list of parameters already sorted
+ /// a string representing the normalized parameters
+ protected string NormalizeRequestParameters(IList parameters)
+ {
+ StringBuilder sb = new StringBuilder();
+ QueryParameter p = null;
+ for (int i = 0; i < parameters.Count; i++)
+ {
+ p = parameters[i];
+ sb.AppendFormat("{0}={1}", p.Name, p.Value);
+
+ if (i < parameters.Count - 1)
+ {
+ sb.Append("&");
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ ///
+ /// Generate the signature base that is used to produce the signature
+ ///
+ /// The full url that needs to be signed including its non OAuth url parameters
+ /// The consumer key
+ /// The token, if available. If not available pass null or an empty string
+ /// The token secret, if available. If not available pass null or an empty string
+ /// The callback URL (for OAuth 1.0a).If your client cannot accept callbacks, the value MUST be 'oob'
+ /// This value MUST be included when exchanging Request Tokens for Access Tokens. Otherwise pass a null or an empty string
+ /// The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)
+ /// The signature type. To use the default values use OAuthBase.SignatureTypes.
+ /// The signature base
+ public string GenerateSignatureBase(Uri url, string consumerKey, string token, string tokenSecret, string callBackUrl, string oauthVerifier, string httpMethod, string timeStamp, string nonce, string signatureType, out string normalizedUrl, out string normalizedRequestParameters)
+ {
+ if (token == null)
+ {
+ token = string.Empty;
+ }
+
+ if (tokenSecret == null)
+ {
+ tokenSecret = string.Empty;
+ }
+
+ if (string.IsNullOrEmpty(consumerKey))
+ {
+ throw new ArgumentNullException("consumerKey");
+ }
+
+ if (string.IsNullOrEmpty(httpMethod))
+ {
+ throw new ArgumentNullException("httpMethod");
+ }
+
+ if (string.IsNullOrEmpty(signatureType))
+ {
+ throw new ArgumentNullException("signatureType");
+ }
+
+ normalizedUrl = null;
+ normalizedRequestParameters = null;
+
+ List parameters = GetQueryParameters(url.Query);
+ parameters.Add(new QueryParameter(OAuthVersionKey, OAuthVersion));
+ parameters.Add(new QueryParameter(OAuthNonceKey, nonce));
+ parameters.Add(new QueryParameter(OAuthTimestampKey, timeStamp));
+ parameters.Add(new QueryParameter(OAuthSignatureMethodKey, signatureType));
+ parameters.Add(new QueryParameter(OAuthConsumerKeyKey, consumerKey));
+
+ if (!string.IsNullOrEmpty(callBackUrl))
+ {
+ parameters.Add(new QueryParameter(OAuthCallbackKey, UrlEncode(callBackUrl)));
+ }
+
+
+ if (!string.IsNullOrEmpty(oauthVerifier))
+ {
+ parameters.Add(new QueryParameter(OAuthVerifierKey, oauthVerifier));
+ }
+
+ if (!string.IsNullOrEmpty(token))
+ {
+ parameters.Add(new QueryParameter(OAuthTokenKey, token));
+ }
+
+ parameters.Sort(new QueryParameterComparer());
+
+ normalizedUrl = string.Format("{0}://{1}", url.Scheme, url.Host);
+ if (!((url.Scheme == "http" && url.Port == 80) || (url.Scheme == "https" && url.Port == 443)))
+ {
+ normalizedUrl += ":" + url.Port;
+ }
+ normalizedUrl += url.AbsolutePath;
+ normalizedRequestParameters = NormalizeRequestParameters(parameters);
+
+ StringBuilder signatureBase = new StringBuilder();
+ signatureBase.AppendFormat("{0}&", httpMethod.ToUpper());
+ signatureBase.AppendFormat("{0}&", UrlEncode(normalizedUrl));
+ signatureBase.AppendFormat("{0}", UrlEncode(normalizedRequestParameters));
+
+ return signatureBase.ToString();
+ }
+
+ ///
+ /// Generate the signature value based on the given signature base and hash algorithm
+ ///
+ /// The signature based as produced by the GenerateSignatureBase method or by any other means
+ /// The hash algorithm used to perform the hashing. If the hashing algorithm requires initialization or a key it should be set prior to calling this method
+ /// A base64 string of the hash value
+ public string GenerateSignatureUsingHash(string signatureBase, HashAlgorithm hash)
+ {
+ return ComputeHash(hash, signatureBase);
+ }
+
+ ///
+ /// Generates a signature using the HMAC-SHA1 algorithm
+ ///
+ /// The full url that needs to be signed including its non OAuth url parameters
+ /// The consumer key
+ /// The consumer seceret
+ /// The token, if available. If not available pass null or an empty string
+ /// The token secret, if available. If not available pass null or an empty string
+ /// The callback URL (for OAuth 1.0a).If your client cannot accept callbacks, the value MUST be 'oob'
+ /// This value MUST be included when exchanging Request Tokens for Access Tokens. Otherwise pass a null or an empty string
+ /// The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)
+ /// A base64 string of the hash value
+ public string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string callBackUrl, string oauthVerifier, string httpMethod, string timeStamp, string nonce, out string normalizedUrl, out string normalizedRequestParameters)
+ {
+ return GenerateSignature(url, consumerKey, consumerSecret, token, tokenSecret, callBackUrl, oauthVerifier, httpMethod, timeStamp, nonce, SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters);
+ }
+
+ ///
+ /// Generates a signature using the specified signatureType
+ ///
+ /// The full url that needs to be signed including its non OAuth url parameters
+ /// The consumer key
+ /// The consumer seceret
+ /// The token, if available. If not available pass null or an empty string
+ /// The token secret, if available. If not available pass null or an empty string
+ /// The callback URL (for OAuth 1.0a).If your client cannot accept callbacks, the value MUST be 'oob'
+ /// This value MUST be included when exchanging Request Tokens for Access Tokens. Otherwise pass a null or an empty string
+ /// The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc)
+ /// The type of signature to use
+ /// A base64 string of the hash value
+ public string GenerateSignature(Uri url, string consumerKey, string consumerSecret, string token, string tokenSecret, string callBackUrl, string oauthVerifier, string httpMethod, string timeStamp, string nonce, SignatureTypes signatureType, out string normalizedUrl, out string normalizedRequestParameters)
+ {
+ normalizedUrl = null;
+ normalizedRequestParameters = null;
+
+ switch (signatureType)
+ {
+ case SignatureTypes.PLAINTEXT:
+ return HttpUtility.UrlEncode(string.Format("{0}&{1}", consumerSecret, tokenSecret));
+ case SignatureTypes.HMACSHA1:
+ string signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, callBackUrl, oauthVerifier, httpMethod, timeStamp, nonce, HMACSHA1SignatureType, out normalizedUrl, out normalizedRequestParameters);
+
+ HMACSHA1 hmacsha1 = new HMACSHA1();
+ hmacsha1.Key = Encoding.ASCII.GetBytes(string.Format("{0}&{1}", UrlEncode(consumerSecret), string.IsNullOrEmpty(tokenSecret) ? "" : UrlEncode(tokenSecret)));
+
+ return GenerateSignatureUsingHash(signatureBase, hmacsha1);
+ case SignatureTypes.RSASHA1:
+ throw new NotImplementedException();
+ default:
+ throw new ArgumentException("Unknown signature type", "signatureType");
+ }
+ }
+
+ ///
+ /// Generate the timestamp for the signature
+ ///
+ ///
+ public virtual string GenerateTimeStamp()
+ {
+ // Default implementation of UNIX time of the current UTC time
+ TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+ return Convert.ToInt64(ts.TotalSeconds).ToString();
+ }
+
+ ///
+ /// Generate a nonce
+ ///
+ ///
+ public virtual string GenerateNonce()
+ {
+ // Just a simple implementation of a random number between 123400 and 9999999
+ return random.Next(123400, 9999999).ToString();
+ }
+
+ }
+}
\ No newline at end of file
diff -r 24e9488ac152 -r d1688622fa88 Agendas/trunk/src/Agendas.Twitter/oAuthTwitter.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.Twitter/oAuthTwitter.cs Fri Jun 03 21:35:59 2011 -0300
@@ -0,0 +1,275 @@
+using System;
+using System.Configuration;
+using System.Web;
+using System.Net;
+using System.IO;
+using System.Collections.Specialized;
+
+namespace AltNetHispano.Agendas.Twitter
+{
+ public class oAuthTwitter : OAuthBase
+ {
+ public enum Method { GET, POST, DELETE };
+ public const string REQUEST_TOKEN = "http://twitter.com/oauth/request_token";
+ public const string AUTHORIZE = "http://twitter.com/oauth/authorize";
+ public const string ACCESS_TOKEN = "http://twitter.com/oauth/access_token";
+
+ private string _consumerKey = "";
+ private string _consumerSecret = "";
+ private string _token = "";
+ private string _tokenSecret = "";
+ private string _callBackUrl = "oob";
+ private string _oauthVerifier = "";
+
+
+#region Properties
+ public string ConsumerKey
+ {
+ get
+ {
+ if (_consumerKey.Length == 0)
+ {
+ _consumerKey = ConfigurationManager.AppSettings["consumerKey"];
+ }
+ return _consumerKey;
+ }
+ set { _consumerKey = value; }
+ }
+
+ public string ConsumerSecret {
+ get {
+ if (_consumerSecret.Length == 0)
+ {
+ _consumerSecret = ConfigurationManager.AppSettings["consumerSecret"];
+ }
+ return _consumerSecret;
+ }
+ set { _consumerSecret = value; }
+ }
+
+ public string Token { get { return _token; } set { _token = value; } }
+ public string TokenSecret { get { return _tokenSecret; } set { _tokenSecret = value; } }
+ public string CallBackUrl { get { return _callBackUrl; } set { _callBackUrl = value; } }
+ public string OAuthVerifier { get { return _oauthVerifier; } set { _oauthVerifier = value; } }
+
+#endregion
+
+ ///
+ /// Get the link to Twitter's authorization page for this application.
+ ///
+ /// The url with a valid request token, or a null string.
+ public string AuthorizationLinkGet()
+ {
+ string ret = null;
+
+ string response = oAuthWebRequest(Method.GET, REQUEST_TOKEN, String.Empty);
+ if (response.Length > 0)
+ {
+ //response contains token and token secret. We only need the token.
+ NameValueCollection qs = HttpUtility.ParseQueryString(response);
+
+ if (qs["oauth_callback_confirmed"] != null)
+ {
+ if (qs["oauth_callback_confirmed"] != "true")
+ {
+ throw new Exception("OAuth callback not confirmed.");
+ }
+ }
+
+ if (qs["oauth_token"] != null)
+ {
+ ret = AUTHORIZE + "?oauth_token=" + qs["oauth_token"];
+ }
+ }
+ return ret;
+ }
+
+ ///
+ /// Exchange the request token for an access token.
+ ///
+ /// The oauth_token is supplied by Twitter's authorization page following the callback.
+ /// An oauth_verifier parameter is provided to the client either in the pre-configured callback URL
+ public void AccessTokenGet(string authToken, string oauthVerifier)
+ {
+ this.Token = authToken;
+ this.OAuthVerifier = oauthVerifier;
+
+ string response = oAuthWebRequest(Method.GET, ACCESS_TOKEN, String.Empty);
+
+ if (response.Length > 0)
+ {
+ //Store the Token and Token Secret
+ NameValueCollection qs = HttpUtility.ParseQueryString(response);
+ if (qs["oauth_token"] != null)
+ {
+ this.Token = qs["oauth_token"];
+ }
+ if (qs["oauth_token_secret"] != null)
+ {
+ this.TokenSecret = qs["oauth_token_secret"];
+ }
+ }
+ }
+
+ ///
+ /// Submit a web request using oAuth.
+ ///
+ /// GET or POST
+ /// The full url, including the querystring.
+ /// Data to post (querystring format)
+ /// The web server response.
+ public string oAuthWebRequest(Method method, string url, string postData)
+ {
+ string outUrl = "";
+ string querystring = "";
+ string ret = "";
+
+
+ //Setup postData for signing.
+ //Add the postData to the querystring.
+ if (method == Method.POST || method == Method.DELETE)
+ {
+ if (postData.Length > 0)
+ {
+ //Decode the parameters and re-encode using the oAuth UrlEncode method.
+ NameValueCollection qs = HttpUtility.ParseQueryString(postData);
+ postData = "";
+ foreach (string key in qs.AllKeys)
+ {
+ if (postData.Length > 0)
+ {
+ postData += "&";
+ }
+ qs[key] = HttpUtility.UrlDecode(qs[key]);
+ qs[key] = this.UrlEncode(qs[key]);
+ postData += key + "=" + qs[key];
+
+ }
+ if (url.IndexOf("?") > 0)
+ {
+ url += "&";
+ }
+ else
+ {
+ url += "?";
+ }
+ url += postData;
+ }
+ }
+
+ Uri uri = new Uri(url);
+
+ string nonce = this.GenerateNonce();
+ string timeStamp = this.GenerateTimeStamp();
+
+ //Generate Signature
+ string sig = this.GenerateSignature(uri,
+ this.ConsumerKey,
+ this.ConsumerSecret,
+ this.Token,
+ this.TokenSecret,
+ this.CallBackUrl,
+ this.OAuthVerifier,
+ method.ToString(),
+ timeStamp,
+ nonce,
+ out outUrl,
+ out querystring);
+
+ querystring += "&oauth_signature=" + this.UrlEncode(sig);
+
+ //Convert the querystring to postData
+ if (method == Method.POST || method == Method.DELETE)
+ {
+ postData = querystring;
+ querystring = "";
+ }
+
+ if (querystring.Length > 0)
+ {
+ outUrl += "?";
+ }
+
+ ret = WebRequest(method, outUrl + querystring, postData);
+
+ return ret;
+ }
+
+ ///
+ /// Web Request Wrapper
+ ///
+ /// Http Method
+ /// Full url to the web resource
+ /// Data to post in querystring format
+ /// The web server response.
+ public string WebRequest(Method method, string url, string postData)
+ {
+ HttpWebRequest webRequest = null;
+ StreamWriter requestWriter = null;
+ string responseData = "";
+
+ webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
+ webRequest.Method = method.ToString();
+ webRequest.ServicePoint.Expect100Continue = false;
+ //webRequest.UserAgent = "Identify your application please.";
+ //webRequest.Timeout = 20000;
+
+ if (method == Method.POST || method == Method.DELETE)
+ {
+ webRequest.ContentType = "application/x-www-form-urlencoded";
+
+ //POST the data.
+ requestWriter = new StreamWriter(webRequest.GetRequestStream());
+ try
+ {
+ requestWriter.Write(postData);
+ }
+ catch
+ {
+ throw;
+ }
+ finally
+ {
+ requestWriter.Close();
+ requestWriter = null;
+ }
+ }
+
+ responseData = WebResponseGet(webRequest);
+
+ webRequest = null;
+
+ return responseData;
+
+ }
+
+ ///
+ /// Process the web response.
+ ///
+ /// The request object.
+ /// The response data.
+ public string WebResponseGet(HttpWebRequest webRequest)
+ {
+ StreamReader responseReader = null;
+ string responseData = "";
+
+ try
+ {
+ responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
+ responseData = responseReader.ReadToEnd();
+ }
+ catch
+ {
+ throw;
+ }
+ finally
+ {
+ webRequest.GetResponse().GetResponseStream().Close();
+ responseReader.Close();
+ responseReader = null;
+ }
+
+ return responseData;
+ }
+ }
+}
diff -r 24e9488ac152 -r d1688622fa88 Agendas/trunk/src/Agendas.Web/Agendas.Web.csproj
--- a/Agendas/trunk/src/Agendas.Web/Agendas.Web.csproj Tue May 31 16:31:24 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Web/Agendas.Web.csproj Fri Jun 03 21:35:59 2011 -0300
@@ -164,6 +164,10 @@
{444D25FB-FC1C-48DC-9EAD-D4C78F2A10CA}
Agendas.Resources
+
+ {D8DA7ED2-A274-4DF6-9DD2-A9DC65F4C2F5}
+ Agendas.Twitter
+
@@ -193,7 +197,7 @@
False
- True
+ False
1424
/
diff -r 24e9488ac152 -r d1688622fa88 Agendas/trunk/src/Agendas.Web/Controllers/AccountController.cs
--- a/Agendas/trunk/src/Agendas.Web/Controllers/AccountController.cs Tue May 31 16:31:24 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Web/Controllers/AccountController.cs Fri Jun 03 21:35:59 2011 -0300
@@ -1,6 +1,8 @@
-using System.Web.Mvc;
+using System;
+using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
+using AltNetHispano.Agendas.Twitter;
using AltNetHispano.Agendas.Web.Models;
namespace AltNetHispano.Agendas.Web.Controllers
@@ -55,7 +57,61 @@
return View(model);
}
- // **************************************
+ public ActionResult TwitterLogOn()
+ {
+ var oAuth = new oAuthTwitter();
+
+ if (Request["oauth_token"] == null)
+ {
+ //Redirect the user to Twitter for authorization.
+ //Using oauth_callback for local testing.
+ oAuth.CallBackUrl = "http://localhost:1424/Account/TwitterLogOn";
+ Response.Redirect(oAuth.AuthorizationLinkGet());
+ }
+ else
+ {
+ //Get the access token and secret.
+ oAuth.AccessTokenGet(Request["oauth_token"], Request["oauth_verifier"]);
+ if (oAuth.TokenSecret.Length > 0)
+ {
+ //We now have the credentials, so make a call to the Twitter API.
+ const string url = "http://twitter.com/account/verify_credentials.xml";
+ string xml = oAuth.oAuthWebRequest(oAuthTwitter.Method.GET, url, String.Empty);
+
+ var username = GetXmlContent(xml, "screen_name");
+ //TODO: Validar que este usuario de twitter corresponde a un usuario del sitio
+
+ FormsService.SignIn(username, false);
+ return RedirectToAction("Index", "Home");
+
+ //POST Test
+ //url = "http://twitter.com/statuses/update.xml";
+ //xml = oAuth.oAuthWebRequest(oAuthTwitter.Method.POST, url, "status=" + oAuth.UrlEncode("Hello @swhitley - Testing the .NET oAuth API"));
+ //apiResponse.InnerHtml = Server.HtmlEncode(xml);
+ }
+ }
+
+ return RedirectToAction("LogOn");
+ }
+
+ private string GetXmlContent(string xml, string tagName)
+ {
+ var tagStart = "<" + tagName + ">";
+ var tagEnd = "" + tagName + ">";
+
+ var start = xml.IndexOf(tagStart)+tagStart.Length;
+ if (start>tagStart.Length)
+ {
+ var end = xml.IndexOf(tagEnd, start);
+ if (end>0)
+ {
+ return xml.Substring(start, end - start);
+ }
+ }
+ return string.Empty;
+ }
+
+ // **************************************
// URL: /Account/LogOff
// **************************************
diff -r 24e9488ac152 -r d1688622fa88 Agendas/trunk/src/Agendas.Web/Views/Account/LogOn.cshtml
--- a/Agendas/trunk/src/Agendas.Web/Views/Account/LogOn.cshtml Tue May 31 16:31:24 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Web/Views/Account/LogOn.cshtml Fri Jun 03 21:35:59 2011 -0300
@@ -9,6 +9,7 @@
@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
+@Html.ActionLink("Twitter", "TwitterLogOn")
@using (Html.BeginForm()) {