Abstraction of authenticators. Reworked Gmail authentication.

This commit is contained in:
Burak Kaan Köse
2024-11-20 01:45:48 +01:00
parent 8367efa174
commit 7fad15524f
44 changed files with 354 additions and 605 deletions

View File

@@ -1,30 +0,0 @@
using System;
using SQLite;
using Wino.Core.Domain.Models.Authentication;
namespace Wino.Core.Domain.Entities.Shared
{
public class TokenInformation : TokenInformationBase
{
[PrimaryKey]
public Guid Id { get; set; }
public Guid AccountId { get; set; }
/// <summary>
/// Unique object storage for authenticators if needed.
/// </summary>
public string UniqueId { get; set; }
public string Address { get; set; }
public void RefreshTokens(TokenInformationBase tokenInformationBase)
{
if (tokenInformationBase == null)
throw new ArgumentNullException(nameof(tokenInformationBase));
AccessToken = tokenInformationBase.AccessToken;
RefreshToken = tokenInformationBase.RefreshToken;
ExpiresAt = tokenInformationBase.ExpiresAt;
}
}
}

View File

@@ -48,7 +48,7 @@ namespace Wino.Core.Domain.Interfaces
/// Creates new account with the given server information if any.
/// Also sets the account as Startup account if there are no accounts.
/// </summary>
Task CreateAccountAsync(MailAccount account, TokenInformation tokenInformation, CustomServerInformation customServerInformation);
Task CreateAccountAsync(MailAccount account, CustomServerInformation customServerInformation);
/// <summary>
/// Fixed authentication errors for account by forcing interactive login.

View File

@@ -1,6 +1,7 @@
using System.Threading.Tasks;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Authentication;
namespace Wino.Core.Domain.Interfaces
{
@@ -11,26 +12,28 @@ namespace Wino.Core.Domain.Interfaces
/// </summary>
MailProviderType ProviderType { get; }
/// <summary>
/// Gets the token from the cache if exists.
/// If the token is expired, tries to refresh.
/// This can throw AuthenticationAttentionException if silent refresh fails.
/// </summary>
/// <param name="account">Account to get token for.</param>
/// <returns>Valid token info to be used in integrators.</returns>
Task<TokenInformation> GetTokenAsync(MailAccount account);
Task<TokenInformationEx> GetTokenInformationAsync(MailAccount account);
/// <summary>
/// Initial creation of token. Requires user interaction.
/// This will cache the token but still returns for account creation
/// since account address is required.
/// </summary>
/// <returns>Freshly created TokenInformation..</returns>
Task<TokenInformation> GenerateTokenAsync(MailAccount account, bool saveToken);
Task<TokenInformationEx> GenerateTokenInformationAsync(MailAccount account);
/// <summary>
/// ClientId in case of needed for authorization/authentication.
/// </summary>
string ClientId { get; }
///// <summary>
///// Gets the token for the given account from the cache.
///// Forces interactive login if the token is not found.
///// </summary>
///// <param name="account">Account to get access token for.</param>
///// <returns>Access token</returns>
//Task<string> GetTokenAsync(MailAccount account);
///// <summary>
///// Forces an interactive login to get the token for the given account.
///// </summary>
///// <param name="account">Account to get access token for.</param>
///// <returns>Access token</returns>
//// Task<string> GenerateTokenAsync(MailAccount account);
///// <summary>
///// ClientId in case of needed for authorization/authentication.
///// </summary>
//string ClientId { get; }
}
}

View File

@@ -0,0 +1,10 @@
namespace Wino.Core.Domain.Interfaces
{
public interface IAuthenticatorConfig
{
string OutlookAuthenticatorClientId { get; }
string[] OutlookScope { get; }
string GmailAuthenticatorClientId { get; }
string[] GmailScope { get; }
}
}

View File

@@ -5,5 +5,6 @@
{
bool ProposeCopyAuthURL { get; set; }
}
public interface IImapAuthenticator : IAuthenticator { }
}

View File

@@ -1,7 +1,5 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Wino.Core.Domain.Models.Authorization;
namespace Wino.Core.Domain.Interfaces
{
@@ -13,13 +11,6 @@ namespace Wino.Core.Domain.Interfaces
Task LaunchFileAsync(string filePath);
Task<bool> LaunchUriAsync(Uri uri);
/// <summary>
/// Launches the default browser with the specified uri and waits for protocol activation to finish.
/// </summary>
/// <param name="authenticator"></param>
/// <returns>Response callback from the browser.</returns>
Task<Uri> GetAuthorizationResponseUriAsync(IAuthenticator authenticator, string authorizationUri, CancellationToken cancellationToken = default);
/// <summary>
/// Finalizes GetAuthorizationResponseUriAsync for current IAuthenticator.
/// </summary>
@@ -32,11 +23,6 @@ namespace Wino.Core.Domain.Interfaces
Task PinAppToTaskbarAsync();
/// <summary>
/// Some cryptographic shit is needed for requesting Google authentication in UWP.
/// </summary>
GoogleAuthorizationRequest GetGoogleAuthorizationRequest();
/// <summary>
/// Gets or sets the function that returns a pointer for main window hwnd for UWP.
/// This is used to display WAM broker dialog on running UWP app called by a windowless server code.

View File

@@ -5,5 +5,6 @@
/// </summary>
/// <param name="SenderName">Display sender name for the account.</param>
/// <param name="Base64ProfilePictureData">Base 64 encoded profile picture data of the account. Thumbnail size.</param>
public record ProfileInformation(string SenderName, string Base64ProfilePictureData);
/// <param name="AccountAddress">Address of the profile.</param>
public record ProfileInformation(string SenderName, string Base64ProfilePictureData, string AccountAddress);
}

View File

@@ -1,20 +0,0 @@
using System;
namespace Wino.Core.Domain.Models.Authentication
{
public class TokenInformationBase
{
public string AccessToken { get; set; }
public string RefreshToken { get; set; }
/// <summary>
/// UTC date for token expiration.
/// </summary>
public DateTime ExpiresAt { get; set; }
/// <summary>
/// Gets the value indicating whether the token is expired or not.
/// </summary>
public bool IsExpired => DateTime.UtcNow >= ExpiresAt;
}
}

View File

@@ -0,0 +1,11 @@
namespace Wino.Core.Domain.Models.Authentication
{
/// <summary>
/// Previously known as TokenInformation.
/// We used to store this model in the database.
/// Now we store it in the memory.
/// </summary>
/// <param name="AccessToken">Access token/</param>
/// <param name="AccountAddress">Address of the authenticated user.</param>
public record TokenInformationEx(string AccessToken, string AccountAddress);
}