Skip to content

Commit

Permalink
feat!: The great nullification
Browse files Browse the repository at this point in the history
- Adapted the code to nullable context
- Sealed all remaining classes
- Refactored various parts of the code to match new NET 8.0 standards
  • Loading branch information
SakuraIsayeki committed Jan 12, 2024
1 parent 006ff2e commit daadec2
Show file tree
Hide file tree
Showing 72 changed files with 467 additions and 499 deletions.
17 changes: 8 additions & 9 deletions WowsKarma.Api/Controllers/Admin/ModActionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
using WowsKarma.Api.Services.Posts;
using WowsKarma.Common;


namespace WowsKarma.Api.Controllers.Admin;


[ApiController, Route("api/mod/action"), Authorize(Roles = ApiRoles.CM)]
public class ModActionController : ControllerBase
public sealed class ModActionController : ControllerBase
{
private readonly ModService _service;

Expand Down Expand Up @@ -40,22 +39,22 @@ public ModActionController(ModService service)
[HttpGet("list"), AllowAnonymous, ProducesResponseType(typeof(IEnumerable<PostModActionDTO>), 200), ProducesResponseType(204)]
public IActionResult List([FromQuery] Guid postId = default, [FromQuery] uint userId = default)
{
IEnumerable<PostModAction> modActions;
PostModAction[] modActions = [];

if (postId != default)
{
modActions = _service.GetPostModActions(postId).ToArray();
modActions = [.. _service.GetPostModActions(postId)];
}
else if (userId is not 0)
{
modActions = _service.GetPostModActions(userId).ToArray();
modActions = [.. _service.GetPostModActions(userId)];
}
else
{
return BadRequest("Please use a search query (Post/User).");
}

return modActions?.Count() is null or 0
return modActions is []
? base.StatusCode(204)
: base.StatusCode(200, modActions.Adapt<IEnumerable<PostModActionDTO>>());
}
Expand All @@ -73,16 +72,16 @@ public IActionResult List([FromQuery] Guid postId = default, [FromQuery] uint us
public async Task<IActionResult> Submit([FromBody] PostModActionDTO modAction,
[FromServices] PostService postService)
{
Post post = postService.GetPost(modAction.PostId);
uint modId = uint.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier));
Post post = postService.GetPost(modAction.PostId) ?? throw new InvalidOperationException("Post ID is invalid.");
uint modId = uint.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? throw new BadHttpRequestException("Missing NameIdentifier claim."));

if ((post.AuthorId == modId || post.PlayerId == modId) && !User.IsInRole(ApiRoles.Administrator))
{
return StatusCode(403, $"CMs cannot act on Posts with relation to self. This restriction is lifted for users with {ApiRoles.Administrator} role.");
}

await _service.SubmitPostModActionAsync(modAction with { ModId = modId });
return StatusCode(202);
return Accepted();
}

/// <summary>
Expand Down
23 changes: 12 additions & 11 deletions WowsKarma.Api/Controllers/Admin/PlatformBansController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace WowsKarma.Api.Controllers.Admin;

[ApiController, Route("api/mod/bans"), Authorize(Roles = $"{ApiRoles.CM},{ApiRoles.Administrator}")]
public class PlatformBansController : ControllerBase
public sealed class PlatformBansController : ControllerBase
{
private readonly ModService _service;

Expand Down Expand Up @@ -39,23 +39,24 @@ public IActionResult FetchBans(uint userId, bool currentOnly)
return Ok(bans.ProjectToType<PlatformBanDTO>().AsAsyncEnumerable());
}

