Restore support for EF User store generics
This commit is contained in:
parent
6b6b21a5bf
commit
104f216191
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:28248/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNET_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
{
|
{
|
||||||
|
|
@ -52,7 +51,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// <typeparam name="TUser">The type of user objects.</typeparam>
|
/// <typeparam name="TUser">The type of user objects.</typeparam>
|
||||||
/// <typeparam name="TRole">The type of role 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="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>, IdentityUserToken<TKey>>
|
||||||
where TUser : IdentityUser<TKey>
|
where TUser : IdentityUser<TKey>
|
||||||
where TRole : IdentityRole<TKey>
|
where TRole : IdentityRole<TKey>
|
||||||
where TKey : IEquatable<TKey>
|
where TKey : IEquatable<TKey>
|
||||||
|
|
@ -69,6 +68,41 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IdentityDbContext()
|
protected IdentityDbContext()
|
||||||
{ }
|
{ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
/// <typeparam name="TUserToken">The type of the user token object.</typeparam>
|
||||||
|
public abstract class IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> : 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>
|
||||||
|
where TUserToken : IdentityUserToken<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.
|
||||||
|
/// </summary>
|
||||||
|
protected IdentityDbContext()
|
||||||
|
{ }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of Users.
|
/// Gets or sets the <see cref="DbSet{TEntity}"/> of Users.
|
||||||
|
|
@ -78,22 +112,22 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User claims.
|
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User claims.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<IdentityUserClaim<TKey>> UserClaims { get; set; }
|
public DbSet<TUserClaim> UserClaims { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User logins.
|
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User logins.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<IdentityUserLogin<TKey>> UserLogins { get; set; }
|
public DbSet<TUserLogin> UserLogins { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User roles.
|
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User roles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<IdentityUserRole<TKey>> UserRoles { get; set; }
|
public DbSet<TUserRole> UserRoles { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User tokens.
|
/// Gets or sets the <see cref="DbSet{TEntity}"/> of User tokens.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<IdentityUserToken<TKey>> UserTokens { get; set; }
|
public DbSet<TUserToken> UserTokens { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of roles.
|
/// Gets or sets the <see cref="DbSet{TEntity}"/> of roles.
|
||||||
|
|
@ -103,7 +137,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="DbSet{TEntity}"/> of role claims.
|
/// Gets or sets the <see cref="DbSet{TEntity}"/> of role claims.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<IdentityRoleClaim<TKey>> RoleClaims { get; set; }
|
public DbSet<TRoleClaim> RoleClaims { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configures the schema needed for the identity framework.
|
/// Configures the schema needed for the identity framework.
|
||||||
|
|
@ -144,31 +178,31 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
b.HasMany(r => r.Claims).WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();
|
b.HasMany(r => r.Claims).WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Entity<IdentityUserClaim<TKey>>(b =>
|
builder.Entity<TUserClaim>(b =>
|
||||||
{
|
{
|
||||||
b.HasKey(uc => uc.Id);
|
b.HasKey(uc => uc.Id);
|
||||||
b.ToTable("AspNetUserClaims");
|
b.ToTable("AspNetUserClaims");
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Entity<IdentityRoleClaim<TKey>>(b =>
|
builder.Entity<TRoleClaim>(b =>
|
||||||
{
|
{
|
||||||
b.HasKey(rc => rc.Id);
|
b.HasKey(rc => rc.Id);
|
||||||
b.ToTable("AspNetRoleClaims");
|
b.ToTable("AspNetRoleClaims");
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Entity<IdentityUserRole<TKey>>(b =>
|
builder.Entity<TUserRole>(b =>
|
||||||
{
|
{
|
||||||
b.HasKey(r => new { r.UserId, r.RoleId });
|
b.HasKey(r => new { r.UserId, r.RoleId });
|
||||||
b.ToTable("AspNetUserRoles");
|
b.ToTable("AspNetUserRoles");
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Entity<IdentityUserLogin<TKey>>(b =>
|
builder.Entity<TUserLogin>(b =>
|
||||||
{
|
{
|
||||||
b.HasKey(l => new { l.LoginProvider, l.ProviderKey });
|
b.HasKey(l => new { l.LoginProvider, l.ProviderKey });
|
||||||
b.ToTable("AspNetUserLogins");
|
b.ToTable("AspNetUserLogins");
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Entity<IdentityUserToken<TKey>>(b =>
|
builder.Entity<TUserToken>(b =>
|
||||||
{
|
{
|
||||||
b.HasKey(l => new { l.UserId, l.LoginProvider, l.Name });
|
b.HasKey(l => new { l.UserId, l.LoginProvider, l.Name });
|
||||||
b.ToTable("AspNetUserTokens");
|
b.ToTable("AspNetUserTokens");
|
||||||
|
|
|
||||||
|
|
@ -43,16 +43,9 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
{
|
{
|
||||||
Type userStoreType;
|
Type userStoreType;
|
||||||
Type roleStoreType;
|
Type roleStoreType;
|
||||||
if (keyType != null)
|
keyType = keyType ?? typeof(string);
|
||||||
{
|
userStoreType = typeof(UserStore<,,,>).MakeGenericType(userType, roleType, contextType, keyType);
|
||||||
userStoreType = typeof(UserStore<,,,>).MakeGenericType(userType, roleType, contextType, keyType);
|
roleStoreType = typeof(RoleStore<,,>).MakeGenericType(roleType, contextType, keyType);
|
||||||
roleStoreType = typeof(RoleStore<,,>).MakeGenericType(roleType, contextType, keyType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
userStoreType = typeof(UserStore<,,>).MakeGenericType(userType, roleType, contextType);
|
|
||||||
roleStoreType = typeof(RoleStore<,>).MakeGenericType(roleType, contextType);
|
|
||||||
}
|
|
||||||
|
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.AddScoped(
|
services.AddScoped(
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,21 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// Represents a role in the identity system
|
/// Represents a role in the identity system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TKey">The type used for the primary key for the role.</typeparam>
|
/// <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>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a role in the identity system
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TKey">The type used for the primary key for the role.</typeparam>
|
||||||
|
/// <typeparam name="TUserRole">The type used for user roles.</typeparam>
|
||||||
|
/// <typeparam name="TRoleClaim">The type used for role claims.</typeparam>
|
||||||
|
public class IdentityRole<TKey, TUserRole, TRoleClaim>
|
||||||
|
where TKey : IEquatable<TKey>
|
||||||
|
where TUserRole : IdentityUserRole<TKey>
|
||||||
|
where TRoleClaim : IdentityRoleClaim<TKey>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of <see cref="IdentityRole{TKey}"/>.
|
/// Initializes a new instance of <see cref="IdentityRole{TKey}"/>.
|
||||||
|
|
@ -58,12 +72,12 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Navigation property for the users in this role.
|
/// Navigation property for the users in this role.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual ICollection<IdentityUserRole<TKey>> Users { get; } = new List<IdentityUserRole<TKey>>();
|
public virtual ICollection<TUserRole> Users { get; } = new List<TUserRole>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Navigation property for claims in this role.
|
/// Navigation property for claims in this role.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual ICollection<IdentityRoleClaim<TKey>> Claims { get; } = new List<IdentityRoleClaim<TKey>>();
|
public virtual ICollection<TRoleClaim> Claims { get; } = new List<TRoleClaim>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the primary key for this role.
|
/// Gets or sets the primary key for this role.
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
{
|
{
|
||||||
|
|
@ -30,5 +31,16 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// Gets or sets the claim value for this claim.
|
/// Gets or sets the claim value for this claim.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual string ClaimValue { get; set; }
|
public virtual string ClaimValue { get; set; }
|
||||||
|
|
||||||
|
public virtual Claim ToClaim()
|
||||||
|
{
|
||||||
|
return new Claim(ClaimType, ClaimValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void InitializeFromClaim(Claim other)
|
||||||
|
{
|
||||||
|
ClaimType = other?.Type;
|
||||||
|
ClaimValue = other?.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,18 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// Represents a user in the identity system
|
/// Represents a user in the identity system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TKey">The type used for the primary key for the user.</typeparam>
|
/// <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="TUserClaim">The type representing a claim.</typeparam>
|
||||||
|
/// <typeparam name="TUserRole">The type representing a user role.</typeparam>
|
||||||
|
/// <typeparam name="TUserLogin">The type representing a user external login.</typeparam>
|
||||||
|
public class IdentityUser<TKey, TUserClaim, TUserRole, TUserLogin> where TKey : IEquatable<TKey>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of <see cref="IdentityUser{TKey}"/>.
|
/// Initializes a new instance of <see cref="IdentityUser{TKey}"/>.
|
||||||
|
|
@ -140,17 +151,17 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Navigation property for the roles this user belongs to.
|
/// Navigation property for the roles this user belongs to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual ICollection<IdentityUserRole<TKey>> Roles { get; } = new List<IdentityUserRole<TKey>>();
|
public virtual ICollection<TUserRole> Roles { get; } = new List<TUserRole>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Navigation property for the claims this user possesses.
|
/// Navigation property for the claims this user possesses.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual ICollection<IdentityUserClaim<TKey>> Claims { get; } = new List<IdentityUserClaim<TKey>>();
|
public virtual ICollection<TUserClaim> Claims { get; } = new List<TUserClaim>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Navigation property for this users login accounts.
|
/// Navigation property for this users login accounts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual ICollection<IdentityUserLogin<TKey>> Logins { get; } = new List<IdentityUserLogin<TKey>>();
|
public virtual ICollection<TUserLogin> Logins { get; } = new List<TUserLogin>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the username for this user.
|
/// Returns the username for this user.
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
{
|
{
|
||||||
|
|
@ -30,5 +31,24 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// Gets or sets the claim value for this claim.
|
/// Gets or sets the claim value for this claim.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual string ClaimValue { get; set; }
|
public virtual string ClaimValue { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the entity into a Claim instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual Claim ToClaim()
|
||||||
|
{
|
||||||
|
return new Claim(ClaimType, ClaimValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads the type and value from the Claim.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="claim"></param>
|
||||||
|
public virtual void InitializeFromClaim(Claim claim)
|
||||||
|
{
|
||||||
|
ClaimType = claim.Type;
|
||||||
|
ClaimValue = claim.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,12 +40,39 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// <typeparam name="TRole">The type of the class representing a role.</typeparam>
|
/// <typeparam name="TRole">The type of the class representing a role.</typeparam>
|
||||||
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam>
|
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam>
|
||||||
/// <typeparam name="TKey">The type of the primary key for a role.</typeparam>
|
/// <typeparam name="TKey">The type of the primary key for a role.</typeparam>
|
||||||
public class RoleStore<TRole, TContext, TKey> :
|
public class RoleStore<TRole, TContext, TKey> : RoleStore<TRole, TContext, TKey, IdentityUserRole<TKey>, IdentityRoleClaim<TKey>>,
|
||||||
IQueryableRoleStore<TRole>,
|
IQueryableRoleStore<TRole>,
|
||||||
IRoleClaimStore<TRole>
|
IRoleClaimStore<TRole>
|
||||||
where TRole : IdentityRole<TKey>
|
where TRole : IdentityRole<TKey>
|
||||||
where TKey : IEquatable<TKey>
|
where TKey : IEquatable<TKey>
|
||||||
where TContext : DbContext
|
where TContext : DbContext
|
||||||
|
{
|
||||||
|
public RoleStore(TContext context, IdentityErrorDescriber describer = null) : base(context, describer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityRoleClaim<TKey> CreateRoleClaim(TRole role, Claim claim)
|
||||||
|
{
|
||||||
|
return new IdentityRoleClaim<TKey> { RoleId = role.Id, ClaimType = claim.Type, ClaimValue = claim.Value };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of a persistence store for roles.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TRole">The type of the class representing a role.</typeparam>
|
||||||
|
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam>
|
||||||
|
/// <typeparam name="TKey">The type of the primary key for a role.</typeparam>
|
||||||
|
/// <typeparam name="TUserRole">The type of the class representing a user role.</typeparam>
|
||||||
|
/// <typeparam name="TRoleClaim">The type of the class representing a role claim.</typeparam>
|
||||||
|
public abstract class RoleStore<TRole, TContext, TKey, TUserRole, TRoleClaim> :
|
||||||
|
IQueryableRoleStore<TRole>,
|
||||||
|
IRoleClaimStore<TRole>
|
||||||
|
where TRole : IdentityRole<TKey, TUserRole, TRoleClaim>
|
||||||
|
where TKey : IEquatable<TKey>
|
||||||
|
where TContext : DbContext
|
||||||
|
where TUserRole : IdentityUserRole<TKey>
|
||||||
|
where TRoleClaim : IdentityRoleClaim<TKey>
|
||||||
{
|
{
|
||||||
public RoleStore(TContext context, IdentityErrorDescriber describer = null)
|
public RoleStore(TContext context, IdentityErrorDescriber describer = null)
|
||||||
{
|
{
|
||||||
|
|
@ -358,8 +385,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
throw new ArgumentNullException(nameof(claim));
|
throw new ArgumentNullException(nameof(claim));
|
||||||
}
|
}
|
||||||
|
|
||||||
RoleClaims.Add(new IdentityRoleClaim<TKey> { RoleId = role.Id, ClaimType = claim.Type, ClaimValue = claim.Value });
|
RoleClaims.Add(CreateRoleClaim(role, claim));
|
||||||
|
|
||||||
return Task.FromResult(false);
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,6 +422,14 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
get { return Context.Set<TRole>(); }
|
get { return Context.Set<TRole>(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbSet<IdentityRoleClaim<TKey>> RoleClaims { get { return Context.Set<IdentityRoleClaim<TKey>>(); } }
|
private DbSet<TRoleClaim> RoleClaims { get { return Context.Set<TRoleClaim>(); } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a entity representing a role claim.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="role"></param>
|
||||||
|
/// <param name="claim"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract TRoleClaim CreateRoleClaim(TRole role, Claim claim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ using Microsoft.EntityFrameworkCore;
|
||||||
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of a persistence store for users, using the default implementation
|
/// Represents a new instance of a persistence store for users, using the default implementation
|
||||||
/// of <see cref="IdentityUser{TKey}"/> with a string as a primary key.
|
/// of <see cref="IdentityUser{TKey}"/> with a string as a primary key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UserStore : UserStore<IdentityUser<string>>
|
public class UserStore : UserStore<IdentityUser<string>>
|
||||||
|
|
@ -26,25 +26,78 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// Creates a new instance of a persistence store for the specified user type.
|
/// Creates a new instance of a persistence store for the specified user type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TUser">The type representing a user.</typeparam>
|
/// <typeparam name="TUser">The type representing a user.</typeparam>
|
||||||
public class UserStore<TUser> : UserStore<TUser, IdentityRole, DbContext>
|
public class UserStore<TUser> : UserStore<TUser, IdentityRole, DbContext, string>
|
||||||
where TUser : IdentityUser<string>, new()
|
where TUser : IdentityUser<string>, new()
|
||||||
{
|
{
|
||||||
public UserStore(DbContext context, IdentityErrorDescriber describer = null) : base(context, describer) { }
|
public UserStore(DbContext context, IdentityErrorDescriber describer = null) : base(context, describer) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of a persistence store for the specified user and role types.
|
/// Represents a new instance of a persistence store for the specified user and role types.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TUser">The type representing a user.</typeparam>
|
/// <typeparam name="TUser">The type representing a user.</typeparam>
|
||||||
/// <typeparam name="TRole">The type representing a role.</typeparam>
|
/// <typeparam name="TRole">The type representing a role.</typeparam>
|
||||||
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam>
|
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam>
|
||||||
public class UserStore<TUser, TRole, TContext> : UserStore<TUser, TRole, TContext, string>
|
public class UserStore<TUser, TRole, TContext> : UserStore<TUser, TRole, TContext, string>
|
||||||
where TUser : IdentityUser<string>, new()
|
where TUser : IdentityUser<string>
|
||||||
where TRole : IdentityRole<string>, new()
|
where TRole : IdentityRole<string>
|
||||||
where TContext : DbContext
|
where TContext : DbContext
|
||||||
{
|
{
|
||||||
public UserStore(TContext context, IdentityErrorDescriber describer = null) : base(context, describer) { }
|
public UserStore(TContext context, IdentityErrorDescriber describer = null) : base(context, describer) { }
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a new instance of a persistence store for the specified user and role types.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TUser">The type representing a user.</typeparam>
|
||||||
|
/// <typeparam name="TRole">The type representing a role.</typeparam>
|
||||||
|
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam>
|
||||||
|
/// <typeparam name="TKey">The type of the primary key for a role.</typeparam>
|
||||||
|
public class UserStore<TUser, TRole, TContext, TKey> : UserStore<TUser, TRole, TContext, TKey, IdentityUserClaim<TKey>, IdentityUserRole<TKey>, IdentityUserLogin<TKey>, IdentityUserToken<TKey>>
|
||||||
|
where TUser : IdentityUser<TKey>
|
||||||
|
where TRole : IdentityRole<TKey>
|
||||||
|
where TContext : DbContext
|
||||||
|
where TKey : IEquatable<TKey>
|
||||||
|
{
|
||||||
|
public UserStore(TContext context, IdentityErrorDescriber describer = null) : base(context, describer) { }
|
||||||
|
|
||||||
|
protected override IdentityUserRole<TKey> CreateUserRole(TUser user, TRole role)
|
||||||
|
{
|
||||||
|
return new IdentityUserRole<TKey>()
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
RoleId = role.Id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserClaim<TKey> CreateUserClaim(TUser user, Claim claim)
|
||||||
|
{
|
||||||
|
var userClaim = new IdentityUserClaim<TKey> { UserId = user.Id };
|
||||||
|
userClaim.InitializeFromClaim(claim);
|
||||||
|
return userClaim;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserLogin<TKey> CreateUserLogin(TUser user, UserLoginInfo login)
|
||||||
|
{
|
||||||
|
return new IdentityUserLogin<TKey>
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
ProviderKey = login.ProviderKey,
|
||||||
|
LoginProvider = login.LoginProvider,
|
||||||
|
ProviderDisplayName = login.ProviderDisplayName
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserToken<TKey> CreateUserToken(TUser user, string loginProvider, string name, string value)
|
||||||
|
{
|
||||||
|
return new IdentityUserToken<TKey>
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
LoginProvider = loginProvider,
|
||||||
|
Name = name,
|
||||||
|
Value = value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a new instance of a persistence store for the specified user and role types.
|
/// Represents a new instance of a persistence store for the specified user and role types.
|
||||||
|
|
@ -53,7 +106,11 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// <typeparam name="TRole">The type representing a role.</typeparam>
|
/// <typeparam name="TRole">The type representing a role.</typeparam>
|
||||||
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam>
|
/// <typeparam name="TContext">The type of the data context class used to access the store.</typeparam>
|
||||||
/// <typeparam name="TKey">The type of the primary key for a role.</typeparam>
|
/// <typeparam name="TKey">The type of the primary key for a role.</typeparam>
|
||||||
public class UserStore<TUser, TRole, TContext, TKey> :
|
/// <typeparam name="TUserClaim">The type representing a claim.</typeparam>
|
||||||
|
/// <typeparam name="TUserRole">The type representing a user role.</typeparam>
|
||||||
|
/// <typeparam name="TUserLogin">The type representing a user external login.</typeparam>
|
||||||
|
/// <typeparam name="TUserToken">The type representing a user token.</typeparam>
|
||||||
|
public abstract class UserStore<TUser, TRole, TContext, TKey, TUserClaim, TUserRole, TUserLogin, TUserToken> :
|
||||||
IUserLoginStore<TUser>,
|
IUserLoginStore<TUser>,
|
||||||
IUserRoleStore<TUser>,
|
IUserRoleStore<TUser>,
|
||||||
IUserClaimStore<TUser>,
|
IUserClaimStore<TUser>,
|
||||||
|
|
@ -65,12 +122,15 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
IQueryableUserStore<TUser>,
|
IQueryableUserStore<TUser>,
|
||||||
IUserTwoFactorStore<TUser>,
|
IUserTwoFactorStore<TUser>,
|
||||||
IUserAuthenticationTokenStore<TUser>
|
IUserAuthenticationTokenStore<TUser>
|
||||||
where TUser : IdentityUser<TKey>
|
where TUser : IdentityUser<TKey, TUserClaim, TUserRole, TUserLogin>
|
||||||
where TRole : IdentityRole<TKey>
|
where TRole : IdentityRole<TKey, TUserRole, IdentityRoleClaim<TKey>>
|
||||||
where TContext : DbContext
|
where TContext : DbContext
|
||||||
where TKey : IEquatable<TKey>
|
where TKey : IEquatable<TKey>
|
||||||
|
where TUserClaim : IdentityUserClaim<TKey>
|
||||||
|
where TUserRole : IdentityUserRole<TKey>
|
||||||
|
where TUserLogin : IdentityUserLogin<TKey>
|
||||||
|
where TUserToken : IdentityUserToken<TKey>
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of <see cref="UserStore"/>.
|
/// Creates a new instance of <see cref="UserStore"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -98,6 +158,46 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IdentityErrorDescriber ErrorDescriber { get; set; }
|
public IdentityErrorDescriber ErrorDescriber { get; set; }
|
||||||
|
|
||||||
|
private DbSet<TRole> Roles { get { return Context.Set<TRole>(); } }
|
||||||
|
private DbSet<TUserClaim> UserClaims { get { return Context.Set<TUserClaim>(); } }
|
||||||
|
private DbSet<TUserRole> UserRoles { get { return Context.Set<TUserRole>(); } }
|
||||||
|
private DbSet<TUserLogin> UserLogins { get { return Context.Set<TUserLogin>(); } }
|
||||||
|
private DbSet<TUserToken> UserTokens { get { return Context.Set<TUserToken>(); } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new entity to represent a user role.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <param name="role"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract TUserRole CreateUserRole(TUser user, TRole role);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new entity representing a user claim.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <param name="claim"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract TUserClaim CreateUserClaim(TUser user, Claim claim);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new entity representing a user login.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <param name="login"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract TUserLogin CreateUserLogin(TUser user, UserLoginInfo login);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new entity representing a user token.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <param name="loginProvider"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract TUserToken CreateUserToken(TUser user, string loginProvider, string name, string value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a flag indicating if changes should be persisted after CreateAsync, UpdateAsync and DeleteAsync are called.
|
/// Gets or sets a flag indicating if changes should be persisted after CreateAsync, UpdateAsync and DeleteAsync are called.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -109,7 +209,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
/// <summary>Saves the current store.</summary>
|
/// <summary>Saves the current store.</summary>
|
||||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
||||||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
||||||
private Task SaveChanges(CancellationToken cancellationToken)
|
protected Task SaveChanges(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return AutoSaveChanges ? Context.SaveChangesAsync(cancellationToken) : Task.FromResult(0);
|
return AutoSaveChanges ? Context.SaveChangesAsync(cancellationToken) : Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
@ -418,8 +518,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.RoleNotFound, normalizedRoleName));
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.RoleNotFound, normalizedRoleName));
|
||||||
}
|
}
|
||||||
var ur = new IdentityUserRole<TKey> { UserId = user.Id, RoleId = roleEntity.Id };
|
UserRoles.Add(CreateUserRole(user, roleEntity));
|
||||||
UserRoles.Add(ur);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -520,12 +619,6 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbSet<TRole> Roles { get { return Context.Set<TRole>(); } }
|
|
||||||
private DbSet<IdentityUserClaim<TKey>> UserClaims { get { return Context.Set<IdentityUserClaim<TKey>>(); } }
|
|
||||||
private DbSet<IdentityUserRole<TKey>> UserRoles { get { return Context.Set<IdentityUserRole<TKey>>(); } }
|
|
||||||
private DbSet<IdentityUserLogin<TKey>> UserLogins { get { return Context.Set<IdentityUserLogin<TKey>>(); } }
|
|
||||||
private DbSet<IdentityUserToken<TKey>> UserTokens { get { return Context.Set<IdentityUserToken<TKey>>(); } }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the claims associated with the specified <paramref name="user"/> as an asynchronous operation.
|
/// Get the claims associated with the specified <paramref name="user"/> as an asynchronous operation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -540,7 +633,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
throw new ArgumentNullException(nameof(user));
|
throw new ArgumentNullException(nameof(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
return await UserClaims.Where(uc => uc.UserId.Equals(user.Id)).Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToListAsync(cancellationToken);
|
return await UserClaims.Where(uc => uc.UserId.Equals(user.Id)).Select(c => c.ToClaim()).ToListAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -563,7 +656,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
}
|
}
|
||||||
foreach (var claim in claims)
|
foreach (var claim in claims)
|
||||||
{
|
{
|
||||||
UserClaims.Add(new IdentityUserClaim<TKey> { UserId = user.Id, ClaimType = claim.Type, ClaimValue = claim.Value });
|
UserClaims.Add(CreateUserClaim(user, claim));
|
||||||
}
|
}
|
||||||
return Task.FromResult(false);
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|
@ -648,14 +741,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(login));
|
throw new ArgumentNullException(nameof(login));
|
||||||
}
|
}
|
||||||
var l = new IdentityUserLogin<TKey>
|
UserLogins.Add(CreateUserLogin(user, login));
|
||||||
{
|
|
||||||
UserId = user.Id,
|
|
||||||
ProviderKey = login.ProviderKey,
|
|
||||||
LoginProvider = login.LoginProvider,
|
|
||||||
ProviderDisplayName = login.ProviderDisplayName
|
|
||||||
};
|
|
||||||
UserLogins.Add(l);
|
|
||||||
return Task.FromResult(false);
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -676,8 +762,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(user));
|
throw new ArgumentNullException(nameof(user));
|
||||||
}
|
}
|
||||||
var userId = user.Id;
|
var entry = await UserLogins.SingleOrDefaultAsync(userLogin => userLogin.UserId.Equals(user.Id) && userLogin.LoginProvider == loginProvider && userLogin.ProviderKey == providerKey, cancellationToken);
|
||||||
var entry = await UserLogins.SingleOrDefaultAsync(l => l.UserId.Equals(userId) && l.LoginProvider == loginProvider && l.ProviderKey == providerKey, cancellationToken);
|
|
||||||
if (entry != null)
|
if (entry != null)
|
||||||
{
|
{
|
||||||
UserLogins.Remove(entry);
|
UserLogins.Remove(entry);
|
||||||
|
|
@ -1198,7 +1283,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
return new List<TUser>();
|
return new List<TUser>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<IdentityUserToken<TKey>> FindToken(TUser user, string loginProvider, string name, CancellationToken cancellationToken)
|
private Task<TUserToken> FindToken(TUser user, string loginProvider, string name, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var userId = user.Id;
|
var userId = user.Id;
|
||||||
return UserTokens.SingleOrDefaultAsync(l => l.UserId.Equals(userId) && l.LoginProvider == loginProvider && l.Name == name, cancellationToken);
|
return UserTokens.SingleOrDefaultAsync(l => l.UserId.Equals(userId) && l.LoginProvider == loginProvider && l.Name == name, cancellationToken);
|
||||||
|
|
@ -1218,13 +1303,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
||||||
var token = await FindToken(user, loginProvider, name, cancellationToken);
|
var token = await FindToken(user, loginProvider, name, cancellationToken);
|
||||||
if (token == null)
|
if (token == null)
|
||||||
{
|
{
|
||||||
UserTokens.Add(new IdentityUserToken<TKey>
|
UserTokens.Add(CreateUserToken(user, loginProvider, name, value));
|
||||||
{
|
|
||||||
UserId = user.Id,
|
|
||||||
LoginProvider = loginProvider,
|
|
||||||
Name = name,
|
|
||||||
Value = value
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
|
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
|
||||||
{
|
{
|
||||||
|
|
@ -22,7 +21,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
|
||||||
{ }
|
{ }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InMemoryContext<TUser, TRole, TKey> : IdentityDbContext<TUser,TRole,TKey>
|
public class InMemoryContext<TUser, TRole, TKey> : IdentityDbContext<TUser, TRole, TKey>
|
||||||
where TUser : IdentityUser<TKey>
|
where TUser : IdentityUser<TKey>
|
||||||
where TRole : IdentityRole<TKey>
|
where TRole : IdentityRole<TKey>
|
||||||
where TKey : IEquatable<TKey>
|
where TKey : IEquatable<TKey>
|
||||||
|
|
@ -35,4 +34,23 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
|
||||||
optionsBuilder.UseInMemoryDatabase();
|
optionsBuilder.UseInMemoryDatabase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract class InMemoryContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> : IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
|
||||||
|
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>
|
||||||
|
where TUserToken : IdentityUserToken<TKey>
|
||||||
|
{
|
||||||
|
public InMemoryContext(DbContextOptions options) : base(options)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
optionsBuilder.UseInMemoryDatabase();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,6 @@ using System;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using Microsoft.AspNetCore.Identity.Test;
|
using Microsoft.AspNetCore.Identity.Test;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
|
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,320 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Identity.Test;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test
|
||||||
|
{
|
||||||
|
public class InMemoryEFUserStoreTestWithGenerics : UserManagerTestBase<IdentityUserWithGenerics, MyIdentityRole, string>, IDisposable
|
||||||
|
{
|
||||||
|
private readonly InMemoryContextWithGenerics _context;
|
||||||
|
private UserStoreWithGenerics _store;
|
||||||
|
|
||||||
|
public InMemoryEFUserStoreTestWithGenerics()
|
||||||
|
{
|
||||||
|
var services = new ServiceCollection();
|
||||||
|
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||||
|
services.AddDbContext<InMemoryContextWithGenerics>(options => options.UseInMemoryDatabase());
|
||||||
|
_context = services.BuildServiceProvider().GetRequiredService<InMemoryContextWithGenerics>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override object CreateTestContext()
|
||||||
|
{
|
||||||
|
return _context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AddUserStore(IServiceCollection services, object context = null)
|
||||||
|
{
|
||||||
|
_store = new UserStoreWithGenerics((InMemoryContextWithGenerics)context, "TestContext");
|
||||||
|
services.AddSingleton<IUserStore<IdentityUserWithGenerics>>(_store);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AddRoleStore(IServiceCollection services, object context = null)
|
||||||
|
{
|
||||||
|
services.AddSingleton<IRoleStore<MyIdentityRole>>(new RoleStoreWithGenerics((InMemoryContextWithGenerics)context, "TestContext"));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserWithGenerics CreateTestUser(string namePrefix = "", string email = "", string phoneNumber = "",
|
||||||
|
bool lockoutEnabled = false, DateTimeOffset? lockoutEnd = default(DateTimeOffset?), bool useNamePrefixAsUserName = false)
|
||||||
|
{
|
||||||
|
return new IdentityUserWithGenerics
|
||||||
|
{
|
||||||
|
UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
|
||||||
|
Email = email,
|
||||||
|
PhoneNumber = phoneNumber,
|
||||||
|
LockoutEnabled = lockoutEnabled,
|
||||||
|
LockoutEnd = lockoutEnd
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override MyIdentityRole CreateTestRole(string roleNamePrefix = "", bool useRoleNamePrefixAsRoleName = false)
|
||||||
|
{
|
||||||
|
var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format("{0}{1}", roleNamePrefix, Guid.NewGuid());
|
||||||
|
return new MyIdentityRole(roleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void SetUserPasswordHash(IdentityUserWithGenerics user, string hashedPassword)
|
||||||
|
{
|
||||||
|
user.PasswordHash = hashedPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Expression<Func<IdentityUserWithGenerics, bool>> UserNameEqualsPredicate(string userName) => u => u.UserName == userName;
|
||||||
|
|
||||||
|
protected override Expression<Func<MyIdentityRole, bool>> RoleNameEqualsPredicate(string roleName) => r => r.Name == roleName;
|
||||||
|
|
||||||
|
protected override Expression<Func<IdentityUserWithGenerics, bool>> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
|
||||||
|
|
||||||
|
protected override Expression<Func<MyIdentityRole, bool>> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName);
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanAddRemoveUserClaimWithIssuer()
|
||||||
|
{
|
||||||
|
if (ShouldSkipDbTests())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var manager = CreateManager();
|
||||||
|
var user = CreateTestUser();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
|
Claim[] claims = { new Claim("c1", "v1", null, "i1"), new Claim("c2", "v2", null, "i2"), new Claim("c2", "v3", null, "i3") };
|
||||||
|
foreach (Claim c in claims)
|
||||||
|
{
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
var userId = await manager.GetUserIdAsync(user);
|
||||||
|
var userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(3, userClaims.Count);
|
||||||
|
Assert.Equal(3, userClaims.Intersect(claims, ClaimEqualityComparer.Default).Count());
|
||||||
|
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[0]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(2, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[1]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[2]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(0, userClaims.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task RemoveClaimWithIssuerOnlyAffectsUser()
|
||||||
|
{
|
||||||
|
if (ShouldSkipDbTests())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var manager = CreateManager();
|
||||||
|
var user = CreateTestUser();
|
||||||
|
var user2 = CreateTestUser();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2));
|
||||||
|
Claim[] claims = { new Claim("c", "v", null, "i1"), new Claim("c2", "v2", null, "i2"), new Claim("c2", "v3", null, "i3") };
|
||||||
|
foreach (Claim c in claims)
|
||||||
|
{
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c));
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user2, c));
|
||||||
|
}
|
||||||
|
var userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(3, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[0]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(2, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[1]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[2]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(0, userClaims.Count);
|
||||||
|
var userClaims2 = await manager.GetClaimsAsync(user2);
|
||||||
|
Assert.Equal(3, userClaims2.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanReplaceUserClaimWithIssuer()
|
||||||
|
{
|
||||||
|
if (ShouldSkipDbTests())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var manager = CreateManager();
|
||||||
|
var user = CreateTestUser();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, new Claim("c", "a", "i")));
|
||||||
|
var userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, userClaims.Count);
|
||||||
|
Claim claim = new Claim("c", "b", "i");
|
||||||
|
Claim oldClaim = userClaims.FirstOrDefault();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.ReplaceClaimAsync(user, oldClaim, claim));
|
||||||
|
var newUserClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, newUserClaims.Count);
|
||||||
|
Claim newClaim = newUserClaims.FirstOrDefault();
|
||||||
|
Assert.Equal(claim.Type, newClaim.Type);
|
||||||
|
Assert.Equal(claim.Value, newClaim.Value);
|
||||||
|
Assert.Equal(claim.Issuer, newClaim.Issuer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClaimEqualityComparer : IEqualityComparer<Claim>
|
||||||
|
{
|
||||||
|
public static IEqualityComparer<Claim> Default = new ClaimEqualityComparer();
|
||||||
|
|
||||||
|
public bool Equals(Claim x, Claim y)
|
||||||
|
{
|
||||||
|
return x.Value == y.Value && x.Type == y.Type && x.Issuer == y.Issuer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetHashCode(Claim obj)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Generic Type defintions
|
||||||
|
|
||||||
|
public class IdentityUserWithGenerics : IdentityUser<string, IdentityUserClaimWithIssuer, IdentityUserRoleWithDate, IdentityUserLoginWithContext>
|
||||||
|
{
|
||||||
|
public IdentityUserWithGenerics()
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStoreWithGenerics : UserStore<IdentityUserWithGenerics, MyIdentityRole, InMemoryContextWithGenerics, string, IdentityUserClaimWithIssuer, IdentityUserRoleWithDate, IdentityUserLoginWithContext, IdentityUserTokenWithStuff>
|
||||||
|
{
|
||||||
|
public string LoginContext { get; set; }
|
||||||
|
|
||||||
|
public UserStoreWithGenerics(InMemoryContextWithGenerics context, string loginContext) : base(context)
|
||||||
|
{
|
||||||
|
LoginContext = loginContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserRoleWithDate CreateUserRole(IdentityUserWithGenerics user, MyIdentityRole role)
|
||||||
|
{
|
||||||
|
return new IdentityUserRoleWithDate()
|
||||||
|
{
|
||||||
|
RoleId = role.Id,
|
||||||
|
UserId = user.Id,
|
||||||
|
Created = DateTime.UtcNow
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserClaimWithIssuer CreateUserClaim(IdentityUserWithGenerics user, Claim claim)
|
||||||
|
{
|
||||||
|
return new IdentityUserClaimWithIssuer { UserId = user.Id, ClaimType = claim.Type, ClaimValue = claim.Value, Issuer = claim.Issuer };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserLoginWithContext CreateUserLogin(IdentityUserWithGenerics user, UserLoginInfo login)
|
||||||
|
{
|
||||||
|
return new IdentityUserLoginWithContext
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
ProviderKey = login.ProviderKey,
|
||||||
|
LoginProvider = login.LoginProvider,
|
||||||
|
ProviderDisplayName = login.ProviderDisplayName,
|
||||||
|
Context = LoginContext
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserTokenWithStuff CreateUserToken(IdentityUserWithGenerics user, string loginProvider, string name, string value)
|
||||||
|
{
|
||||||
|
return new IdentityUserTokenWithStuff
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
LoginProvider = loginProvider,
|
||||||
|
Name = name,
|
||||||
|
Value = value,
|
||||||
|
Stuff = "stuff"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RoleStoreWithGenerics : RoleStore<MyIdentityRole, InMemoryContextWithGenerics, string, IdentityUserRoleWithDate, IdentityRoleClaim<string>>
|
||||||
|
{
|
||||||
|
private string _loginContext;
|
||||||
|
public RoleStoreWithGenerics(InMemoryContextWithGenerics context, string loginContext) : base(context)
|
||||||
|
{
|
||||||
|
_loginContext = loginContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityRoleClaim<string> CreateRoleClaim(MyIdentityRole role, Claim claim)
|
||||||
|
{
|
||||||
|
return new IdentityRoleClaim<string> { RoleId = role.Id, ClaimType = claim.Type, ClaimValue = claim.Value };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityUserClaimWithIssuer : IdentityUserClaim<string>
|
||||||
|
{
|
||||||
|
public string Issuer { get; set; }
|
||||||
|
|
||||||
|
public override Claim ToClaim()
|
||||||
|
{
|
||||||
|
return new Claim(ClaimType, ClaimValue, null, Issuer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InitializeFromClaim(Claim other)
|
||||||
|
{
|
||||||
|
ClaimValue = other.Value;
|
||||||
|
ClaimType = other.Type;
|
||||||
|
Issuer = other.Issuer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityUserRoleWithDate : IdentityUserRole<string>
|
||||||
|
{
|
||||||
|
public DateTime Created { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MyIdentityRole : IdentityRole<string, IdentityUserRoleWithDate, IdentityRoleClaim<string>>
|
||||||
|
{
|
||||||
|
public MyIdentityRole() : base()
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyIdentityRole(string roleName) : this()
|
||||||
|
{
|
||||||
|
Name = roleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityUserTokenWithStuff : IdentityUserToken<string>
|
||||||
|
{
|
||||||
|
public string Stuff { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityUserLoginWithContext : IdentityUserLogin<string>
|
||||||
|
{
|
||||||
|
public string Context { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InMemoryContextWithGenerics : InMemoryContext<IdentityUserWithGenerics, MyIdentityRole, string, IdentityUserClaimWithIssuer, IdentityUserRoleWithDate, IdentityUserLoginWithContext, IdentityRoleClaim<string>, IdentityUserTokenWithStuff>
|
||||||
|
{
|
||||||
|
public InMemoryContextWithGenerics(DbContextOptions options) : base(options)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
optionsBuilder.UseInMemoryDatabase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,6 @@ using Microsoft.AspNetCore.Identity.Test;
|
||||||
using Microsoft.AspNetCore.Testing.xunit;
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Identity.Test;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
|
||||||
|
{
|
||||||
|
public class UserStoreWithGenericsTest : UserManagerTestBase<IdentityUserWithGenerics, MyIdentityRole, string>, IClassFixture<ScratchDatabaseFixture>
|
||||||
|
{
|
||||||
|
private readonly ScratchDatabaseFixture _fixture;
|
||||||
|
|
||||||
|
public UserStoreWithGenericsTest(ScratchDatabaseFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContextWithGenerics CreateContext()
|
||||||
|
{
|
||||||
|
var db = DbUtil.Create<ContextWithGenerics>(_fixture.ConnectionString);
|
||||||
|
db.Database.EnsureCreated();
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override object CreateTestContext()
|
||||||
|
{
|
||||||
|
return CreateContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldSkipDbTests()
|
||||||
|
{
|
||||||
|
return TestPlatformHelper.IsMono || !TestPlatformHelper.IsWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AddUserStore(IServiceCollection services, object context = null)
|
||||||
|
{
|
||||||
|
services.AddSingleton<IUserStore<IdentityUserWithGenerics>>(new UserStoreWithGenerics((ContextWithGenerics)context, "TestContext"));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AddRoleStore(IServiceCollection services, object context = null)
|
||||||
|
{
|
||||||
|
services.AddSingleton<IRoleStore<MyIdentityRole>>(new RoleStoreWithGenerics((ContextWithGenerics)context, "TestContext"));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserWithGenerics CreateTestUser(string namePrefix = "", string email = "", string phoneNumber = "",
|
||||||
|
bool lockoutEnabled = false, DateTimeOffset? lockoutEnd = default(DateTimeOffset?), bool useNamePrefixAsUserName = false)
|
||||||
|
{
|
||||||
|
return new IdentityUserWithGenerics
|
||||||
|
{
|
||||||
|
UserName = useNamePrefixAsUserName ? namePrefix : string.Format("{0}{1}", namePrefix, Guid.NewGuid()),
|
||||||
|
Email = email,
|
||||||
|
PhoneNumber = phoneNumber,
|
||||||
|
LockoutEnabled = lockoutEnabled,
|
||||||
|
LockoutEnd = lockoutEnd
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override MyIdentityRole CreateTestRole(string roleNamePrefix = "", bool useRoleNamePrefixAsRoleName = false)
|
||||||
|
{
|
||||||
|
var roleName = useRoleNamePrefixAsRoleName ? roleNamePrefix : string.Format("{0}{1}", roleNamePrefix, Guid.NewGuid());
|
||||||
|
return new MyIdentityRole(roleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void SetUserPasswordHash(IdentityUserWithGenerics user, string hashedPassword)
|
||||||
|
{
|
||||||
|
user.PasswordHash = hashedPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Expression<Func<IdentityUserWithGenerics, bool>> UserNameEqualsPredicate(string userName) => u => u.UserName == userName;
|
||||||
|
|
||||||
|
protected override Expression<Func<MyIdentityRole, bool>> RoleNameEqualsPredicate(string roleName) => r => r.Name == roleName;
|
||||||
|
|
||||||
|
protected override Expression<Func<IdentityUserWithGenerics, bool>> UserNameStartsWithPredicate(string userName) => u => u.UserName.StartsWith(userName);
|
||||||
|
|
||||||
|
protected override Expression<Func<MyIdentityRole, bool>> RoleNameStartsWithPredicate(string roleName) => r => r.Name.StartsWith(roleName);
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanAddRemoveUserClaimWithIssuer()
|
||||||
|
{
|
||||||
|
if (ShouldSkipDbTests())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var manager = CreateManager();
|
||||||
|
var user = CreateTestUser();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
|
Claim[] claims = { new Claim("c1", "v1", null, "i1"), new Claim("c2", "v2", null, "i2"), new Claim("c2", "v3", null, "i3") };
|
||||||
|
foreach (Claim c in claims)
|
||||||
|
{
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
var userId = await manager.GetUserIdAsync(user);
|
||||||
|
var userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(3, userClaims.Count);
|
||||||
|
Assert.Equal(3, userClaims.Intersect(claims, ClaimEqualityComparer.Default).Count());
|
||||||
|
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[0]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(2, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[1]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[2]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(0, userClaims.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task RemoveClaimWithIssuerOnlyAffectsUser()
|
||||||
|
{
|
||||||
|
if (ShouldSkipDbTests())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var manager = CreateManager();
|
||||||
|
var user = CreateTestUser();
|
||||||
|
var user2 = CreateTestUser();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2));
|
||||||
|
Claim[] claims = { new Claim("c", "v", null, "i1"), new Claim("c2", "v2", null, "i2"), new Claim("c2", "v3", null, "i3") };
|
||||||
|
foreach (Claim c in claims)
|
||||||
|
{
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c));
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user2, c));
|
||||||
|
}
|
||||||
|
var userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(3, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[0]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(2, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[1]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, userClaims.Count);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[2]));
|
||||||
|
userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(0, userClaims.Count);
|
||||||
|
var userClaims2 = await manager.GetClaimsAsync(user2);
|
||||||
|
Assert.Equal(3, userClaims2.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanReplaceUserClaimWithIssuer()
|
||||||
|
{
|
||||||
|
if (ShouldSkipDbTests())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var manager = CreateManager();
|
||||||
|
var user = CreateTestUser();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, new Claim("c", "a", "i")));
|
||||||
|
var userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, userClaims.Count);
|
||||||
|
Claim claim = new Claim("c", "b", "i");
|
||||||
|
Claim oldClaim = userClaims.FirstOrDefault();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.ReplaceClaimAsync(user, oldClaim, claim));
|
||||||
|
var newUserClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, newUserClaims.Count);
|
||||||
|
Claim newClaim = newUserClaims.FirstOrDefault();
|
||||||
|
Assert.Equal(claim.Type, newClaim.Type);
|
||||||
|
Assert.Equal(claim.Value, newClaim.Value);
|
||||||
|
Assert.Equal(claim.Issuer, newClaim.Issuer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClaimEqualityComparer : IEqualityComparer<Claim>
|
||||||
|
{
|
||||||
|
public static IEqualityComparer<Claim> Default = new ClaimEqualityComparer();
|
||||||
|
|
||||||
|
public bool Equals(Claim x, Claim y)
|
||||||
|
{
|
||||||
|
return x.Value == y.Value && x.Type == y.Type && x.Issuer == y.Issuer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetHashCode(Claim obj)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Generic Type defintions
|
||||||
|
|
||||||
|
public class IdentityUserWithGenerics : IdentityUser<string, IdentityUserClaimWithIssuer, IdentityUserRoleWithDate, IdentityUserLoginWithContext>
|
||||||
|
{
|
||||||
|
public IdentityUserWithGenerics()
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserStoreWithGenerics : UserStore<IdentityUserWithGenerics, MyIdentityRole, ContextWithGenerics, string, IdentityUserClaimWithIssuer, IdentityUserRoleWithDate, IdentityUserLoginWithContext, IdentityUserTokenWithStuff>
|
||||||
|
{
|
||||||
|
public string LoginContext { get; set; }
|
||||||
|
|
||||||
|
public UserStoreWithGenerics(ContextWithGenerics context, string loginContext) : base(context)
|
||||||
|
{
|
||||||
|
LoginContext = loginContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserRoleWithDate CreateUserRole(IdentityUserWithGenerics user, MyIdentityRole role)
|
||||||
|
{
|
||||||
|
return new IdentityUserRoleWithDate()
|
||||||
|
{
|
||||||
|
RoleId = role.Id,
|
||||||
|
UserId = user.Id,
|
||||||
|
Created = DateTime.UtcNow
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserClaimWithIssuer CreateUserClaim(IdentityUserWithGenerics user, Claim claim)
|
||||||
|
{
|
||||||
|
return new IdentityUserClaimWithIssuer { UserId = user.Id, ClaimType = claim.Type, ClaimValue = claim.Value, Issuer = claim.Issuer };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserLoginWithContext CreateUserLogin(IdentityUserWithGenerics user, UserLoginInfo login)
|
||||||
|
{
|
||||||
|
return new IdentityUserLoginWithContext
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
ProviderKey = login.ProviderKey,
|
||||||
|
LoginProvider = login.LoginProvider,
|
||||||
|
ProviderDisplayName = login.ProviderDisplayName,
|
||||||
|
Context = LoginContext
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityUserTokenWithStuff CreateUserToken(IdentityUserWithGenerics user, string loginProvider, string name, string value)
|
||||||
|
{
|
||||||
|
return new IdentityUserTokenWithStuff
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
LoginProvider = loginProvider,
|
||||||
|
Name = name,
|
||||||
|
Value = value,
|
||||||
|
Stuff = "stuff"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RoleStoreWithGenerics : RoleStore<MyIdentityRole, ContextWithGenerics, string, IdentityUserRoleWithDate, IdentityRoleClaim<string>>
|
||||||
|
{
|
||||||
|
private string _loginContext;
|
||||||
|
public RoleStoreWithGenerics(ContextWithGenerics context, string loginContext) : base(context)
|
||||||
|
{
|
||||||
|
_loginContext = loginContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IdentityRoleClaim<string> CreateRoleClaim(MyIdentityRole role, Claim claim)
|
||||||
|
{
|
||||||
|
return new IdentityRoleClaim<string> { RoleId = role.Id, ClaimType = claim.Type, ClaimValue = claim.Value };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityUserClaimWithIssuer : IdentityUserClaim<string>
|
||||||
|
{
|
||||||
|
public string Issuer { get; set; }
|
||||||
|
|
||||||
|
public override Claim ToClaim()
|
||||||
|
{
|
||||||
|
return new Claim(ClaimType, ClaimValue, null, Issuer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InitializeFromClaim(Claim other)
|
||||||
|
{
|
||||||
|
ClaimValue = other.Value;
|
||||||
|
ClaimType = other.Type;
|
||||||
|
Issuer = other.Issuer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityUserRoleWithDate : IdentityUserRole<string>
|
||||||
|
{
|
||||||
|
public DateTime Created { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MyIdentityRole : IdentityRole<string, IdentityUserRoleWithDate, IdentityRoleClaim<string>>
|
||||||
|
{
|
||||||
|
public MyIdentityRole() : base()
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyIdentityRole(string roleName) : this()
|
||||||
|
{
|
||||||
|
Name = roleName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityUserTokenWithStuff : IdentityUserToken<string>
|
||||||
|
{
|
||||||
|
public string Stuff { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentityUserLoginWithContext : IdentityUserLogin<string>
|
||||||
|
{
|
||||||
|
public string Context { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ContextWithGenerics : IdentityDbContext<IdentityUserWithGenerics, MyIdentityRole, string, IdentityUserClaimWithIssuer, IdentityUserRoleWithDate, IdentityUserLoginWithContext, IdentityRoleClaim<string>, IdentityUserTokenWithStuff>
|
||||||
|
{
|
||||||
|
public ContextWithGenerics(DbContextOptions options) : base(options) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue