using LocationsApi.Models; using LocationsApi.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace LocationsApi.Controllers; [ApiController] [Route("api/[controller]")] public class LocationsController : ControllerBase { private readonly LocationService _locations; public LocationsController(LocationService locations) { _locations = locations; } [Authorize(Roles = "USER,SUPER")] [HttpGet] public async Task>> GetAll( [FromQuery] int? minQ, [FromQuery] int? maxQ, [FromQuery] int? minR, [FromQuery] int? maxR) { if (!User.IsInRole("SUPER")) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrWhiteSpace(username)) { return Unauthorized(); } var visible = await _locations.GetVisibleAsync(username); if (minQ.HasValue && maxQ.HasValue && minR.HasValue && maxR.HasValue) { visible = visible .Where(x => x.Q >= minQ.Value && x.Q <= maxQ.Value && x.R >= minR.Value && x.R <= maxR.Value) .ToList(); } return Ok(visible); } var locations = minQ.HasValue && maxQ.HasValue && minR.HasValue && maxR.HasValue ? await _locations.GetRangeAsync(minQ.Value, maxQ.Value, minR.Value, maxR.Value) : await _locations.GetAllAsync(); return Ok(locations.Select(LocationResponse.FromLocation).ToList()); } [Authorize(Roles = "USER,SUPER")] [HttpGet("{q:int}/{r:int}")] public async Task> Get(int q, int r) { if (!User.IsInRole("SUPER")) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrWhiteSpace(username)) { return Unauthorized(); } var visibleLocation = await _locations.GetVisibleLocationAsync(username, q, r); return visibleLocation is null ? NotFound() : Ok(visibleLocation); } var location = await _locations.GetAsync(q, r); return location is null ? NotFound() : Ok(LocationResponse.FromLocation(location)); } [Authorize(Roles = "USER,SUPER")] [HttpPost("claim")] public async Task> Claim([FromBody] ClaimLocationRequest request) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrWhiteSpace(username)) { return Unauthorized(); } if (!User.IsInRole("SUPER") && !await _locations.CanSeeAsync(username, request.Q, request.R)) { return NotFound(); } var location = await _locations.ClaimAsync(request.Q, request.R, username); if (location is null) { return Conflict("Location is already controlled by another player."); } return Ok(LocationResponse.FromLocation(location)); } [Authorize(Roles = "USER,SUPER")] [HttpGet("home")] public async Task> GetHome() { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrWhiteSpace(username)) { return Unauthorized(); } var home = await _locations.GetHomeAsync(username); return home is null ? NotFound() : Ok(LocationResponse.FromLocation(home)); } [Authorize(Roles = "USER,SUPER")] [HttpPost("home")] public async Task> AssignHome() { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrWhiteSpace(username)) { return Unauthorized(); } var home = await _locations.AssignHomeAsync(username); return Ok(LocationResponse.FromLocation(home)); } [Authorize(Roles = "USER,SUPER")] [HttpGet("visible")] public async Task>> GetVisible([FromQuery] int? depth) { var username = User.FindFirstValue(ClaimTypes.Name); if (string.IsNullOrWhiteSpace(username)) { return Unauthorized(); } return Ok(await _locations.GetVisibleAsync(username, depth)); } [Authorize(Roles = "SUPER")] [HttpPut] public async Task> Upsert([FromBody] UpsertLocationRequest request) { var location = await _locations.UpsertAsync(request); return Ok(LocationResponse.FromLocation(location)); } }