Got at least one data fetching method working; turns out, we can't use a patched LogicStack to get the data
This commit is contained in:
31
Vendor/EmbedIO-3.5.2/Authentication/Auth.cs
vendored
Normal file
31
Vendor/EmbedIO-3.5.2/Authentication/Auth.cs
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace EmbedIO.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides useful authentication-related constants.
|
||||
/// </summary>
|
||||
public static class Auth
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IPrincipal"/> interface representing
|
||||
/// no user. To be used instead of <see langword="null"/>
|
||||
/// to initialize or set properties of type <see cref="IPrincipal"/>.
|
||||
/// </summary>
|
||||
public static IPrincipal NoUser { get; } = new GenericPrincipal(
|
||||
new GenericIdentity(string.Empty, string.Empty),
|
||||
null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and returns an <see cref="IPrincipal"/> interface
|
||||
/// representing an unauthenticated user, with the given
|
||||
/// authentication type.
|
||||
/// </summary>
|
||||
/// <param name="authenticationType">The type of authentication used to identify the user.</param>
|
||||
/// <returns>An <see cref="IPrincipal"/> interface.</returns>
|
||||
public static IPrincipal CreateUnauthenticatedPrincipal(string authenticationType)
|
||||
=> new GenericPrincipal(
|
||||
new GenericIdentity(string.Empty, authenticationType),
|
||||
null);
|
||||
}
|
||||
}
|
||||
46
Vendor/EmbedIO-3.5.2/Authentication/BasicAuthenticationModule.cs
vendored
Normal file
46
Vendor/EmbedIO-3.5.2/Authentication/BasicAuthenticationModule.cs
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EmbedIO.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple HTTP basic authentication module that stores credentials
|
||||
/// in a <seealso cref="ConcurrentDictionary{TKey,TValue}"/>.
|
||||
/// </summary>
|
||||
public class BasicAuthenticationModule : BasicAuthenticationModuleBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BasicAuthenticationModule"/> class.
|
||||
/// </summary>
|
||||
/// <param name="baseRoute">The base route.</param>
|
||||
/// <param name="realm">The authentication realm.</param>
|
||||
/// <remarks>
|
||||
/// <para>If <paramref name="realm"/> is <see langword="null"/> or the empty string,
|
||||
/// the <see cref="BasicAuthenticationModuleBase.Realm">Realm</see> property will be set equal to
|
||||
/// <see cref="IWebModule.BaseRoute">BaseRoute</see>.</para>
|
||||
/// </remarks>
|
||||
public BasicAuthenticationModule(string baseRoute, string? realm = null)
|
||||
: base(baseRoute, realm)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary of valid user names and passwords.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The accounts.
|
||||
/// </value>
|
||||
public ConcurrentDictionary<string, string> Accounts { get; } = new ConcurrentDictionary<string, string>(StringComparer.InvariantCulture);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task<bool> VerifyCredentialsAsync(string path, string userName, string password, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(VerifyCredentialsInternal(userName, password));
|
||||
|
||||
private bool VerifyCredentialsInternal(string userName, string password)
|
||||
=> userName != null
|
||||
&& Accounts.TryGetValue(userName, out var storedPassword)
|
||||
&& string.Equals(password, storedPassword, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
103
Vendor/EmbedIO-3.5.2/Authentication/BasicAuthenticationModuleBase.cs
vendored
Normal file
103
Vendor/EmbedIO-3.5.2/Authentication/BasicAuthenticationModuleBase.cs
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EmbedIO.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see href="https://tools.ietf.org/html/rfc7617">HTTP basic authentication</see>.
|
||||
/// </summary>
|
||||
public abstract class BasicAuthenticationModuleBase : WebModuleBase
|
||||
{
|
||||
private readonly string _wwwAuthenticateHeaderValue;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BasicAuthenticationModuleBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="baseRoute">The base URL path.</param>
|
||||
/// <param name="realm">The authentication realm.</param>
|
||||
/// <remarks>
|
||||
/// <para>If <paramref name="realm"/> is <see langword="null"/> or the empty string,
|
||||
/// the <see cref="Realm"/> property will be set equal to
|
||||
/// <see cref="IWebModule.BaseRoute">BaseRoute</see>.</para>
|
||||
/// </remarks>
|
||||
protected BasicAuthenticationModuleBase(string baseRoute, string? realm)
|
||||
: base(baseRoute)
|
||||
{
|
||||
Realm = string.IsNullOrEmpty(realm) ? BaseRoute : realm;
|
||||
|
||||
_wwwAuthenticateHeaderValue = $"Basic realm=\"{Realm}\" charset=UTF-8";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override bool IsFinalHandler => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authentication realm.
|
||||
/// </summary>
|
||||
public string Realm { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected sealed override async Task OnRequestAsync(IHttpContext context)
|
||||
{
|
||||
async Task<bool> IsAuthenticatedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var (userName, password) = GetCredentials(context.Request);
|
||||
return await VerifyCredentialsAsync(context.RequestedPath, userName, password, context.CancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
// Credentials were not formatted correctly.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
context.Response.Headers.Set(HttpHeaderNames.WWWAuthenticate, _wwwAuthenticateHeaderValue);
|
||||
|
||||
if (!await IsAuthenticatedAsync().ConfigureAwait(false))
|
||||
throw HttpException.Unauthorized();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies the credentials given in the <c>Authentication</c> request header.
|
||||
/// </summary>
|
||||
/// <param name="path">The URL path requested by the client. Note that this is relative
|
||||
/// to the module's <see cref="WebModuleBase.BaseRoute">BaseRoute</see>.</param>
|
||||
/// <param name="userName">The user name, or <see langword="null" /> if none has been given.</param>
|
||||
/// <param name="password">The password, or <see langword="null" /> if none has been given.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> use to cancel the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> whose result will be <see langword="true" /> if the given credentials
|
||||
/// are valid, <see langword="false" /> if they are not.</returns>
|
||||
protected abstract Task<bool> VerifyCredentialsAsync(string path, string userName, string password, CancellationToken cancellationToken);
|
||||
|
||||
private static (string UserName, string Password) GetCredentials(IHttpRequest request)
|
||||
{
|
||||
var authHeader = request.Headers[HttpHeaderNames.Authorization];
|
||||
|
||||
if (authHeader == null)
|
||||
return default;
|
||||
|
||||
if (!authHeader.StartsWith("basic ", StringComparison.OrdinalIgnoreCase))
|
||||
return default;
|
||||
|
||||
string credentials;
|
||||
try
|
||||
{
|
||||
credentials = WebServer.DefaultEncoding.GetString(Convert.FromBase64String(authHeader.Substring(6).Trim()));
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
var separatorPos = credentials.IndexOf(':');
|
||||
return separatorPos < 0
|
||||
? (credentials, string.Empty)
|
||||
: (credentials.Substring(0, separatorPos), credentials.Substring(separatorPos + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Vendor/EmbedIO-3.5.2/Authentication/BasicAuthenticationModuleExtensions.cs
vendored
Normal file
34
Vendor/EmbedIO-3.5.2/Authentication/BasicAuthenticationModuleExtensions.cs
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
|
||||
namespace EmbedIO.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for <see cref="BasicAuthenticationModule"/>.
|
||||
/// </summary>
|
||||
public static class BasicAuthenticationModuleExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a username and password to the <see cref="BasicAuthenticationModule.Accounts">Accounts</see> dictionary.
|
||||
/// </summary>
|
||||
/// <param name="this">The <see cref="BasicAuthenticationModule"/> on which this method is called.</param>
|
||||
/// <param name="userName">The user name.</param>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns><paramref name="this"/>, with the user name and password added.</returns>
|
||||
/// <exception cref="NullReferenceException"><paramref name="this"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="userName"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="OverflowException">
|
||||
/// <para>The <see cref="BasicAuthenticationModule.Accounts">Accounts</see> dictionary already contains
|
||||
/// the maximum number of elements (<see cref="int.MaxValue">MaxValue</see>).</para>
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>If a <paramref name="userName"/> account already exists,
|
||||
/// its password is replaced with <paramref name="password"/>.</para>
|
||||
/// </remarks>
|
||||
public static BasicAuthenticationModule WithAccount(this BasicAuthenticationModule @this, string userName, string password)
|
||||
{
|
||||
@this.Accounts.AddOrUpdate(userName, password, (_, __) => password);
|
||||
|
||||
return @this;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user