using System; using System.Threading.Tasks; using Microsoft.Owin; using Microsoft.Owin.Security.DataProtection; namespace Umbraco.Web.Security { /// /// Adapted from Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware /// public class IdentityFactoryMiddleware : OwinMiddleware where TResult : class, IDisposable where TOptions : IdentityFactoryOptions { /// /// Constructor /// /// The next middleware in the OWIN pipeline to invoke /// Configuration options for the middleware public IdentityFactoryMiddleware(OwinMiddleware next, TOptions options) : base(next) { if (options == null) { throw new ArgumentNullException("options"); } if (options.Provider == null) { throw new ArgumentNullException("options.Provider"); } Options = options; } /// /// Configuration options /// public TOptions Options { get; private set; } /// /// Create an object using the Options.Provider, storing it in the OwinContext and then disposes the object when finished /// /// /// public override async Task Invoke(IOwinContext context) { var instance = Options.Provider.Create(Options, context); try { context.Set(instance); if (Next != null) { await Next.Invoke(context); } } finally { Options.Provider.Dispose(Options, instance); } } } public class IdentityFactoryOptions where T : class, IDisposable { /// /// Used to configure the data protection provider /// public IDataProtectionProvider DataProtectionProvider { get; set; } /// /// Provider used to Create and Dispose objects /// public IdentityFactoryProvider Provider { get; set; } } public class IdentityFactoryProvider where T : class, IDisposable { /// /// Constructor /// public IdentityFactoryProvider() { OnDispose = (options, instance) => { }; OnCreate = (options, context) => null; } /// /// A delegate assigned to this property will be invoked when the related method is called /// public Func, IOwinContext, T> OnCreate { get; set; } /// /// A delegate assigned to this property will be invoked when the related method is called /// public Action, T> OnDispose { get; set; } /// /// Calls the OnCreate Delegate /// /// /// /// public virtual T Create(IdentityFactoryOptions options, IOwinContext context) { return OnCreate(options, context); } /// /// Calls the OnDispose delegate /// /// /// public virtual void Dispose(IdentityFactoryOptions options, T instance) { OnDispose(options, instance); } } }