1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-02 16:42:50 -05:00

Run formatting (#2230)

This commit is contained in:
Justin Baur
2022-08-29 16:06:55 -04:00
committed by GitHub
parent 9b7aef0763
commit 7f5f010e1e
1205 changed files with 73813 additions and 75022 deletions

View File

@ -3,91 +3,90 @@ using Bit.Core.Settings;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.SignalR;
namespace Bit.Notifications
namespace Bit.Notifications;
public class AzureQueueHostedService : IHostedService, IDisposable
{
public class AzureQueueHostedService : IHostedService, IDisposable
private readonly ILogger _logger;
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly GlobalSettings _globalSettings;
private Task _executingTask;
private CancellationTokenSource _cts;
private QueueClient _queueClient;
public AzureQueueHostedService(
ILogger<AzureQueueHostedService> logger,
IHubContext<NotificationsHub> hubContext,
GlobalSettings globalSettings)
{
private readonly ILogger _logger;
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly GlobalSettings _globalSettings;
_logger = logger;
_hubContext = hubContext;
_globalSettings = globalSettings;
}
private Task _executingTask;
private CancellationTokenSource _cts;
private QueueClient _queueClient;
public Task StartAsync(CancellationToken cancellationToken)
{
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
_executingTask = ExecuteAsync(_cts.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}
public AzureQueueHostedService(
ILogger<AzureQueueHostedService> logger,
IHubContext<NotificationsHub> hubContext,
GlobalSettings globalSettings)
public async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
{
_logger = logger;
_hubContext = hubContext;
_globalSettings = globalSettings;
return;
}
_logger.LogWarning("Stopping service.");
_cts.Cancel();
await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
cancellationToken.ThrowIfCancellationRequested();
}
public Task StartAsync(CancellationToken cancellationToken)
{
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
_executingTask = ExecuteAsync(_cts.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}
public void Dispose()
{ }
public async Task StopAsync(CancellationToken cancellationToken)
private async Task ExecuteAsync(CancellationToken cancellationToken)
{
_queueClient = new QueueClient(_globalSettings.Notifications.ConnectionString, "notifications");
while (!cancellationToken.IsCancellationRequested)
{
if (_executingTask == null)
try
{
return;
}
_logger.LogWarning("Stopping service.");
_cts.Cancel();
await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
cancellationToken.ThrowIfCancellationRequested();
}
public void Dispose()
{ }
private async Task ExecuteAsync(CancellationToken cancellationToken)
{
_queueClient = new QueueClient(_globalSettings.Notifications.ConnectionString, "notifications");
while (!cancellationToken.IsCancellationRequested)
{
try
var messages = await _queueClient.ReceiveMessagesAsync(32);
if (messages.Value?.Any() ?? false)
{
var messages = await _queueClient.ReceiveMessagesAsync(32);
if (messages.Value?.Any() ?? false)
foreach (var message in messages.Value)
{
foreach (var message in messages.Value)
try
{
try
await HubHelpers.SendNotificationToHubAsync(
message.DecodeMessageText(), _hubContext, cancellationToken);
await _queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
}
catch (Exception e)
{
_logger.LogError("Error processing dequeued message: " +
$"{message.MessageId} x{message.DequeueCount}. {e.Message}", e);
if (message.DequeueCount > 2)
{
await HubHelpers.SendNotificationToHubAsync(
message.DecodeMessageText(), _hubContext, cancellationToken);
await _queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
}
catch (Exception e)
{
_logger.LogError("Error processing dequeued message: " +
$"{message.MessageId} x{message.DequeueCount}. {e.Message}", e);
if (message.DequeueCount > 2)
{
await _queueClient.DeleteMessageAsync(message.MessageId, message.PopReceipt);
}
}
}
}
else
{
await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
}
}
catch (Exception e)
else
{
_logger.LogError("Error processing messages.", e);
await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
}
}
_logger.LogWarning("Done processing.");
catch (Exception e)
{
_logger.LogError("Error processing messages.", e);
}
}
_logger.LogWarning("Done processing.");
}
}

View File

@ -1,27 +1,26 @@
namespace Bit.Notifications
namespace Bit.Notifications;
public class ConnectionCounter
{
public class ConnectionCounter
private int _count = 0;
public void Increment()
{
private int _count = 0;
Interlocked.Increment(ref _count);
}
public void Increment()
{
Interlocked.Increment(ref _count);
}
public void Decrement()
{
Interlocked.Decrement(ref _count);
}
public void Decrement()
{
Interlocked.Decrement(ref _count);
}
public void Reset()
{
_count = 0;
}
public void Reset()
{
_count = 0;
}
public int GetCount()
{
return _count;
}
public int GetCount()
{
return _count;
}
}

View File

@ -1,21 +1,20 @@
using Bit.Core.Utilities;
using Microsoft.AspNetCore.Mvc;
namespace Bit.Notifications.Controllers
{
public class InfoController : Controller
{
[HttpGet("~/alive")]
[HttpGet("~/now")]
public DateTime GetAlive()
{
return DateTime.UtcNow;
}
namespace Bit.Notifications.Controllers;
[HttpGet("~/version")]
public JsonResult GetVersion()
{
return Json(CoreHelpers.GetVersion());
}
public class InfoController : Controller
{
[HttpGet("~/alive")]
[HttpGet("~/now")]
public DateTime GetAlive()
{
return DateTime.UtcNow;
}
[HttpGet("~/version")]
public JsonResult GetVersion()
{
return Json(CoreHelpers.GetVersion());
}
}

View File

@ -4,29 +4,28 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
namespace Bit.Notifications
namespace Bit.Notifications;
[Authorize("Internal")]
public class SendController : Controller
{
[Authorize("Internal")]
public class SendController : Controller
private readonly IHubContext<NotificationsHub> _hubContext;
public SendController(IHubContext<NotificationsHub> hubContext)
{
private readonly IHubContext<NotificationsHub> _hubContext;
_hubContext = hubContext;
}
public SendController(IHubContext<NotificationsHub> hubContext)
[HttpPost("~/send")]
[SelfHosted(SelfHostedOnly = true)]
public async Task PostSend()
{
using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
{
_hubContext = hubContext;
}
[HttpPost("~/send")]
[SelfHosted(SelfHostedOnly = true)]
public async Task PostSend()
{
using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
var notificationJson = await reader.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(notificationJson))
{
var notificationJson = await reader.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(notificationJson))
{
await HubHelpers.SendNotificationToHubAsync(notificationJson, _hubContext);
}
await HubHelpers.SendNotificationToHubAsync(notificationJson, _hubContext);
}
}
}

View File

@ -1,57 +1,56 @@
using Bit.Core.Settings;
using Microsoft.AspNetCore.SignalR;
namespace Bit.Notifications
namespace Bit.Notifications;
public class HeartbeatHostedService : IHostedService, IDisposable
{
public class HeartbeatHostedService : IHostedService, IDisposable
private readonly ILogger _logger;
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly GlobalSettings _globalSettings;
private Task _executingTask;
private CancellationTokenSource _cts;
public HeartbeatHostedService(
ILogger<AzureQueueHostedService> logger,
IHubContext<NotificationsHub> hubContext,
GlobalSettings globalSettings)
{
private readonly ILogger _logger;
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly GlobalSettings _globalSettings;
_logger = logger;
_hubContext = hubContext;
_globalSettings = globalSettings;
}
private Task _executingTask;
private CancellationTokenSource _cts;
public Task StartAsync(CancellationToken cancellationToken)
{
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
_executingTask = ExecuteAsync(_cts.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}
public HeartbeatHostedService(
ILogger<AzureQueueHostedService> logger,
IHubContext<NotificationsHub> hubContext,
GlobalSettings globalSettings)
public async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
{
_logger = logger;
_hubContext = hubContext;
_globalSettings = globalSettings;
return;
}
_logger.LogWarning("Stopping service.");
_cts.Cancel();
await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
cancellationToken.ThrowIfCancellationRequested();
}
public Task StartAsync(CancellationToken cancellationToken)
public void Dispose()
{ }
private async Task ExecuteAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
_executingTask = ExecuteAsync(_cts.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}
public async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
{
return;
}
_logger.LogWarning("Stopping service.");
_cts.Cancel();
await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
cancellationToken.ThrowIfCancellationRequested();
}
public void Dispose()
{ }
private async Task ExecuteAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
await _hubContext.Clients.All.SendAsync("Heartbeat");
await Task.Delay(120000);
}
_logger.LogWarning("Done with heartbeat.");
await _hubContext.Clients.All.SendAsync("Heartbeat");
await Task.Delay(120000);
}
_logger.LogWarning("Done with heartbeat.");
}
}

