You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Dotnet-WebAPI/API/Controllers/TeamsController.cs

185 lines
6.1 KiB

using System.ComponentModel.DataAnnotations;
using API.Context;
using API.Validation;
using AppContext.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Model;
using Services;
namespace API.Controllers;
[ApiController]
[Authorize]
public class TeamsController(ITeamService service, ITacticService tactics,IContextAccessor accessor) : ControllerBase
{
public record CreateTeamRequest(
[Name] string Name,
[Url] string Picture,
[RegularExpression("^#[0-9A-F]{6}$")] string FirstColor,
[RegularExpression("^#[0-9A-F]{6}$")] string SecondColor
);
[HttpPost("/teams")]
public async Task<IActionResult> CreateTeam([FromBody] CreateTeamRequest req)
{
var userId = accessor.CurrentUserId(HttpContext);
var team = await service.AddTeam(req.Name, req.Picture, req.FirstColor, req.SecondColor);
await service.AddMember(team.Id, userId, MemberRole.Coach);
return Ok(team);
}
[HttpGet("/teams/{teamId:int}/members")]
public async Task<IActionResult> GetMembersOf(int teamId)
{
var accessibility =
await service.EnsureAccessibility(accessor.CurrentUserId(HttpContext), teamId, MemberRole.Player);
switch (accessibility)
{
case ITeamService.TeamAccessibility.Authorized:
return Ok(await service.GetMembersOf(teamId));
case ITeamService.TeamAccessibility.NotFound:
case ITeamService.TeamAccessibility.Unauthorized:
return NotFound();
default: //unreachable
return Problem();
}
}
public record AddMemberRequest(
int UserId,
[AllowedValues("PLAYER", "COACH")] string Role
);
[HttpPost("/teams/{teamId:int}/members")]
public async Task<IActionResult> AddMember(int teamId, [FromBody] AddMemberRequest req)
{
if (!Enum.TryParse<MemberRole>(req.Role, true, out var role))
{
throw new Exception($"Unable to convert string input '{req.Role}' to a role enum variant.");
}
var accessibility =
await service.EnsureAccessibility(accessor.CurrentUserId(HttpContext), teamId, MemberRole.Coach);
switch (accessibility)
{
case ITeamService.TeamAccessibility.Authorized:
{
var result = await service.AddMember(teamId, req.UserId, role);
if (result == null)
return Forbid();
return Ok(result);
}
case ITeamService.TeamAccessibility.NotFound:
case ITeamService.TeamAccessibility.Unauthorized:
return NotFound();
default: //unreachable
return Problem();
}
}
public record UpdateMemberRequest(
[AllowedValues("PLAYER", "COACH")] string Role
);
[HttpPut("/team/{teamId:int}/members/{userId:int}")]
public async Task<IActionResult> UpdateMember(int teamId, int userId, [FromBody] UpdateMemberRequest req)
{
if (!Enum.TryParse<MemberRole>(req.Role, true, out var role))
{
throw new Exception($"Unable to convert string input '{req.Role}' to a role enum variant.");
}
var accessibility =
await service.EnsureAccessibility(accessor.CurrentUserId(HttpContext), teamId, MemberRole.Coach);
switch (accessibility)
{
case ITeamService.TeamAccessibility.Authorized:
{
var updated = await service.UpdateMember(new Member(teamId, userId, role));
return updated ? Ok() : NotFound();
}
case ITeamService.TeamAccessibility.NotFound:
case ITeamService.TeamAccessibility.Unauthorized:
return NotFound();
default: //unreachable
return Problem();
}
}
[HttpDelete("/team/{teamId:int}/members/{userId:int}")]
public async Task<IActionResult> RemoveMember(int teamId, int userId)
{
var accessibility =
await service.EnsureAccessibility(accessor.CurrentUserId(HttpContext), teamId, MemberRole.Coach);
switch (accessibility)
{
case ITeamService.TeamAccessibility.Authorized:
{
var removed = await service.RemoveMember(teamId, userId);
return removed ? Ok() : NotFound();
}
case ITeamService.TeamAccessibility.NotFound:
case ITeamService.TeamAccessibility.Unauthorized:
return NotFound();
default: //unreachable
return Problem();
}
}
public record ShareTacticToTeamRequest(
int TacticId,
int TeamId
);
[HttpPost("/team/share-tactic")]
public async Task<IActionResult> ShareTactic([FromBody] ShareTacticToTeamRequest sharedTactic)
{
var userId = accessor.CurrentUserId(HttpContext);
var success = await tactics.ShareTactic(sharedTactic.TacticId, null, sharedTactic.TeamId);
return success ? Ok() : BadRequest();
}
[HttpDelete("/tactics/shared/{tacticId:int}/team/{teamId:int}")]
public async Task<IActionResult> UnshareTactic(int tacticId, int teamId)
{
var currentUserId = accessor.CurrentUserId(HttpContext);
var tactic = await tactics.GetTactic(tacticId);
if (tactic == null)
{
return NotFound();
}
if (currentUserId != tactic.OwnerId)
{
return Unauthorized();
}
var success = await tactics.UnshareTactic(tacticId, null, teamId);
return success ? Ok() : NotFound();
}
[HttpGet("/tactics/shared/team/{teamId:int}")]
public async Task<IActionResult> GetSharedTacticsToTeam(int teamId)
{
var currentUserId = accessor.CurrentUserId(HttpContext);
if (!await service.IsUserInTeam(currentUserId, teamId))
{
return Unauthorized();
}
var sharedTactics = await service.GetSharedTacticsToTeam(teamId);
return sharedTactics != null ? Ok(sharedTactics) : NotFound();
}
}