added auth handlers, added role seed, separate username/email, implemented some web endpoints
This commit is contained in:
parent
1f94b624d2
commit
0ad552c334
@ -32,6 +32,8 @@ namespace Selector.Model
|
||||
.HasOne(w => w.User)
|
||||
.WithMany(u => u.Watchers)
|
||||
.HasForeignKey(w => w.UserId);
|
||||
|
||||
SeedData.Seed(modelBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,4 +19,33 @@ namespace Selector.Model
|
||||
|
||||
public List<Watcher> Watchers { get; set; }
|
||||
}
|
||||
|
||||
public class ApplicationUserDTO
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
public bool SpotifyIsLinked { get; set; }
|
||||
public DateTime SpotifyLastRefresh { get; set; }
|
||||
public int SpotifyTokenExpiry { get; set; }
|
||||
public string SpotifyAccessToken { get; set; }
|
||||
public string SpotifyRefreshToken { get; set; }
|
||||
|
||||
public string LastFmUsername { get; set; }
|
||||
|
||||
public static explicit operator ApplicationUserDTO(ApplicationUser user) => new() {
|
||||
UserName = user.UserName,
|
||||
Email = user.Email,
|
||||
PhoneNumber = user.PhoneNumber,
|
||||
|
||||
SpotifyIsLinked = user.SpotifyIsLinked,
|
||||
SpotifyLastRefresh = user.SpotifyLastRefresh,
|
||||
SpotifyTokenExpiry = user.SpotifyTokenExpiry,
|
||||
SpotifyAccessToken = user.SpotifyAccessToken,
|
||||
SpotifyRefreshToken = user.SpotifyRefreshToken,
|
||||
|
||||
LastFmUsername = user.LastFmUsername
|
||||
};
|
||||
}
|
||||
}
|
36
Selector.Model/Authorisation/Constants.cs
Normal file
36
Selector.Model/Authorisation/Constants.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization.Infrastructure;
|
||||
|
||||
namespace Selector.Model.Authorisation
|
||||
{
|
||||
public static class WatcherOperations
|
||||
{
|
||||
public static OperationAuthorizationRequirement Create = new() { Name = Constants.CreateOpName };
|
||||
public static OperationAuthorizationRequirement Read = new() { Name = Constants.ReadOpName };
|
||||
public static OperationAuthorizationRequirement Update = new() { Name = Constants.UpdateOpName };
|
||||
public static OperationAuthorizationRequirement Delete = new() { Name = Constants.DeleteOpName };
|
||||
}
|
||||
|
||||
public static class UserOperations
|
||||
{
|
||||
public static OperationAuthorizationRequirement Create = new() { Name = Constants.CreateOpName };
|
||||
public static OperationAuthorizationRequirement Read = new() { Name = Constants.ReadOpName };
|
||||
public static OperationAuthorizationRequirement Update = new() { Name = Constants.UpdateOpName };
|
||||
public static OperationAuthorizationRequirement Delete = new() { Name = Constants.DeleteOpName };
|
||||
}
|
||||
|
||||
public class Constants
|
||||
{
|
||||
public const string CreateOpName = "Create";
|
||||
public const string ReadOpName = "Read";
|
||||
public const string UpdateOpName = "Update";
|
||||
public const string DeleteOpName = "Delete";
|
||||
|
||||
public const string AdminRole = "Admin";
|
||||
}
|
||||
}
|
34
Selector.Model/Authorisation/User/UserIsAdminAuthHandler.cs
Normal file
34
Selector.Model/Authorisation/User/UserIsAdminAuthHandler.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization.Infrastructure;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace Selector.Model.Authorisation
|
||||
{
|
||||
public class UserIsAdminAuthHandler
|
||||
: AuthorizationHandler<OperationAuthorizationRequirement, ApplicationUser>
|
||||
{
|
||||
protected override Task HandleRequirementAsync(
|
||||
AuthorizationHandlerContext context,
|
||||
OperationAuthorizationRequirement requirement,
|
||||
ApplicationUser resource
|
||||
) {
|
||||
if (context.User == null || resource == null)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (context.User.IsInRole(Constants.AdminRole))
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
48
Selector.Model/Authorisation/User/UserIsSelfAuthHandler.cs
Normal file
48
Selector.Model/Authorisation/User/UserIsSelfAuthHandler.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization.Infrastructure;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace Selector.Model.Authorisation
|
||||
{
|
||||
public class UserIsSelfAuthHandler
|
||||
: AuthorizationHandler<OperationAuthorizationRequirement, ApplicationUser>
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> userManager;
|
||||
|
||||
public UserIsSelfAuthHandler(UserManager<ApplicationUser> userManager)
|
||||
{
|
||||
this.userManager = userManager;
|
||||
}
|
||||
|
||||
protected override Task HandleRequirementAsync(
|
||||
AuthorizationHandlerContext context,
|
||||
OperationAuthorizationRequirement requirement,
|
||||
ApplicationUser resource
|
||||
) {
|
||||
if (context.User == null || resource == null)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (requirement.Name != Constants.ReadOpName &&
|
||||
requirement.Name != Constants.UpdateOpName &&
|
||||
requirement.Name != Constants.DeleteOpName)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (resource.Id == userManager.GetUserId(context.User))
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization.Infrastructure;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace Selector.Model.Authorisation
|
||||
{
|
||||
public class WatcherIsAdminAuthHandler
|
||||
: AuthorizationHandler<OperationAuthorizationRequirement, Watcher>
|
||||
{
|
||||
protected override Task HandleRequirementAsync(
|
||||
AuthorizationHandlerContext context,
|
||||
OperationAuthorizationRequirement requirement,
|
||||
Watcher resource
|
||||
) {
|
||||
if (context.User == null || resource == null)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (context.User.IsInRole(Constants.AdminRole))
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization.Infrastructure;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace Selector.Model.Authorisation
|
||||
{
|
||||
public class WatcherIsOwnerAuthHandler
|
||||
: AuthorizationHandler<OperationAuthorizationRequirement, Watcher>
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> userManager;
|
||||
|
||||
public WatcherIsOwnerAuthHandler(UserManager<ApplicationUser> userManager)
|
||||
{
|
||||
this.userManager = userManager;
|
||||
}
|
||||
|
||||
protected override Task HandleRequirementAsync(
|
||||
AuthorizationHandlerContext context,
|
||||
OperationAuthorizationRequirement requirement,
|
||||
Watcher resource
|
||||
) {
|
||||
if (context.User == null || resource == null)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (requirement.Name != Constants.CreateOpName &&
|
||||
requirement.Name != Constants.ReadOpName &&
|
||||
requirement.Name != Constants.UpdateOpName &&
|
||||
requirement.Name != Constants.DeleteOpName)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
if (resource.UserId == userManager.GetUserId(context.User))
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
33
Selector.Model/SeedData.cs
Normal file
33
Selector.Model/SeedData.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using Selector.Model.Authorisation;
|
||||
|
||||
namespace Selector.Model
|
||||
{
|
||||
public static class SeedData
|
||||
{
|
||||
public static void Seed(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<IdentityRole>().HasData(
|
||||
GetRole(Constants.AdminRole, "00c64c0a-3387-4933-9575-83443fa9092b")
|
||||
);
|
||||
}
|
||||
|
||||
public static IdentityRole GetRole(string name, string id)
|
||||
{
|
||||
return new IdentityRole
|
||||
{
|
||||
Name = name,
|
||||
NormalizedName = name.ToUpperInvariant(),
|
||||
Id = id
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,9 @@ namespace Selector.Model
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public string UserId { get; set; }
|
||||
[Required]
|
||||
public ApplicationUser User { get; set; }
|
||||
|
||||
public WatcherType Type { get; set; }
|
||||
|
@ -14,9 +14,9 @@
|
||||
<hr />
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
<label asp-for="Input.Username"></label>
|
||||
<input asp-for="Input.Username" class="form-control" />
|
||||
<span asp-validation-for="Input.Username" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Password"></label>
|
||||
|
@ -45,8 +45,7 @@ namespace Selector.Web.Areas.Identity.Pages.Account
|
||||
public class InputModel
|
||||
{
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
public string Email { get; set; }
|
||||
public string Username { get; set; }
|
||||
|
||||
[Required]
|
||||
[DataType(DataType.Password)]
|
||||
@ -83,7 +82,7 @@ namespace Selector.Web.Areas.Identity.Pages.Account
|
||||
{
|
||||
// This doesn't count login failures towards account lockout
|
||||
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
|
||||
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
|
||||
var result = await _signInManager.PasswordSignInAsync(Input.Username, Input.Password, Input.RememberMe, lockoutOnFailure: false);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
_logger.LogInformation("User logged in.");
|
||||
|
@ -12,6 +12,11 @@
|
||||
<h4>Create a new account.</h4>
|
||||
<hr />
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Username"></label>
|
||||
<input asp-for="Input.Username" class="form-control" />
|
||||
<span asp-validation-for="Input.Username" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
|
@ -47,6 +47,10 @@ namespace Selector.Web.Areas.Identity.Pages.Account
|
||||
|
||||
public class InputModel
|
||||
{
|
||||
[Required]
|
||||
[Display(Name = "Username")]
|
||||
public string Username { get; set; }
|
||||
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
[Display(Name = "Email")]
|
||||
@ -76,7 +80,7 @@ namespace Selector.Web.Areas.Identity.Pages.Account
|
||||
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email };
|
||||
var user = new ApplicationUser { UserName = Input.Username, Email = Input.Email };
|
||||
var result = await _userManager.CreateAsync(user, Input.Password);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
|
34
Selector.Web/Controller/BaseAuthController.cs
Normal file
34
Selector.Web/Controller/BaseAuthController.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using Selector.Model;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Selector.Web.Controller {
|
||||
|
||||
public class BaseAuthController: Microsoft.AspNetCore.Mvc.Controller
|
||||
{
|
||||
protected ApplicationDbContext Context { get; }
|
||||
protected IAuthorizationService AuthorizationService { get; }
|
||||
protected UserManager<ApplicationUser> UserManager { get; }
|
||||
protected ILogger<BaseAuthController> Logger { get; }
|
||||
|
||||
public BaseAuthController(
|
||||
ApplicationDbContext context,
|
||||
IAuthorizationService auth,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILogger<BaseAuthController> logger
|
||||
) {
|
||||
Context = context;
|
||||
AuthorizationService = auth;
|
||||
UserManager = userManager;
|
||||
Logger = logger;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,46 +4,91 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Selector.Model;
|
||||
|
||||
namespace Selector.Web.Controller {
|
||||
using Selector.Model;
|
||||
using Selector.Model.Authorisation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Selector.Web.Controller
|
||||
{
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class UsersController {
|
||||
public class UsersController : BaseAuthController
|
||||
{
|
||||
public UsersController(
|
||||
ApplicationDbContext context,
|
||||
IAuthorizationService auth,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILogger<UsersController> logger
|
||||
) : base(context, auth, userManager, logger) { }
|
||||
|
||||
private readonly ApplicationDbContext db;
|
||||
|
||||
public UsersController(ApplicationDbContext context)
|
||||
{
|
||||
db = context;
|
||||
}
|
||||
|
||||
[HttpGet()]
|
||||
public async Task<ActionResult<IEnumerable<ApplicationUser>>> Get(string username)
|
||||
[HttpGet]
|
||||
[Authorize(Roles = Constants.AdminRole)]
|
||||
public async Task<ActionResult<IEnumerable<ApplicationUserDTO>>> Get()
|
||||
{
|
||||
// TODO: Authorise
|
||||
return await db.Users.ToListAsync();
|
||||
return await Context.Users.AsNoTracking().Select(u => (ApplicationUserDTO)u).ToListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class UserController {
|
||||
public class UserController : BaseAuthController
|
||||
{
|
||||
public UserController(
|
||||
ApplicationDbContext context,
|
||||
IAuthorizationService auth,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILogger<UserController> logger
|
||||
) : base(context, auth, userManager, logger) { }
|
||||
|
||||
private readonly ApplicationDbContext db;
|
||||
|
||||
public UserController(ApplicationDbContext context)
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<ApplicationUserDTO>> Get()
|
||||
{
|
||||
db = context;
|
||||
var userId = UserManager.GetUserId(User);
|
||||
var user = await Context.Users.AsNoTracking().FirstOrDefaultAsync(u => u.Id == userId);
|
||||
|
||||
if (user is null)
|
||||
{
|
||||
Logger.LogWarning($"No user found for [{userId}], even though the 'me' route was used");
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var isAuthed = await AuthorizationService.AuthorizeAsync(User, user, UserOperations.Read);
|
||||
|
||||
if (!isAuthed.Succeeded)
|
||||
{
|
||||
Logger.LogWarning($"User [{user.UserName}] not authorised to view themselves?");
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
return (ApplicationUserDTO)user;
|
||||
}
|
||||
|
||||
[HttpGet("{username}")]
|
||||
public async Task<ActionResult<ApplicationUser>> Get(string username)
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<ApplicationUserDTO>> GetById(string id)
|
||||
{
|
||||
// TODO: Implement
|
||||
return await db.Users.SingleAsync();
|
||||
var usernameUpper = id.ToUpperInvariant();
|
||||
|
||||
var user = await Context.Users.AsNoTracking().FirstOrDefaultAsync(u => u.Id == id)
|
||||
?? await Context.Users.AsNoTracking().FirstOrDefaultAsync(u => u.NormalizedUserName == usernameUpper);
|
||||
|
||||
if (user is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var isAuthed = await AuthorizationService.AuthorizeAsync(User, user, UserOperations.Read);
|
||||
|
||||
if (!isAuthed.Succeeded)
|
||||
{
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
return (ApplicationUserDTO)user;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,46 +4,72 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using Selector.Model;
|
||||
using Selector.Model.Authorisation;
|
||||
|
||||
namespace Selector.Web.Controller {
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class WatchersController {
|
||||
|
||||
private readonly ApplicationDbContext db;
|
||||
|
||||
public WatchersController(ApplicationDbContext context)
|
||||
{
|
||||
db = context;
|
||||
}
|
||||
public class WatchersController : BaseAuthController
|
||||
{
|
||||
public WatchersController(
|
||||
ApplicationDbContext context,
|
||||
IAuthorizationService auth,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILogger<WatchersController> logger
|
||||
) : base(context, auth, userManager, logger) { }
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<Watcher>>> Get()
|
||||
{
|
||||
// TODO: Authorise
|
||||
return await db.Watcher.ToListAsync();
|
||||
var isAuthed = User.IsInRole(Constants.AdminRole);
|
||||
|
||||
if(isAuthed)
|
||||
{
|
||||
return await Context.Watcher.AsNoTracking().ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
var userId = UserManager.GetUserId(User);
|
||||
return await Context.Watcher.AsNoTracking().Where(w => w.UserId == userId).ToListAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class WatcherController {
|
||||
|
||||
private readonly ApplicationDbContext db;
|
||||
|
||||
public WatcherController(ApplicationDbContext context)
|
||||
{
|
||||
db = context;
|
||||
}
|
||||
public class WatcherController : BaseAuthController
|
||||
{
|
||||
public WatcherController(
|
||||
ApplicationDbContext context,
|
||||
IAuthorizationService auth,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILogger<WatcherController> logger
|
||||
) : base(context, auth, userManager, logger) { }
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<Watcher>> Get(int id)
|
||||
{
|
||||
// TODO: Implement
|
||||
return await db.Watcher.FirstAsync();
|
||||
var watcher = await Context.Watcher.AsNoTracking().FirstOrDefaultAsync(w => w.Id == id);
|
||||
|
||||
if(watcher is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var isAuthed = await AuthorizationService.AuthorizeAsync(User, watcher, WatcherOperations.Read);
|
||||
|
||||
if(!isAuthed.Succeeded)
|
||||
{
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
return watcher;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">Welcome</h1>
|
||||
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
|
||||
<partial name="_LoginPartial" />
|
||||
</div>
|
||||
|
||||
|
@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using Selector.Model;
|
||||
using Selector.Model.Authorisation;
|
||||
|
||||
namespace Selector.Web
|
||||
{
|
||||
@ -80,6 +81,12 @@ namespace Selector.Web
|
||||
.RequireAuthenticatedUser()
|
||||
.Build();
|
||||
});
|
||||
|
||||
services.AddScoped<IAuthorizationHandler, WatcherIsOwnerAuthHandler>();
|
||||
services.AddSingleton<IAuthorizationHandler, WatcherIsAdminAuthHandler>();
|
||||
|
||||
services.AddScoped<IAuthorizationHandler, UserIsSelfAuthHandler>();
|
||||
services.AddSingleton<IAuthorizationHandler, UserIsAdminAuthHandler>();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
Loading…
Reference in New Issue
Block a user