View File

@ -3,67 +3,66 @@ using Bit.Core.Enums;
using Bit.Core.Models;
using Microsoft.AspNetCore.SignalR;
namespace Bit.Notifications
namespace Bit.Notifications;
public static class HubHelpers
{
public static class HubHelpers
public static async Task SendNotificationToHubAsync(string notificationJson,
IHubContext<NotificationsHub> hubContext, CancellationToken cancellationToken = default(CancellationToken))
{
public static async Task SendNotificationToHubAsync(string notificationJson,
IHubContext<NotificationsHub> hubContext, CancellationToken cancellationToken = default(CancellationToken))
var notification = JsonSerializer.Deserialize<PushNotificationData<object>>(notificationJson);
switch (notification.Type)
{
var notification = JsonSerializer.Deserialize<PushNotificationData<object>>(notificationJson);
switch (notification.Type)
{
case PushType.SyncCipherUpdate:
case PushType.SyncCipherCreate:
case PushType.SyncCipherDelete:
case PushType.SyncLoginDelete:
var cipherNotification =
JsonSerializer.Deserialize<PushNotificationData<SyncCipherPushNotification>>(
case PushType.SyncCipherUpdate:
case PushType.SyncCipherCreate:
case PushType.SyncCipherDelete:
case PushType.SyncLoginDelete:
var cipherNotification =
JsonSerializer.Deserialize<PushNotificationData<SyncCipherPushNotification>>(
notificationJson);
if (cipherNotification.Payload.UserId.HasValue)
{
await hubContext.Clients.User(cipherNotification.Payload.UserId.ToString())
.SendAsync("ReceiveMessage", cipherNotification, cancellationToken);
}
else if (cipherNotification.Payload.OrganizationId.HasValue)
{
await hubContext.Clients.Group(
$"Organization_{cipherNotification.Payload.OrganizationId}")
.SendAsync("ReceiveMessage", cipherNotification, cancellationToken);
}
break;
case PushType.SyncFolderUpdate:
case PushType.SyncFolderCreate:
case PushType.SyncFolderDelete:
var folderNotification =
JsonSerializer.Deserialize<PushNotificationData<SyncFolderPushNotification>>(
notificationJson);
await hubContext.Clients.User(folderNotification.Payload.UserId.ToString())
.SendAsync("ReceiveMessage", folderNotification, cancellationToken);
break;
case PushType.SyncCiphers:
case PushType.SyncVault:
case PushType.SyncOrgKeys:
case PushType.SyncSettings:
case PushType.LogOut:
var userNotification =
JsonSerializer.Deserialize<PushNotificationData<UserPushNotification>>(
notificationJson);
await hubContext.Clients.User(userNotification.Payload.UserId.ToString())
.SendAsync("ReceiveMessage", userNotification, cancellationToken);
break;
case PushType.SyncSendCreate:
case PushType.SyncSendUpdate:
case PushType.SyncSendDelete:
var sendNotification =
JsonSerializer.Deserialize<PushNotificationData<SyncSendPushNotification>>(
notificationJson);
if (cipherNotification.Payload.UserId.HasValue)
{
await hubContext.Clients.User(cipherNotification.Payload.UserId.ToString())
.SendAsync("ReceiveMessage", cipherNotification, cancellationToken);
}
else if (cipherNotification.Payload.OrganizationId.HasValue)
{
await hubContext.Clients.Group(
$"Organization_{cipherNotification.Payload.OrganizationId}")
.SendAsync("ReceiveMessage", cipherNotification, cancellationToken);
}
break;
case PushType.SyncFolderUpdate:
case PushType.SyncFolderCreate:
case PushType.SyncFolderDelete:
var folderNotification =
JsonSerializer.Deserialize<PushNotificationData<SyncFolderPushNotification>>(
notificationJson);
await hubContext.Clients.User(folderNotification.Payload.UserId.ToString())
.SendAsync("ReceiveMessage", folderNotification, cancellationToken);
break;
case PushType.SyncCiphers:
case PushType.SyncVault:
case PushType.SyncOrgKeys:
case PushType.SyncSettings:
case PushType.LogOut:
var userNotification =
JsonSerializer.Deserialize<PushNotificationData<UserPushNotification>>(
notificationJson);
await hubContext.Clients.User(userNotification.Payload.UserId.ToString())
.SendAsync("ReceiveMessage", userNotification, cancellationToken);
break;
case PushType.SyncSendCreate:
case PushType.SyncSendUpdate:
case PushType.SyncSendDelete:
var sendNotification =
JsonSerializer.Deserialize<PushNotificationData<SyncSendPushNotification>>(
notificationJson);
await hubContext.Clients.User(sendNotification.Payload.UserId.ToString())
.SendAsync("ReceiveMessage", sendNotification, cancellationToken);
break;
default:
break;
}
await hubContext.Clients.User(sendNotification.Payload.UserId.ToString())
.SendAsync("ReceiveMessage", sendNotification, cancellationToken);
break;
default:
break;
}
}
}

View File

@ -2,36 +2,35 @@
using Bit.Core.Settings;
using Quartz;
namespace Bit.Notifications.Jobs
namespace Bit.Notifications.Jobs;
public class JobsHostedService : BaseJobsHostedService
{
public class JobsHostedService : BaseJobsHostedService
public JobsHostedService(
GlobalSettings globalSettings,
IServiceProvider serviceProvider,
ILogger<JobsHostedService> logger,
ILogger<JobListener> listenerLogger)
: base(globalSettings, serviceProvider, logger, listenerLogger) { }
public override async Task StartAsync(CancellationToken cancellationToken)
{
public JobsHostedService(
GlobalSettings globalSettings,
IServiceProvider serviceProvider,
ILogger<JobsHostedService> logger,
ILogger<JobListener> listenerLogger)
: base(globalSettings, serviceProvider, logger, listenerLogger) { }
var everyFiveMinutesTrigger = TriggerBuilder.Create()
.WithIdentity("EveryFiveMinutesTrigger")
.StartNow()
.WithCronSchedule("0 */30 * * * ?")
.Build();
public override async Task StartAsync(CancellationToken cancellationToken)
Jobs = new List<Tuple<Type, ITrigger>>
{
var everyFiveMinutesTrigger = TriggerBuilder.Create()
.WithIdentity("EveryFiveMinutesTrigger")
.StartNow()
.WithCronSchedule("0 */30 * * * ?")
.Build();
new Tuple<Type, ITrigger>(typeof(LogConnectionCounterJob), everyFiveMinutesTrigger)
};
Jobs = new List<Tuple<Type, ITrigger>>
{
new Tuple<Type, ITrigger>(typeof(LogConnectionCounterJob), everyFiveMinutesTrigger)
};
await base.StartAsync(cancellationToken);
}
await base.StartAsync(cancellationToken);
}
public static void AddJobsServices(IServiceCollection services)
{
services.AddTransient<LogConnectionCounterJob>();
}
public static void AddJobsServices(IServiceCollection services)
{
services.AddTransient<LogConnectionCounterJob>();
}
}

