diff --git a/bitwarden-core.sln b/bitwarden-core.sln index 57e8d7763..d3f66295c 100644 --- a/bitwarden-core.sln +++ b/bitwarden-core.sln @@ -36,6 +36,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Setup", "util\Setup\Setup.c EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "util\Server\Server.csproj", "{66B0A682-658A-4A82-B606-A077A4871448}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jobs", "src\Jobs\Jobs.csproj", "{7DCEBD8F-E5F3-4A3C-BD35-B64341590B74}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -76,6 +78,10 @@ Global {66B0A682-658A-4A82-B606-A077A4871448}.Debug|Any CPU.Build.0 = Debug|Any CPU {66B0A682-658A-4A82-B606-A077A4871448}.Release|Any CPU.ActiveCfg = Release|Any CPU {66B0A682-658A-4A82-B606-A077A4871448}.Release|Any CPU.Build.0 = Release|Any CPU + {7DCEBD8F-E5F3-4A3C-BD35-B64341590B74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7DCEBD8F-E5F3-4A3C-BD35-B64341590B74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7DCEBD8F-E5F3-4A3C-BD35-B64341590B74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7DCEBD8F-E5F3-4A3C-BD35-B64341590B74}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -89,6 +95,7 @@ Global {04148736-3C0B-445E-8B74-2020E7A53502} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D} {EF2164EF-1FC0-4518-A2ED-CE02D3630B00} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E} {66B0A682-658A-4A82-B606-A077A4871448} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84E} + {7DCEBD8F-E5F3-4A3C-BD35-B64341590B74} = {DD5BD056-4AAE-43EF-BBD2-0B569B8DA84D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E01CBF68-2E20-425F-9EDB-E0A6510CA92F} diff --git a/src/Core/Utilities/ConfigurationBuilderExtensions.cs b/src/Core/Utilities/ConfigurationBuilderExtensions.cs index 7b909f6af..0307284f7 100644 --- a/src/Core/Utilities/ConfigurationBuilderExtensions.cs +++ b/src/Core/Utilities/ConfigurationBuilderExtensions.cs @@ -14,7 +14,7 @@ namespace Bit.Core.Utilities .AddJsonFile("settings.json") .AddJsonFile($"settings.{env.EnvironmentName}.json", optional: true); - if(env.IsDevelopment()) + if(env.IsDevelopment() && !string.IsNullOrWhiteSpace(userSecretsId)) { builder.AddUserSecrets(userSecretsId); } diff --git a/src/Identity/Startup.cs b/src/Identity/Startup.cs index 886dc2c64..230d19323 100644 --- a/src/Identity/Startup.cs +++ b/src/Identity/Startup.cs @@ -7,7 +7,6 @@ using Microsoft.Extensions.Configuration; using Bit.Core; using Bit.Core.Utilities; using Serilog.Events; -using Microsoft.AspNetCore.HttpOverrides; namespace Bit.Identity { diff --git a/src/Jobs/Jobs.csproj b/src/Jobs/Jobs.csproj new file mode 100644 index 000000000..be69add01 --- /dev/null +++ b/src/Jobs/Jobs.csproj @@ -0,0 +1,20 @@ + + + + Exe + netcoreapp2.0 + Jobs + Bit.Jobs + bitwarden-Jobs + + + + + + + + + + + + diff --git a/src/Jobs/NoopServer.cs b/src/Jobs/NoopServer.cs new file mode 100644 index 000000000..2ec7214bb --- /dev/null +++ b/src/Jobs/NoopServer.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Http.Features; + +namespace Bit.Jobs +{ + public class NoopServer : IServer + { + public IFeatureCollection Features => new FeatureCollection(); + + public void Dispose() + { } + + public void Start(IHttpApplication application) + { } + } +} diff --git a/src/Jobs/Program.cs b/src/Jobs/Program.cs new file mode 100644 index 000000000..40df2b6ab --- /dev/null +++ b/src/Jobs/Program.cs @@ -0,0 +1,46 @@ +using Bit.Core.Services; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using System.IO; +using System.Threading.Tasks; + +namespace Bit.Jobs +{ + public class Program + { + private static ILicensingService _licensingService; + + public static void Main(string[] args) + { + var host = new WebHostBuilder() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseStartup() + .UseServer(new NoopServer()) + .Build(); + + _licensingService = host.Services.GetRequiredService(); + + MainAsync(args).Wait(); + } + + private async static Task MainAsync(string[] args) + { + if(args.Length == 0) + { + return; + } + + switch(args[0]) + { + case "validate-licenses": + await _licensingService.ValidateOrganizationsAsync(); + break; + case "refresh-licenses": + // TODO + break; + default: + break; + } + } + } +} diff --git a/src/Jobs/Properties/launchSettings.json b/src/Jobs/Properties/launchSettings.json new file mode 100644 index 000000000..b4d140a0a --- /dev/null +++ b/src/Jobs/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "Jobs": { + "commandName": "Project", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:4409/" + } + } +} \ No newline at end of file diff --git a/src/Jobs/Startup.cs b/src/Jobs/Startup.cs new file mode 100644 index 000000000..b49189734 --- /dev/null +++ b/src/Jobs/Startup.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Configuration; +using Bit.Core; +using Bit.Core.Utilities; +using Microsoft.Extensions.Logging; +using Microsoft.AspNetCore.Builder; + +namespace Bit.Jobs +{ + public class Startup + { + public Startup(IHostingEnvironment env) + { + var builder = new ConfigurationBuilder() + .AddSettingsConfiguration(env, "bitwarden-Jobs"); + Configuration = builder.Build(); + Environment = env; + } + + public IConfigurationRoot Configuration { get; private set; } + public IHostingEnvironment Environment { get; set; } + + public void ConfigureServices(IServiceCollection services) + { + // Options + services.AddOptions(); + + // Settings + var globalSettings = services.AddGlobalSettingsServices(Configuration); + + // Data Protection + services.AddCustomDataProtectionServices(Environment, globalSettings); + + // Repositories + services.AddSqlServerRepositories(); + + // Context + services.AddScoped(); + + // Identity + services.AddCustomIdentityServices(globalSettings); + + // Services + services.AddBaseServices(); + services.AddDefaultServices(globalSettings); + } + + public void Configure( + IApplicationBuilder app, + IHostingEnvironment env, + ILoggerFactory loggerFactory, + IApplicationLifetime appLifetime, + GlobalSettings globalSettings) + { + loggerFactory + .AddSerilog(env, appLifetime, globalSettings) + .AddConsole() + .AddDebug(); + } + } +} diff --git a/src/Jobs/settings.Preview.json b/src/Jobs/settings.Preview.json new file mode 100644 index 000000000..ddc6d3c3d --- /dev/null +++ b/src/Jobs/settings.Preview.json @@ -0,0 +1,10 @@ +{ + "globalSettings": { + "baseServiceUri": { + "vault": "https://preview-vault.bitwarden.com", + "api": "https://preview-api.bitwarden.com", + "identity": "https://preview-identity.bitwarden.com", + "identityInternal": "https://preview-identity.bitwarden.com" + } + } +} diff --git a/src/Jobs/settings.Production.json b/src/Jobs/settings.Production.json new file mode 100644 index 000000000..58866c8fc --- /dev/null +++ b/src/Jobs/settings.Production.json @@ -0,0 +1,13 @@ +{ + "globalSettings": { + "baseServiceUri": { + "vault": "https://vault.bitwarden.com", + "api": "https://api.bitwarden.com", + "identity": "https://identity.bitwarden.com", + "identityInternal": "https://identity.bitwarden.com" + }, + "braintree": { + "production": true + } + } +} diff --git a/src/Jobs/settings.Staging.json b/src/Jobs/settings.Staging.json new file mode 100644 index 000000000..5d31355e3 --- /dev/null +++ b/src/Jobs/settings.Staging.json @@ -0,0 +1,10 @@ +{ + "globalSettings": { + "baseServiceUri": { + "vault": "https://vault.bitwarden.com", + "api": "https://api.bitwarden.com", + "identity": "https://identity.bitwarden.com", + "identityInternal": "https://identity.bitwarden.com" + } + } +} diff --git a/src/Jobs/settings.json b/src/Jobs/settings.json new file mode 100644 index 000000000..a24d412e6 --- /dev/null +++ b/src/Jobs/settings.json @@ -0,0 +1,51 @@ +{ + "globalSettings": { + "selfHosted": false, + "siteName": "bitwarden", + "projectName": "Jobs", + "stripeApiKey": "SECRET", + "baseServiceUri": { + "vault": "http://localhost:4001", + "api": "http://localhost:4000", + "identity": "http://localhost:33656", + "internalIdentity": "http://localhost:33656" + }, + "sqlServer": { + "connectionString": "SECRET" + }, + "mail": { + "sendGridApiKey": "SECRET", + "replyToEmail": "hello@bitwarden.com" + }, + "identityServer": { + "certificateThumbprint": "SECRET" + }, + "dataProtection": { + "certificateThumbprint": "SECRET" + }, + "storage": { + "connectionString": "SECRET" + }, + "documentDb": { + "uri": "SECRET", + "key": "SECRET" + }, + "notificationHub": { + "connectionString": "SECRET", + "hubName": "SECRET" + }, + "yubico": { + "clientid": "SECRET", + "key": "SECRET" + }, + "duo": { + "aKey": "SECRET" + }, + "braintree": { + "production": false, + "merchantId": "SECRET", + "publicKey": "SECRET", + "privateKey": "SECRET" + } + } +}