Skip to content
This repository has been archived by the owner on Dec 20, 2018. It is now read-only.

Add Generic arguments for IdentityUser and UserStore #643

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 139 additions & 16 deletions src/Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Infrastructure;
using Microsoft.Data.Entity.Metadata;
using Microsoft.Data.Entity.Metadata.Builders;

namespace Microsoft.AspNet.Identity.EntityFramework
{
Expand All @@ -26,7 +27,7 @@ public class IdentityDbContext<TUser> : IdentityDbContext<TUser, IdentityRole, s
/// <typeparam name="TUser">The type of user objects.</typeparam>
/// <typeparam name="TRole">The type of role objects.</typeparam>
/// <typeparam name="TKey">The type of the primary key for users and roles.</typeparam>
public class IdentityDbContext<TUser, TRole, TKey> : DbContext
public class IdentityDbContext<TUser, TRole, TKey> : IdentityDbContext<TUser, TRole, TKey, IdentityUserClaim<TKey>, IdentityUserRole<TKey>, IdentityUserLogin<TKey>, IdentityRoleClaim<TKey>>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
Expand Down Expand Up @@ -65,6 +66,89 @@ public IdentityDbContext(IServiceProvider serviceProvider, DbContextOptions opti
protected IdentityDbContext()
{

}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call these methods something more like CreateXyzModel instead of OnBuild since these are called from OnModelCreating?

protected override void OnBuildUser(EntityTypeBuilder<TUser> builder)
{
}

protected override void OnBuildRole(EntityTypeBuilder<TRole> builder)
{
}

protected override void OnBuildUserClaim(EntityTypeBuilder<IdentityUserClaim<TKey>> builder)
{
builder.HasKey(uc => uc.Id);
}

protected override void OnBuildRoleClaim(EntityTypeBuilder<IdentityRoleClaim<TKey>> builder)
{
builder.HasKey(rc => rc.Id);
}

protected override void OnBuildUserRole(EntityTypeBuilder<IdentityUserRole<TKey>> builder)
{
builder.HasKey(r => new { r.UserId, r.RoleId });
}

protected override void OnBuildUserLogin(EntityTypeBuilder<IdentityUserLogin<TKey>> builder)
{
builder.HasKey(l => new { l.LoginProvider, l.ProviderKey });
}
}

/// <summary>
/// Base class for the Entity Framework database context used for identity.
/// </summary>
/// <typeparam name="TUser">The type of user objects.</typeparam>
/// <typeparam name="TRole">The type of role objects.</typeparam>
/// <typeparam name="TKey">The type of the primary key for users and roles.</typeparam>
/// <typeparam name="TUserClaim">The type of the user claim object.</typeparam>
/// <typeparam name="TUserRole">The type of the user role object.</typeparam>
/// <typeparam name="TUserLogin">The type of the user login object.</typeparam>
/// <typeparam name="TRoleClaim">The type of the role claim object.</typeparam>
public abstract class IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim> : DbContext
where TUser : IdentityUser<TKey, TUserClaim, TUserRole, TUserLogin>
where TRole : IdentityRole<TKey, TUserRole, TRoleClaim>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim: IdentityRoleClaim<TKey>
{
/// <summary>
/// Initializes a new instance of <see cref="IdentityDbContext"/>.
/// </summary>
/// <param name="options">The options to be used by a <see cref="DbContext"/>.</param>
public IdentityDbContext(DbContextOptions options) : base(options)
{

}

/// <summary>
/// Initializes a new instance of the <see cref="IdentityDbContext" /> class using an <see cref="IServiceProvider" />.
/// </summary>
/// <param name="serviceProvider"> The service provider to be used.</param>
public IdentityDbContext(IServiceProvider serviceProvider) : base(serviceProvider)
{

}

/// <summary>
/// Initializes a new instance of the <see cref="IdentityDbContext" /> class using an <see cref="IServiceProvider" />.
/// </summary>
/// <param name="options">The options to be used by a <see cref="DbContext"/>.</param>
/// <param name="serviceProvider"> The service provider to be used.</param>
public IdentityDbContext(IServiceProvider serviceProvider, DbContextOptions options) : base(serviceProvider, options)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="IdentityDbContext" /> class.
/// </summary>
protected IdentityDbContext()
{

}

/// <summary>
Expand All @@ -75,17 +159,17 @@ protected IdentityDbContext()
/// <summary>
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User claims.
/// </summary>
public DbSet<IdentityUserClaim<TKey>> UserClaims { get; set; }
public DbSet<TUserClaim> UserClaims { get; set; }

/// <summary>
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User logins.
/// </summary>
public DbSet<IdentityUserLogin<TKey>> UserLogins { get; set; }
public DbSet<TUserLogin> UserLogins { get; set; }

/// <summary>
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User roles.
/// </summary>
public DbSet<IdentityUserRole<TKey>> UserRoles { get; set; }
public DbSet<TUserRole> UserRoles { get; set; }

/// <summary>
/// Gets or sets the <see cref="DbSet{TEntity}"/> of roles.
Expand All @@ -95,14 +179,12 @@ protected IdentityDbContext()
/// <summary>
/// Gets or sets the <see cref="DbSet{TEntity}"/> of role claims.
/// </summary>
public DbSet<IdentityRoleClaim<TKey>> RoleClaims { get; set; }
public DbSet<TRoleClaim> RoleClaims { get; set; }

/// <summary>
/// Configures the schema needed for the identity framework.
/// </summary>
/// <param name="builder">
/// The builder being used to construct the model for this context.
/// </param>
/// <param name="builder">The builder being used to construct the model for this context.</param>
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<TUser>(b =>
Expand All @@ -117,9 +199,12 @@ protected override void OnModelCreating(ModelBuilder builder)
b.Property(u => u.NormalizedUserName).HasMaxLength(256);
b.Property(u => u.Email).HasMaxLength(256);
b.Property(u => u.NormalizedEmail).HasMaxLength(256);

b.HasMany(u => u.Claims).WithOne().HasForeignKey(uc => uc.UserId).IsRequired();
b.HasMany(u => u.Logins).WithOne().HasForeignKey(ul => ul.UserId).IsRequired();
b.HasMany(u => u.Roles).WithOne().HasForeignKey(ur => ur.UserId).IsRequired();

OnBuildUser(b);
});

builder.Entity<TRole>(b =>
Expand All @@ -134,31 +219,69 @@ protected override void OnModelCreating(ModelBuilder builder)

b.HasMany(r => r.Users).WithOne().HasForeignKey(ur => ur.RoleId).IsRequired();
b.HasMany(r => r.Claims).WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();

OnBuildRole(b);
});

