Skip to content

Commit

Permalink
Move login to Google Auth
Browse files Browse the repository at this point in the history
  • Loading branch information
NixFey committed Mar 19, 2024
1 parent 393c401 commit c0de552
Show file tree
Hide file tree
Showing 21 changed files with 303 additions and 77 deletions.
20 changes: 20 additions & 0 deletions Auth/UserAccessHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Authorization;

namespace fim_queueing_admin.Auth;

public class UserAccessHandler : AuthorizationHandler<UserAccessRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserAccessRequirement requirement)
{
// If user does not have the claim, get out of here
if (!context.User.HasClaim(c => c.Type == ClaimTypes.AccessLevel)) return Task.CompletedTask;

// Get their level
var accessLevel = context.User.FindFirst(c => c.Type == ClaimTypes.AccessLevel)!.Value;

// Succeed if the level has the necessary permission
if (Action.ActionMap[accessLevel].Contains(requirement.Action)) context.Succeed(requirement);

return Task.CompletedTask;
}
}
45 changes: 45 additions & 0 deletions Auth/UserAccessLevel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
namespace fim_queueing_admin.Auth;

public class UserAccessLevel
{
public const string ReadOnly = "2687ba63-c15a-47fa-bbc3-b9c4802a6fd6";
public const string Editor = "3c3aac31-0349-4b90-bafb-3344bd4c8333";
public const string Admin = "9ab85fca-724e-42d5-a4a2-cd1dff1f45e2";
}

public static class Action
{
public const string ViewDisplay = nameof(ViewDisplay);
public const string ManageDisplay = nameof(ManageDisplay);
public const string ViewEvent = nameof(ViewEvent);
public const string ManageEvent = nameof(ManageEvent);
public const string CreateEvent = nameof(CreateEvent);
public const string ViewAlert = nameof(ViewAlert);
public const string ManageAlert = nameof(ManageAlert);
public const string CreateAlert = nameof(CreateAlert);
public const string ViewCart = nameof(ViewCart);
public const string ManageCart = nameof(ManageCart);
public const string CreateCart = nameof(CreateCart);
public const string ViewUser = nameof(ViewUser);
public const string ManageUser = nameof(ManageUser);
public const string Admin = nameof(Admin);

internal static readonly Dictionary<string, string[]> ActionMap = new()
{
{
UserAccessLevel.ReadOnly,
[ViewDisplay, ViewEvent, ViewAlert, ViewCart]
},
{
UserAccessLevel.Editor,
[
ViewDisplay, ManageDisplay, ViewEvent, ManageEvent,
ViewAlert, ManageAlert, CreateAlert, ViewCart, ManageCart
]
},
{
UserAccessLevel.Admin,
typeof(Action).GetFields().Select(f => (string)f.GetValue(null)!).ToArray() // All permissions
}
};
}
17 changes: 17 additions & 0 deletions Auth/UserAccessRequirement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Authorization;

namespace fim_queueing_admin.Auth;

public class UserAccessRequirement(string action) : IAuthorizationRequirement
{
public string Action { get; } = action;
}

public class AuthorizeOperationAttribute(string action) : AuthorizeAttribute,
IAuthorizationRequirementData
{
public IEnumerable<IAuthorizationRequirement> GetRequirements()
{
return new[] { new UserAccessRequirement(action) };
}
}
1 change: 1 addition & 0 deletions ClaimTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ public static class ClaimTypes
private const string ClaimNamespace = "https://fimav.us/claims/";
public const string CartId = ClaimNamespace + "CartId";
public const string CartName = ClaimNamespace + "CartName";
public const string AccessLevel = ClaimNamespace + "AccessLevel";
}
5 changes: 3 additions & 2 deletions Controllers/AdminController.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Text.Json;
using fim_queueing_admin.Auth;
using fim_queueing_admin.Services;
using Firebase.Database;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Action = fim_queueing_admin.Auth.Action;

namespace fim_queueing_admin.Controllers;