/// <summary>
/// Emits a new Platform Ban.
/// </summary>
/// <param name="submitted">Platform Ban to emit</param>
/// <param name="days">(Helper) Sets a temporary ban, to the number of specified days starting from UTC now.</param>
/// <response code="202">Platform Ban was successfuly submitted.</response>
/// <summary>
/// Emits a new Platform Ban.
/// </summary>
/// <param name="submitted">Platform Ban to emit</param>
/// <param name="authDb">(DI)</param>
/// <param name="days">(Helper) Sets a temporary ban, to the number of specified days starting from UTC now.</param>
/// <response code="202">Platform Ban was successfuly submitted.</response>
[HttpPost, ProducesResponseType(202)]
public async Task<IActionResult> SubmitBan([FromBody] PlatformBanDTO submitted, [FromServices] AuthDbContext authDb, [FromQuery] uint days = 0)
{
await _service.EmitPlatformBanAsync(submitted with
{
ModId = User.ToAccountListing().Id,
ModId = User.ToAccountListing()!.Id,
Reverted = false,
BannedUntil = days is 0 ? null : DateTime.UtcNow.AddDays(days)
BannedUntil = days is 0 ? null : DateTimeOffset.UtcNow.AddDays(days)
}, authDb);

return StatusCode(202);
return Accepted();
}

