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,