diff --git a/.gitignore b/.gitignore index 6f9e0ec..a203027 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ bin obj +.idea *ReSharper* packages *.pyc diff --git a/OAuth2/Client/IClient.cs b/OAuth2/Client/IClient.cs index e4df633..f37f1c8 100644 --- a/OAuth2/Client/IClient.cs +++ b/OAuth2/Client/IClient.cs @@ -44,7 +44,7 @@ public interface IClient /// Callback request payload (parameters). /// Request.QueryString /// - UserInfo GetUserInfo(NameValueCollection parameters); + UserInfo GetUserInfo(NameValueCollection parameters, NameValueCollection queryParameters = null); /// /// Client configuration object. diff --git a/OAuth2/Client/Impl/FacebookClient.cs b/OAuth2/Client/Impl/FacebookClient.cs index 6697905..45d23f1 100644 --- a/OAuth2/Client/Impl/FacebookClient.cs +++ b/OAuth2/Client/Impl/FacebookClient.cs @@ -71,7 +71,7 @@ protected override Endpoint UserInfoServiceEndpoint /// protected override void BeforeGetUserInfo(BeforeAfterRequestArgs args) { - args.Request.AddParameter("fields", "id,first_name,last_name,email,picture"); + args.Request.AddParameter("fields", "id,first_name,last_name,email,picture.width(256).height(256)"); } /// @@ -81,7 +81,7 @@ protected override void BeforeGetUserInfo(BeforeAfterRequestArgs args) protected override UserInfo ParseUserInfo(string content) { var response = JObject.Parse(content); - const string avatarUriTemplate = "{0}?type={1}"; + const string avatarUriTemplate = "{0}"; var avatarUri = response["picture"]["data"]["url"].Value(); return new UserInfo { @@ -91,9 +91,9 @@ protected override UserInfo ParseUserInfo(string content) Email = response["email"].SafeGet(x => x.Value()), AvatarUri = { - Small = !string.IsNullOrWhiteSpace(avatarUri) ? string.Format(avatarUriTemplate, avatarUri, "small") : string.Empty, - Normal = !string.IsNullOrWhiteSpace(avatarUri) ? string.Format(avatarUriTemplate, avatarUri, "normal") : string.Empty, - Large = !string.IsNullOrWhiteSpace(avatarUri) ? string.Format(avatarUriTemplate, avatarUri, "large") : string.Empty + Small = !string.IsNullOrWhiteSpace(avatarUri) ? string.Format(avatarUriTemplate, avatarUri) : string.Empty, + Normal = !string.IsNullOrWhiteSpace(avatarUri) ? string.Format(avatarUriTemplate, avatarUri) : string.Empty, + Large = !string.IsNullOrWhiteSpace(avatarUri) ? string.Format(avatarUriTemplate, avatarUri) : string.Empty } }; } diff --git a/OAuth2/Client/Impl/TwitterClient.cs b/OAuth2/Client/Impl/TwitterClient.cs index cdd2cfb..230be78 100644 --- a/OAuth2/Client/Impl/TwitterClient.cs +++ b/OAuth2/Client/Impl/TwitterClient.cs @@ -1,3 +1,4 @@ +using System; using Newtonsoft.Json.Linq; using OAuth2.Configuration; using OAuth2.Infrastructure; @@ -109,14 +110,14 @@ protected override UserInfo ParseUserInfo(string content) return new UserInfo { Id = response["id"].Value(), - Email = null, + Email = response["email"] == null ? null : response["email"].Value(), FirstName = firstName, LastName = lastName, AvatarUri = { - Small = avatarUri.Replace("normal", "mini"), - Normal = avatarUri, - Large = avatarUri.Replace("normal", "bigger") + Small = avatarUri, + Normal = avatarUri.Replace("normal", "bigger"), + Large = avatarUri.Replace("_normal", "") } }; } diff --git a/OAuth2/Client/OAuth2Client.cs b/OAuth2/Client/OAuth2Client.cs index 134d47a..7e26cc8 100644 --- a/OAuth2/Client/OAuth2Client.cs +++ b/OAuth2/Client/OAuth2Client.cs @@ -41,7 +41,7 @@ public abstract class OAuth2Client : IClient /// /// Access token returned by provider. Can be used for further calls of provider API. /// - public string AccessToken { get; private set; } + public string AccessToken { get; set; } /// /// Refresh token returned by provider. Can be used for further calls of provider API. @@ -110,11 +110,19 @@ public virtual string GetLoginLinkUri(string state = null) /// Obtains user information using OAuth2 service and data provided via callback request. /// /// Callback request payload (parameters). - public UserInfo GetUserInfo(NameValueCollection parameters) + /// Callback request payload (query parameters). + public UserInfo GetUserInfo(NameValueCollection parameters, NameValueCollection queryParameters = null) { - GrantType = "authorization_code"; - CheckErrorAndSetState(parameters); - QueryAccessToken(parameters); + queryParameters = queryParameters ?? new NameValueCollection(); + + if (this.AccessToken == null) + { + GrantType = "authorization_code"; + CheckErrorAndSetState(parameters); + + QueryAccessToken(parameters); + } + return GetUserInfo(); } @@ -126,7 +134,10 @@ public string GetToken(NameValueCollection parameters) { GrantType = "authorization_code"; CheckErrorAndSetState(parameters); - QueryAccessToken(parameters); + + if (this.AccessToken == null) + QueryAccessToken(parameters); + return AccessToken; } diff --git a/OAuth2/Client/OAuthClient.cs b/OAuth2/Client/OAuthClient.cs index 909fe4b..6bb115a 100644 --- a/OAuth2/Client/OAuthClient.cs +++ b/OAuth2/Client/OAuthClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Specialized; +using System.Runtime.InteropServices.ComTypes; using System.Web; using OAuth2.Configuration; using OAuth2.Infrastructure; @@ -38,12 +39,12 @@ public abstract class OAuthClient : IClient /// /// Access token received from service. Can be used for further service API calls. /// - public string AccessToken { get; private set; } + public string AccessToken { get; set; } /// /// Access token secret received from service. Can be used for further service API calls. /// - public string AccessTokenSecret { get; private set; } + public string AccessTokenSecret { get; set; } /// /// Initializes a new instance of the class. @@ -78,13 +79,20 @@ public string GetLoginLinkUri(string state = null) /// /// Callback request payload (parameters). /// Request.QueryString + /// Callback request payload for query user info (parameters). + /// Request.QueryString /// - public UserInfo GetUserInfo(NameValueCollection parameters) + public UserInfo GetUserInfo(NameValueCollection parameters, NameValueCollection queryParameters = null) { - AccessToken = parameters.GetOrThrowUnexpectedResponse(OAuthTokenKey); - QueryAccessToken(parameters.GetOrThrowUnexpectedResponse("oauth_verifier")); + queryParameters = queryParameters ?? new NameValueCollection(); + + if (this.AccessToken == null || this.AccessTokenSecret == null) + { + AccessToken = parameters.GetOrThrowUnexpectedResponse(OAuthTokenKey); + QueryAccessToken(parameters.GetOrThrowUnexpectedResponse("oauth_verifier")); + } - var result = ParseUserInfo(QueryUserInfo()); + var result = ParseUserInfo(QueryUserInfo(queryParameters)); result.ProviderName = Name; return result; @@ -207,7 +215,7 @@ protected virtual void BeforeGetUserInfo(BeforeAfterRequestArgs args) /// /// Queries user info using corresponding service and data received by access token request. /// - private string QueryUserInfo() + private string QueryUserInfo(NameValueCollection queryParameters) { var client = _factory.CreateClient(UserInfoServiceEndpoint); client.Authenticator = OAuth1Authenticator.ForProtectedResource( @@ -215,6 +223,11 @@ private string QueryUserInfo() var request = _factory.CreateRequest(UserInfoServiceEndpoint); + foreach(var parameter in queryParameters.AllKeys) + { + request.AddParameter(parameter, queryParameters[parameter]); + } + BeforeGetUserInfo(new BeforeAfterRequestArgs { Client = client,