View File

@ -2,25 +2,24 @@
using Bit.Core.Jobs;
using Quartz;
namespace Bit.Notifications.Jobs
namespace Bit.Notifications.Jobs;
public class LogConnectionCounterJob : BaseJob
{
public class LogConnectionCounterJob : BaseJob
private readonly ConnectionCounter _connectionCounter;
public LogConnectionCounterJob(
ILogger<LogConnectionCounterJob> logger,
ConnectionCounter connectionCounter)
: base(logger)
{
private readonly ConnectionCounter _connectionCounter;
_connectionCounter = connectionCounter;
}
public LogConnectionCounterJob(
ILogger<LogConnectionCounterJob> logger,
ConnectionCounter connectionCounter)
: base(logger)
{
_connectionCounter = connectionCounter;
}
protected override Task ExecuteJobAsync(IJobExecutionContext context)
{
_logger.LogInformation(Constants.BypassFiltersEventId,
"Connection count for server {0}: {1}", Environment.MachineName, _connectionCounter.GetCount());
return Task.FromResult(0);
}
protected override Task ExecuteJobAsync(IJobExecutionContext context)
{
_logger.LogInformation(Constants.BypassFiltersEventId,
"Connection count for server {0}: {1}", Environment.MachineName, _connectionCounter.GetCount());
return Task.FromResult(0);
}
}

