new_version_init
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Authentication.Models
|
||||
{
|
||||
internal class ValidateResponseFail
|
||||
{
|
||||
[JsonProperty("status", Required = Required.Always)]
|
||||
public int Status { get; set; }
|
||||
|
||||
[JsonProperty("message", Required = Required.Always)]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Authentication.Models
|
||||
{
|
||||
internal class ValidateResponseSuccess
|
||||
{
|
||||
[JsonProperty("client_id", Required = Required.Always)]
|
||||
public string ClientId { get; set; }
|
||||
|
||||
[JsonProperty("login", Required = Required.Always)]
|
||||
public string Login { get; set; }
|
||||
|
||||
[JsonProperty("scopes", Required = Required.Always)]
|
||||
public List<string> Scopes { get; set; }
|
||||
|
||||
[JsonProperty("user_id", Required = Required.Always)]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[JsonProperty("expires_in", Required = Required.Always)]
|
||||
public int ExpiresIn { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Services.Authentication;
|
||||
using VDownload.Services.Encryption;
|
||||
using VDownload.Services.HttpClient;
|
||||
using VDownload.Sources.Twitch.Authentication.Models;
|
||||
using VDownload.Sources.Twitch.Configuration;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Authentication
|
||||
{
|
||||
public interface ITwitchAuthenticationService
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
string AuthenticationPageUrl { get; }
|
||||
Regex AuthenticationPageRedirectUrlRegex { get; }
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region METHODS
|
||||
|
||||
Task<byte[]?> GetToken();
|
||||
Task SetToken(byte[] token);
|
||||
Task DeleteToken();
|
||||
Task<TwitchValidationResult> ValidateToken(byte[] token);
|
||||
bool AuthenticationPageClosePredicate(string url);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class TwitchAuthenticationService : ITwitchAuthenticationService
|
||||
{
|
||||
#region SERVICES
|
||||
|
||||
private TwitchAuthenticationConfiguration _authenticationConfiguration;
|
||||
private TwitchApiAuthConfiguration _apiAuthConfiguration;
|
||||
|
||||
private IHttpClientService _httpClientService;
|
||||
private IAuthenticationService _authenticationService;
|
||||
private IEncryptionService _encryptionService;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PROPERTIES
|
||||
|
||||
public string AuthenticationPageUrl { get; private set; }
|
||||
public Regex AuthenticationPageRedirectUrlRegex { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public TwitchAuthenticationService(TwitchConfiguration configuration, IHttpClientService httpClientService, IAuthenticationService authenticationService, IEncryptionService encryptionService)
|
||||
{
|
||||
_authenticationConfiguration = configuration.Authentication;
|
||||
_apiAuthConfiguration = configuration.Api.Auth;
|
||||
|
||||
_httpClientService = httpClientService;
|
||||
_authenticationService = authenticationService;
|
||||
_encryptionService = encryptionService;
|
||||
|
||||
AuthenticationPageUrl = string.Format(_authenticationConfiguration.Url, _authenticationConfiguration.ClientId, _authenticationConfiguration.RedirectUrl, _authenticationConfiguration.ResponseType, string.Join(' ', _authenticationConfiguration.Scopes));
|
||||
AuthenticationPageRedirectUrlRegex = _authenticationConfiguration.RedirectUrlRegex;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PUBLIC METHODS
|
||||
|
||||
public async Task<byte[]?> GetToken()
|
||||
{
|
||||
await _authenticationService.Load();
|
||||
|
||||
byte[]? tokenEncrypted = _authenticationService.AuthenticationData.Twitch.Token;
|
||||
|
||||
if (tokenEncrypted is not null && tokenEncrypted.Length == 0)
|
||||
{
|
||||
tokenEncrypted = null;
|
||||
}
|
||||
|
||||
if (tokenEncrypted is not null)
|
||||
{
|
||||
tokenEncrypted = _encryptionService.Decrypt(tokenEncrypted);
|
||||
}
|
||||
|
||||
return tokenEncrypted;
|
||||
}
|
||||
|
||||
public async Task SetToken(byte[] token)
|
||||
{
|
||||
Task loadTask = _authenticationService.Load();
|
||||
|
||||
byte[] tokenEncrypted = _encryptionService.Encrypt(token);
|
||||
|
||||
await loadTask;
|
||||
|
||||
_authenticationService.AuthenticationData.Twitch.Token = tokenEncrypted;
|
||||
|
||||
await _authenticationService.Save();
|
||||
}
|
||||
|
||||
public async Task DeleteToken()
|
||||
{
|
||||
await _authenticationService.Load();
|
||||
_authenticationService.AuthenticationData.Twitch.Token = null;
|
||||
await _authenticationService.Save();
|
||||
}
|
||||
|
||||
public async Task<TwitchValidationResult> ValidateToken(byte[] token)
|
||||
{
|
||||
Token tokenData = new Token(_apiAuthConfiguration.TokenSchema, token);
|
||||
HttpRequest request = new HttpRequest(HttpMethodType.GET, _apiAuthConfiguration.Endpoints.Validate);
|
||||
request.Headers.Add("Authorization", $"{tokenData}");
|
||||
string response = await _httpClientService.SendRequestAsync(request);
|
||||
|
||||
try
|
||||
{
|
||||
ValidateResponseSuccess success = JsonConvert.DeserializeObject<ValidateResponseSuccess>(response);
|
||||
return new TwitchValidationResult(success);
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
{}
|
||||
|
||||
try
|
||||
{
|
||||
ValidateResponseFail fail = JsonConvert.DeserializeObject<ValidateResponseFail>(response);
|
||||
return new TwitchValidationResult(fail);
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
{}
|
||||
|
||||
throw new Exception(response);
|
||||
}
|
||||
|
||||
public bool AuthenticationPageClosePredicate(string url)
|
||||
{
|
||||
bool close = url.StartsWith(_authenticationConfiguration.RedirectUrl);
|
||||
return close;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Sources.Twitch.Authentication.Models;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Authentication
|
||||
{
|
||||
public class TwitchValidationResult
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public bool Success { get; private set; }
|
||||
public int? FailStatusCode { get; private set; }
|
||||
public string? FailMessage { get; private set; }
|
||||
public TwitchValidationTokenData TokenData { get; private set; }
|
||||
public DateTime ValidationDate { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
private TwitchValidationResult()
|
||||
{
|
||||
ValidationDate = DateTime.Now;
|
||||
}
|
||||
|
||||
internal TwitchValidationResult(ValidateResponseFail fail)
|
||||
{
|
||||
Success = false;
|
||||
FailStatusCode = fail.Status;
|
||||
FailMessage = fail.Message;
|
||||
}
|
||||
|
||||
internal TwitchValidationResult(ValidateResponseSuccess success)
|
||||
{
|
||||
Success = true;
|
||||
TokenData = new TwitchValidationTokenData(success);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VDownload.Sources.Twitch.Authentication.Models;
|
||||
|
||||
namespace VDownload.Sources.Twitch.Authentication
|
||||
{
|
||||
public class TwitchValidationTokenData
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public string ClientId { get; private set; }
|
||||
public string Login { get; private set; }
|
||||
public IEnumerable<string> Scopes { get; private set; }
|
||||
public string UserId { get; private set; }
|
||||
public DateTime ExpirationDate { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region CONSTRUCTORS
|
||||
|
||||
internal TwitchValidationTokenData(ValidateResponseSuccess response)
|
||||
{
|
||||
ClientId = response.ClientId;
|
||||
Login = response.Login;
|
||||
Scopes = response.Scopes;
|
||||
UserId = response.UserId;
|
||||
ExpirationDate = DateTime.Now.AddSeconds(response.ExpiresIn);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\VDownload.Services\VDownload.Services.Authentication\VDownload.Services.Authentication.csproj" />
|
||||
<ProjectReference Include="..\..\..\VDownload.Services\VDownload.Services.Encryption\VDownload.Services.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\..\VDownload.Services\VDownload.Services.HttpClient\VDownload.Services.HttpClient.csproj" />
|
||||
<ProjectReference Include="..\VDownload.Sources.Twitch.Configuration\VDownload.Sources.Twitch.Configuration.csproj" />
|
||||
<ProjectReference Include="..\VDownload.Sources.Twitch\VDownload.Sources.Twitch.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user