diff --git a/src/Core/GlobalSettings.cs b/src/Core/GlobalSettings.cs
index d89d8e5f61..194de26341 100644
--- a/src/Core/GlobalSettings.cs
+++ b/src/Core/GlobalSettings.cs
@@ -36,17 +36,44 @@ namespace Bit.Core
public class SqlServerSettings
{
- public string ConnectionString { get; set; }
+ private string _connectionString;
+
+ public string ConnectionString
+ {
+ get => _connectionString;
+ set
+ {
+ _connectionString = value.Trim('"');
+ }
+ }
}
public class StorageSettings
{
- public string ConnectionString { get; set; }
+ private string _connectionString;
+
+ public string ConnectionString
+ {
+ get => _connectionString;
+ set
+ {
+ _connectionString = value.Trim('"');
+ }
+ }
}
public class AttachmentSettings
{
- public string ConnectionString { get; set; }
+ private string _connectionString;
+
+ public string ConnectionString
+ {
+ get => _connectionString;
+ set
+ {
+ _connectionString = value.Trim('"');
+ }
+ }
public string BaseDirectory { get; set; }
public string BaseUrl { get; set; }
}
@@ -87,7 +114,16 @@ namespace Bit.Core
public class NotificationHubSettings
{
- public string ConnectionString { get; set; }
+ private string _connectionString;
+
+ public string ConnectionString
+ {
+ get => _connectionString;
+ set
+ {
+ _connectionString = value.Trim('"');
+ }
+ }
public string HubName { get; set; }
}
diff --git a/util/MsSql/.dockerignore b/util/MsSql/.dockerignore
index 9dbc71be96..e46e7fae1c 100644
--- a/util/MsSql/.dockerignore
+++ b/util/MsSql/.dockerignore
@@ -1,3 +1,4 @@
*
!entrypoint.sh
!setup.sql
+!setup.sh
diff --git a/util/MsSql/Dockerfile b/util/MsSql/Dockerfile
index d24112848a..aebc5f597b 100644
--- a/util/MsSql/Dockerfile
+++ b/util/MsSql/Dockerfile
@@ -1,6 +1,8 @@
FROM microsoft/mssql-server-linux
COPY setup.sql /
+COPY setup.sh /
+RUN chmod +x /setup.sh
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
diff --git a/util/MsSql/entrypoint.sh b/util/MsSql/entrypoint.sh
index a049275c73..31c85e404e 100644
--- a/util/MsSql/entrypoint.sh
+++ b/util/MsSql/entrypoint.sh
@@ -1,4 +1,4 @@
#!/bin/sh
+/setup.sh &
/opt/mssql/bin/sqlservr
-/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P ${SA_PASSWORD} -i /setup.sql
diff --git a/util/MsSql/setup.sh b/util/MsSql/setup.sh
new file mode 100644
index 0000000000..447abfbf0a
--- /dev/null
+++ b/util/MsSql/setup.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+sleep 60s
+/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P ${SA_PASSWORD} -i /setup.sql
diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile
index 51cca202b4..48165c4aab 100644
--- a/util/Setup/Dockerfile
+++ b/util/Setup/Dockerfile
@@ -1,4 +1,4 @@
-FROM microsoft/dotnet:2.0.0-preview2-runtime
+FROM microsoft/dotnet:2.0.0-runtime
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
diff --git a/util/Setup/Helpers.cs b/util/Setup/Helpers.cs
index 7e07acd093..211f4669b4 100644
--- a/util/Setup/Helpers.cs
+++ b/util/Setup/Helpers.cs
@@ -1,6 +1,8 @@
using System;
+using System.IO;
using System.Security.Cryptography;
using System.Text;
+using System.Threading.Tasks;
namespace Setup
{
@@ -87,5 +89,31 @@ namespace Setup
return characters;
}
+
+ public static string MakeSqlConnectionString(string server, string database, string username, string password)
+ {
+ return $"Server=tcp:{server},1433;Initial Catalog={database};Persist Security Info=False;User ID={username};" +
+ $"Password={password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;" +
+ "Connection Timeout=30;";
+ }
+
+ public static string GetDatabasePasswordFronEnvFile()
+ {
+ if(!File.Exists("/bitwarden/docker/mssql.override.env"))
+ {
+ return null;
+ }
+
+ var lines = File.ReadAllLines("/bitwarden/docker/mssql.override.env");
+ foreach(var line in lines)
+ {
+ if(line.StartsWith("SA_PASSWORD="))
+ {
+ return line.Split(new char[] { '=' }, 2)[1];
+ }
+ }
+
+ return null;
+ }
}
}
diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs
index 3e423e59bf..e0cb3d2144 100644
--- a/util/Setup/Program.cs
+++ b/util/Setup/Program.cs
@@ -1,7 +1,9 @@
-using System;
+using DbUp;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Reflection;
using System.Runtime.InteropServices;
namespace Setup
@@ -25,7 +27,22 @@ namespace Setup
{
_args = args;
_parameters = ParseParameters();
+ if(_parameters.ContainsKey("install"))
+ {
+ Install();
+ }
+ else if(_parameters.ContainsKey("update"))
+ {
+ Update();
+ }
+ else
+ {
+ Console.WriteLine("No top-level command detected. Exiting...");
+ }
+ }
+ private static void Install()
+ {
_installationId = _parameters.ContainsKey("install_id") ?
_parameters["install_id"].ToLowerInvariant() : null;
_installationKey = _parameters.ContainsKey("install_key") ?
@@ -65,6 +82,41 @@ namespace Setup
BuildAppSettingsFiles();
}
+ private static void Update()
+ {
+ if(_parameters.ContainsKey("db"))
+ {
+ MigrateDatabase();
+ }
+ }
+
+ private static void MigrateDatabase()
+ {
+ Console.WriteLine("Migrating database.");
+
+ var dbPass = Helpers.GetDatabasePasswordFronEnvFile();
+ var connectionString = Helpers.MakeSqlConnectionString("mssql", "vault", "sa", dbPass ?? string.Empty);
+ var upgrader = DeployChanges.To
+ .SqlDatabase(connectionString)
+ .JournalToSqlTable("dbo", "Migration")
+ .WithScriptsAndCodeEmbeddedInAssembly(Assembly.GetExecutingAssembly(),
+ s => s.Contains($".DbScripts.") && !s.Contains(".Archive."))
+ .WithTransaction()
+ .WithExecutionTimeout(new TimeSpan(0, 5, 0))
+ .LogToConsole()
+ .Build();
+
+ var result = upgrader.PerformUpgrade();
+ if(result.Successful)
+ {
+ Console.WriteLine("Migration successful.");
+ }
+ else
+ {
+ Console.WriteLine("Migration failed.");
+ }
+ }
+
private static void MakeCerts()
{
if(!_ssl)
@@ -255,9 +307,7 @@ server {{
Console.WriteLine("Building docker environment override files.");
Directory.CreateDirectory("/bitwarden/docker/");
var dbPass = _parameters.ContainsKey("db_pass") ? _parameters["db_pass"].ToLowerInvariant() : "REPLACE";
- var dbConnectionString = "Server=tcp:mssql,1433;Initial Catalog=vault;Persist Security Info=False;User ID=sa;" +
- $"Password={dbPass};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;" +
- "Connection Timeout=30;";
+ var dbConnectionString = Helpers.MakeSqlConnectionString("mssql", "vault", "sa", dbPass);
using(var sw = File.CreateText("/bitwarden/docker/global.override.env"))
{
diff --git a/util/Setup/Setup.csproj b/util/Setup/Setup.csproj
index ce1697ae88..bb1e3b662c 100644
--- a/util/Setup/Setup.csproj
+++ b/util/Setup/Setup.csproj
@@ -3,6 +3,16 @@
Exe
netcoreapp2.0
+ 1701;1702;1705;NU1701
+
+
+
+
+
+
+
+
+