Skip to content

Commit

Permalink
Email template start and rework training models
Browse files Browse the repository at this point in the history
  • Loading branch information
fixterjake committed Oct 24, 2023
1 parent f1446dc commit a01968c
Show file tree
Hide file tree
Showing 130 changed files with 10,959 additions and 552 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/create-tag.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
jobs:
CreateTag:
if: github.event.pull_request.merged == true
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
permissions:
contents: write
steps:
Expand Down
57 changes: 23 additions & 34 deletions Memphis.API/Controllers/AirportsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Memphis.API.Data;
using Memphis.API.Extensions;
using Memphis.API.Services;
using Memphis.Shared.Dtos;
using Memphis.Shared.Models;
using Memphis.Shared.Utils;
using Microsoft.AspNetCore.Authorization;
Expand All @@ -22,12 +23,12 @@ public class AirportsController : ControllerBase
private readonly DatabaseContext _context;
private readonly RedisService _redisService;
private readonly LoggingService _loggingService;
private readonly IValidator<Airport> _validator;
private readonly IValidator<AirportDto> _validator;
private readonly IHub _sentryHub;
private readonly ILogger<AirportsController> _logger;

public AirportsController(DatabaseContext context, RedisService redisService, LoggingService loggingService,
IValidator<Airport> validator, IHub sentryHub, ILogger<AirportsController> logger)
IValidator<AirportDto> validator, IHub sentryHub, ILogger<AirportsController> logger)
{
_context = context;
_redisService = redisService;
Expand All @@ -39,17 +40,17 @@ public AirportsController(DatabaseContext context, RedisService redisService, Lo


[HttpPost]
[Authorize(Roles = Constants.CAN_AIRPORTS)]
[Authorize(Roles = Constants.CanAirports)]
[ProducesResponseType(typeof(Response<Airport>), 200)]
[ProducesResponseType(typeof(Response<IList<ValidationFailure>>), 400)]
[ProducesResponseType(401)]
[ProducesResponseType(403)]
[ProducesResponseType(typeof(Response<string?>), 500)]
public async Task<ActionResult<Response<Airport>>> CreateAirport(Airport data)
public async Task<ActionResult<Response<Airport>>> CreateAirport(AirportDto data)
{
try
{
if (!await _redisService.ValidateRoles(Request.HttpContext.User, Constants.CAN_AIRPORTS_LIST))
if (!await _redisService.ValidateRoles(Request.HttpContext.User, Constants.CanAirportsList))
return StatusCode(401);

var validation = await _validator.ValidateAsync(data);
Expand All @@ -63,13 +64,16 @@ public async Task<ActionResult<Response<Airport>>> CreateAirport(Airport data)
});
}

var result = await _context.Airports.AddAsync(data);
var result = await _context.Airports.AddAsync(new Airport
{
Name = data.Name,
Icao = data.Icao,
});
await _context.SaveChangesAsync();
var newData = JsonConvert.SerializeObject(result.Entity);
await _loggingService.AddWebsiteLog(Request, $"Created airport {result.Entity.Id}", string.Empty, newData);

await _redisService.RemoveCached("airports");
return CreatedAtAction(nameof(GetAirport), new { airportId = result.Entity.Id }, new Response<Airport>
return Ok(new Response<Airport>
{
StatusCode = 200,
Message = $"Created airport '{result.Entity.Id}'",
Expand All @@ -90,20 +94,7 @@ public async Task<ActionResult<Response<IList<Airport>>>> GetAirports()
{
try
{
var cached = await _redisService.GetCached("airports");
_logger.LogDebug("Cached airports: {Airports}", cached);
if (cached != null)
{
var cachedResult = JsonConvert.DeserializeObject<IList<Airport>>(cached);
return Ok(new Response<IList<Airport>>
{
StatusCode = 200,
Message = $"Got {cachedResult?.Count} airports",
Data = cachedResult
});
}
var result = await _context.Airports.ToListAsync();
await _redisService.SetCached("airports", JsonConvert.SerializeObject(result));
return Ok(new Response<IList<Airport>>
{
StatusCode = 200,
Expand Down Expand Up @@ -151,19 +142,19 @@ public async Task<ActionResult<Response<IList<Airport>>>> GetAirport(int airport
}
}

[HttpPut]
[Authorize(Roles = Constants.CAN_AIRPORTS)]
[HttpPut("{airportId:int}")]
[Authorize(Roles = Constants.CanAirports)]
[ProducesResponseType(typeof(Response<Airport>), 200)]
[ProducesResponseType(typeof(Response<IList<ValidationFailure>>), 400)]
[ProducesResponseType(401)]
[ProducesResponseType(403)]
[ProducesResponseType(typeof(Response<int>), 404)]
[ProducesResponseType(typeof(Response<string?>), 404)]
[ProducesResponseType(typeof(Response<string?>), 500)]
public async Task<ActionResult<Response<Airport>>> UpdateAirport(Airport data)
public async Task<ActionResult<Response<Airport>>> UpdateAirport(int airportId, AirportDto data)
{
try
{
if (!await _redisService.ValidateRoles(Request.HttpContext.User, Constants.CAN_AIRPORTS_LIST))
if (!await _redisService.ValidateRoles(Request.HttpContext.User, Constants.CanAirportsList))
return StatusCode(401);

var validation = await _validator.ValidateAsync(data);
Expand All @@ -177,14 +168,13 @@ public async Task<ActionResult<Response<Airport>>> UpdateAirport(Airport data)
});
}

var airport = await _context.Airports.FindAsync(data.Id);
var airport = await _context.Airports.FindAsync(airportId);
if (airport == null)
{
return NotFound(new Response<int>
return NotFound(new Response<string?>
{
StatusCode = 404,
Message = $"Airport '{data.Id}' not found",
Data = data.Id
Message = $"Airport '{airportId}' not found",
});
}

Expand All @@ -197,7 +187,6 @@ public async Task<ActionResult<Response<Airport>>> UpdateAirport(Airport data)

await _loggingService.AddWebsiteLog(Request, $"Updated airport '{airport.Id}'", oldData, newData);

await _redisService.RemoveCached("airports");
return Ok(new Response<Airport>
{
StatusCode = 200,
Expand All @@ -213,7 +202,7 @@ public async Task<ActionResult<Response<Airport>>> UpdateAirport(Airport data)
}

[HttpDelete("{airportId:int}")]
[Authorize(Roles = Constants.CAN_AIRPORTS)]
[Authorize(Roles = Constants.CanAirports)]
[ProducesResponseType(typeof(Response<string?>), 200)]
[ProducesResponseType(401)]
[ProducesResponseType(403)]
Expand All @@ -223,7 +212,7 @@ public async Task<ActionResult<Response<string>>> DeleteAirport(int airportId)
{
try
{
if (!await _redisService.ValidateRoles(Request.HttpContext.User, Constants.CAN_AIRPORTS_LIST))
if (!await _redisService.ValidateRoles(Request.HttpContext.User, Constants.CanAirportsList))
return StatusCode(401);

var airport = await _context.Airports.FindAsync(airportId);
Expand Down Expand Up @@ -256,4 +245,4 @@ public async Task<ActionResult<Response<string>>> DeleteAirport(int airportId)
return _sentryHub.CaptureException(ex).ReturnActionResult();
}
}
}
}
60 changes: 33 additions & 27 deletions Memphis.API/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Memphis.API.Data;
using Memphis.API.Extensions;
using Memphis.API.Services;
using Memphis.Shared.Dtos;
using Memphis.Shared.Dtos.auth;
using Memphis.Shared.Enums;
using Memphis.Shared.Utils;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -25,7 +25,8 @@ public class AuthController : ControllerBase
private readonly IHub _sentryHub;
private readonly ILogger<AuthController> _logger;

public AuthController(DatabaseContext context, RedisService redisService, IHub sentryHub, ILogger<AuthController> logger)
public AuthController(DatabaseContext context, RedisService redisService, IHub sentryHub,
ILogger<AuthController> logger)
{
_context = context;
_redisService = redisService;
Expand All @@ -41,12 +42,13 @@ public async Task<IActionResult> RedirectToVatsim()
try
{
var authUrl = Environment.GetEnvironmentVariable("CONNECT_AUTH_URL") ??
throw new ArgumentNullException("CONNECT_AUTH_URL env variable not found");
throw new ArgumentNullException("CONNECT_AUTH_URL env variable not found");
var clientId = Environment.GetEnvironmentVariable("CONNECT_CLIENT_ID") ??
throw new ArgumentNullException("CONNECT_CLIENT_ID env variable not found");
throw new ArgumentNullException("CONNECT_CLIENT_ID env variable not found");
var redirectUrl = Environment.GetEnvironmentVariable("CONNECT_REDIRECT_URL") ??
throw new ArgumentNullException("CONNECT_REDIRECT_URL env variable not found");
var url = $"{authUrl}/oauth/authorize?client_id={clientId}&redirect_uri={redirectUrl}&response_type=code&scope=full_name+vatsim_details+email";
throw new ArgumentNullException("CONNECT_REDIRECT_URL env variable not found");
var url =
$"{authUrl}/oauth/authorize?client_id={clientId}&redirect_uri={redirectUrl}&response_type=code&scope=full_name+vatsim_details+email";
await Task.CompletedTask;
return RedirectPreserveMethod(url);
}
Expand All @@ -64,23 +66,24 @@ public async Task<IActionResult> ProcessCallback(string code)
try
{
var authUrl = Environment.GetEnvironmentVariable("CONNECT_AUTH_URL") ??
throw new ArgumentNullException("CONNECT_AUTH_URL env variable not found");
throw new ArgumentNullException("CONNECT_AUTH_URL env variable not found");
var clientId = Environment.GetEnvironmentVariable("CONNECT_CLIENT_ID") ??
throw new ArgumentNullException("CONNECT_CLIENT_ID env variable not found");
throw new ArgumentNullException("CONNECT_CLIENT_ID env variable not found");
var clientSecret = Environment.GetEnvironmentVariable("CONNECT_CLIENT_SECRET") ??
throw new ArgumentNullException("CONNECT_CLIENT_SECRET env variable not found");
throw new ArgumentNullException("CONNECT_CLIENT_SECRET env variable not found");
var redirectUrl = Environment.GetEnvironmentVariable("CONNECT_REDIRECT_URL") ??
throw new ArgumentNullException("CONNECT_REDIRECT_URL env variable not found");
throw new ArgumentNullException("CONNECT_REDIRECT_URL env variable not found");
var uiRedirect = Environment.GetEnvironmentVariable("CONNEXT_REDIRECT_URL_UI") ??
throw new ArgumentNullException("CONNEXT_REDIRECT_URL_UI env variable not found");
throw new ArgumentNullException("CONNEXT_REDIRECT_URL_UI env variable not found");
var issuer = Environment.GetEnvironmentVariable("JWT_ISSUER") ??
throw new ArgumentNullException("JWT_ISSUER env variable not found");
throw new ArgumentNullException("JWT_ISSUER env variable not found");
var audience = Environment.GetEnvironmentVariable("JWT_AUDIENCE") ??
throw new ArgumentNullException("JWT_AUDIENCE env variable not found");
throw new ArgumentNullException("JWT_AUDIENCE env variable not found");
var secret = Environment.GetEnvironmentVariable("JWT_SECRET") ??
throw new ArgumentNullException("JWT_SECRET env variable not found");
throw new ArgumentNullException("JWT_SECRET env variable not found");
var expirationDays = int.Parse(Environment.GetEnvironmentVariable("JWT_ACCESS_EXPIRATION") ??
throw new ArgumentNullException("JWT_ACCESS_EXPIRATION env variable not found"));
throw new ArgumentNullException(
"JWT_ACCESS_EXPIRATION env variable not found"));

var tokenRequest = new FormUrlEncodedContent(new Dictionary<string, string>
{
Expand All @@ -101,7 +104,8 @@ public async Task<IActionResult> ProcessCallback(string code)
var token = JsonConvert.DeserializeObject<VatsimTokenDto>(content);
if (token == null)
{
_logger.LogError("Invalid VATSIM token response:\nconnect response code: {Code}\ncontent: {Content}", response.StatusCode, content);
_logger.LogError("Invalid VATSIM token response:\nconnect response code: {Code}\ncontent: {Content}",
response.StatusCode, content);
throw new InvalidDataException("Invalid VATSIM token response");
}

Expand All @@ -110,21 +114,22 @@ public async Task<IActionResult> ProcessCallback(string code)

if (data == null)
{
_logger.LogError("Invalid VATSIM data response:\nconnect response code: {Code}\ndata: {Data}", response.StatusCode, data);
_logger.LogError("Invalid VATSIM data response:\nconnect response code: {Code}\ndata: {Data}",
response.StatusCode, data);
throw new InvalidDataException("Invalid VATSIM data response");
}

var claims = new List<Claim>()
{
new Claim("cid", $"{data.Data.Cid}"),
new Claim("email", data.Data.PersonalDetails.Email),
new Claim("fullName", data.Data.PersonalDetails.NameFull),
new Claim("firstName", data.Data.PersonalDetails.NameFirst),
new Claim("lastName", data.Data.PersonalDetails.NameLast),
new Claim("rating", $"{data.Data.VatsimDetails.ControllerRating.Id}"),
new Claim("ratingLong", data.Data.VatsimDetails.ControllerRating.Long),
new Claim("region", data.Data.VatsimDetails.Region.Id),
new Claim("division", data.Data.VatsimDetails.Division.Id),
new("cid", $"{data.Data.Cid}"),
new("email", data.Data.PersonalDetails.Email),
new("fullName", data.Data.PersonalDetails.NameFull),
new("firstName", data.Data.PersonalDetails.NameFirst),
new("lastName", data.Data.PersonalDetails.NameLast),
new("rating", $"{data.Data.VatsimDetails.ControllerRating.Id}"),
new("ratingLong", data.Data.VatsimDetails.ControllerRating.Long),
new("region", data.Data.VatsimDetails.Region.Id),
new("division", data.Data.VatsimDetails.Division.Id),
};
var user = await _context.Users.Include(x => x.Roles).FirstOrDefaultAsync(x => x.Id == data.Data.Cid);

Expand All @@ -138,7 +143,8 @@ public async Task<IActionResult> ProcessCallback(string code)
claims,
expires: DateTime.UtcNow.AddDays(expirationDays),
signingCredentials: new SigningCredentials(
new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)), SecurityAlgorithms.HmacSha256Signature
new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)),
SecurityAlgorithms.HmacSha256Signature
)
);
var accessTokenNone = new JwtSecurityTokenHandler().WriteToken(jwtNone);
Expand Down
Loading

0 comments on commit a01968c

Please sign in to comment.