View File

@ -2,48 +2,47 @@
using Bit.Core.Settings;
using Microsoft.AspNetCore.Authorization;
namespace Bit.Notifications
namespace Bit.Notifications;
[Authorize("Application")]
public class NotificationsHub : Microsoft.AspNetCore.SignalR.Hub
{
[Authorize("Application")]
public class NotificationsHub : Microsoft.AspNetCore.SignalR.Hub
private readonly ConnectionCounter _connectionCounter;
private readonly GlobalSettings _globalSettings;
public NotificationsHub(ConnectionCounter connectionCounter, GlobalSettings globalSettings)
{
private readonly ConnectionCounter _connectionCounter;
private readonly GlobalSettings _globalSettings;
_connectionCounter = connectionCounter;
_globalSettings = globalSettings;
}
public NotificationsHub(ConnectionCounter connectionCounter, GlobalSettings globalSettings)
public override async Task OnConnectedAsync()
{
var currentContext = new CurrentContext(null);
await currentContext.BuildAsync(Context.User, _globalSettings);
if (currentContext.Organizations != null)
{
_connectionCounter = connectionCounter;
_globalSettings = globalSettings;
}
public override async Task OnConnectedAsync()
{
var currentContext = new CurrentContext(null);
await currentContext.BuildAsync(Context.User, _globalSettings);
if (currentContext.Organizations != null)
foreach (var org in currentContext.Organizations)
{
foreach (var org in currentContext.Organizations)
{
await Groups.AddToGroupAsync(Context.ConnectionId, $"Organization_{org.Id}");
}
await Groups.AddToGroupAsync(Context.ConnectionId, $"Organization_{org.Id}");
}
_connectionCounter.Increment();
await base.OnConnectedAsync();
}
_connectionCounter.Increment();
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
public override async Task OnDisconnectedAsync(Exception exception)
{
var currentContext = new CurrentContext(null);
await currentContext.BuildAsync(Context.User, _globalSettings);
if (currentContext.Organizations != null)
{
var currentContext = new CurrentContext(null);
await currentContext.BuildAsync(Context.User, _globalSettings);
if (currentContext.Organizations != null)
foreach (var org in currentContext.Organizations)
{
foreach (var org in currentContext.Organizations)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"Organization_{org.Id}");
}
await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"Organization_{org.Id}");
}
_connectionCounter.Decrement();
await base.OnDisconnectedAsync(exception);
}
_connectionCounter.Decrement();
await base.OnDisconnectedAsync(exception);
}
}

