Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Core/Resgrid.Services/AuditService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -43,7 +44,13 @@ public async Task<List<AuditLog>> GetAuditLogsForDepartmentPagedAsync(int depart
var safePage = page < 1 ? 1 : page;
var safePageSize = pageSize < 1 ? 1 : (pageSize > 1000 ? 1000 : pageSize);

var logs = await _auditLogsRepository.GetAuditLogsForDepartmentPagedAsync(departmentId, startDate, endDate, (int?)logType, safePage, safePageSize);
// Normalize the time window so callers that leave a bound unset (DateTime.MinValue) don't
// crash or silently return nothing. Floor the inclusive start at the SQL datetime minimum,
// and default the exclusive end to "now" when it is unset or precedes the start.
var safeStart = startDate < (DateTime)SqlDateTime.MinValue ? (DateTime)SqlDateTime.MinValue : startDate;
var safeEnd = (endDate == default(DateTime) || endDate < safeStart) ? DateTime.UtcNow : endDate;

var logs = await _auditLogsRepository.GetAuditLogsForDepartmentPagedAsync(departmentId, safeStart, safeEnd, (int?)logType, safePage, safePageSize);
return logs.ToList();
}

Expand Down
14 changes: 10 additions & 4 deletions Providers/Resgrid.Providers.Bus.Rabbit/RabbitConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static async Task<bool> VerifyAndCreateClients(string clientName)
{
if (_connection != null && !_connection.IsOpen)
{
_connection.Dispose();
await _connection.DisposeAsync();
_connection = null;
_factory = null;
RaiseConnectionReset();
Expand Down Expand Up @@ -82,7 +82,9 @@ public static async Task<bool> VerifyAndCreateClients(string clientName)
{
try
{
using var channel = await _connection.CreateChannelAsync();
// await using to close the channel via DisposeAsync and release its channel number; a
// synchronous Dispose() on a v7 IChannel skips the async close handshake and leaks channels.
await using var channel = await _connection.CreateChannelAsync();

await channel.QueueDeclareAsync(queue: SetQueueNameForEnv(ServiceBusConfig.SystemQueueName),
durable: true,
Expand Down Expand Up @@ -180,9 +182,13 @@ public static async Task<IConnection> CreateConnection(string clientName)
if (_connection == null)
await VerifyAndCreateClients(clientName);

if (!_connection.IsOpen)
// _connection can still be null here if VerifyAndCreateClients failed to connect (e.g. primary
// host down and no fallback host configured), so guard before accessing IsOpen to avoid an NRE.
if (_connection == null || !_connection.IsOpen)
{
_connection.Dispose();
if (_connection != null)
await _connection.DisposeAsync();

_connection = null;
_factory = null;
RaiseConnectionReset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,9 @@ private async Task<bool> RetryQueueItem(BasicDeliverEventArgs ea, Exception mex)
var connection = await RabbitConnection.CreateConnection(_clientName);
if (connection != null)
{
using (var channel = await connection.CreateChannelAsync())
// await using to close the channel via DisposeAsync and release its channel number; the
// synchronous Dispose() on a v7 IChannel skips the async close handshake and leaks channels.
await using (var channel = await connection.CreateChannelAsync())
{
var props = new BasicProperties();
props.DeliveryMode = DeliveryModes.Persistent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ private async Task<bool> SendMessage(string queueName, string message, bool dura
var connection = await RabbitConnection.CreateConnection(_clientName);
if (connection != null)
{
using (var channel = await connection.CreateChannelAsync())
// await using so the channel is closed via DisposeAsync(): the synchronous Dispose() on a
// v7 IChannel skips the async Channel.Close/CloseOk handshake that releases the channel
// number back to the SessionManager, leaking channels until the connection hits its limit
// (ChannelAllocationException: "The connection cannot support any more channels").
await using (var channel = await connection.CreateChannelAsync())
{
if (channel != null)
{
Expand Down
9 changes: 7 additions & 2 deletions Providers/Resgrid.Providers.Bus.Rabbit/RabbitTopicProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ private static async Task<bool> VerifyAndCreateClients(string clientName)

if (connection != null)
{
using (var channel = await connection.CreateChannelAsync())
// await using to close the channel via DisposeAsync and release its channel number (see SendMessage).
await using (var channel = await connection.CreateChannelAsync())
{
await channel.ExchangeDeclareAsync(RabbitConnection.SetQueueNameForEnv(Topics.EventingTopic), "fanout");
}
Expand All @@ -157,7 +158,11 @@ private async Task<bool> SendMessage(string topicName, string message)
var connection = await RabbitConnection.CreateConnection(_clientName);
if (connection != null)
{
using (var channel = await connection.CreateChannelAsync())
// await using so the channel is closed via DisposeAsync(): the synchronous Dispose() on a
// v7 IChannel skips the async Channel.Close/CloseOk handshake that releases the channel
// number back to the SessionManager, leaking channels until the connection hits its limit
// (ChannelAllocationException: "The connection cannot support any more channels").
await using (var channel = await connection.CreateChannelAsync())
{
await channel.BasicPublishAsync(exchange: RabbitConnection.SetQueueNameForEnv(topicName),
routingKey: "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Threading.Tasks;
using Dapper;
Expand Down Expand Up @@ -37,8 +38,12 @@ public async Task<IEnumerable<AuditLog>> GetAuditLogsForDepartmentPagedAsync(int
{
var dynamicParameters = new DynamicParametersExtension();
dynamicParameters.Add("DepartmentId", departmentId);
dynamicParameters.Add("StartDate", startDate);
dynamicParameters.Add("EndDate", endDate);
// Bind the bounds as DateTime2 so out-of-SqlDateTime-range values (e.g. DateTime.MinValue
// from an unset start filter) don't trigger "SqlDateTime overflow". datetime2 covers
// 0001-9999 on SQL Server (vs datetime's 1753 floor) and maps to timestamp on PostgreSQL,
// comparing correctly against the loggedon column either way.
dynamicParameters.Add("StartDate", startDate, DbType.DateTime2);
dynamicParameters.Add("EndDate", endDate, DbType.DateTime2);
dynamicParameters.Add("Offset", (page - 1) * pageSize);
dynamicParameters.Add("PageSize", pageSize);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,9 @@ public Task<string> GetNormalizedUserNameAsync(IdentityUser user, CancellationTo
if (user == null)
throw new ArgumentNullException(nameof(user));

return Task.FromResult(user.UserName);
// Prefer the stored normalized name; fall back to UserName.ToUpperInvariant() for legacy
// rows whose NormalizedUserName was never populated (see SetNormalizedUserNameAsync).
return Task.FromResult(user.NormalizedUserName ?? user.UserName?.ToUpperInvariant());
}

public Task<string> GetPasswordHashAsync(IdentityUser user, CancellationToken cancellationToken)
Expand Down Expand Up @@ -806,6 +808,11 @@ public Task SetNormalizedUserNameAsync(IdentityUser user, string normalizedName,
if (user == null)
throw new ArgumentNullException(nameof(user));

// Persist the normalized name so new users (created via UserManager.CreateAsync during
// department/account signup) get NormalizedUserName populated; otherwise it inserts as NULL
// and lookups keyed on normalizedusername (= UserName.ToUpperInvariant()) can't find the user.
user.NormalizedUserName = normalizedName ?? user.UserName?.ToUpperInvariant();

return Task.FromResult(0);
}

Expand Down
Loading