update .net, setup modern logging
Some checks failed
Build and Publish / Build Yale Access Backend (pull_request) Failing after 1m28s
Build and Publish / Push Yale Access Backend Docker Image (pull_request) Has been skipped
Build and Publish / Build Yale Access Frontend (pull_request) Successful in 1m42s
Build and Publish / Push Yale Access Frontend Docker Image (pull_request) Has been skipped
Some checks failed
Build and Publish / Build Yale Access Backend (pull_request) Failing after 1m28s
Build and Publish / Push Yale Access Backend Docker Image (pull_request) Has been skipped
Build and Publish / Build Yale Access Frontend (pull_request) Successful in 1m42s
Build and Publish / Push Yale Access Frontend Docker Image (pull_request) Has been skipped
This commit is contained in:
@@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Serilog;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using YaleAccess.Models;
|
using YaleAccess.Models;
|
||||||
|
|
||||||
@@ -14,15 +13,8 @@ namespace YaleAccess.Controllers
|
|||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[EnableCors]
|
[EnableCors]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class AuthenticationController : ControllerBase
|
public class AuthenticationController(IOptions<Models.Options.AuthenticationOptions> authenticationOptions, ILogger<AuthenticationController> logger) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly Models.Options.AuthenticationOptions _authenticationOptions;
|
|
||||||
|
|
||||||
public AuthenticationController(IOptions<Models.Options.AuthenticationOptions> authenticationOptions)
|
|
||||||
{
|
|
||||||
_authenticationOptions = authenticationOptions.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("login")]
|
[HttpPost("login")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public async Task<IActionResult> Login([FromBody] string password)
|
public async Task<IActionResult> Login([FromBody] string password)
|
||||||
@@ -30,7 +22,7 @@ namespace YaleAccess.Controllers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Check if the password is correct
|
// Check if the password is correct
|
||||||
if (password != _authenticationOptions.Password)
|
if (password != authenticationOptions.Value.Password)
|
||||||
{
|
{
|
||||||
return Unauthorized(new ApiResponse("Incorrect password."));
|
return Unauthorized(new ApiResponse("Incorrect password."));
|
||||||
}
|
}
|
||||||
@@ -50,7 +42,7 @@ namespace YaleAccess.Controllers
|
|||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occurred logging in.");
|
logger.LogError(ex, "An error occurred logging in.");
|
||||||
return BadRequest(new ApiResponse("An error occurred logging in."));
|
return BadRequest(new ApiResponse("An error occurred logging in."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,7 +60,7 @@ namespace YaleAccess.Controllers
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occured logging out.");
|
logger.LogError(ex, "An error occured logging out.");
|
||||||
return BadRequest(new ApiResponse("An error occured logging out."));
|
return BadRequest(new ApiResponse("An error occured logging out."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace YaleAccess.Controllers
|
namespace YaleAccess.Controllers
|
||||||
{
|
{
|
||||||
@@ -9,13 +8,13 @@ namespace YaleAccess.Controllers
|
|||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[EnableCors]
|
[EnableCors]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class HealthController : ControllerBase
|
public class HealthController(ILogger<HealthController> logger) : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public IActionResult Health()
|
public IActionResult Health()
|
||||||
{
|
{
|
||||||
Log.Logger.Information("Hit the health endpoint.");
|
logger.LogInformation("Hit the health endpoint.");
|
||||||
return Ok("Service is healthy");
|
return Ok("Service is healthy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Serilog;
|
|
||||||
using YaleAccess.Data;
|
using YaleAccess.Data;
|
||||||
using YaleAccess.Models;
|
using YaleAccess.Models;
|
||||||
|
|
||||||
@@ -12,27 +11,20 @@ namespace YaleAccess.Controllers
|
|||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[EnableCors]
|
[EnableCors]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class PeopleController : ControllerBase
|
public class PeopleController(ILogger<PeopleController> logger, YaleContext context) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly YaleContext _context;
|
|
||||||
|
|
||||||
public PeopleController(YaleContext context)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetPeople()
|
public async Task<IActionResult> GetPeople()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Return all people
|
// Return all people
|
||||||
List<Person> people = await _context.People.ToListAsync();
|
List<Person> people = await context.People.ToListAsync();
|
||||||
return Ok(new ApiResponse(people));
|
return Ok(new ApiResponse(people));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occured retriving the people.");
|
logger.LogError(ex, "An error occured retriving the people.");
|
||||||
return BadRequest(new ApiResponse("An error occured retriving the people."));
|
return BadRequest(new ApiResponse("An error occured retriving the people."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,15 +38,15 @@ namespace YaleAccess.Controllers
|
|||||||
Person newPerson = new() { Name = person.Name, PhoneNumber = person.PhoneNumber };
|
Person newPerson = new() { Name = person.Name, PhoneNumber = person.PhoneNumber };
|
||||||
|
|
||||||
// Add the person
|
// Add the person
|
||||||
await _context.AddAsync(newPerson);
|
await context.AddAsync(newPerson);
|
||||||
await _context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
// Return the newly created person
|
// Return the newly created person
|
||||||
return Ok(new ApiResponse(newPerson));
|
return Ok(new ApiResponse(newPerson));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occured creating the person.");
|
logger.LogError(ex, "An error occured creating the person.");
|
||||||
return BadRequest(new ApiResponse("An error occured creating the person."));
|
return BadRequest(new ApiResponse("An error occured creating the person."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,18 +57,18 @@ namespace YaleAccess.Controllers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Ensure the person exists
|
// Ensure the person exists
|
||||||
Person person = await _context.People.FindAsync(id) ?? throw new Exception("Person not found.");
|
Person person = await context.People.FindAsync(id) ?? throw new Exception("Person not found.");
|
||||||
|
|
||||||
// Remove the person
|
// Remove the person
|
||||||
_context.Remove(person);
|
context.Remove(person);
|
||||||
await _context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
// Return the newly removed person
|
// Return the newly removed person
|
||||||
return Ok(new ApiResponse(person));
|
return Ok(new ApiResponse(person));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occured deletiong the person.");
|
logger.LogError(ex, "An error occured deletiong the person.");
|
||||||
return BadRequest(new ApiResponse("An error occured deletiong the person."));
|
return BadRequest(new ApiResponse("An error occured deletiong the person."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Serilog;
|
|
||||||
using YaleAccess.Models;
|
using YaleAccess.Models;
|
||||||
using YaleAccess.Models.Options;
|
using YaleAccess.Models.Options;
|
||||||
using YaleAccess.Services;
|
using YaleAccess.Services;
|
||||||
@@ -14,33 +13,27 @@ namespace YaleAccess.Controllers
|
|||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[EnableCors]
|
[EnableCors]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class YaleController : ControllerBase
|
public class YaleController(
|
||||||
|
ILogger<YaleController> logger,
|
||||||
|
IYaleAccessor yaleAccessor,
|
||||||
|
IOptions<CodesOptions> codeOptions,
|
||||||
|
SMSService smsService
|
||||||
|
) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IYaleAccessor _yaleAccessor;
|
|
||||||
private readonly CodesOptions _codeOptions;
|
|
||||||
private readonly SMSService _smsService;
|
|
||||||
|
|
||||||
public YaleController(IYaleAccessor yaleAccessor, IOptions<CodesOptions> codeOptions, SMSService smsService)
|
|
||||||
{
|
|
||||||
_yaleAccessor = yaleAccessor;
|
|
||||||
_codeOptions = codeOptions.Value;
|
|
||||||
_smsService = smsService;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("codes")]
|
[HttpGet("codes")]
|
||||||
public async Task<IActionResult> GetUserCodes()
|
public async Task<IActionResult> GetUserCodes()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Get the home code first
|
// Get the home code first
|
||||||
YaleUserCode homeCode = await _yaleAccessor.GetCodeInformationAsync(_codeOptions.Home);
|
YaleUserCode homeCode = await yaleAccessor.GetCodeInformationAsync(codeOptions.Value.Home);
|
||||||
homeCode.IsHome = true;
|
homeCode.IsHome = true;
|
||||||
|
|
||||||
// Get the guest codes
|
// Get the guest codes
|
||||||
List<YaleUserCode> guestCodes = new();
|
List<YaleUserCode> guestCodes = new();
|
||||||
foreach (int code in Enumerable.Range(_codeOptions.GuestCodeRangeStart, _codeOptions.GuestCodeRangeCount))
|
foreach (int code in Enumerable.Range(codeOptions.Value.GuestCodeRangeStart, codeOptions.Value.GuestCodeRangeCount))
|
||||||
{
|
{
|
||||||
guestCodes.Add(await _yaleAccessor.GetCodeInformationAsync(code));
|
guestCodes.Add(await yaleAccessor.GetCodeInformationAsync(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the home code to the list
|
// Add the home code to the list
|
||||||
@@ -51,7 +44,7 @@ namespace YaleAccess.Controllers
|
|||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occurred retriving the codes.");
|
logger.LogError(ex, "An error occurred retriving the codes.");
|
||||||
return BadRequest(new ApiResponse("An error occurred retriving the codes."));
|
return BadRequest(new ApiResponse("An error occurred retriving the codes."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,23 +62,23 @@ namespace YaleAccess.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the new code
|
// Set the new code
|
||||||
bool result = await _yaleAccessor.SetUserCode(id, newCode);
|
bool result = await yaleAccessor.SetUserCode(id, newCode);
|
||||||
|
|
||||||
// Return the result
|
// Return the result
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
Log.Logger.Information("Updated code for user {id} to {code}", id, newCode);
|
logger.LogInformation("Updated code for user {id} to {code}", id, newCode);
|
||||||
return Ok(new ApiResponse(true));
|
return Ok(new ApiResponse(true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Logger.Information("Failed to update code for user {id} to {code}", id, newCode);
|
logger.LogInformation("Failed to update code for user {id} to {code}", id, newCode);
|
||||||
return BadRequest(new ApiResponse("An error occurred setting the code."));
|
return BadRequest(new ApiResponse("An error occurred setting the code."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occurred setting the code.");
|
logger.LogError(ex, "An error occurred setting the code.");
|
||||||
return BadRequest(new ApiResponse("An error occurred setting the code."));
|
return BadRequest(new ApiResponse("An error occurred setting the code."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,30 +89,30 @@ namespace YaleAccess.Controllers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// First validate the user code
|
// First validate the user code
|
||||||
string validCode = YaleAccessor.ValidateClearCode(id, _codeOptions.Home);
|
string validCode = YaleAccessor.ValidateClearCode(id, codeOptions.Value.Home);
|
||||||
if (validCode != string.Empty)
|
if (validCode != string.Empty)
|
||||||
{
|
{
|
||||||
return BadRequest(new ApiResponse(validCode));
|
return BadRequest(new ApiResponse(validCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the available status
|
// Set the available status
|
||||||
bool result = await _yaleAccessor.SetCodeAsAvailable(id);
|
bool result = await yaleAccessor.SetCodeAsAvailable(id);
|
||||||
|
|
||||||
// Return the result
|
// Return the result
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
Log.Logger.Information("Updated code status for user {id} to available", id);
|
logger.LogInformation("Updated code status for user {id} to available", id);
|
||||||
return Ok(new ApiResponse(true));
|
return Ok(new ApiResponse(true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Logger.Information("Failed to update code status for user {id} to available", id);
|
logger.LogInformation("Failed to update code status for user {id} to available", id);
|
||||||
return BadRequest(new ApiResponse("An error occurred setting the code status."));
|
return BadRequest(new ApiResponse("An error occurred setting the code status."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occurred setting the code status.");
|
logger.LogError(ex, "An error occurred setting the code status.");
|
||||||
return BadRequest(new ApiResponse("An error occurred setting the code status."));
|
return BadRequest(new ApiResponse("An error occurred setting the code status."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,17 +123,17 @@ namespace YaleAccess.Controllers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Get the user code
|
// Get the user code
|
||||||
YaleUserCode userCode = await _yaleAccessor.GetCodeInformationAsync(id);
|
YaleUserCode userCode = await yaleAccessor.GetCodeInformationAsync(id);
|
||||||
|
|
||||||
// Send the code via SMS to the phone number
|
// Send the code via SMS to the phone number
|
||||||
await _smsService.SendCodeViaSMSAsync(userCode.Code, phoneNumber);
|
await smsService.SendCodeViaSMSAsync(userCode.Code, phoneNumber);
|
||||||
|
|
||||||
// Return success
|
// Return success
|
||||||
return Ok(new ApiResponse(true));
|
return Ok(new ApiResponse(true));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, "An error occurred sending the code.");
|
logger.LogError(ex, "An error occurred sending the code.");
|
||||||
return BadRequest(new ApiResponse("An error occurred sending the code."));
|
return BadRequest(new ApiResponse("An error occurred sending the code."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
|
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 8080
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY ["YaleAccess.csproj", "."]
|
COPY ["YaleAccess.csproj", "."]
|
||||||
RUN dotnet restore "./YaleAccess.csproj"
|
RUN dotnet restore "./YaleAccess.csproj"
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Serilog;
|
using OpenTelemetry.Logs;
|
||||||
using Serilog.Events;
|
|
||||||
using YaleAccess.Data;
|
using YaleAccess.Data;
|
||||||
using YaleAccess.Models.Options;
|
using YaleAccess.Models.Options;
|
||||||
using YaleAccess.Services;
|
using YaleAccess.Services;
|
||||||
@@ -10,15 +9,25 @@ using YaleAccess.Services.Interfaces;
|
|||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
// Create the bootstraper logger
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
|
||||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
|
|
||||||
.Enrich.FromLogContext()
|
|
||||||
.WriteTo.Console()
|
|
||||||
.CreateLogger();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
|
||||||
|
|
||||||
|
builder.Logging.AddOpenTelemetry(logging =>
|
||||||
|
{
|
||||||
|
logging.IncludeFormattedMessage = true;
|
||||||
|
logging.IncludeScopes = true;
|
||||||
|
|
||||||
|
if (useOtlpExporter)
|
||||||
|
{
|
||||||
|
logging.AddOtlpExporter();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("OTEL_EXPORTER_OTLP_ENDPOINT is not set. Skipping OTLP exporter configuration.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
@@ -41,13 +50,6 @@ try
|
|||||||
|
|
||||||
// Get a copy of the configuration
|
// Get a copy of the configuration
|
||||||
IConfiguration configuration = builder.Configuration;
|
IConfiguration configuration = builder.Configuration;
|
||||||
string logLocation = configuration["LogLocation"] ?? "Log.txt";
|
|
||||||
|
|
||||||
// Setup the application logger
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
|
||||||
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Error)
|
|
||||||
.WriteTo.File(logLocation, rollingInterval: RollingInterval.Day)
|
|
||||||
.CreateLogger();
|
|
||||||
|
|
||||||
// Configure the DI services
|
// Configure the DI services
|
||||||
builder.Services.AddScoped<SMSService>();
|
builder.Services.AddScoped<SMSService>();
|
||||||
@@ -100,9 +102,6 @@ try
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Setup logging flow
|
|
||||||
builder.Host.UseSerilog();
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Create the database if it doesn't exist
|
// Create the database if it doesn't exist
|
||||||
@@ -144,11 +143,7 @@ catch (Exception ex)
|
|||||||
// Ignore host aborted exceptions caused by build checks
|
// Ignore host aborted exceptions caused by build checks
|
||||||
if (ex is not HostAbortedException)
|
if (ex is not HostAbortedException)
|
||||||
{
|
{
|
||||||
Log.Fatal(ex, "Host terminated unexpectedly");
|
Console.WriteLine("Host terminated unexpectedly");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
Log.CloseAndFlush();
|
|
||||||
}
|
|
||||||
@@ -1,35 +1,27 @@
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Serilog;
|
|
||||||
using Twilio;
|
using Twilio;
|
||||||
using Twilio.Rest.Api.V2010.Account;
|
using Twilio.Rest.Api.V2010.Account;
|
||||||
using YaleAccess.Models.Options;
|
using YaleAccess.Models.Options;
|
||||||
|
|
||||||
namespace YaleAccess.Services
|
namespace YaleAccess.Services
|
||||||
{
|
{
|
||||||
public class SMSService
|
public class SMSService(ILogger<SMSService> logger, IOptions<TwiloOptions> twiloOptions)
|
||||||
{
|
{
|
||||||
private readonly TwiloOptions _twiloOptions;
|
|
||||||
|
|
||||||
public SMSService(IOptions<TwiloOptions> twiloOptions)
|
|
||||||
{
|
|
||||||
_twiloOptions = twiloOptions.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SendCodeViaSMSAsync(string code, string phoneNumber)
|
public async Task SendCodeViaSMSAsync(string code, string phoneNumber)
|
||||||
{
|
{
|
||||||
// Create a Twilio client
|
// Create a Twilio client
|
||||||
TwilioClient.Init(_twiloOptions.AccountSid, _twiloOptions.AuthToken);
|
TwilioClient.Init(twiloOptions.Value.AccountSid, twiloOptions.Value.AuthToken);
|
||||||
|
|
||||||
// Send the message
|
// Send the message
|
||||||
var message = await MessageResource.CreateAsync(
|
var message = await MessageResource.CreateAsync(
|
||||||
body: $"{_twiloOptions.Message} {code}",
|
body: $"{twiloOptions.Value.Message} {code}",
|
||||||
from: new Twilio.Types.PhoneNumber(_twiloOptions.FromNumber),
|
from: new Twilio.Types.PhoneNumber(twiloOptions.Value.FromNumber),
|
||||||
to: new Twilio.Types.PhoneNumber(phoneNumber)
|
to: new Twilio.Types.PhoneNumber(phoneNumber)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Log the message
|
// Log the message
|
||||||
Log.Logger.Information("SMS sent to {PhoneNumber} with message SID {MessageSid}.", phoneNumber, message.Sid);
|
logger.LogInformation("SMS sent to {PhoneNumber} with message SID {MessageSid}.", phoneNumber, message.Sid);
|
||||||
Log.Logger.Debug("SMS message: {MessageBody}", message.Body);
|
logger.LogDebug("SMS message: {MessageBody}", message.Body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Serilog;
|
|
||||||
using YaleAccess.Models;
|
using YaleAccess.Models;
|
||||||
using YaleAccess.Models.Options;
|
using YaleAccess.Models.Options;
|
||||||
using YaleAccess.Services.Interfaces;
|
using YaleAccess.Services.Interfaces;
|
||||||
@@ -38,10 +37,11 @@ namespace YaleAccess.Services
|
|||||||
|
|
||||||
#endregion Dispose Logic
|
#endregion Dispose Logic
|
||||||
|
|
||||||
|
private readonly ILogger<YaleAccessor> _logger;
|
||||||
private Driver? driver = null;
|
private Driver? driver = null;
|
||||||
private readonly ZWaveNode lockNode = null!;
|
private readonly ZWaveNode lockNode = null!;
|
||||||
|
|
||||||
public YaleAccessor(IOptions<ZWaveOptions> zwave, IOptions<DevicesOptions> device)
|
public YaleAccessor(IOptions<ZWaveOptions> zwave, IOptions<DevicesOptions> device, ILogger<YaleAccessor> logger)
|
||||||
{
|
{
|
||||||
// Retrive options from configuration
|
// Retrive options from configuration
|
||||||
ZWaveOptions zwaveOptions = zwave.Value;
|
ZWaveOptions zwaveOptions = zwave.Value;
|
||||||
@@ -75,6 +75,8 @@ namespace YaleAccess.Services
|
|||||||
|
|
||||||
// Get the lock node from the driver
|
// Get the lock node from the driver
|
||||||
lockNode = driver.Controller.Nodes.Get(devicesOptions.YaleLockNodeId);
|
lockNode = driver.Controller.Nodes.Get(devicesOptions.YaleLockNodeId);
|
||||||
|
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<YaleUserCode> GetCodeInformationAsync(int userCodeId)
|
public async Task<YaleUserCode> GetCodeInformationAsync(int userCodeId)
|
||||||
@@ -101,7 +103,7 @@ namespace YaleAccess.Services
|
|||||||
// If the result is not successful log the message
|
// If the result is not successful log the message
|
||||||
if (!result.Success)
|
if (!result.Success)
|
||||||
{
|
{
|
||||||
Log.Logger.Error("Failed to set user code {@userCodeId} to {@code}. Error message: {message}", userCodeId, code, result.Message);
|
_logger.LogError("Failed to set user code {@userCodeId} to {@code}. Error message: {message}", userCodeId, code, result.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the result
|
// Return the result
|
||||||
@@ -116,7 +118,7 @@ namespace YaleAccess.Services
|
|||||||
// If the result is not successful log the message
|
// If the result is not successful log the message
|
||||||
if (!result.Success)
|
if (!result.Success)
|
||||||
{
|
{
|
||||||
Log.Logger.Error("Failed to set user code {@userCode} to available status. Error message: {message}", userCode, result.Message);
|
_logger.LogError("Failed to set user code {@userCode} to available status. Error message: {message}", userCode, result.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the result
|
// Return the result
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<UserSecretsId>83aa9238-2d6b-483c-b60d-886f32d17532</UserSecretsId>
|
<UserSecretsId>83aa9238-2d6b-483c-b60d-886f32d17532</UserSecretsId>
|
||||||
@@ -17,23 +17,20 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.13" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.20" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.20">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<PackageReference Include="Semver" Version="2.3.0" />
|
<PackageReference Include="OpenTelemetry" Version="1.15.0" />
|
||||||
<PackageReference Include="Serilog" Version="3.0.1" />
|
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.0" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
|
<PackageReference Include="Semver" Version="3.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.3" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
<PackageReference Include="System.Reactive" Version="6.1.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
|
||||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
|
||||||
<PackageReference Include="System.Threading.Channels" Version="5.0.0" />
|
|
||||||
<PackageReference Include="Twilio" Version="7.8.0" />
|
<PackageReference Include="Twilio" Version="7.8.0" />
|
||||||
<PackageReference Include="Websocket.Client" Version="4.6.1" />
|
<PackageReference Include="Websocket.Client" Version="4.6.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user