View File

@ -1,51 +1,50 @@
using Bit.Core.Utilities;
using Serilog.Events;
namespace Bit.Notifications
namespace Bit.Notifications;
public class Program
{
public class Program
public static void Main(string[] args)
{
public static void Main(string[] args)
{
Host
.CreateDefaultBuilder(args)
.ConfigureCustomAppConfiguration(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureLogging((hostingContext, logging) =>
logging.AddSerilog(hostingContext, e =>
Host
.CreateDefaultBuilder(args)
.ConfigureCustomAppConfiguration(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureLogging((hostingContext, logging) =>
logging.AddSerilog(hostingContext, e =>
{
var context = e.Properties["SourceContext"].ToString();
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
{
var context = e.Properties["SourceContext"].ToString();
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
{
return e.Level > LogEventLevel.Error;
}
return e.Level > LogEventLevel.Error;
}
if (e.Level == LogEventLevel.Error &&
e.MessageTemplate.Text == "Failed connection handshake.")
{
return false;
}
if (e.Level == LogEventLevel.Error &&
e.MessageTemplate.Text == "Failed connection handshake.")
{
return false;
}
if (e.Level == LogEventLevel.Error &&
e.MessageTemplate.Text.StartsWith("Failed writing message."))
{
return false;
}
if (e.Level == LogEventLevel.Error &&
e.MessageTemplate.Text.StartsWith("Failed writing message."))
{
return false;
}
if (e.Level == LogEventLevel.Warning &&
e.MessageTemplate.Text.StartsWith("Heartbeat took longer"))
{
return false;
}
if (e.Level == LogEventLevel.Warning &&
e.MessageTemplate.Text.StartsWith("Heartbeat took longer"))
{
return false;
}
return e.Level >= LogEventLevel.Warning;
}));
})
.Build()
.Run();
}
return e.Level >= LogEventLevel.Warning;
}));
})
.Build()
.Run();
}
}

