This repository has been archived by the owner on Nov 24, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GH-78: Add handler for authentication requests
- Loading branch information
1 parent
dde8554
commit f76a327
Showing
5 changed files
with
249 additions
and
209 deletions.
There are no files selected for viewing
232 changes: 232 additions & 0 deletions
232
Source/Lib/TraktApiSharp/Requests/Handler/AuthenticationRequestHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
namespace TraktApiSharp.Requests.Handler | ||
{ | ||
using Authentication; | ||
using Core; | ||
using Exceptions; | ||
using Extensions; | ||
using Objects.Authentication.Implementations; | ||
using Responses; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net.Http; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Utils; | ||
|
||
internal sealed class AuthenticationRequestHandler : IAuthenticationRequestHandler | ||
{ | ||
private readonly TraktClient _client; | ||
|
||
internal AuthenticationRequestHandler(TraktClient client) | ||
{ | ||
_client = client; | ||
} | ||
|
||
public string CreateAuthorizationUrl() | ||
{ | ||
string clientId = _client.ClientId; | ||
string redirectUri = _client.Authentication.RedirectUri; | ||
return CreateAuthorizationUrl(clientId, redirectUri); | ||
} | ||
|
||
public string CreateAuthorizationUrl(string clientId) | ||
{ | ||
string redirectUri = _client.Authentication.RedirectUri; | ||
return CreateAuthorizationUrl(clientId, redirectUri); | ||
} | ||
|
||
public string CreateAuthorizationUrl(string clientId, string redirectUri) | ||
{ | ||
ValidateAuthorizationUrlArguments(clientId, redirectUri); | ||
return BuildAuthorizationUrl(clientId, redirectUri); | ||
} | ||
|
||
public string CreateAuthorizationUrl(string clientId, string redirectUri, string state) | ||
{ | ||
ValidateAuthorizationUrlArguments(clientId, redirectUri, state); | ||
return BuildAuthorizationUrl(clientId, redirectUri, state); | ||
} | ||
|
||
public string CreateAuthorizationUrlWithDefaultState() | ||
{ | ||
string clientId = _client.ClientId; | ||
string redirectUri = _client.Authentication.RedirectUri; | ||
string state = _client.Authentication.AntiForgeryToken; | ||
return CreateAuthorizationUrl(clientId, redirectUri, state); | ||
} | ||
|
||
public string CreateAuthorizationUrlWithDefaultState(string clientId) | ||
{ | ||
string redirectUri = _client.Authentication.RedirectUri; | ||
string state = _client.Authentication.AntiForgeryToken; | ||
return CreateAuthorizationUrl(clientId, redirectUri, state); | ||
} | ||
|
||
public string CreateAuthorizationUrlWithDefaultState(string clientId, string redirectUri) | ||
{ | ||
string state = _client.Authentication.AntiForgeryToken; | ||
return CreateAuthorizationUrl(clientId, redirectUri, state); | ||
} | ||
|
||
public async Task<Pair<bool, TraktResponse<TraktAuthorization>>> CheckIfAuthorizationIsExpiredOrWasRevokedAsync(bool autoRefresh = false, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
if (_client.Authorization.IsExpired) | ||
return new Pair<bool, TraktResponse<TraktAuthorization>>(true, new TraktResponse<TraktAuthorization>()); | ||
|
||
bool throwResponseExceptions = true; | ||
|
||
try | ||
{ | ||
throwResponseExceptions = _client.Configuration.ThrowResponseExceptions; | ||
_client.Configuration.ThrowResponseExceptions = true; | ||
await _client.Sync.GetLastActivitiesAsync(cancellationToken); | ||
} | ||
catch (TraktAuthorizationException) | ||
{ | ||
if (!autoRefresh) | ||
return new Pair<bool, TraktResponse<TraktAuthorization>>(true, new TraktResponse<TraktAuthorization>()); | ||
|
||
var request = new AuthorizationRefreshRequest | ||
{ | ||
RequestBody = new AuthorizationRefreshRequestBody | ||
{ | ||
ClientId = _client.ClientId, | ||
ClientSecret = _client.ClientSecret, | ||
RefreshToken = _client.Authorization.RefreshToken, | ||
RedirectUri = _client.Authentication.RedirectUri | ||
} | ||
}; | ||
|
||
TraktResponse<TraktAuthorization> response = await RefreshAuthorizationAsync(request, cancellationToken); | ||
return new Pair<bool, TraktResponse<TraktAuthorization>>(response.IsSuccess, response); | ||
} | ||
finally | ||
{ | ||
_client.Configuration.ThrowResponseExceptions = throwResponseExceptions; | ||
} | ||
|
||
return new Pair<bool, TraktResponse<TraktAuthorization>>(true, new TraktResponse<TraktAuthorization>()); | ||
} | ||
|
||
public async Task<Pair<bool, TraktResponse<TraktAuthorization>>> CheckIfAuthorizationIsExpiredOrWasRevokedAsync(TraktAuthorization authorization, bool autoRefresh = false, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
if (authorization == null) | ||
throw new ArgumentNullException(nameof(authorization)); | ||
|
||
TraktAuthorization currentAuthorization = _client.Authorization; | ||
_client.Authorization = authorization; | ||
|
||
var result = new Pair<bool, TraktResponse<TraktAuthorization>>(true, new TraktResponse<TraktAuthorization>()); | ||
|
||
try | ||
{ | ||
result = await CheckIfAuthorizationIsExpiredOrWasRevokedAsync(autoRefresh, cancellationToken); | ||
} | ||
finally | ||
{ | ||
_client.Authorization = currentAuthorization; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
public async Task<bool> CheckIfAccessTokenWasRevokedOrIsNotValidAsync(string accessToken, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
if (string.IsNullOrEmpty(accessToken) || accessToken.ContainsSpace()) | ||
throw new ArgumentException("access token must not be null, empty or contain any spaces", nameof(accessToken)); | ||
|
||
TraktAuthorization currentAuthorization = _client.Authorization; | ||
_client.Authorization = TraktAuthorization.CreateWith(accessToken); | ||
|
||
bool throwResponseExceptions = true; | ||
|
||
try | ||
{ | ||
throwResponseExceptions = _client.Configuration.ThrowResponseExceptions; | ||
_client.Configuration.ThrowResponseExceptions = true; | ||
await _client.Sync.GetLastActivitiesAsync(cancellationToken); | ||
return false; | ||
} | ||
catch (TraktAuthorizationException) | ||
{ | ||
return true; | ||
} | ||
finally | ||
{ | ||
_client.Configuration.ThrowResponseExceptions = throwResponseExceptions; | ||
_client.Authorization = currentAuthorization; | ||
} | ||
} | ||
|
||
public Task<TraktResponse<TraktDevice>> GetDeviceAsync(DeviceRequest request, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
|
||
public Task<TraktResponse<TraktAuthorization>> GetAuthorizationAsync(AuthorizationRequest request, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
|
||
public Task<TraktResponse<TraktAuthorization>> PollForAuthorizationAsync(AuthorizationPollRequest request, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
|
||
public Task<TraktResponse<TraktAuthorization>> RefreshAuthorizationAsync(AuthorizationRefreshRequest request, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
|
||
public Task<TraktNoContentResponse> RevokeAuthorizationAsync(AuthorizationRevokeRequest request, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
|
||
private string CreateEncodedAuthorizationUri(string clientId, string redirectUri, string state = null) | ||
{ | ||
var uriParams = new Dictionary<string, string> | ||
{ | ||
["response_type"] = "code", | ||
["client_id"] = clientId, | ||
["redirect_uri"] = redirectUri | ||
}; | ||
|
||
if (!string.IsNullOrEmpty(state)) | ||
uriParams["state"] = state; | ||
|
||
var encodedUriContent = new FormUrlEncodedContent(uriParams); | ||
string encodedUri = encodedUriContent.ReadAsStringAsync().Result; | ||
|
||
if (string.IsNullOrEmpty(encodedUri)) | ||
throw new ArgumentException("authorization uri not valid"); | ||
|
||
return $"?{encodedUri}"; | ||
} | ||
|
||
private string BuildAuthorizationUrl(string clientId, string redirectUri, string state = null) | ||
{ | ||
string encodedUriParams = CreateEncodedAuthorizationUri(clientId, redirectUri, state); | ||
bool isStagingUsed = _client.Configuration.UseSandboxEnvironment; | ||
string baseUrl = isStagingUsed ? Constants.OAuthBaseAuthorizeStagingUrl : Constants.OAuthBaseAuthorizeUrl; | ||
return $"{baseUrl}/{Constants.OAuthAuthorizeUri}{encodedUriParams}"; | ||
} | ||
|
||
private void ValidateAuthorizationUrlArguments(string clientId, string redirectUri) | ||
{ | ||
if (string.IsNullOrEmpty(clientId) || clientId.ContainsSpace()) | ||
throw new ArgumentException("client id not valid", nameof(clientId)); | ||
|
||
if (string.IsNullOrEmpty(redirectUri) || redirectUri.ContainsSpace()) | ||
throw new ArgumentException("redirect uri not valid", nameof(redirectUri)); | ||
} | ||
|
||
private void ValidateAuthorizationUrlArguments(string clientId, string redirectUri, string state) | ||
{ | ||
ValidateAuthorizationUrlArguments(clientId, redirectUri); | ||
|
||
if (string.IsNullOrEmpty(state) || state.ContainsSpace()) | ||
throw new ArgumentException("state not valid", nameof(state)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.