// using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using System.Security.Claims; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using PhoneToolMX.Models; using System.Net.NetworkInformation; // ReSharper disable CheckNamespace // ReSharper disable UnusedAutoPropertyAccessor.Global namespace PhoneToolMX.Data { public class PTMXContext : DbContext { public DbSet Phones { get; set; } public DbSet PhoneModels { get; set; } public DbSet Extensions { get; set; } public DbSet CustomData { get; set; } public DbSet Users { get; set; } public PTMXContext(DbContextOptions options) : base(options) { } #region Public helpers /// /// Adds an entity to the database, marking the given as its owner. /// /// The that owns this entity. /// The entity to be created. /// A model conforming to . /// The entity entry for the created entity. public async Task> AddOwnable(User owner, TEntity entity) where TEntity: OwnedBase { var set = Set(); entity.Owners ??= new List(); entity.Owners.Add(owner); var entry = await AddAsync(entity); return entry; } /// /// Gets all entities of a certain model owned by the . /// /// The object to be considered the owner. /// A model conforming to /// All entities of the model owned by the given user public ICollection GetOwned(User owner) where TEntity : class, IOwnedModel { if (owner == null) return null; var entity = Set().Where(x => x.Owners.Any(o => o.Id == owner.Id)); // eager load all w/ AlwaysInclude entity = typeof(TEntity).GetProperties() .Where(p => p.GetCustomAttributes(typeof(AlwaysIncludeAttribute), true) .Length != 0) .Aggregate(entity, (current, prop) => current.Include(prop.Name)); return entity.ToList(); } /// /// Gets a model entity by its Id /// /// Id of the model, or null if you're like that /// A model confirming to that has a given DbSet /// The model defined by the Id, or null if none exist. /// If null is provided as the id, null will be returned. id is nullable solely for compatibility. /// public TEntity GetEntityById(int? id) where TEntity : class, IModel { return id == null ? null : Set().FirstOrDefault(o => o.Id == id); } #endregion protected override void OnModelCreating(ModelBuilder modelBuilder) { // Core of PTMX: Phones and extensions var ext = modelBuilder.Entity(); ext.HasKey(x => x.Id); ext.Property(x => x.Id).UseIdentityColumn(); ext.Property(x => x.ExtId).HasComputedColumnSql("\"Id\" + 1000", stored: true); ext .Property(p => p.Password) .HasDefaultValueSql("encode(gen_random_bytes(18), 'base64')"); var phone = modelBuilder.Entity(); phone .HasMany(p => p.Extensions) .WithMany(x => x.Phones); phone.HasKey(p => p.Id); phone.Property(p => p.Id).UseIdentityColumn(); // Randomly generates a 24-char password // Wallpapers, ringtones, etc var cd = modelBuilder.Entity(); cd.HasKey(c => c.Id); cd.Property(c => c.Id).UseIdentityColumn(); // Phone models, for custom tests var pm = modelBuilder.Entity(); pm.HasKey(p => p.Id); pm.Property(p => p.Id).UseIdentityColumn(); pm.HasData(new PhoneModel { Id = 0, ModelName = "Polycom VVX300/310", MaxExtensions = 6, PreVvxPolycom = false, }); // Authz/RBAC var userEnt = modelBuilder.Entity(); userEnt .HasMany(u => u.Phones) .WithMany(p => p.Owners); userEnt .HasMany(u => u.Extensions) .WithMany(x => x.Owners); userEnt .HasKey(u => u.Id); modelBuilder.Entity() .HasKey(r => r.Id); } } }