/// <summary>
Expand All @@ -64,7 +65,7 @@ await _service.EmitPlatformBanAsync(submitted with
/// <param name="id">ID of Platform Ban to revert.</param>
/// <response code="200">Platform Ban was successfully reverted.</response>
[HttpDelete("{id:guid}"), ProducesResponseType(200)]
public async Task<IActionResult> RevertBan([FromQuery] Guid id)
public async Task<IActionResult> RevertBan(Guid id)
{
await _service.RevertPlatformBanAsync(id);

Expand Down
43 changes: 20 additions & 23 deletions WowsKarma.Api/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,32 @@
using Microsoft.AspNetCore.Mvc;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using WowsKarma.Api.Infrastructure.Attributes;
using WowsKarma.Api.Services.Authentication;
using WowsKarma.Api.Services.Authentication.Jwt;
using WowsKarma.Api.Services.Authentication.Wargaming;
using WowsKarma.Common;


namespace WowsKarma.Api.Controllers;


/// <summary>
/// Provides API Authentication endpoints.
/// </summary>
[ApiController, Route("api/[controller]"), ETag(false)]
public class AuthController : ControllerBase
public sealed class AuthController : ControllerBase
{
private readonly IConfiguration config;
private readonly UserService userService;
private readonly WargamingAuthService wargamingAuthService;
private readonly JwtService jwtService;
private readonly IConfiguration _config;
private readonly UserService _userService;
private readonly WargamingAuthService _wargamingAuthService;
private readonly JwtService _jwtService;


public AuthController(IConfiguration config, UserService userService, WargamingAuthService wargamingAuthService, JwtService jwtService)
{
this.config = config;
this.userService = userService;
this.wargamingAuthService = wargamingAuthService;
this.jwtService = jwtService;
_config = config;
_userService = userService;
_wargamingAuthService = wargamingAuthService;
_jwtService = jwtService;
}

/// <summary>
Expand All @@ -57,33 +54,33 @@ public AuthController(IConfiguration config, UserService userService, WargamingA
[HttpGet("wg-callback"), ProducesResponseType(302), ProducesResponseType(200), ProducesResponseType(403)]
public async Task<IActionResult> WgAuthCallback()
{
bool valid = await wargamingAuthService.VerifyIdentity(Request);
bool valid = await _wargamingAuthService.VerifyIdentity(Request);

if (!valid)
{
return StatusCode(403);
}

JwtSecurityToken token = await userService.CreateTokenAsync(WargamingIdentity.FromUri(new(Request.Query["openid.identity"].FirstOrDefault()
JwtSecurityToken token = await _userService.CreateTokenAsync(WargamingIdentity.FromUri(new(Request.Query["openid.identity"].FirstOrDefault()
?? throw new BadHttpRequestException("Missing OpenID identity"))));

Response.Cookies.Append(
config[$"Api:{Startup.ApiRegion.ToRegionString()}:CookieName"],
jwtService.TokenHandler.WriteToken(token),
_config[$"Api:{Startup.ApiRegion.ToRegionString()}:CookieName"] ?? throw new ApplicationException("Missing Api:{region}:CookieName in configuration."),
_jwtService.TokenHandler.WriteToken(token),
new()
{
Domain = config[$"Api:{Startup.ApiRegion.ToRegionString()}:CookieDomain"],
Domain = _config[$"Api:{Startup.ApiRegion.ToRegionString()}:CookieDomain"],
HttpOnly = false,
IsEssential = true,
#if RELEASE
Secure = true,
Secure = true,
#endif
Expires = DateTime.UtcNow.AddDays(7)
});

return Request.Query["redirectUri"].FirstOrDefault() is { } redirectUri
? Redirect(redirectUri)
: StatusCode(200);
: Ok();
}

/// <summary>
Expand All @@ -94,8 +91,8 @@ public async Task<IActionResult> WgAuthCallback()
[HttpPost("renew-seed"), Authorize, ProducesResponseType(200), ProducesResponseType(401)]
public async Task<IActionResult> RenewSeed()
{
await userService.RenewSeedTokenAsync(uint.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)));
return StatusCode(200);
await _userService.RenewSeedTokenAsync(uint.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? throw new BadHttpRequestException("Missing NameIdentifier claim.")));
return Ok();
}

/// <summary>
Expand All @@ -106,7 +103,7 @@ public async Task<IActionResult> RenewSeed()
[HttpGet("refresh-token"), Authorize, ProducesResponseType(typeof(string), 200), ProducesResponseType(401)]
public async Task<IActionResult> RefreshToken()
{
JwtSecurityToken token = await userService.CreateTokenAsync(new(User.Claims));
return StatusCode(200, jwtService.TokenHandler.WriteToken(token));
JwtSecurityToken token = await _userService.CreateTokenAsync(new(User.Claims));
return StatusCode(200, _jwtService.TokenHandler.WriteToken(token));
}
}
17 changes: 7 additions & 10 deletions WowsKarma.Api/Controllers/ClanController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.ComponentModel.DataAnnotations;
using System.Threading;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using WowsKarma.Api.Services;
Expand All @@ -8,7 +7,7 @@
namespace WowsKarma.Api.Controllers;

[ApiController, Route("api/[controller]")]
public class ClanController : ControllerBase
public sealed class ClanController : ControllerBase
{
private readonly ClanService _clanService;

Expand All @@ -34,14 +33,12 @@ public ClanController(ClanService clanService)
/// <param name="ct"></param>
/// <returns>Clan Info, with members (if selected)</returns>
[HttpGet("{clanId}"), ProducesResponseType(typeof(ClanProfileDTO), 200), ProducesResponseType(typeof(ClanProfileFullDTO), 200)]
public async Task<ClanProfileDTO> GetClan(uint clanId, bool includeMembers = true, CancellationToken ct = default)
{
Clan clan = await _clanService.GetClanAsync(clanId, includeMembers, ct);

return includeMembers
? clan.Adapt<ClanProfileFullDTO>()
: clan.Adapt<ClanProfileDTO>();
}
public async Task<ClanProfileDTO?> GetClan(uint clanId, bool includeMembers = true, CancellationToken ct = default)
=> await _clanService.GetClanAsync(clanId, includeMembers, ct) is { } clan
? includeMembers
? clan.Adapt<ClanProfileFullDTO>()
: clan.Adapt<ClanProfileDTO>()
: null;

/// <summary>
/// Searches all clans relevant to a given search string.
Expand Down
6 changes: 2 additions & 4 deletions WowsKarma.Api/Controllers/PlayerController.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using System.Threading;
using Hangfire;
using Mapster;
using WowsKarma.Api.Services;
using WowsKarma.Common;


namespace WowsKarma.Api.Controllers;

[ApiController, Route("api/[controller]")]
public class PlayerController : ControllerBase
public sealed class PlayerController : ControllerBase
{
private readonly PlayerService _playerService;

Expand Down Expand Up @@ -63,7 +61,7 @@ public async Task<IActionResult> GetAccount(uint id, bool includeClanInfo = true
Player playerProfile = await _playerService.GetPlayerAsync(id, false, includeClanInfo);

return playerProfile is null
? NoContent()
? NotFound()
: Ok(playerProfile.Adapt<PlayerProfileDTO>());
}

Expand Down
Loading

0 comments on commit daadec2

Please sign in to comment.