View File

@ -6,115 +6,114 @@ using IdentityModel;
using Microsoft.AspNetCore.SignalR;
using Microsoft.IdentityModel.Logging;
namespace Bit.Notifications
namespace Bit.Notifications;
public class Startup
{
public class Startup
public Startup(IWebHostEnvironment env, IConfiguration configuration)
{
public Startup(IWebHostEnvironment env, IConfiguration configuration)
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
Configuration = configuration;
Environment = env;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; set; }
public void ConfigureServices(IServiceCollection services)
{
// Options
services.AddOptions();
// Settings
var globalSettings = services.AddGlobalSettingsServices(Configuration, Environment);
// Identity
services.AddIdentityAuthenticationServices(globalSettings, Environment, config =>
{
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
Configuration = configuration;
Environment = env;
config.AddPolicy("Application", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim(JwtClaimTypes.AuthenticationMethod, "Application", "external");
policy.RequireClaim(JwtClaimTypes.Scope, "api");
});
config.AddPolicy("Internal", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim(JwtClaimTypes.Scope, "internal");
});
});
// SignalR
var signalRServerBuilder = services.AddSignalR().AddMessagePackProtocol(options =>
{
options.SerializerOptions = MessagePack.MessagePackSerializerOptions.Standard
.WithResolver(MessagePack.Resolvers.ContractlessStandardResolver.Instance);
});
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.RedisConnectionString))
{
signalRServerBuilder.AddStackExchangeRedis(globalSettings.Notifications.RedisConnectionString,
options =>
{
options.Configuration.ChannelPrefix = "Notifications";
});
}
services.AddSingleton<IUserIdProvider, SubjectUserIdProvider>();
services.AddSingleton<ConnectionCounter>();
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; set; }
// Mvc
services.AddMvc();
public void ConfigureServices(IServiceCollection services)
services.AddHostedService<HeartbeatHostedService>();
if (!globalSettings.SelfHosted)
{
// Options
services.AddOptions();
// Settings
var globalSettings = services.AddGlobalSettingsServices(Configuration, Environment);
// Identity
services.AddIdentityAuthenticationServices(globalSettings, Environment, config =>
// Hosted Services
Jobs.JobsHostedService.AddJobsServices(services);
services.AddHostedService<Jobs.JobsHostedService>();
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
{
config.AddPolicy("Application", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim(JwtClaimTypes.AuthenticationMethod, "Application", "external");
policy.RequireClaim(JwtClaimTypes.Scope, "api");
});
config.AddPolicy("Internal", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim(JwtClaimTypes.Scope, "internal");
});
});
// SignalR
var signalRServerBuilder = services.AddSignalR().AddMessagePackProtocol(options =>
{
options.SerializerOptions = MessagePack.MessagePackSerializerOptions.Standard
.WithResolver(MessagePack.Resolvers.ContractlessStandardResolver.Instance);
});
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.RedisConnectionString))
{
signalRServerBuilder.AddStackExchangeRedis(globalSettings.Notifications.RedisConnectionString,
options =>
{
options.Configuration.ChannelPrefix = "Notifications";
});
services.AddHostedService<AzureQueueHostedService>();
}
services.AddSingleton<IUserIdProvider, SubjectUserIdProvider>();
services.AddSingleton<ConnectionCounter>();
// Mvc
services.AddMvc();
services.AddHostedService<HeartbeatHostedService>();
if (!globalSettings.SelfHosted)
{
// Hosted Services
Jobs.JobsHostedService.AddJobsServices(services);
services.AddHostedService<Jobs.JobsHostedService>();
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
{
services.AddHostedService<AzureQueueHostedService>();
}
}
}
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings)
{
IdentityModelEventSource.ShowPII = true;
app.UseSerilog(env, appLifetime, globalSettings);
// Add general security headers
app.UseMiddleware<SecurityHeadersMiddleware>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Add routing
app.UseRouting();
// Add Cors
app.UseCors(policy => policy.SetIsOriginAllowed(o => CoreHelpers.IsCorsOriginAllowed(o, globalSettings))
.AllowAnyMethod().AllowAnyHeader().AllowCredentials());
// Add authentication to the request pipeline.
app.UseAuthentication();
app.UseAuthorization();
// Add endpoints to the request pipeline.
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<NotificationsHub>("/hub", options =>
{
options.ApplicationMaxBufferSize = 2048; // client => server messages are not even used
options.TransportMaxBufferSize = 4096;
});
endpoints.MapDefaultControllerRoute();
});
}
}
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
IHostApplicationLifetime appLifetime,
GlobalSettings globalSettings)
{
IdentityModelEventSource.ShowPII = true;
app.UseSerilog(env, appLifetime, globalSettings);
// Add general security headers
app.UseMiddleware<SecurityHeadersMiddleware>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Add routing
app.UseRouting();
// Add Cors
app.UseCors(policy => policy.SetIsOriginAllowed(o => CoreHelpers.IsCorsOriginAllowed(o, globalSettings))
.AllowAnyMethod().AllowAnyHeader().AllowCredentials());
// Add authentication to the request pipeline.
app.UseAuthentication();
app.UseAuthorization();
// Add endpoints to the request pipeline.
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<NotificationsHub>("/hub", options =>
{
options.ApplicationMaxBufferSize = 2048; // client => server messages are not even used
options.TransportMaxBufferSize = 4096;
});
endpoints.MapDefaultControllerRoute();
});
}
}

View File

@ -1,13 +1,12 @@
using IdentityModel;
using Microsoft.AspNetCore.SignalR;
namespace Bit.Notifications
namespace Bit.Notifications;
public class SubjectUserIdProvider : IUserIdProvider
{
public class SubjectUserIdProvider : IUserIdProvider
public string GetUserId(HubConnectionContext connection)
{
public string GetUserId(HubConnectionContext connection)
{
return connection.User?.FindFirst(JwtClaimTypes.Subject)?.Value;
}
return connection.User?.FindFirst(JwtClaimTypes.Subject)?.Value;
}
}