BaseIdentityContext.cs

113 lines | 3.627 kB Blame History Raw Download
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;

using IdentityServer4.EntityFramework.Entities;
using IdentityServer4.EntityFramework.Extensions;
using IdentityServer4.EntityFramework.Interfaces;
using IdentityServer4.EntityFramework.Options;


using Tools.Identity.EF.Entities;

namespace Tools.Identity.EF
{

#warning Подходит только для Identity Server 3.*

    /// <summary>
    /// Database abstraction for a combined <see cref="DbContext"/> using ASP.NET Identity and Identity Server.
    /// Данный контекст используется для работы Identity и IndetityServer
    /// </summary>
    /// <typeparam name="TUser"></typeparam>
    /// <typeparam name="TRole"></typeparam>
    /// <typeparam name="TKey">Key of the IdentityUser entity</typeparam>
    public class BaseIdentityContext<TKey, TUser, TRole, TUserRole>
        :
        IdentityDbContext<
            TUser, 
            TRole, 
            TKey,
            IdentityUserClaim<TKey>, 
            BaseUserRole<TKey, TUser, TRole>, 
            IdentityUserLogin<TKey>,        
            IdentityRoleClaim<TKey>,       
            IdentityUserToken<TKey>
            >,
        IPersistedGrantDbContext

        where TKey : IEquatable<TKey>
        where TUser : BaseUser<TKey, TUser, TRole>
        where TRole : BaseRole<TKey, TUser, TRole>
        where TUserRole : BaseUserRole<TKey, TUser, TRole>

    {
        private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;


        /// <summary>
        /// Initializes a new instance of <see cref="ApiAuthorizationDbContext{TUser, TRole, TKey}"/>.
        /// </summary>
        /// <param name="options">The <see cref="DbContextOptions"/>.</param>
        /// <param name="operationalStoreOptions">The <see cref="IOptions{OperationalStoreOptions}"/>.</param>
        public BaseIdentityContext
        (
            DbContextOptions options,
            IOptions<OperationalStoreOptions> operationalStoreOptions
        )
            : base(options)
        {
            _operationalStoreOptions = operationalStoreOptions;
        }


        #region IPersistedGrantDbContext

        /// <summary>
        /// Gets or sets the <see cref="DbSet{PersistedGrant}"/>.
        /// </summary>
        public DbSet<PersistedGrant> PersistedGrants { get; set; }

        /// <summary>
        /// Gets or sets the <see cref="DbSet{DeviceFlowCodes}"/>.
        /// </summary>
        public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }

        Task<int> IPersistedGrantDbContext.SaveChangesAsync() 
            => base.SaveChangesAsync();

        #endregion

        /// <inheritdoc />
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder
                .ConfigurePersistedGrantContext(_operationalStoreOptions.Value);

            //builder.Entity<UserRole<TKey, TUser, TRole>>()
            //    .HasKey(t => new { t.UserId, t.RoleId });

            builder.Entity<BaseUserRole<TKey, TUser, TRole>>()
                .HasOne(sc => sc.User)
                .WithMany(s => s.Roles)
                .HasForeignKey(sc => sc.UserId)
                .IsRequired();

            builder.Entity<BaseUserRole<TKey, TUser, TRole>>()
                .HasOne(sc => sc.Role)
                .WithMany(c => c.Users)
                .HasForeignKey(sc => sc.RoleId)
                .IsRequired();
        }
    }

}