using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Raven.Client.Documents.Session; using System.Security.Claims; using System.Threading.Tasks; using zero.Core.Cultures; using zero.Core.Database; using zero.Core.Entities; using zero.Core.Extensions; using zero.Core.Options; using zero.Core.Routing; namespace zero.Core { public class ZeroContext : IZeroContext { /// public IApplication Application { get; protected set; } /// public string AppId { get; protected set; } /// public ClaimsPrincipal BackofficeUser { get; protected set; } /// public bool IsBackofficeRequest { get; protected set; } /// public IZeroOptions Options { get; protected set; } /// public IRoute Route { get; private set; } /// public IResolvedRoute ResolvedRoute { get; private set; } /// public IZeroStore Store { get; private set; } protected IApplicationResolver AppResolver { get; private set; } protected ICultureResolver CultureResolver { get; private set; } protected ILogger Logger { get; private set; } private bool _resolved = false; public ZeroContext(IZeroOptions options, IApplicationResolver appResolver, ICultureResolver cultureResolver, ILogger logger, IZeroStore store) { Options = options; AppResolver = appResolver; CultureResolver = cultureResolver; Logger = logger; Store = store; } /// public async virtual Task Resolve(HttpContext context) { if (_resolved) { return; } if (context?.Request is null) { Store.ResolvedDatabase = null; return; } if (!Options.SetupCompleted) { return; } _resolved = true; // check if the current request is a backoffice request IsBackofficeRequest = context.IsBackofficeRequest(Options.BackofficePath); // get the currently logged-in backoffice user BackofficeUser = new ClaimsPrincipal(); AuthenticateResult authResult = await context.AuthenticateAsync(Constants.Auth.BackofficeScheme); if (authResult?.Principal is not null) { BackofficeUser = authResult.Principal; } // resolve current application Application = await AppResolver.Resolve(context, BackofficeUser); AppId = Application.Id; // set default database for document store Store.ResolvedDatabase = Application.Database; // set current culture await CultureResolver.Resolve(this); // resolve request route if (IsBackofficeRequest is false && context.Request.RouteValues.TryGetValue("zero.route", out object route)) { ResolvedRoute = (IResolvedRoute)route; Route = ResolvedRoute.Route; } } } public interface IZeroContext { /// /// Currently loaded application /// IApplication Application { get; } /// /// Current loaded application Id /// string AppId { get; } /// /// Resolved backoffice user principal /// ClaimsPrincipal BackofficeUser { get; } /// /// Whether the current request is a backoffice request or not /// bool IsBackofficeRequest { get; } /// /// Global zero options /// IZeroOptions Options { get; } /// /// Document store /// IZeroStore Store { get; } /// /// Matching (frontend) path route /// IRoute Route { get; } /// /// Matching (frontend) resolved route /// IResolvedRoute ResolvedRoute { get; } /// /// Resolves the current application (for backoffice + frontend requests) and /// the currently active backoffice user, as users are not signed in with the default scheme and do therefore not populate HttpContext.User /// Task Resolve(HttpContext context); } }