diff --git a/OdectyMVC/BasicAuthenticationHandler.cs b/OdectyMVC/BasicAuthenticationHandler.cs index 2aaec5f..6f8cf9a 100644 --- a/OdectyMVC/BasicAuthenticationHandler.cs +++ b/OdectyMVC/BasicAuthenticationHandler.cs @@ -24,16 +24,16 @@ public BasicAuthenticationHandler( protected override Task HandleAuthenticateAsync() { - if (!Request.Headers.ContainsKey("Authorization")) + if (!Request!.Headers.ContainsKey("Authorization")) return Task.FromResult(AuthenticateResult.Fail("Missing Authorization Header")); try { - var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); + var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]!); if (!authHeader.Scheme.Equals("Basic", StringComparison.OrdinalIgnoreCase)) return Task.FromResult(AuthenticateResult.Fail("Invalid scheme")); - var credentials = Encoding.UTF8.GetString(Convert.FromBase64String(authHeader.Parameter)).Split(':'); + var credentials = Encoding.UTF8.GetString(Convert.FromBase64String(authHeader.Parameter ?? string.Empty)).Split(':'); var username = credentials[0]; var password = credentials[1]; diff --git a/OdectyMVC/DataLayer/GaugeListModelRepository.cs b/OdectyMVC/DataLayer/GaugeListModelRepository.cs index 95b6061..39f1351 100644 --- a/OdectyMVC/DataLayer/GaugeListModelRepository.cs +++ b/OdectyMVC/DataLayer/GaugeListModelRepository.cs @@ -64,8 +64,8 @@ public async Task GetLastPhoto(int id, CancellationToken cancella private sealed class OdectyStatGaugeDto { public int Id { get; set; } - public string Description { get; set; } - public string Type { get; set; } + public string? Description { get; set; } + public required string Type { get; set; } public decimal LastValue { get; set; } public DateTime? LastMeasurementAt { get; set; } public bool HasPhoto { get; set; } diff --git a/OdectyMVC/DataLayer/MessageQueue.cs b/OdectyMVC/DataLayer/MessageQueue.cs index 9c74de8..66a793f 100644 --- a/OdectyMVC/DataLayer/MessageQueue.cs +++ b/OdectyMVC/DataLayer/MessageQueue.cs @@ -9,7 +9,7 @@ namespace OdectyMVC.DataLayer { public class MessageQueue : IMessageQueue { - private readonly IChannel model; + private readonly IChannel? model; private readonly IOptions options; public MessageQueue(RabbitMQProvider rabbitMQProvider, IOptions options) diff --git a/OdectyMVC/DataLayer/QueueMapping.cs b/OdectyMVC/DataLayer/QueueMapping.cs index c5cfa6a..612c28d 100644 --- a/OdectyMVC/DataLayer/QueueMapping.cs +++ b/OdectyMVC/DataLayer/QueueMapping.cs @@ -2,7 +2,7 @@ public class QueueMapping { - public string QueueName { get; set; } - public string RoutingKey { get; set; } - public string ExchangeName { get; set; } + public required string QueueName { get; set; } + public string? RoutingKey { get; set; } + public string? ExchangeName { get; set; } } diff --git a/OdectyMVC/DataLayer/RabbitMQProvider.cs b/OdectyMVC/DataLayer/RabbitMQProvider.cs index d6d1902..1f010b0 100644 --- a/OdectyMVC/DataLayer/RabbitMQProvider.cs +++ b/OdectyMVC/DataLayer/RabbitMQProvider.cs @@ -6,7 +6,7 @@ namespace OdectyMVC.DataLayer; public class RabbitMQProvider : IDisposable { - private readonly IConnection connection; + private readonly IConnection? connection; private readonly IOptions options; private readonly bool connected = false; private bool first = true; @@ -15,16 +15,15 @@ public class RabbitMQProvider : IDisposable public RabbitMQProvider(IOptions options) { + this.options = options; try { var factory = new ConnectionFactory(); - factory.HostName = options.Value.HostName; - factory.UserName = options.Value.UserName; - factory.Password = options.Value.Password; - factory.VirtualHost = options.Value.VirtualHost; - + factory.HostName = this.options.Value.HostName; + factory.UserName = this.options.Value.UserName; + factory.Password = this.options.Value.Password; + factory.VirtualHost = this.options.Value.VirtualHost; connection = factory.CreateConnectionAsync().Result; - this.options = options; connected = true; } catch @@ -33,17 +32,17 @@ public RabbitMQProvider(IOptions options) } } - public async Task CreateModel() + public async Task CreateModel() { if (connected) { if (first) { - using var model = await connection.CreateChannelAsync(); + using var model = await connection!.CreateChannelAsync(); await model.ExchangeDeclareAsync(options.Value.ExchangeName, ExchangeType.Direct, true, false, null); foreach (var exchange in options.Value.QueueMappings.Select(q => q.ExchangeName).Distinct()) { - if (exchange.StartsWith("amq.")) + if (exchange == null || exchange.StartsWith("amq.")) { continue; } @@ -55,12 +54,20 @@ public async Task CreateModel() } foreach (var map in options.Value.QueueMappings) { + if (map.ExchangeName == null || map.RoutingKey == null) + { + continue; + } await model.QueueBindAsync(map.QueueName, map.ExchangeName, map.RoutingKey); } first = false; } } - return await connection.CreateChannelAsync(); + if (connection != null) + { + return await connection.CreateChannelAsync(); + } + return null; } public void Dispose() diff --git a/OdectyMVC/Models/GaugeListModel.cs b/OdectyMVC/Models/GaugeListModel.cs index 283135c..3b5f3d1 100644 --- a/OdectyMVC/Models/GaugeListModel.cs +++ b/OdectyMVC/Models/GaugeListModel.cs @@ -3,8 +3,8 @@ namespace OdectyMVC.Models public class GaugeListModel { public int Id { get; set; } - public string Description { get; set; } - public string Type { get; set; } + public string? Description { get; set; } + public required string Type { get; set; } public decimal LastValue { get; set; } public DateTime? LastMeasurementAt { get; set; } public bool HasPhoto { get; set; } diff --git a/OdectyMVC/OdectyMVC.csproj b/OdectyMVC/OdectyMVC.csproj index 0893cd3..1c71d8a 100644 --- a/OdectyMVC/OdectyMVC.csproj +++ b/OdectyMVC/OdectyMVC.csproj @@ -1,24 +1,24 @@  - net9.0 + net10.0 enable enable - - + + - + - - - - - - + + + + + + false diff --git a/OdectyMVC/Options/BasicAuthentication.cs b/OdectyMVC/Options/BasicAuthentication.cs index 4f4ee31..e56349b 100644 --- a/OdectyMVC/Options/BasicAuthentication.cs +++ b/OdectyMVC/Options/BasicAuthentication.cs @@ -2,6 +2,6 @@ public class BasicAuthentication { - public string Username { get; set; } - public string Password { get; set; } + public required string Username { get; set; } + public required string Password { get; set; } } diff --git a/OdectyMVC/Options/OdectyStatSettings.cs b/OdectyMVC/Options/OdectyStatSettings.cs index a862df9..802b4e0 100644 --- a/OdectyMVC/Options/OdectyStatSettings.cs +++ b/OdectyMVC/Options/OdectyStatSettings.cs @@ -2,5 +2,5 @@ namespace OdectyMVC.Options; public class OdectyStatSettings { - public string BaseUrl { get; set; } + public required string BaseUrl { get; set; } } diff --git a/OdectyMVC/Options/RabbitMQSettings.cs b/OdectyMVC/Options/RabbitMQSettings.cs index 4b72b56..4c77b57 100644 --- a/OdectyMVC/Options/RabbitMQSettings.cs +++ b/OdectyMVC/Options/RabbitMQSettings.cs @@ -4,10 +4,10 @@ namespace OdectyMVC.Options; public class RabbitMQSettings { - public string HostName { get; set; } - public string UserName { get; set; } - public string Password { get; set; } - public string VirtualHost { get; set; } - public string ExchangeName { get; set; } + public required string HostName { get; set; } + public required string UserName { get; set; } + public required string Password { get; set; } + public required string VirtualHost { get; set; } + public required string ExchangeName { get; set; } public List QueueMappings { get; set; } = new(); } diff --git a/OdectyMVC/Program.cs b/OdectyMVC/Program.cs index a1b27a3..a0bffe8 100644 --- a/OdectyMVC/Program.cs +++ b/OdectyMVC/Program.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.Identity.Web; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using OdectyMVC; using OdectyMVC.Application; using OdectyMVC.Contracts; @@ -99,6 +99,11 @@ { OnTokenValidated = context => { + if (context.Principal == null) + { + context.Fail("Unauthorized access"); + return Task.CompletedTask; + } var email = context.Principal.FindFirst("preferred_username")?.Value ?? context.Principal.FindFirst(ClaimTypes.Email)?.Value; if (string.IsNullOrEmpty(email) || !allowedEmails.Contains(email.ToLowerInvariant())) @@ -117,19 +122,9 @@ Type = SecuritySchemeType.Http, Scheme = "basic", }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement + options.AddSecurityRequirement(document => new OpenApiSecurityRequirement { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference - { - Id = "basic", - Type = ReferenceType.SecurityScheme - } - }, - Array.Empty() - } + { new OpenApiSecuritySchemeReference("basic", document), Array.Empty().ToList() } }); }); #else