mirror of
https://github.com/sphildreth/roadie
synced 2024-11-25 05:30:24 +00:00
WIP
This commit is contained in:
parent
97483dee11
commit
0344d1e604
15 changed files with 163 additions and 134 deletions
|
@ -54,7 +54,8 @@ namespace Roadie.Api.Controllers
|
|||
}
|
||||
// If successful login return OK with generated token
|
||||
var user = await userManager.FindByNameAsync(model.Username);
|
||||
return Ok(this.tokenService.GenerateToken(user));
|
||||
var t = await this.tokenService.GenerateToken(user, this.userManager);
|
||||
return Ok(t);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -76,7 +77,7 @@ namespace Roadie.Api.Controllers
|
|||
if (!String.IsNullOrWhiteSpace(username))
|
||||
{
|
||||
var user = await userManager.FindByNameAsync(username);
|
||||
return Ok(this.tokenService.GenerateToken(user));
|
||||
return Ok(await this.tokenService.GenerateToken(user, this.userManager));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -103,7 +104,7 @@ namespace Roadie.Api.Controllers
|
|||
if (identityResult.Succeeded)
|
||||
{
|
||||
await signInManager.SignInAsync(user, isPersistent: false);
|
||||
return Ok(this.tokenService.GenerateToken(user));
|
||||
return Ok(this.tokenService.GenerateToken(user, this.userManager));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -129,7 +130,7 @@ namespace Roadie.Api.Controllers
|
|||
if (identityResult.Succeeded)
|
||||
{
|
||||
await signInManager.SignInAsync(user, isPersistent: false);
|
||||
return Ok(this.tokenService.GenerateToken(user));
|
||||
return Ok(this.tokenService.GenerateToken(user, this.userManager));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Roadie.Api.Services;
|
||||
using Roadie.Library.Caching;
|
||||
using Roadie.Library.Identity;
|
||||
using Roadie.Library.Models;
|
||||
using System;
|
||||
using System.Net;
|
||||
|
@ -19,11 +21,14 @@ namespace Roadie.Api.Controllers
|
|||
{
|
||||
private IArtistService ArtistService { get; }
|
||||
|
||||
public ArtistController(IArtistService artistService, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration)
|
||||
private UserManager<ApplicationUser> UserManager { get; }
|
||||
|
||||
public ArtistController(IArtistService artistService, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, UserManager<ApplicationUser> userManager)
|
||||
: base(cacheManager, configuration)
|
||||
{
|
||||
this._logger = logger.CreateLogger("RoadieApi.Controllers.ArtistController");
|
||||
this.ArtistService = artistService;
|
||||
this.UserManager = userManager;
|
||||
}
|
||||
|
||||
//[EnableQuery]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Roadie.Library.Data;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Identity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -9,6 +10,6 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
public interface ITokenService
|
||||
{
|
||||
string GenerateToken(ApplicationUser user);
|
||||
Task<string> GenerateToken(ApplicationUser user, UserManager<ApplicationUser> userManager);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Roadie.Library.Data;
|
||||
using Roadie.Library.Identity;
|
||||
using System;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Api.Services
|
||||
{
|
||||
|
@ -16,10 +19,13 @@ namespace Roadie.Api.Services
|
|||
this._configuration = configuration;
|
||||
}
|
||||
|
||||
public string GenerateToken(ApplicationUser user)
|
||||
public async Task<string> GenerateToken(ApplicationUser user, UserManager<ApplicationUser> userManager)
|
||||
{
|
||||
var utcNow = DateTime.UtcNow;
|
||||
|
||||
var roles = await userManager.GetRolesAsync(user);
|
||||
var userRoles = roles.Select(r => new Claim(ClaimTypes.Role, r)).ToArray();
|
||||
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
|
||||
var claims = new Claim[]
|
||||
|
@ -28,7 +34,7 @@ namespace Roadie.Api.Services
|
|||
new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Iat, utcNow.ToString())
|
||||
};
|
||||
}.Union(userRoles);
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(this._configuration.GetValue<String>("Tokens:PrivateKey")));
|
||||
|
|
|
@ -33,16 +33,16 @@ namespace Roadie.Api
|
|||
private readonly IConfiguration _configuration;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
|
||||
public static string AssemblyDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
|
||||
var uri = new UriBuilder(codeBase);
|
||||
string path = Uri.UnescapeDataString(uri.Path);
|
||||
return Path.GetDirectoryName(path);
|
||||
}
|
||||
}
|
||||
//public static string AssemblyDirectory
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// string codeBase = Assembly.GetExecutingAssembly().CodeBase;
|
||||
// var uri = new UriBuilder(codeBase);
|
||||
// string path = Uri.UnescapeDataString(uri.Path);
|
||||
// return Path.GetDirectoryName(path);
|
||||
// }
|
||||
//}
|
||||
|
||||
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
|
||||
{
|
||||
|
@ -55,22 +55,8 @@ namespace Roadie.Api
|
|||
src => src.Artist.RoadieId)
|
||||
.Compile();
|
||||
|
||||
//TypeAdapterConfig<Roadie.Library.Data.ReleaseMedia, Roadie.Library.Models.Releases.ReleaseMediaList>
|
||||
// .NewConfig()
|
||||
// .Map(rml => rml.Id,
|
||||
// src => src.RoadieId)
|
||||
// .Compile();
|
||||
|
||||
//TypeAdapterConfig<Roadie.Library.Data.Track, Roadie.Library.Models.TrackList>
|
||||
// .NewConfig()
|
||||
// .Map(rml => rml.ReleaseArtistId,
|
||||
// src => src.Artist.RoadieId)
|
||||
// .Compile();
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.PreserveReference(true);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
@ -113,22 +99,6 @@ namespace Roadie.Api
|
|||
|
||||
services.AddSingleton<IHttpEncoder, HttpEncoder>();
|
||||
|
||||
//services.AddSingleton<IRoadieSettings, RoadieSettings>(options =>
|
||||
//{
|
||||
// var settingsPath = Path.Combine(AssemblyDirectory, "settings.json");
|
||||
// var settings = new RoadieSettings();
|
||||
// if (File.Exists(settingsPath))
|
||||
// {
|
||||
// var settingsFileContents = File.ReadAllText(settingsPath);
|
||||
// var fromSettingsFile = Newtonsoft.Json.JsonConvert.DeserializeObject<RoadieSettings>(settingsFileContents);
|
||||
// if (fromSettingsFile != null)
|
||||
// {
|
||||
// settings.MergeWith(fromSettingsFile);
|
||||
// }
|
||||
// }
|
||||
// return settings;
|
||||
//});
|
||||
|
||||
var cacheManager = new MemoryCacheManager(this._loggerFactory.CreateLogger<MemoryCacheManager>(), new CachePolicy(TimeSpan.FromHours(4)));
|
||||
services.AddSingleton<ICacheManager>(cacheManager);
|
||||
|
||||
|
@ -141,13 +111,13 @@ namespace Roadie.Api
|
|||
));
|
||||
|
||||
services.AddIdentity<ApplicationUser, ApplicationRole>()
|
||||
.AddEntityFrameworkStores<ApplicationUserDbContext>()
|
||||
.AddClaimsPrincipalFactory<ApplicationClaimsFactory>();
|
||||
.AddRoles<ApplicationRole>()
|
||||
.AddEntityFrameworkStores<ApplicationUserDbContext>();
|
||||
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
options.AddPolicy("Admin", policy => policy.RequireClaim("Admin"));
|
||||
options.AddPolicy("Editor", policy => policy.RequireClaim("Editor"));
|
||||
options.AddPolicy("Admin", policy => policy.RequireRole("Admin"));
|
||||
options.AddPolicy("Editor", policy => policy.RequireRole("Editor"));
|
||||
});
|
||||
|
||||
services.Configure<IConfiguration>(this._configuration);
|
||||
|
@ -210,7 +180,7 @@ namespace Roadie.Api
|
|||
services.AddScoped<IHttpContext>(factory =>
|
||||
{
|
||||
var actionContext = factory.GetService<IActionContextAccessor>()
|
||||
.ActionContext;
|
||||
.ActionContext;
|
||||
return new HttpContext(new UrlHelper(actionContext));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace Roadie.Library.Data
|
|||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
builder
|
||||
.Entity<Release>()
|
||||
.Property(e => e.ReleaseType)
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
public class ApplicationClaimsFactory : UserClaimsPrincipalFactory<ApplicationUser, ApplicationRole>
|
||||
{
|
||||
public const string SecurityClaimRoleType = "req-security-claim";
|
||||
|
||||
private readonly ApplicationUserDbContext _applicationUserDbContext = null;
|
||||
|
||||
public ApplicationClaimsFactory(
|
||||
ApplicationUserDbContext applicationUserDbContext,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
RoleManager<ApplicationRole> roleManager,
|
||||
IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
|
||||
{
|
||||
_applicationUserDbContext = applicationUserDbContext;
|
||||
}
|
||||
|
||||
#pragma warning disable 1998
|
||||
public override async Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
|
||||
{
|
||||
var usersRoles = (from ur in _applicationUserDbContext.UsersInRoles.Where(x => x.UserId == user.Id)
|
||||
join r in _applicationUserDbContext.Roles on ur.UserRoleId equals r.Id
|
||||
select r);
|
||||
IEnumerable<Claim> userClaims = null;
|
||||
if (usersRoles.Any())
|
||||
{
|
||||
userClaims = usersRoles.Select(x => new Claim(SecurityClaimRoleType, x.Name));
|
||||
}
|
||||
return new ClaimsPrincipal(new ClaimsIdentity(userClaims, "Password"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,9 +16,9 @@ namespace Roadie.Library.Identity
|
|||
[StringLength(200)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Column("id")]
|
||||
[Key]
|
||||
public override int Id { get; set; }
|
||||
//[Column("id")]
|
||||
//[Key]
|
||||
//public override int Id { get; set; }
|
||||
|
||||
[Column("isLocked")]
|
||||
public bool? IsLocked { get; set; }
|
||||
|
@ -35,9 +35,11 @@ namespace Roadie.Library.Identity
|
|||
[StringLength(36)]
|
||||
public string RoadieId { get; set; }
|
||||
|
||||
public virtual ICollection<ApplicationRoleClaim> RoleClaims { get; set; }
|
||||
|
||||
[Column("status")]
|
||||
public short? Status { get; set; }
|
||||
|
||||
public ICollection<UsersInRoles> Users { get; set; }
|
||||
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
|
||||
}
|
||||
}
|
14
RoadieLibrary/Identity/ApplicationRoleClaim.cs
Normal file
14
RoadieLibrary/Identity/ApplicationRoleClaim.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
[Table("userRoleClaims")]
|
||||
public class ApplicationRoleClaim : IdentityRoleClaim<int>
|
||||
{
|
||||
public virtual ApplicationRole Role { get; set; }
|
||||
|
||||
[Column("userRoleId")]
|
||||
public override int RoleId { get; set; }
|
||||
}
|
||||
}
|
|
@ -14,13 +14,15 @@ namespace Roadie.Library.Identity
|
|||
[StringLength(100)]
|
||||
public string ApiToken { get; set; }
|
||||
|
||||
public ICollection<UserArtist> ArtistRatings { get; set; }
|
||||
public virtual ICollection<UserArtist> ArtistRatings { get; set; }
|
||||
|
||||
[Column("avatar", TypeName = "blob")]
|
||||
public byte[] Avatar { get; set; }
|
||||
|
||||
public ICollection<Bookmark> Bookmarks { get; set; }
|
||||
|
||||
public virtual ICollection<ApplicationUserClaim> Claims { get; set; }
|
||||
|
||||
[Column("createdDate")]
|
||||
public DateTime? CreatedDate { get; set; }
|
||||
|
||||
|
@ -101,7 +103,7 @@ namespace Roadie.Library.Identity
|
|||
[StringLength(36)]
|
||||
public Guid RoadieId { get; set; }
|
||||
|
||||
public ICollection<UsersInRoles> Roles { get; set; }
|
||||
// public virtual ICollection<UsersInRoles> Roles { get; set; }
|
||||
|
||||
[Column("status")]
|
||||
public short? Status { get; set; }
|
||||
|
@ -122,5 +124,7 @@ namespace Roadie.Library.Identity
|
|||
[Required]
|
||||
[StringLength(20)]
|
||||
public string Username { get; set; }
|
||||
|
||||
public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
|
||||
}
|
||||
}
|
11
RoadieLibrary/Identity/ApplicationUserClaim.cs
Normal file
11
RoadieLibrary/Identity/ApplicationUserClaim.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
[Table("userClaims")]
|
||||
public class ApplicationUserClaim : IdentityUserClaim<int>
|
||||
{
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,22 +1,72 @@
|
|||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
public class ApplicationUserDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>
|
||||
public class ApplicationUserDbContext : IdentityDbContext<
|
||||
ApplicationUser, ApplicationRole, int,
|
||||
ApplicationUserClaim, ApplicationUserRole, IdentityUserLogin<int>,
|
||||
ApplicationRoleClaim, IdentityUserToken<int>>
|
||||
{
|
||||
public DbSet<UsersInRoles> UsersInRoles { get; set; }
|
||||
|
||||
public ApplicationUserDbContext(DbContextOptions<ApplicationUserDbContext> options) : base(options)
|
||||
public ApplicationUserDbContext(DbContextOptions<ApplicationUserDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
modelBuilder.Entity<ApplicationUser>().ToTable("user");
|
||||
modelBuilder.Entity<ApplicationRole>().ToTable("userrole");
|
||||
builder.Entity<ApplicationUser>(b =>
|
||||
{
|
||||
b.ToTable("user");
|
||||
|
||||
// Each User can have many UserClaims
|
||||
b.HasMany(e => e.Claims)
|
||||
.WithOne(e => e.User)
|
||||
.HasForeignKey(uc => uc.UserId)
|
||||
.IsRequired();
|
||||
|
||||
// Each User can have many entries in the UserRole join table
|
||||
b.HasMany(e => e.UserRoles)
|
||||
.WithOne(e => e.User)
|
||||
.HasForeignKey(ur => ur.UserId)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
builder.Entity<ApplicationRole>(b =>
|
||||
{
|
||||
b.ToTable("userrole");
|
||||
b.HasKey(ar => ar.Id);
|
||||
|
||||
// Each Role can have many entries in the UserRole join table
|
||||
b.HasMany(e => e.UserRoles)
|
||||
.WithOne(e => e.Role)
|
||||
.HasForeignKey(ur => ur.RoleId)
|
||||
.IsRequired();
|
||||
|
||||
// Each Role can have many associated RoleClaims
|
||||
b.HasMany(e => e.RoleClaims)
|
||||
.WithOne(e => e.Role)
|
||||
.HasForeignKey(rc => rc.RoleId)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
builder.Entity<ApplicationUserClaim>(b =>
|
||||
{
|
||||
b.ToTable("userClaims");
|
||||
});
|
||||
|
||||
builder.Entity<ApplicationUserRole>(b =>
|
||||
{
|
||||
b.ToTable("usersInRoles");
|
||||
});
|
||||
|
||||
builder.Entity<ApplicationRoleClaim>(b =>
|
||||
{
|
||||
b.ToTable("userRoleClaims");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
17
RoadieLibrary/Identity/ApplicationUserRole.cs
Normal file
17
RoadieLibrary/Identity/ApplicationUserRole.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
[Table("usersInRoles")]
|
||||
public class ApplicationUserRole : IdentityUserRole<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public virtual ApplicationRole Role { get; set; }
|
||||
|
||||
[Column("userRoleId")]
|
||||
public override int RoleId { get; set; }
|
||||
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Identity
|
||||
{
|
||||
[Table("usersInRoles")]
|
||||
public class UsersInRoles
|
||||
{
|
||||
[Column("id")]
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public ApplicationRole Role { get; set; }
|
||||
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
[Column("userId")]
|
||||
public int UserId { get; set; }
|
||||
|
||||
[Column("userRoleId")]
|
||||
public int UserRoleId { get; set; }
|
||||
}
|
||||
}
|
|
@ -12,8 +12,8 @@ namespace Roadie.Library
|
|||
public const string NotModified = "NotModified";
|
||||
public const string OkMessage = "OK";
|
||||
|
||||
private List<Exception> _errors = new List<Exception>();
|
||||
private List<string> _messages = new List<string>();
|
||||
private List<Exception> _errors;
|
||||
private List<string> _messages;
|
||||
public Dictionary<string, object> AdditionalData { get; set; }
|
||||
public T Data { get; set; }
|
||||
public IEnumerable<Exception> Errors { get; set; }
|
||||
|
@ -63,6 +63,10 @@ namespace Roadie.Library
|
|||
{
|
||||
if (exception != null)
|
||||
{
|
||||
if(this._errors == null)
|
||||
{
|
||||
this._errors = new List<Exception>();
|
||||
}
|
||||
this._errors.Add(exception);
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +75,10 @@ namespace Roadie.Library
|
|||
{
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
if(this._messages == null)
|
||||
{
|
||||
this._messages = new List<string>();
|
||||
}
|
||||
this._messages.Add(message);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue