diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs index 74978537c3..440bbf1442 100644 --- a/src/Api/Startup.cs +++ b/src/Api/Startup.cs @@ -158,11 +158,8 @@ namespace Bit.Api }) .AddDebug(); - // Forwarded headers - if(!env.IsDevelopment()) - { - app.UseForwardedHeadersForAzure(); - } + // Default Middleware + app.UseDefaultMiddleware(env); if(!globalSettings.SelfHosted) { diff --git a/src/Billing/Startup.cs b/src/Billing/Startup.cs index a3fd900876..1c04a768f6 100644 --- a/src/Billing/Startup.cs +++ b/src/Billing/Startup.cs @@ -69,11 +69,8 @@ namespace Bit.Billing app.UseDeveloperExceptionPage(); } - // Forwarded headers - if(!env.IsDevelopment()) - { - app.UseForwardedHeadersForAzure(); - } + // Default Middleware + app.UseDefaultMiddleware(env); app.UseMvc(); } diff --git a/src/Core/Models/Api/Response/VersionResponseModel.cs b/src/Core/Models/Api/Response/VersionResponseModel.cs index 9830d7f711..4b241ee427 100644 --- a/src/Core/Models/Api/Response/VersionResponseModel.cs +++ b/src/Core/Models/Api/Response/VersionResponseModel.cs @@ -1,5 +1,5 @@ using System; -using System.Reflection; +using Bit.Core.Utilities; namespace Bit.Core.Models.Api { @@ -8,13 +8,12 @@ namespace Bit.Core.Models.Api public VersionResponseModel() : base("version") { - Version = Assembly.GetEntryAssembly() - .GetCustomAttribute() - .InformationalVersion; - VersionInt = Convert.ToInt32(Version.Replace(".", string.Empty)); + var info = CoreHelpers.GetVersionInfo(); + Version = info.version; + VersionWeight = info.versionWeight; } public string Version { get; set; } - public int VersionInt { get; set; } + public int VersionWeight { get; set; } } } diff --git a/src/Core/Utilities/CoreHelpers.cs b/src/Core/Utilities/CoreHelpers.cs index 9f7ba6e371..ff92e28eba 100644 --- a/src/Core/Utilities/CoreHelpers.cs +++ b/src/Core/Utilities/CoreHelpers.cs @@ -19,6 +19,8 @@ namespace Bit.Core.Utilities private static readonly long _baseDateTicks = new DateTime(1900, 1, 1).Ticks; private static readonly DateTime _epoc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static readonly Random _random = new Random(); + private static string _version; + private static int _versionWeight; /// /// Generate sequential Guid for Sql Server. @@ -372,5 +374,26 @@ namespace Bit.Core.Utilities return val.ToString(); } + + public static (string version, int versionWeight) GetVersionInfo() + { + if(string.IsNullOrWhiteSpace(_version)) + { + _version = Assembly.GetEntryAssembly() + .GetCustomAttribute() + .InformationalVersion; + + var dashIndex = _version.IndexOf('-'); + var trimmedVersion = dashIndex > 0 ? _version.Substring(0, dashIndex) : _version; + + var semVerParts = trimmedVersion.Split('.').Reverse().ToArray(); + for(var i = 0; i < semVerParts.Length; i++) + { + _versionWeight += (i + 1) * Convert.ToInt32(semVerParts[i]); + } + } + + return (_version, _versionWeight); + } } } diff --git a/src/Core/Utilities/ServiceCollectionExtensions.cs b/src/Core/Utilities/ServiceCollectionExtensions.cs index 20cc0af949..9a6693d829 100644 --- a/src/Core/Utilities/ServiceCollectionExtensions.cs +++ b/src/Core/Utilities/ServiceCollectionExtensions.cs @@ -15,12 +15,14 @@ using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; #if NET461 using Microsoft.WindowsAzure.Storage; #endif using System; using System.IO; using SqlServerRepos = Bit.Core.Repositories.SqlServer; +using System.Threading.Tasks; namespace Bit.Core.Utilities { @@ -267,19 +269,35 @@ namespace Bit.Core.Utilities return globalSettings; } - public static void UseForwardedHeadersForAzure(this IApplicationBuilder app) + public static void UseDefaultMiddleware(this IApplicationBuilder app, IHostingEnvironment env) { - // ref: https://github.com/aspnet/Docs/issues/2384 - var forwardOptions = new ForwardedHeadersOptions + if(!env.IsDevelopment()) { - ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, - RequireHeaderSymmetry = false - }; + // Adjust headers for proxy. + // ref: https://github.com/aspnet/Docs/issues/2384 + var forwardOptions = new ForwardedHeadersOptions + { + ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, + RequireHeaderSymmetry = false + }; + forwardOptions.KnownNetworks.Clear(); + forwardOptions.KnownProxies.Clear(); + app.UseForwardedHeaders(forwardOptions); + } - forwardOptions.KnownNetworks.Clear(); - forwardOptions.KnownProxies.Clear(); + // Add version information to response headers + app.Use(async (httpContext, next) => + { + httpContext.Response.OnStarting((state) => + { + var info = CoreHelpers.GetVersionInfo(); + httpContext.Response.Headers.Append("Version", info.version); + httpContext.Response.Headers.Append("VersionWeight", info.versionWeight.ToString()); + return Task.FromResult(0); + }, null); - app.UseForwardedHeaders(forwardOptions); + await next.Invoke(); + }); } } } diff --git a/src/Identity/Startup.cs b/src/Identity/Startup.cs index 230d193234..bb0cd83706 100644 --- a/src/Identity/Startup.cs +++ b/src/Identity/Startup.cs @@ -72,11 +72,8 @@ namespace Bit.Identity .AddConsole() .AddDebug(); - // Forwarded headers - if(!env.IsDevelopment()) - { - app.UseForwardedHeadersForAzure(); - } + // Default Middleware + app.UseDefaultMiddleware(env); // Add IdentityServer to the request pipeline. app.UseIdentityServer();