Update to dotnet 9.0, add user roles, MatchStats and OpenApi/Scalar in dev
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using LaDOSE.Business.Interface;
|
||||
using LaDOSE.Entity;
|
||||
using LaDOSE.Entity.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LaDOSE.Business.Service
|
||||
{
|
||||
@@ -20,8 +21,9 @@ namespace LaDOSE.Business.Service
|
||||
{
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
|
||||
return null;
|
||||
var p = _context.ApplicationUser.ToList();
|
||||
var user = _context.ApplicationUser.SingleOrDefault(x => x.Username == username);
|
||||
var user = _context.ApplicationUser
|
||||
.Include(x => x.UserRoles).ThenInclude(ur => ur.Role)
|
||||
.SingleOrDefault(x => x.Username == username);
|
||||
|
||||
// check if username exists
|
||||
if (user == null)
|
||||
@@ -37,23 +39,44 @@ namespace LaDOSE.Business.Service
|
||||
|
||||
public IEnumerable<ApplicationUser> GetAll()
|
||||
{
|
||||
return _context.ApplicationUser;
|
||||
return _context.ApplicationUser
|
||||
.Include(x => x.UserRoles).ThenInclude(ur => ur.Role)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Roles are included because authorization reads them on every authenticated
|
||||
/// request (see the OnTokenValidated handler in Startup).
|
||||
/// </summary>
|
||||
public ApplicationUser GetById(int id)
|
||||
{
|
||||
return _context.ApplicationUser.Find(id);
|
||||
return _context.ApplicationUser
|
||||
.Include(x => x.UserRoles).ThenInclude(ur => ur.Role)
|
||||
.SingleOrDefault(x => x.Id == id);
|
||||
}
|
||||
|
||||
public ApplicationUser Create(ApplicationUser user, string password)
|
||||
public IEnumerable<ApplicationRole> GetAllRoles()
|
||||
{
|
||||
return _context.ApplicationRole.OrderBy(x => x.Name).ToList();
|
||||
}
|
||||
|
||||
public ApplicationUser Create(ApplicationUser user, string password, IEnumerable<string> roleNames = null)
|
||||
{
|
||||
// validation
|
||||
if (string.IsNullOrWhiteSpace(user?.Username))
|
||||
throw new Exception("Username is required");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(password))
|
||||
throw new Exception("Password is required");
|
||||
|
||||
if (_context.ApplicationUser.Any(x => x.Username == user.Username))
|
||||
throw new Exception("Username \"" + user.Username + "\" is already taken");
|
||||
|
||||
// EF fills userid/roleid on the join rows from these navigations when it saves.
|
||||
user.UserRoles = ResolveRoles(roleNames)
|
||||
.Select(role => new ApplicationUserRole { Role = role })
|
||||
.ToList();
|
||||
|
||||
byte[] passwordHash, passwordSalt;
|
||||
CreatePasswordHash(password, out passwordHash, out passwordSalt);
|
||||
|
||||
@@ -66,6 +89,35 @@ namespace LaDOSE.Business.Service
|
||||
return user;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns role names into the existing rows of <c>applicationrole</c>. An unknown
|
||||
/// name is an error rather than a new role, so a typo cannot quietly produce an
|
||||
/// account with no privileges — or, worse, a second spelling of "Admin".
|
||||
/// </summary>
|
||||
private List<ApplicationRole> ResolveRoles(IEnumerable<string> roleNames)
|
||||
{
|
||||
var wanted = (roleNames ?? Enumerable.Empty<string>())
|
||||
.Where(name => !string.IsNullOrWhiteSpace(name))
|
||||
.Select(name => name.Trim())
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
if (wanted.Count == 0)
|
||||
return new List<ApplicationRole>();
|
||||
|
||||
var known = _context.ApplicationRole.ToList();
|
||||
var resolved = new List<ApplicationRole>();
|
||||
foreach (var name in wanted)
|
||||
{
|
||||
var role = known.FirstOrDefault(r => string.Equals(r.Name, name, StringComparison.OrdinalIgnoreCase));
|
||||
if (role == null)
|
||||
throw new Exception($"Unknown role \"{name}\"");
|
||||
resolved.Add(role);
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
public void Update(ApplicationUser userParam, string password = null)
|
||||
{
|
||||
var user = _context.ApplicationUser.Find(userParam.Id);
|
||||
@@ -101,12 +153,18 @@ namespace LaDOSE.Business.Service
|
||||
|
||||
public void Delete(int id)
|
||||
{
|
||||
var user = _context.ApplicationUser.Find(id);
|
||||
if (user != null)
|
||||
{
|
||||
_context.ApplicationUser.Remove(user);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
// applicationuserrole's foreign keys are ON DELETE RESTRICT, so the join rows
|
||||
// have to go first — clearing the collection makes EF delete them.
|
||||
var user = _context.ApplicationUser
|
||||
.Include(x => x.UserRoles).ThenInclude(ur => ur.Role)
|
||||
.SingleOrDefault(x => x.Id == id);
|
||||
|
||||
if (user == null)
|
||||
return;
|
||||
|
||||
user.UserRoles?.Clear();
|
||||
_context.ApplicationUser.Remove(user);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
// private helper methods
|
||||
|
||||
Reference in New Issue
Block a user