builder.Entity<IdentityUserClaim<TKey>>(b =>
builder.Entity<TUserClaim>(b =>
{
b.HasKey(uc => uc.Id);
b.ToTable("AspNetUserClaims");
OnBuildUserClaim(b);
});

builder.Entity<IdentityRoleClaim<TKey>>(b =>
builder.Entity<TRoleClaim>(b =>
{
b.HasKey(rc => rc.Id);
b.ToTable("AspNetRoleClaims");
OnBuildRoleClaim(b);
});

builder.Entity<IdentityUserRole<TKey>>(b =>
builder.Entity<TUserRole>(b =>
{
b.HasKey(r => new { r.UserId, r.RoleId });
b.ToTable("AspNetUserRoles");
OnBuildUserRole(b);
});

builder.Entity<IdentityUserLogin<TKey>>(b =>
builder.Entity<TUserLogin>(b =>
{
b.HasKey(l => new { l.LoginProvider, l.ProviderKey });
b.ToTable("AspNetUserLogins");
OnBuildUserLogin(b);
});
}

/// <summary>
/// Allow further customization of the <typeparamref name="TRole"/> schema
/// </summary>
/// <param name="builder">Entity type builder of <typeparamref name="TRole"/></param>
protected abstract void OnBuildRole(EntityTypeBuilder<TRole> builder);

/// <summary>
/// Allow further customization of the <typeparamref name="TUser"/> schema
/// </summary>
/// <param name="builder">Entity type builder of <typeparamref name="TUser"/></param>
protected abstract void OnBuildUser(EntityTypeBuilder<TUser> builder);

/// <summary>
/// Allow further customization of the <typeparamref name="TUserClaim"/> schema
/// </summary>
/// <param name="builder">Entity type builder of <typeparamref name="TUserClaim"/></param>
protected abstract void OnBuildUserClaim(EntityTypeBuilder<TUserClaim> builder);

/// <summary>
/// Allow further customization of the <typeparamref name="TRoleClaim"/> schema
/// </summary>
/// <param name="builder">Entity type builder of <typeparamref name="TRoleClaim"/></param>
protected abstract void OnBuildRoleClaim(EntityTypeBuilder<TRoleClaim> builder);

/// <summary>
/// Allow further customization of the <typeparamref name="TUserRole"/> schema
/// </summary>
/// <param name="builder">Entity type builder of <typeparamref name="TUserRole"/></param>
protected abstract void OnBuildUserRole(EntityTypeBuilder<TUserRole> builder);

/// <summary>
/// Allow further customization of the <typeparamref name="TUserLogin"/> schema
/// </summary>
/// <param name="builder">Entity type builder of <typeparamref name="TUserLogin"/></param>
protected abstract void OnBuildUserLogin(EntityTypeBuilder<TUserLogin> builder);
}
}
14 changes: 11 additions & 3 deletions src/Microsoft.AspNet.Identity.EntityFramework/IdentityRole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@ public IdentityRole(string roleName) : this()
/// Represents a role in the identity system
/// </summary>
/// <typeparam name="TKey">The type used for the primary key for the role.</typeparam>
public class IdentityRole<TKey> where TKey : IEquatable<TKey>
public class IdentityRole<TKey> : IdentityRole<TKey, IdentityUserRole<TKey>, IdentityRoleClaim<TKey>>
where TKey : IEquatable<TKey>
{
}

public class IdentityRole<TKey, TUserRole, TRoleClaim>
where TKey : IEquatable<TKey>
where TUserRole: IdentityUserRole<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
{
/// <summary>
/// Initializes a new instance of <see cref="IdentityRole{TKey}"/>.
Expand All @@ -58,12 +66,12 @@ public IdentityRole(string roleName) : this()
/// <summary>
/// Navigation property for the users in this role.
/// </summary>
public virtual ICollection<IdentityUserRole<TKey>> Users { get; } = new List<IdentityUserRole<TKey>>();
public virtual ICollection<TUserRole> Users { get; } = new List<TUserRole>();

/// <summary>
/// Navigation property for claims in this role.
/// </summary>
public virtual ICollection<IdentityRoleClaim<TKey>> Claims { get; } = new List<IdentityRoleClaim<TKey>>();
public virtual ICollection<TRoleClaim> Claims { get; } = new List<TRoleClaim>();

/// <summary>
/// Gets or sets the primary key for this role.
Expand Down
12 changes: 12 additions & 0 deletions src/Microsoft.AspNet.Identity.EntityFramework/IdentityRoleClaim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,17 @@ public class IdentityRoleClaim<TKey> where TKey : IEquatable<TKey>
/// Gets or sets the claim value for this claim.
/// </summary>
public virtual string ClaimValue { get; set; }

public virtual System.Security.Claims.Claim ToClaim()
{
return new System.Security.Claims.Claim(this.ClaimType, this.ClaimValue);
}

public virtual void FromClaim(TKey roleId, System.Security.Claims.Claim other)
{
this.ClaimType = other.Type;
this.ClaimValue = other.Value;
this.RoleId = roleId;
}
}
}
22 changes: 18 additions & 4 deletions src/Microsoft.AspNet.Identity.EntityFramework/IdentityUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,21 @@ public IdentityUser(string userName) : this()
/// Represents a user in the identity system
/// </summary>
/// <typeparam name="TKey">The type used for the primary key for the user.</typeparam>
public class IdentityUser<TKey> where TKey : IEquatable<TKey>
public class IdentityUser<TKey> : IdentityUser<TKey, IdentityUserClaim<TKey>, IdentityUserRole<TKey>, IdentityUserLogin<TKey>>

where TKey : IEquatable<TKey>
{

}

/// <summary>
/// Represents a user in the identity system
/// </summary>
/// <typeparam name="TKey">The type used for the primary key for the user.</typeparam>
/// <typeparam name="TClaim">The type representing a claim.</typeparam>
/// <typeparam name="TRole">The type representing a user role.</typeparam>
/// <typeparam name="TLogin">The type representing a user external login.</typeparam>
public class IdentityUser<TKey, TClaim, TRole, TLogin> where TKey : IEquatable<TKey>
{
/// <summary>
/// Initializes a new instance of <see cref="IdentityUser{TKey}"/>.
Expand Down Expand Up @@ -140,17 +154,17 @@ public IdentityUser(string userName) : this()
/// <summary>
/// Navigation property for the roles this user belongs to.
/// </summary>
public virtual ICollection<IdentityUserRole<TKey>> Roles { get; } = new List<IdentityUserRole<TKey>>();
public virtual ICollection<TRole> Roles { get; } = new List<TRole>();

/// <summary>
/// Navigation property for the claims this user possesses.
/// </summary>
public virtual ICollection<IdentityUserClaim<TKey>> Claims { get; } = new List<IdentityUserClaim<TKey>>();
public virtual ICollection<TClaim> Claims { get; } = new List<TClaim>();

/// <summary>
/// Navigation property for this users login accounts.
/// </summary>
public virtual ICollection<IdentityUserLogin<TKey>> Logins { get; } = new List<IdentityUserLogin<TKey>>();
public virtual ICollection<TLogin> Logins { get; } = new List<TLogin>();

/// <summary>
/// Returns the username for this user.
Expand Down
11 changes: 11 additions & 0 deletions src/Microsoft.AspNet.Identity.EntityFramework/IdentityUserClaim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,16 @@ public class IdentityUserClaim<TKey> where TKey : IEquatable<TKey>
/// Gets or sets the claim value for this claim.
/// </summary>
public virtual string ClaimValue { get; set; }

public virtual System.Security.Claims.Claim ToClaim()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include the namespace instead of fully qualifying

{
return new System.Security.Claims.Claim(this.ClaimType, this.ClaimValue);
}

public virtual void FromClaim(System.Security.Claims.Claim other)
{
this.ClaimType = other.Type;
this.ClaimValue = other.Value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,10 @@ public class IdentityUserLogin<TKey> where TKey : IEquatable<TKey>
/// Gets or sets the of the primary key of the user associated with this login.
/// </summary>
public virtual TKey UserId { get; set; }

public virtual UserLoginInfo ToUserLogin()
{
return new UserLoginInfo(this.LoginProvider, this.ProviderKey, this.ProviderDisplayName);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this.

}
}
}
Loading