[Authorize]
[AuthorizeOperation(Action.Admin)]
public class AdminController : Controller
{
[HttpGet]
Expand Down
10 changes: 8 additions & 2 deletions Controllers/AlertController.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using fim_queueing_admin.Auth;
using fim_queueing_admin.Data;
using fim_queueing_admin.Models;
using fim_queueing_admin.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Action = fim_queueing_admin.Auth.Action;

namespace fim_queueing_admin.Controllers;

[Authorize]
[AuthorizeOperation(Action.ViewAlert)]
[Route("[controller]")]
public partial class AlertController(FimDbContext dbContext, AssistantService assistantService) : Controller
{
Expand All @@ -20,19 +21,22 @@ public ActionResult Index()
return View();
}

[AuthorizeOperation(Action.ManageAlert)]
[HttpGet("[action]/{id:guid}")]
public ActionResult Manage(Guid id)
{
ViewData["id"] = id;
return View();
}

[AuthorizeOperation(Action.CreateAlert)]
[HttpGet("[action]")]
public ActionResult Manage()
{
return View();
}

[AuthorizeOperation(Action.ManageAlert)]
[HttpPost("[action]/{id:guid}")]
public async Task<ActionResult> Manage(Guid id, [FromForm] AlertManageModel model)
{
Expand Down Expand Up @@ -61,6 +65,7 @@ public async Task<ActionResult> Manage(Guid id, [FromForm] AlertManageModel mode
return RedirectToAction(nameof(Index));
}

[AuthorizeOperation(Action.CreateAlert)]
[HttpPost("[action]")]
public async Task<ActionResult> Manage([FromForm] AlertManageModel model)
{
Expand Down Expand Up @@ -89,6 +94,7 @@ public async Task<ActionResult> Manage([FromForm] AlertManageModel model)
return RedirectToAction(nameof(Index));
}

[AuthorizeOperation(Action.Admin)]
[HttpDelete("{id:guid}")]
public async Task<ActionResult> Delete(Guid id)
{
Expand Down
18 changes: 0 additions & 18 deletions Controllers/AssistantController.cs

This file was deleted.

9 changes: 7 additions & 2 deletions Controllers/CartController.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System.ComponentModel.DataAnnotations;
using fim_queueing_admin.Auth;
using fim_queueing_admin.Data;
using fim_queueing_admin.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Action = fim_queueing_admin.Auth.Action;

namespace fim_queueing_admin.Controllers;

[Authorize]
[AuthorizeOperation(Action.ViewCart)]
[Route("[controller]")]
public class CartController(FimDbContext dbContext) : Controller
{
Expand All @@ -17,19 +18,22 @@ public ActionResult Index()
return View();
}

[AuthorizeOperation(Action.ManageCart)]
[HttpGet("[action]/{id:guid}")]
public ActionResult Manage(Guid id)
{
ViewData["id"] = id;
return View();
}

[AuthorizeOperation(Action.CreateCart)]
[HttpGet("[action]")]
public ActionResult Manage()
{
return View();
}

[AuthorizeOperation(Action.ManageCart)]
[HttpPost("[action]/{id:guid}")]
public async Task<ActionResult> Manage(Guid id, [FromForm] CartManageModel model)
{
Expand All @@ -54,6 +58,7 @@ public async Task<ActionResult> Manage(Guid id, [FromForm] CartManageModel model
return RedirectToAction(nameof(Index));
}

[AuthorizeOperation(Action.CreateCart)]
[HttpPost("[action]")]
public async Task<ActionResult> Manage([FromForm] CartManageModel model)
{
Expand Down
14 changes: 11 additions & 3 deletions Controllers/DisplayController.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using fim_queueing_admin.Hubs;
using fim_queueing_admin.Auth;
using fim_queueing_admin.Hubs;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Action = fim_queueing_admin.Auth.Action;

namespace fim_queueing_admin.Controllers;

[Authorize]
[AuthorizeOperation(Action.ViewDisplay)]
public class DisplayController : Controller
{
private readonly IHubContext<DisplayHub> _hubCtx;
Expand All @@ -18,12 +20,13 @@ public DisplayController(IHubContext<DisplayHub> hubCtx, DisplayHubManager manag
}

[HttpGet]
public IActionResult Index()
public IActionResult Index([FromServices] IAuthorizationService asv)
{
return View();
}

[HttpGet]
[AuthorizeOperation(Action.ManageDisplay)]
public IActionResult Manage(string id)
{
if (!_manager.GetConnections().ContainsKey(id))
Expand All @@ -36,34 +39,39 @@ public IActionResult Manage(string id)
}

[HttpPost]
[AuthorizeOperation(Action.ManageDisplay)]
public async Task<IActionResult> SendRefresh(string id)
{
await _hubCtx.Clients.Client(id).SendAsync("SendRefresh");
return RedirectToAction(nameof(Index));
}

[HttpPost]
[AuthorizeOperation(Action.ManageDisplay)]
public async Task<IActionResult> SendRefreshToAll()
{
await _hubCtx.Clients.All.SendAsync("SendRefresh");
return RedirectToAction(nameof(Index));
}

[HttpPost]
[AuthorizeOperation(Action.ManageDisplay)]
public async Task<IActionResult> Identify(string id)
{
await _hubCtx.Clients.Client(id).SendAsync("Identify");
return RedirectToAction(nameof(Index));
}

[HttpPost]
[AuthorizeOperation(Action.ManageDisplay)]
public async Task<IActionResult> IdentifyAll()
{
await _hubCtx.Clients.All.SendAsync("Identify");
return RedirectToAction(nameof(Index));
}

[HttpPost]
[AuthorizeOperation(Action.ManageDisplay)]
public async Task<IActionResult> SendNewRoute(string id, [FromForm] string route)
{
await _hubCtx.Clients.Client(id).SendAsync("SendNewRoute", route);
Expand Down
10 changes: 8 additions & 2 deletions Controllers/EventController.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Text.Json;
using fim_queueing_admin.Auth;
using fim_queueing_admin.Services;
using Firebase.Database;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Action = fim_queueing_admin.Auth.Action;

namespace fim_queueing_admin.Controllers;

[Authorize]
[AuthorizeOperation(Action.ViewEvent)]
[Route("[controller]")]
public class EventController(FirebaseClient client, GlobalState state) : Controller
{
Expand All @@ -30,13 +31,15 @@ public async Task<ActionResult> GetEventVideoStatus(string eventCode, [FromServi
return PartialView("_GetEventVideoStatus", vidStatus.Value);
}

[AuthorizeOperation(Action.ManageEvent)]
[HttpGet("[action]/{id}")]
public IActionResult Manage(string id)
{
ViewData["id"] = id;
return View();
}

[AuthorizeOperation(Action.ManageEvent)]
[HttpPost("[action]/{id}")]
public async Task<IActionResult> UpdateState(string id, [FromForm] string eventState)
{
Expand All @@ -45,6 +48,7 @@ public async Task<IActionResult> UpdateState(string id, [FromForm] string eventS
return RedirectToAction(nameof(Index));
}

[AuthorizeOperation(Action.ManageEvent)]
[HttpPost("[action]/{id}")]
public async Task<IActionResult> UpdateEmbedLink(string id, [FromForm] string link)
{
Expand All @@ -53,6 +57,7 @@ public async Task<IActionResult> UpdateEmbedLink(string id, [FromForm] string li
return RedirectToAction(nameof(Index));
}

[AuthorizeOperation(Action.ManageEvent)]
[HttpPost("[action]/{id}")]
public async Task<IActionResult> UpdateDateTimes(string id, [FromForm] DateTime start, [FromForm] DateTime end, [FromForm] string offset)
{
Expand All @@ -71,6 +76,7 @@ await client.Child($"/seasons/{state.CurrentSeason}/events/{id}")
return RedirectToAction(nameof(Index));
}

[AuthorizeOperation(Action.ManageEvent)]
[HttpPost("[action]/{id}")]
public async Task<IActionResult> UpdateCart(string id, [FromForm] Guid? cartId, [FromServices] AssistantService assistantService)
{
Expand Down
Loading

0 comments on commit c0de552

Please sign in to comment.