mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-29 08:00:19 +01:00
Merge pull request #672 from Cyberboss/DMAPISecurityRequirement [NugetDeploy]
DMAPI security requirement
This commit is contained in:
+10
-1
@@ -55,11 +55,16 @@
|
||||
#define TGS_REBOOT_MODE_SHUTDOWN 1
|
||||
#define TGS_REBOOT_MODE_RESTART 2
|
||||
|
||||
#define TGS_SECURITY_TRUSTED 0
|
||||
#define TGS_SECURITY_SAFE 1
|
||||
#define TGS_SECURITY_ULTRASAFE 2
|
||||
|
||||
//REQUIRED HOOKS
|
||||
|
||||
//Call this somewhere in /world/New() that is always run
|
||||
//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels
|
||||
/world/proc/TgsNew(datum/tgs_event_handler/event_handler)
|
||||
//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated
|
||||
/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
|
||||
return
|
||||
|
||||
//Call this when your initializations are complete and your game is ready to play before any player interactions happen
|
||||
@@ -155,6 +160,10 @@
|
||||
/world/proc/TgsRevision()
|
||||
return
|
||||
|
||||
//Get the current BYOND security level
|
||||
/world/proc/TgsSecurityLevel()
|
||||
return
|
||||
|
||||
//Gets a list of active `/datum/tgs_revision_information/test_merge`s
|
||||
/world/proc/TgsTestMerges()
|
||||
return
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/world/TgsNew(datum/tgs_event_handler/event_handler)
|
||||
/world/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
|
||||
var/current_api = TGS_READ_GLOBAL(tgs)
|
||||
if(current_api)
|
||||
TGS_ERROR_LOG("TgsNew(): TGS API datum already set ([current_api])!")
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
TGS_WRITE_GLOBAL(tgs, new_api)
|
||||
|
||||
var/result = new_api.OnWorldNew(event_handler ? event_handler : new /datum/tgs_event_handler/tgs_default)
|
||||
var/result = new_api.OnWorldNew(event_handler ? event_handler : new /datum/tgs_event_handler/tgs_default, minimum_required_security_level)
|
||||
if(!result || result == TGS_UNIMPLEMENTED)
|
||||
TGS_WRITE_GLOBAL(tgs, null)
|
||||
TGS_ERROR_LOG("Failed to activate API!")
|
||||
@@ -127,6 +127,11 @@
|
||||
if(api)
|
||||
api.ChatPrivateMessage(message, user)
|
||||
|
||||
/world/TgsSecurityLevel()
|
||||
var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
|
||||
if(api)
|
||||
api.SecurityLevel()
|
||||
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ TGS_PROTECT_DATUM(/datum/tgs_api)
|
||||
/datum/tgs_api/proc/ChatPrivateMessage(message, admin_only)
|
||||
return TGS_UNIMPLEMENTED
|
||||
|
||||
/datum/tgs_api/proc/SecurityLevel()
|
||||
return TGS_UNIMPLEMENTED
|
||||
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
/datum/tgs_api/v3210/proc/file2list(filename)
|
||||
return splittext(trim_left(trim_right(file2text(filename))), "\n")
|
||||
|
||||
/datum/tgs_api/v3210/OnWorldNew(datum/tgs_event_handler/event_handler) //don't use event handling in this version
|
||||
/datum/tgs_api/v3210/OnWorldNew(datum/tgs_event_handler/event_handler, minimum_required_security_level) //don't use event handling in this version
|
||||
. = FALSE
|
||||
|
||||
comms_key = world.params[SERVICE_WORLD_PARAM]
|
||||
@@ -191,6 +191,9 @@
|
||||
/datum/tgs_api/v3210/ChatPrivateMessage(message, datum/tgs_chat_user/user)
|
||||
return TGS_UNIMPLEMENTED
|
||||
|
||||
/datum/tgs_api/v3210/SecurityLevel()
|
||||
return TGS_SECURITY_TRUSTED
|
||||
|
||||
#undef REBOOT_MODE_NORMAL
|
||||
#undef REBOOT_MODE_HARD
|
||||
#undef REBOOT_MODE_SHUTDOWN
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
var/chat_commands_json_path
|
||||
var/server_commands_json_path
|
||||
var/reboot_mode = TGS_REBOOT_MODE_NORMAL
|
||||
var/security_level
|
||||
|
||||
var/list/intercepted_message_queue
|
||||
|
||||
@@ -48,7 +49,7 @@
|
||||
/datum/tgs_api/v4/ApiVersion()
|
||||
return "4.0.0.0"
|
||||
|
||||
/datum/tgs_api/v4/OnWorldNew(datum/tgs_event_handler/event_handler)
|
||||
/datum/tgs_api/v4/OnWorldNew(datum/tgs_event_handler/event_handler, minimum_required_security_level)
|
||||
json_path = world.params[TGS4_PARAM_INFO_JSON]
|
||||
if(!json_path)
|
||||
TGS_ERROR_LOG("Missing [TGS4_PARAM_INFO_JSON] world parameter!")
|
||||
@@ -63,14 +64,14 @@
|
||||
return
|
||||
|
||||
access_identifier = cached_json["accessIdentifier"]
|
||||
instance_name = text2num(cached_json["instanceName"])
|
||||
server_commands_json_path = cached_json["serverCommandsJson"]
|
||||
|
||||
if(cached_json["apiValidateOnly"])
|
||||
TGS_INFO_LOG("Validating API and exiting...")
|
||||
Export(TGS4_COMM_VALIDATE)
|
||||
Export(TGS4_COMM_VALIDATE, list(TGS4_PARAMETER_DATA = "[minimum_required_security_level]"))
|
||||
del(world)
|
||||
|
||||
security_level = cached_json["securityLevel"]
|
||||
chat_channels_json_path = cached_json["chatChannelsJson"]
|
||||
chat_commands_json_path = cached_json["chatCommandsJson"]
|
||||
src.event_handler = event_handler
|
||||
@@ -187,7 +188,7 @@
|
||||
|
||||
//request a new port
|
||||
export_lock = FALSE
|
||||
var/list/new_port_json = Export(TGS4_COMM_NEW_PORT, list("current_port" = "[world.port]")) //stringify this on purpose
|
||||
var/list/new_port_json = Export(TGS4_COMM_NEW_PORT, list(TGS4_PARAMETER_DATA = "[world.port]")) //stringify this on purpose
|
||||
|
||||
if(!new_port_json)
|
||||
TGS_ERROR_LOG("No new port response from server![TGS4_PORT_CRITFAIL_MESSAGE]")
|
||||
@@ -295,6 +296,9 @@
|
||||
channel.custom_tag = channel_json["tag"]
|
||||
return channel
|
||||
|
||||
/datum/tgs_api/v4/SecurityLevel()
|
||||
return security_level
|
||||
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Tgstation.Server.Api.Models
|
||||
public bool? Running { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current <see cref="DreamDaemonSecurity"/> of <see cref="DreamDaemon"/>
|
||||
/// The current <see cref="DreamDaemonSecurity"/> of <see cref="DreamDaemon"/>. May be downgraded due to requirements of <see cref="ActiveCompileJob"/>
|
||||
/// </summary>
|
||||
public DreamDaemonSecurity? CurrentSecurity { get; set; }
|
||||
|
||||
|
||||
@@ -17,5 +17,11 @@ namespace Tgstation.Server.Api.Models
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ushort? ApiValidationPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="DreamDaemonSecurity"/> level used to validate the DMAPI
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DreamDaemonSecurity? ApiValidationSecurityLevel { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Tgstation.Server.Api.Models.Internal
|
||||
{
|
||||
@@ -26,5 +27,11 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// The Game folder the results were compiled into
|
||||
/// </summary>
|
||||
public Guid? DirectoryName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The minimum <see cref="DreamDaemonSecurity"/> required to run the <see cref="CompileJob"/>'s output
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DreamDaemonSecurity? MinimumSecurityLevel { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ namespace Tgstation.Server.Api.Rights
|
||||
/// <summary>
|
||||
/// User may list and read all <see cref="Models.CompileJob"/>s
|
||||
/// </summary>
|
||||
CompileJobs = 32
|
||||
CompileJobs = 32,
|
||||
/// <summary>
|
||||
/// User may modify <see cref="Models.DreamMaker.ApiValidationSecurityLevel"/>
|
||||
/// </summary>
|
||||
SetSecurityLevel = 64
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<FileVersion>4.0.0.0</FileVersion>
|
||||
<PackageTags>json web api tgstation-server tgstation ss13 byond</PackageTags>
|
||||
<PackageReleaseNotes>Prototype release</PackageReleaseNotes>
|
||||
<Version>4.0.0.0-preview6003</Version>
|
||||
<Version>4.0.0.0-preview6004</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<DebugType>Full</DebugType>
|
||||
<Version>4.0.0.0-preview9109</Version>
|
||||
<Version>4.0.0.0-preview9110</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>Cyberboss</Authors>
|
||||
<Company>/tg/station 13</Company>
|
||||
|
||||
@@ -125,8 +125,6 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
if (job == null)
|
||||
throw new ArgumentNullException(nameof(job));
|
||||
|
||||
logger.LogTrace("Loading compile job {0}...", job.Id);
|
||||
|
||||
CompileJob finalCompileJob = null;
|
||||
//now load the entire compile job tree
|
||||
await databaseContextFactory.UseContext(async db => finalCompileJob = await db.CompileJobs.Where(x => x.Id == job.Id)
|
||||
|
||||
@@ -125,8 +125,8 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
/// <param name="byondLock">The current <see cref="IByondExecutableLock"/></param>
|
||||
/// <param name="portToUse">The port to use for API validation</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in <see langword="true"/> if the DMAPI was successfully validated, <see langword="false"/> otherwise</returns>
|
||||
async Task<bool> VerifyApi(uint timeout, DreamDaemonSecurity securityLevel, Models.CompileJob job, IByondExecutableLock byondLock, ushort portToUse, CancellationToken cancellationToken)
|
||||
/// <returns>A <see cref="Task"/> representing the running operation</returns>
|
||||
async Task VerifyApi(uint timeout, DreamDaemonSecurity securityLevel, Models.CompileJob job, IByondExecutableLock byondLock, ushort portToUse, CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogTrace("Verifying DMAPI...");
|
||||
var launchParameters = new DreamDaemonLaunchParameters
|
||||
@@ -138,6 +138,8 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
};
|
||||
|
||||
var dirA = ioManager.ConcatPath(job.DirectoryName.ToString(), ADirectoryName);
|
||||
|
||||
job.MinimumSecurityLevel = securityLevel; //needed for the TempDmbProvider
|
||||
var provider = new TemporaryDmbProvider(ioManager.ResolvePath(dirA), String.Concat(job.DmeName, DmbExtension), job);
|
||||
|
||||
var timeoutAt = DateTimeOffset.Now.AddSeconds(timeout);
|
||||
@@ -154,15 +156,36 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
if (!controller.Lifetime.IsCompleted)
|
||||
if (controller.Lifetime.IsCompleted)
|
||||
{
|
||||
logger.LogDebug("API validation timed out!");
|
||||
return false;
|
||||
var validationStatus = controller.ApiValidationStatus;
|
||||
logger.LogTrace("API validation status: {0}", validationStatus);
|
||||
switch (validationStatus)
|
||||
{
|
||||
case ApiValidationStatus.RequiresUltrasafe:
|
||||
job.MinimumSecurityLevel = DreamDaemonSecurity.Ultrasafe;
|
||||
return;
|
||||
case ApiValidationStatus.RequiresSafe:
|
||||
if (securityLevel == DreamDaemonSecurity.Ultrasafe)
|
||||
throw new JobException("This game must be run with at least the 'Safe' DreamDaemon security level!");
|
||||
job.MinimumSecurityLevel = DreamDaemonSecurity.Safe;
|
||||
return;
|
||||
case ApiValidationStatus.RequiresTrusted:
|
||||
if (securityLevel != DreamDaemonSecurity.Trusted)
|
||||
throw new JobException("This game must be run with at least the 'Trusted' DreamDaemon security level!");
|
||||
job.MinimumSecurityLevel = DreamDaemonSecurity.Trusted;
|
||||
return;
|
||||
case ApiValidationStatus.NeverValidated:
|
||||
break;
|
||||
case ApiValidationStatus.BadValidationRequest:
|
||||
throw new JobException("Recieved an unrecognized API validation request from DreamDaemon!");
|
||||
case ApiValidationStatus.UnaskedValidationRequest:
|
||||
default:
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Session controller returned unexpected ApiValidationStatus: {0}", validationStatus));
|
||||
}
|
||||
}
|
||||
|
||||
var validated = controller.ApiValidated;
|
||||
logger.LogTrace("API valid: {0}", validated);
|
||||
return validated;
|
||||
|
||||
throw new JobException("DMAPI validation timed out!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +266,7 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<Models.CompileJob> Compile(Models.RevisionInformation revisionInformation, Api.Models.DreamMaker dreamMakerSettings, DreamDaemonSecurity securityLevel, uint apiValidateTimeout, IRepository repository, CancellationToken cancellationToken)
|
||||
public async Task<Models.CompileJob> Compile(Models.RevisionInformation revisionInformation, Api.Models.DreamMaker dreamMakerSettings, uint apiValidateTimeout, IRepository repository, CancellationToken cancellationToken)
|
||||
{
|
||||
if (revisionInformation == null)
|
||||
throw new ArgumentNullException(nameof(revisionInformation));
|
||||
@@ -254,8 +277,8 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
if (repository == null)
|
||||
throw new ArgumentNullException(nameof(repository));
|
||||
|
||||
if (securityLevel == DreamDaemonSecurity.Ultrasafe)
|
||||
throw new ArgumentOutOfRangeException(nameof(securityLevel), securityLevel, "Cannot compile with ultrasafe security!");
|
||||
if (dreamMakerSettings.ApiValidationSecurityLevel == DreamDaemonSecurity.Ultrasafe)
|
||||
throw new ArgumentOutOfRangeException(nameof(dreamMakerSettings), dreamMakerSettings, "Cannot compile with ultrasafe security!");
|
||||
|
||||
logger.LogTrace("Begin Compile");
|
||||
|
||||
@@ -356,13 +379,18 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
|
||||
var exitCode = await RunDreamMaker(byondLock.DreamMakerPath, job, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var apiValidated = exitCode == 0 && await VerifyApi(apiValidateTimeout, securityLevel, job, byondLock, dreamMakerSettings.ApiValidationPort.Value, cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (exitCode != 0)
|
||||
throw new JobException(String.Format(CultureInfo.InvariantCulture, "DM exited with a non-zero code: {0}{1}{2}", exitCode, Environment.NewLine, job.Output));
|
||||
|
||||
if (!apiValidated)
|
||||
await VerifyApi(apiValidateTimeout, dreamMakerSettings.ApiValidationSecurityLevel.Value, job, byondLock, dreamMakerSettings.ApiValidationPort.Value, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (JobException)
|
||||
{
|
||||
//server never validated or compile failed
|
||||
await eventConsumer.HandleEvent(EventType.CompileFailure, new List<string> { resolvedGameDirectory, exitCode == 0 ? "1" : "0" }, cancellationToken).ConfigureAwait(false);
|
||||
throw new JobException(exitCode == 0 ? "Validation of the TGS api failed!" : String.Format(CultureInfo.InvariantCulture, "DM exited with a non-zero code: {0}{1}{2}", exitCode, Environment.NewLine, job.Output));
|
||||
throw;
|
||||
}
|
||||
|
||||
logger.LogTrace("Running post compile event...");
|
||||
|
||||
@@ -15,11 +15,10 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
/// </summary>
|
||||
/// <param name="revisionInformation">The <see cref="Models.RevisionInformation"/> being compiled from the <paramref name="repository"/></param>
|
||||
/// <param name="dreamMakerSettings">The <see cref="Api.Models.DreamMaker"/> for the compile</param>
|
||||
/// <param name="securityLevel">The <see cref="DreamDaemonSecurity"/> level allowed for API validation</param>
|
||||
/// <param name="apiValidateTimeout">The time in seconds to wait while validating the API</param>
|
||||
/// <param name="repository">The <see cref="IRepository"/> to copy from</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the partially populated <see cref="Models.CompileJob"/> for the operation. In particular, note the <see cref="Models.CompileJob.RevisionInformation"/> field will only have it's <see cref="Api.Models.Internal.RevisionInformation.CommitSha"/> field populated</returns>
|
||||
Task<Models.CompileJob> Compile(Models.RevisionInformation revisionInformation, Api.Models.DreamMaker dreamMakerSettings, DreamDaemonSecurity securityLevel, uint apiValidateTimeout, IRepository repository, CancellationToken cancellationToken);
|
||||
Task<Models.CompileJob> Compile(Models.RevisionInformation revisionInformation, Api.Models.DreamMaker dreamMakerSettings, uint apiValidateTimeout, IRepository repository, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,6 @@ namespace Tgstation.Server.Host.Components
|
||||
var ddSettingsTask = databaseContext.DreamDaemonSettings.Where(x => x.InstanceId == metadata.Id).Select(x => new DreamDaemonSettings
|
||||
{
|
||||
StartupTimeout = x.StartupTimeout,
|
||||
SecurityLevel = x.SecurityLevel
|
||||
}).FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
var dreamMakerSettings = await databaseContext.DreamMakerSettings.Where(x => x.InstanceId == metadata.Id).FirstAsync(cancellationToken).ConfigureAwait(false);
|
||||
@@ -167,7 +166,7 @@ namespace Tgstation.Server.Host.Components
|
||||
databaseContext.Instances.Attach(revInfo.Instance);
|
||||
}
|
||||
|
||||
compileJob = await DreamMaker.Compile(revInfo, dreamMakerSettings, ddSettings.SecurityLevel.Value, ddSettings.StartupTimeout.Value, repo, cancellationToken).ConfigureAwait(false);
|
||||
compileJob = await DreamMaker.Compile(revInfo, dreamMakerSettings, ddSettings.StartupTimeout.Value, repo, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
compileJob.Job = job;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Interop
|
||||
@@ -39,9 +40,14 @@ namespace Tgstation.Server.Host.Components.Interop
|
||||
public string ServerCommandsJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="RevisionInformation"/> of the launch
|
||||
/// The <see cref="Api.Models.Internal.RevisionInformation"/> of the launch
|
||||
/// </summary>
|
||||
public RevisionInformation Revision { get; set; }
|
||||
public Api.Models.Internal.RevisionInformation Revision { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="DreamDaemonSecurity"/> level of the launch
|
||||
/// </summary>
|
||||
public DreamDaemonSecurity SecurityLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TestMerge"/>s in the launch
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// Status of DMAPI validation
|
||||
/// </summary>
|
||||
enum ApiValidationStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The DMAPI never contacted the server for validation
|
||||
/// </summary>
|
||||
NeverValidated,
|
||||
/// <summary>
|
||||
/// The server was contacted for validation but it was never requested
|
||||
/// </summary>
|
||||
UnaskedValidationRequest,
|
||||
/// <summary>
|
||||
/// The validation request was malformed
|
||||
/// </summary>
|
||||
BadValidationRequest,
|
||||
/// <summary>
|
||||
/// Valid API. The game must be run with a minimum security level of <see cref="Api.Models.DreamDaemonSecurity.Safe"/>
|
||||
/// </summary>
|
||||
RequiresSafe,
|
||||
/// <summary>
|
||||
/// Valid API. The game must be run with a security level of <see cref="Api.Models.DreamDaemonSecurity.Trusted"/>
|
||||
/// </summary>
|
||||
RequiresTrusted,
|
||||
/// <summary>
|
||||
/// Valid API. The game must be run with a minimum security level of <see cref="Api.Models.DreamDaemonSecurity.Ultrasafe"/>
|
||||
/// </summary>
|
||||
RequiresUltrasafe
|
||||
}
|
||||
}
|
||||
@@ -25,9 +25,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
bool TerminationWasRequested { get; }
|
||||
|
||||
/// <summary>
|
||||
/// If the DMAPI was validated. This field may only be access once <see cref="IProcessBase.Lifetime"/> completes
|
||||
/// The DMAPI <see cref="Components.Watchdog.ApiValidationStatus"/>
|
||||
/// </summary>
|
||||
bool ApiValidated { get; }
|
||||
ApiValidationStatus ApiValidationStatus { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IDmbProvider"/> being used
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <summary>
|
||||
/// Create a <see cref="ISessionController"/> from a freshly launch DreamDaemon instance
|
||||
/// </summary>
|
||||
/// <param name="launchParameters">The <see cref="DreamDaemonLaunchParameters"/> to use</param>
|
||||
/// <param name="launchParameters">The <see cref="DreamDaemonLaunchParameters"/> to use. <see cref="DreamDaemonLaunchParameters.SecurityLevel"/> will be updated with the minumum required security level for the launch</param>
|
||||
/// <param name="dmbProvider">The <see cref="IDmbProvider"/> to use</param>
|
||||
/// <param name="currentByondLock">The current <see cref="IByondExecutableLock"/> if any</param>
|
||||
/// <param name="primaryPort">If the <see cref="DreamDaemonLaunchParameters.PrimaryPort"/> of <paramref name="launchParameters"/> should be used</param>
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <summary>
|
||||
/// Changes the <see cref="ActiveLaunchParameters"/>. If currently <see cref="Running"/> triggers a graceful restart
|
||||
/// </summary>
|
||||
/// <param name="launchParameters">The new <see cref="DreamDaemonLaunchParameters"/></param>
|
||||
/// <param name="launchParameters">The new <see cref="DreamDaemonLaunchParameters"/>. May be modified</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation</returns>
|
||||
Task ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken);
|
||||
|
||||
@@ -29,13 +29,13 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool ApiValidated
|
||||
public ApiValidationStatus ApiValidationStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Lifetime.IsCompleted)
|
||||
throw new InvalidOperationException("ApiValidated cannot be checked while Lifetime is incomplete!");
|
||||
return apiValidated;
|
||||
return apiValidationStatus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// </summary>
|
||||
readonly ILogger<SessionController> logger;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="DreamDaemonSecurity"/> level the <see cref="process"/> was launched with
|
||||
/// </summary>
|
||||
readonly DreamDaemonSecurity? launchSecurityLevel;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TaskCompletionSource{TResult}"/> <see cref="SetPort(ushort, CancellationToken)"/> waits on when DreamDaemon currently has it's ports closed
|
||||
/// </summary>
|
||||
@@ -151,9 +156,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
bool disposed;
|
||||
|
||||
/// <summary>
|
||||
/// If the DMAPI was validated
|
||||
/// The <see cref="ApiValidationStatus"/> for the <see cref="SessionController"/>
|
||||
/// </summary>
|
||||
bool apiValidated;
|
||||
ApiValidationStatus apiValidationStatus;
|
||||
|
||||
/// <summary>
|
||||
/// If <see cref="process"/> should be kept alive instead
|
||||
@@ -171,8 +176,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <param name="chat">The value of <see cref="chat"/></param>
|
||||
/// <param name="chatJsonTrackingContext">The value of <see cref="chatJsonTrackingContext"/></param>
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
/// <param name="launchSecurityLevel">The value of <see cref="launchSecurityLevel"/></param>
|
||||
/// <param name="startupTimeout">The optional time to wait before failing the <see cref="LaunchResult"/></param>
|
||||
public SessionController(ReattachInformation reattachInformation, IProcess process, IByondExecutableLock byondLock, IByondTopicSender byondTopicSender, IJsonTrackingContext chatJsonTrackingContext, ICommContext interopContext, IChat chat, ILogger<SessionController> logger, uint? startupTimeout)
|
||||
public SessionController(ReattachInformation reattachInformation, IProcess process, IByondExecutableLock byondLock, IByondTopicSender byondTopicSender, IJsonTrackingContext chatJsonTrackingContext, ICommContext interopContext, IChat chat, ILogger<SessionController> logger, DreamDaemonSecurity? launchSecurityLevel, uint? startupTimeout)
|
||||
{
|
||||
this.chatJsonTrackingContext = chatJsonTrackingContext; //null valid
|
||||
this.reattachInformation = reattachInformation ?? throw new ArgumentNullException(nameof(reattachInformation));
|
||||
@@ -183,11 +189,13 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
this.launchSecurityLevel = launchSecurityLevel;
|
||||
|
||||
interopContext.RegisterHandler(this);
|
||||
|
||||
portClosedForReboot = false;
|
||||
disposed = false;
|
||||
apiValidated = false;
|
||||
apiValidationStatus = ApiValidationStatus.NeverValidated;
|
||||
released = false;
|
||||
|
||||
rebootTcs = new TaskCompletionSource<object>();
|
||||
@@ -289,6 +297,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/////UHHHH
|
||||
logger.LogWarning("DreamDaemon sent new port command without providing it's own!");
|
||||
content = new ErrorMessage { Message = "Missing stringified port as data parameter!" };
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -314,7 +323,30 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
}
|
||||
break;
|
||||
case Constants.DMCommandApiValidate:
|
||||
apiValidated = true;
|
||||
if (!launchSecurityLevel.HasValue)
|
||||
{
|
||||
logger.LogWarning("DreamDaemon requested API validation but no intial security level was passed to the session controller!");
|
||||
apiValidationStatus = ApiValidationStatus.UnaskedValidationRequest;
|
||||
content = new ErrorMessage { Message = "Invalid API validation request!" };
|
||||
break;
|
||||
}
|
||||
if (!query.TryGetValue(Constants.DMParameterData, out var stringMinimumSecurityLevel) || !Enum.TryParse<DreamDaemonSecurity>(stringMinimumSecurityLevel, out var minimumSecurityLevel))
|
||||
apiValidationStatus = ApiValidationStatus.BadValidationRequest;
|
||||
else
|
||||
switch (minimumSecurityLevel)
|
||||
{
|
||||
case DreamDaemonSecurity.Safe:
|
||||
apiValidationStatus = ApiValidationStatus.RequiresSafe;
|
||||
break;
|
||||
case DreamDaemonSecurity.Ultrasafe:
|
||||
apiValidationStatus = ApiValidationStatus.RequiresUltrasafe;
|
||||
break;
|
||||
case DreamDaemonSecurity.Trusted:
|
||||
apiValidationStatus = ApiValidationStatus.RequiresTrusted;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Enum.TryParse failed to validate the DreamDaemonSecurity range!");
|
||||
}
|
||||
break;
|
||||
case Constants.DMCommandWorldReboot:
|
||||
if (ClosePortOnReboot)
|
||||
|
||||
@@ -131,6 +131,22 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
//i changed this back from guids, hopefully i don't regret that
|
||||
string JsonFile(string name) => String.Format(CultureInfo.InvariantCulture, "{0}.{1}", name, JsonPostfix);
|
||||
|
||||
var securityLevelToUse = launchParameters.SecurityLevel.Value;
|
||||
switch (dmbProvider.CompileJob.MinimumSecurityLevel)
|
||||
{
|
||||
case DreamDaemonSecurity.Ultrasafe:
|
||||
break;
|
||||
case DreamDaemonSecurity.Safe:
|
||||
if (securityLevelToUse == DreamDaemonSecurity.Ultrasafe)
|
||||
securityLevelToUse = DreamDaemonSecurity.Safe;
|
||||
break;
|
||||
case DreamDaemonSecurity.Trusted:
|
||||
securityLevelToUse = DreamDaemonSecurity.Trusted;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid DreamDaemonSecurity value: {0}", dmbProvider.CompileJob.MinimumSecurityLevel));
|
||||
}
|
||||
|
||||
//setup interop files
|
||||
var interopInfo = new JsonFile
|
||||
{
|
||||
@@ -140,6 +156,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
ChatCommandsJson = JsonFile("chat_commands"),
|
||||
ServerCommandsJson = JsonFile("server_commands"),
|
||||
InstanceName = instance.Name,
|
||||
SecurityLevel = securityLevelToUse,
|
||||
Revision = new Api.Models.Internal.RevisionInformation
|
||||
{
|
||||
CommitSha = dmbProvider.CompileJob.RevisionInformation.CommitSha,
|
||||
@@ -182,7 +199,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
dmbProvider.DmbName,
|
||||
primaryPort ? launchParameters.PrimaryPort : launchParameters.SecondaryPort,
|
||||
launchParameters.AllowWebClient.Value ? "-webclient " : String.Empty,
|
||||
SecurityWord(launchParameters.SecurityLevel.Value),
|
||||
SecurityWord(securityLevelToUse),
|
||||
parameters);
|
||||
|
||||
//launch dd
|
||||
@@ -190,7 +207,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
try
|
||||
{
|
||||
//return the session controller for it
|
||||
return new SessionController(new ReattachInformation
|
||||
var result = new SessionController(new ReattachInformation
|
||||
{
|
||||
AccessIdentifier = accessIdentifier,
|
||||
Dmb = dmbProvider,
|
||||
@@ -200,7 +217,12 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
ChatChannelsJson = interopInfo.ChatChannelsJson,
|
||||
ChatCommandsJson = interopInfo.ChatCommandsJson,
|
||||
ServerCommandsJson = interopInfo.ServerCommandsJson,
|
||||
}, process, byondLock, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger<SessionController>(), launchParameters.StartupTimeout);
|
||||
}, process, byondLock, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger<SessionController>(), launchParameters.SecurityLevel, launchParameters.StartupTimeout);
|
||||
|
||||
//writeback launch parameter's fixed security level
|
||||
launchParameters.SecurityLevel = securityLevelToUse;
|
||||
|
||||
return result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -247,7 +269,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
var process = processExecutor.GetProcess(reattachInformation.ProcessId);
|
||||
try
|
||||
{
|
||||
return new SessionController(reattachInformation, process, byondLock, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger<SessionController>(), null);
|
||||
return new SessionController(reattachInformation, process, byondLock, byondTopicSender, chatJsonTrackingContext, context, chat, loggerFactory.CreateLogger<SessionController>(), null, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
|
||||
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
|
||||
/// <param name="jobManager">The value of <see cref="jobManager"/></param>
|
||||
/// <param name="initialLaunchParameters">The initial value of <see cref="ActiveLaunchParameters"/></param>
|
||||
/// <param name="initialLaunchParameters">The initial value of <see cref="ActiveLaunchParameters"/>. May be modified</param>
|
||||
/// <param name="instance">The value of <see cref="instance"/></param>
|
||||
/// <param name="autoStart">The value of <see cref="autoStart"/></param>
|
||||
public Watchdog(IChat chat, ISessionControllerFactory sessionControllerFactory, IDmbFactory dmbFactory, IServerControl serverUpdater, ILogger<Watchdog> logger, IReattachInfoHandler reattachInfoHandler, IDatabaseContextFactory databaseContextFactory, IByondTopicSender byondTopicSender, IEventConsumer eventConsumer, IJobManager jobManager, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, bool autoStart)
|
||||
|
||||
@@ -196,10 +196,11 @@ namespace Tgstation.Server.Host.Controllers
|
||||
return BadRequest(new ErrorMessage { Message = "Primary port and secondary port cannot be the same!" });
|
||||
|
||||
var wd = instanceManager.GetInstance(Instance).Watchdog;
|
||||
|
||||
//run these in parallel because they are equally as important
|
||||
await Task.WhenAll(DatabaseContext.Save(cancellationToken), wd.ChangeSettings(current, cancellationToken)).ConfigureAwait(false);
|
||||
|
||||
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
|
||||
//run this second because current may be modified by it
|
||||
await wd.ChangeSettings(current, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!oldSoftRestart.Value && current.SoftRestart.Value)
|
||||
await wd.Restart(true, cancellationToken).ConfigureAwait(false);
|
||||
else if (!oldSoftShutdown.Value && current.SoftShutdown.Value)
|
||||
|
||||
@@ -101,12 +101,15 @@ namespace Tgstation.Server.Host.Controllers
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[TgsAuthorize(DreamMakerRights.SetDme | DreamMakerRights.SetApiValidationPort)]
|
||||
[TgsAuthorize(DreamMakerRights.SetDme | DreamMakerRights.SetApiValidationPort | DreamMakerRights.SetApiValidationPort)]
|
||||
public override async Task<IActionResult> Update([FromBody] DreamMaker model, CancellationToken cancellationToken)
|
||||
{
|
||||
if (model.ApiValidationPort == 0)
|
||||
return BadRequest(new ErrorMessage { Message = "API Validation port cannot be 0!" });
|
||||
|
||||
if (model.ApiValidationSecurityLevel == DreamDaemonSecurity.Ultrasafe)
|
||||
return BadRequest(new ErrorMessage { Message = "This version of TGS does not support the ultrasafe DreamDaemon configuration!" });
|
||||
|
||||
var hostModel = await DatabaseContext.DreamMakerSettings.Where(x => x.InstanceId == Instance.Id).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (hostModel == null)
|
||||
return StatusCode((int)HttpStatusCode.Gone);
|
||||
@@ -128,6 +131,13 @@ namespace Tgstation.Server.Host.Controllers
|
||||
hostModel.ApiValidationPort = model.ApiValidationPort;
|
||||
}
|
||||
|
||||
if (model.ApiValidationSecurityLevel.HasValue)
|
||||
{
|
||||
if (!AuthenticationContext.InstanceUser.DreamMakerRights.Value.HasFlag(DreamMakerRights.SetSecurityLevel))
|
||||
return Forbid();
|
||||
hostModel.ApiValidationSecurityLevel = model.ApiValidationSecurityLevel;
|
||||
}
|
||||
|
||||
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
|
||||
return await Read(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,8 @@ namespace Tgstation.Server.Host.Controllers
|
||||
},
|
||||
DreamMakerSettings = new DreamMakerSettings
|
||||
{
|
||||
ApiValidationPort = 1339
|
||||
ApiValidationPort = 1339,
|
||||
ApiValidationSecurityLevel = DreamDaemonSecurity.Safe
|
||||
},
|
||||
Name = model.Name,
|
||||
Online = false,
|
||||
|
||||
-1
@@ -3,7 +3,6 @@ using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace Tgstation.Server.Host.Models.Migrations
|
||||
{
|
||||
|
||||
Generated
+648
@@ -0,0 +1,648 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Tgstation.Server.Host.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.Migrations
|
||||
{
|
||||
[DbContext(typeof(MySqlDatabaseContext))]
|
||||
[Migration("20180918020726_MYAddMinimumSecurity")]
|
||||
partial class MYAddMinimumSecurity
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds the target model
|
||||
/// </summary>
|
||||
/// <param name="modelBuilder">The <see cref="ModelBuilder"/> to use</param>
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.1.3-rtm-32065")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ConnectionString")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("Enabled");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int?>("Provider");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ChatBots");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("ChatSettingsId");
|
||||
|
||||
b.Property<ulong?>("DiscordChannelId");
|
||||
|
||||
b.Property<string>("IrcChannel");
|
||||
|
||||
b.Property<bool?>("IsAdminChannel")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("IsUpdatesChannel")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("IsWatchdogChannel")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Tag");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChatSettingsId", "DiscordChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("ChatSettingsId", "IrcChannel")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ChatChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ByondVersion")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<Guid?>("DirectoryName");
|
||||
|
||||
b.Property<string>("DmeName");
|
||||
|
||||
b.Property<long?>("JobId");
|
||||
|
||||
b.Property<int>("MinimumSecurityLevel");
|
||||
|
||||
b.Property<string>("Output");
|
||||
|
||||
b.Property<long>("RevisionInformationId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DirectoryName");
|
||||
|
||||
b.HasIndex("JobId");
|
||||
|
||||
b.HasIndex("RevisionInformationId");
|
||||
|
||||
b.ToTable("CompileJobs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("AccessToken");
|
||||
|
||||
b.Property<bool?>("AllowWebClient")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("AutoStart")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<ushort?>("PrimaryPort")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int?>("ProcessId");
|
||||
|
||||
b.Property<ushort?>("SecondaryPort")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int>("SecurityLevel");
|
||||
|
||||
b.Property<bool?>("SoftRestart")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("SoftShutdown")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<uint?>("StartupTimeout")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("DreamDaemonSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ushort?>("ApiValidationPort")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int>("ApiValidationSecurityLevel");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<string>("ProjectName");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("DreamMakerSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<uint?>("AutoUpdateInterval")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int>("ConfigurationType");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("Online")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("WatchdogReattachInformationId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Path")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("WatchdogReattachInformationId");
|
||||
|
||||
b.ToTable("Instances");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ByondRights");
|
||||
|
||||
b.Property<ulong>("ChatBotRights");
|
||||
|
||||
b.Property<ulong>("ConfigurationRights");
|
||||
|
||||
b.Property<ulong>("DreamDaemonRights");
|
||||
|
||||
b.Property<ulong>("DreamMakerRights");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<ulong>("InstanceUserRights");
|
||||
|
||||
b.Property<ulong>("RepositoryRights");
|
||||
|
||||
b.Property<long?>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId");
|
||||
|
||||
b.HasIndex("UserId", "InstanceId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("InstanceUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("CancelRight");
|
||||
|
||||
b.Property<ulong?>("CancelRightsType");
|
||||
|
||||
b.Property<bool?>("Cancelled")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("CancelledById");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("ExceptionDetails");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<DateTimeOffset?>("StartedAt")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long>("StartedById");
|
||||
|
||||
b.Property<DateTimeOffset?>("StoppedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CancelledById");
|
||||
|
||||
b.HasIndex("InstanceId");
|
||||
|
||||
b.HasIndex("StartedById");
|
||||
|
||||
b.ToTable("Jobs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("AccessIdentifier")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("ChatChannelsJson")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("ChatCommandsJson")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("CompileJobId");
|
||||
|
||||
b.Property<bool>("IsPrimary");
|
||||
|
||||
b.Property<ushort>("Port");
|
||||
|
||||
b.Property<int>("ProcessId");
|
||||
|
||||
b.Property<int>("RebootState");
|
||||
|
||||
b.Property<string>("ServerCommandsJson")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CompileJobId");
|
||||
|
||||
b.ToTable("ReattachInformations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("AccessToken");
|
||||
|
||||
b.Property<string>("AccessUser");
|
||||
|
||||
b.Property<bool?>("AutoUpdatesKeepTestMerges")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("AutoUpdatesSynchronize")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("CommitterEmail")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("CommitterName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<bool?>("PushTestMergeCommits")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("ShowTestMergeCommitters")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("RepositorySettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("RevisionInformationId");
|
||||
|
||||
b.Property<long>("TestMergeId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RevisionInformationId");
|
||||
|
||||
b.HasIndex("TestMergeId");
|
||||
|
||||
b.ToTable("RevInfoTestMerges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommitSha")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40);
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<string>("OriginCommitSha")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CommitSha")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("InstanceId");
|
||||
|
||||
b.ToTable("RevisionInformations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("BodyAtMerge")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Comment");
|
||||
|
||||
b.Property<DateTimeOffset>("MergedAt");
|
||||
|
||||
b.Property<long>("MergedById");
|
||||
|
||||
b.Property<int?>("Number")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("PrimaryRevisionInformationId");
|
||||
|
||||
b.Property<string>("PullRequestRevision")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("TitleAtMerge")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MergedById");
|
||||
|
||||
b.HasIndex("PrimaryRevisionInformationId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("TestMerges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AdministrationRights");
|
||||
|
||||
b.Property<string>("CanonicalName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<DateTimeOffset?>("CreatedAt")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("CreatedById");
|
||||
|
||||
b.Property<bool?>("Enabled")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("InstanceManagerRights");
|
||||
|
||||
b.Property<DateTimeOffset?>("LastPasswordUpdate");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("PasswordHash");
|
||||
|
||||
b.Property<string>("SystemIdentifier");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CanonicalName")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.WatchdogReattachInformation", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long?>("AlphaId");
|
||||
|
||||
b.Property<bool>("AlphaIsActive");
|
||||
|
||||
b.Property<long?>("BravoId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AlphaId");
|
||||
|
||||
b.HasIndex("BravoId");
|
||||
|
||||
b.ToTable("WatchdogReattachInformations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithMany("ChatSettings")
|
||||
.HasForeignKey("InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
|
||||
.WithMany("Channels")
|
||||
.HasForeignKey("ChatSettingsId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
|
||||
.WithMany()
|
||||
.HasForeignKey("JobId");
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
|
||||
.WithMany("CompileJobs")
|
||||
.HasForeignKey("RevisionInformationId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithOne("DreamDaemonSettings")
|
||||
.HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithOne("DreamMakerSettings")
|
||||
.HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.WatchdogReattachInformation", "WatchdogReattachInformation")
|
||||
.WithMany()
|
||||
.HasForeignKey("WatchdogReattachInformationId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithMany("InstanceUsers")
|
||||
.HasForeignKey("InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.User")
|
||||
.WithMany("InstanceUsers")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CancelledById");
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithMany("Jobs")
|
||||
.HasForeignKey("InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("StartedById")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
|
||||
.WithMany()
|
||||
.HasForeignKey("CompileJobId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithOne("RepositorySettings")
|
||||
.HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
|
||||
.WithMany("ActiveTestMerges")
|
||||
.HasForeignKey("RevisionInformationId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
|
||||
.WithMany("RevisonInformations")
|
||||
.HasForeignKey("TestMergeId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithMany("RevisionInformations")
|
||||
.HasForeignKey("InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
|
||||
.WithMany("TestMerges")
|
||||
.HasForeignKey("MergedById")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
|
||||
.WithOne("PrimaryTestMerge")
|
||||
.HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
|
||||
.WithMany("CreatedUsers")
|
||||
.HasForeignKey("CreatedById");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.WatchdogReattachInformation", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Alpha")
|
||||
.WithMany()
|
||||
.HasForeignKey("AlphaId");
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Bravo")
|
||||
.WithMany()
|
||||
.HasForeignKey("BravoId");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Tgstation.Server.Api.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Add the <see cref="Api.Models.Internal.CompileJob.MinimumSecurityLevel"/> and <see cref="DreamMaker.ApiValidationSecurityLevel"/> columns for MySQL/MariaDB
|
||||
/// </summary>
|
||||
public partial class MYAddMinimumSecurity : Migration
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies the migration
|
||||
/// </summary>
|
||||
/// <param name="migrationBuilder">The <see cref="MigrationBuilder"/> to use</param>
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "ApiValidationSecurityLevel",
|
||||
table: "DreamMakerSettings",
|
||||
nullable: false,
|
||||
defaultValue: (int)DreamDaemonSecurity.Safe);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "MinimumSecurityLevel",
|
||||
table: "CompileJobs",
|
||||
nullable: false,
|
||||
defaultValue: (int)DreamDaemonSecurity.Safe);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unapplies the migration
|
||||
/// </summary>
|
||||
/// <param name="migrationBuilder">The <see cref="MigrationBuilder"/> to use</param>
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ApiValidationSecurityLevel",
|
||||
table: "DreamMakerSettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MinimumSecurityLevel",
|
||||
table: "CompileJobs");
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+676
@@ -0,0 +1,676 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Tgstation.Server.Host.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.Migrations
|
||||
{
|
||||
[DbContext(typeof(SqlServerDatabaseContext))]
|
||||
[Migration("20180918021228_MSAddMinimumSecurity")]
|
||||
partial class MSAddMinimumSecurity
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds the target model
|
||||
/// </summary>
|
||||
/// <param name="modelBuilder">The <see cref="ModelBuilder"/> to use</param>
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.1.3-rtm-32065")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("ConnectionString")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("Enabled");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int?>("Provider");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ChatBots");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<long>("ChatSettingsId");
|
||||
|
||||
b.Property<decimal?>("DiscordChannelId")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<string>("IrcChannel");
|
||||
|
||||
b.Property<bool?>("IsAdminChannel")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("IsUpdatesChannel")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("IsWatchdogChannel")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Tag");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChatSettingsId", "DiscordChannelId")
|
||||
.IsUnique()
|
||||
.HasFilter("[DiscordChannelId] IS NOT NULL");
|
||||
|
||||
b.HasIndex("ChatSettingsId", "IrcChannel")
|
||||
.IsUnique()
|
||||
.HasFilter("[IrcChannel] IS NOT NULL");
|
||||
|
||||
b.ToTable("ChatChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("ByondVersion")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<Guid?>("DirectoryName");
|
||||
|
||||
b.Property<string>("DmeName");
|
||||
|
||||
b.Property<long?>("JobId");
|
||||
|
||||
b.Property<int>("MinimumSecurityLevel");
|
||||
|
||||
b.Property<string>("Output");
|
||||
|
||||
b.Property<long>("RevisionInformationId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DirectoryName");
|
||||
|
||||
b.HasIndex("JobId");
|
||||
|
||||
b.HasIndex("RevisionInformationId");
|
||||
|
||||
b.ToTable("CompileJobs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("AccessToken");
|
||||
|
||||
b.Property<bool?>("AllowWebClient")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("AutoStart")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<int>("PrimaryPort");
|
||||
|
||||
b.Property<int?>("ProcessId");
|
||||
|
||||
b.Property<int>("SecondaryPort");
|
||||
|
||||
b.Property<int>("SecurityLevel");
|
||||
|
||||
b.Property<bool?>("SoftRestart")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("SoftShutdown")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long>("StartupTimeout");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("DreamDaemonSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<int>("ApiValidationPort");
|
||||
|
||||
b.Property<int>("ApiValidationSecurityLevel");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<string>("ProjectName");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("DreamMakerSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<long>("AutoUpdateInterval");
|
||||
|
||||
b.Property<int>("ConfigurationType");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("Online")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("WatchdogReattachInformationId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Path")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("WatchdogReattachInformationId");
|
||||
|
||||
b.ToTable("Instances");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<decimal>("ByondRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<decimal>("ChatBotRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<decimal>("ConfigurationRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<decimal>("DreamDaemonRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<decimal>("DreamMakerRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<decimal>("InstanceUserRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<decimal>("RepositoryRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<long?>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId");
|
||||
|
||||
b.HasIndex("UserId", "InstanceId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("InstanceUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<decimal?>("CancelRight")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<decimal?>("CancelRightsType")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<bool?>("Cancelled")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("CancelledById");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("ExceptionDetails");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<DateTimeOffset?>("StartedAt")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long>("StartedById");
|
||||
|
||||
b.Property<DateTimeOffset?>("StoppedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CancelledById");
|
||||
|
||||
b.HasIndex("InstanceId");
|
||||
|
||||
b.HasIndex("StartedById");
|
||||
|
||||
b.ToTable("Jobs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("AccessIdentifier")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("ChatChannelsJson")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("ChatCommandsJson")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("CompileJobId");
|
||||
|
||||
b.Property<bool>("IsPrimary");
|
||||
|
||||
b.Property<int>("Port");
|
||||
|
||||
b.Property<int>("ProcessId");
|
||||
|
||||
b.Property<int>("RebootState");
|
||||
|
||||
b.Property<string>("ServerCommandsJson")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CompileJobId");
|
||||
|
||||
b.ToTable("ReattachInformations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("AccessToken");
|
||||
|
||||
b.Property<string>("AccessUser");
|
||||
|
||||
b.Property<bool?>("AutoUpdatesKeepTestMerges")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("AutoUpdatesSynchronize")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("CommitterEmail")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("CommitterName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<bool?>("PushTestMergeCommits")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<bool?>("ShowTestMergeCommitters")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstanceId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("RepositorySettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<long>("RevisionInformationId");
|
||||
|
||||
b.Property<long>("TestMergeId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RevisionInformationId");
|
||||
|
||||
b.HasIndex("TestMergeId");
|
||||
|
||||
b.ToTable("RevInfoTestMerges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("CommitSha")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40);
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<string>("OriginCommitSha")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CommitSha")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("InstanceId");
|
||||
|
||||
b.ToTable("RevisionInformations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("Author")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("BodyAtMerge")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Comment");
|
||||
|
||||
b.Property<DateTimeOffset>("MergedAt");
|
||||
|
||||
b.Property<long>("MergedById");
|
||||
|
||||
b.Property<int?>("Number")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("PrimaryRevisionInformationId");
|
||||
|
||||
b.Property<string>("PullRequestRevision")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("TitleAtMerge")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MergedById");
|
||||
|
||||
b.HasIndex("PrimaryRevisionInformationId")
|
||||
.IsUnique()
|
||||
.HasFilter("[PrimaryRevisionInformationId] IS NOT NULL");
|
||||
|
||||
b.ToTable("TestMerges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<decimal>("AdministrationRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<string>("CanonicalName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<DateTimeOffset?>("CreatedAt")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<long?>("CreatedById");
|
||||
|
||||
b.Property<bool?>("Enabled")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<decimal>("InstanceManagerRights")
|
||||
.HasConversion(new ValueConverter<decimal, decimal>(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0)));
|
||||
|
||||
b.Property<DateTimeOffset?>("LastPasswordUpdate");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("PasswordHash");
|
||||
|
||||
b.Property<string>("SystemIdentifier");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CanonicalName")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("CreatedById");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.WatchdogReattachInformation", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<long?>("AlphaId");
|
||||
|
||||
b.Property<bool>("AlphaIsActive");
|
||||
|
||||
b.Property<long?>("BravoId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AlphaId");
|
||||
|
||||
b.HasIndex("BravoId");
|
||||
|
||||
b.ToTable("WatchdogReattachInformations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithMany("ChatSettings")
|
||||
.HasForeignKey("InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
|
||||
.WithMany("Channels")
|
||||
.HasForeignKey("ChatSettingsId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
|
||||
.WithMany()
|
||||
.HasForeignKey("JobId");
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
|
||||
.WithMany("CompileJobs")
|
||||
.HasForeignKey("RevisionInformationId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithOne("DreamDaemonSettings")
|
||||
.HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithOne("DreamMakerSettings")
|
||||
.HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.WatchdogReattachInformation", "WatchdogReattachInformation")
|
||||
.WithMany()
|
||||
.HasForeignKey("WatchdogReattachInformationId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithMany("InstanceUsers")
|
||||
.HasForeignKey("InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.User")
|
||||
.WithMany("InstanceUsers")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("CancelledById");
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithMany("Jobs")
|
||||
.HasForeignKey("InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("StartedById")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
|
||||
.WithMany()
|
||||
.HasForeignKey("CompileJobId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithOne("RepositorySettings")
|
||||
.HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
|
||||
.WithMany("ActiveTestMerges")
|
||||
.HasForeignKey("RevisionInformationId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
|
||||
.WithMany("RevisonInformations")
|
||||
.HasForeignKey("TestMergeId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
|
||||
.WithMany("RevisionInformations")
|
||||
.HasForeignKey("InstanceId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
|
||||
.WithMany("TestMerges")
|
||||
.HasForeignKey("MergedById")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
|
||||
.WithOne("PrimaryTestMerge")
|
||||
.HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
|
||||
.WithMany("CreatedUsers")
|
||||
.HasForeignKey("CreatedById");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.WatchdogReattachInformation", b =>
|
||||
{
|
||||
b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Alpha")
|
||||
.WithMany()
|
||||
.HasForeignKey("AlphaId");
|
||||
|
||||
b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Bravo")
|
||||
.WithMany()
|
||||
.HasForeignKey("BravoId");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Tgstation.Server.Api.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Add the <see cref="Api.Models.Internal.CompileJob.MinimumSecurityLevel"/> and <see cref="DreamMaker.ApiValidationSecurityLevel"/> columns for MSSQL
|
||||
/// </summary>
|
||||
public partial class MSAddMinimumSecurity : Migration
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies the migration
|
||||
/// </summary>
|
||||
/// <param name="migrationBuilder">The <see cref="MigrationBuilder"/> to use</param>
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "ApiValidationSecurityLevel",
|
||||
table: "DreamMakerSettings",
|
||||
nullable: false,
|
||||
defaultValue: (int)DreamDaemonSecurity.Safe);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "MinimumSecurityLevel",
|
||||
table: "CompileJobs",
|
||||
nullable: false,
|
||||
defaultValue: (int)DreamDaemonSecurity.Safe);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unapplies the migration
|
||||
/// </summary>
|
||||
/// <param name="migrationBuilder">The <see cref="MigrationBuilder"/> to use</param>
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ApiValidationSecurityLevel",
|
||||
table: "DreamMakerSettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MinimumSecurityLevel",
|
||||
table: "CompileJobs");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace Tgstation.Server.Host.Models.Migrations
|
||||
{
|
||||
@@ -13,7 +12,7 @@ namespace Tgstation.Server.Host.Models.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.1.2-rtm-30932")
|
||||
.HasAnnotation("ProductVersion", "2.1.3-rtm-32065")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
|
||||
@@ -90,6 +89,8 @@ namespace Tgstation.Server.Host.Models.Migrations
|
||||
|
||||
b.Property<long?>("JobId");
|
||||
|
||||
b.Property<int>("MinimumSecurityLevel");
|
||||
|
||||
b.Property<string>("Output");
|
||||
|
||||
b.Property<long>("RevisionInformationId");
|
||||
@@ -155,6 +156,8 @@ namespace Tgstation.Server.Host.Models.Migrations
|
||||
b.Property<ushort?>("ApiValidationPort")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int>("ApiValidationSecurityLevel");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<string>("ProjectName");
|
||||
|
||||
+5
-1
@@ -14,7 +14,7 @@ namespace Tgstation.Server.Host.Models.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.1.2-rtm-30932")
|
||||
.HasAnnotation("ProductVersion", "2.1.3-rtm-32065")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
@@ -98,6 +98,8 @@ namespace Tgstation.Server.Host.Models.Migrations
|
||||
|
||||
b.Property<long?>("JobId");
|
||||
|
||||
b.Property<int>("MinimumSecurityLevel");
|
||||
|
||||
b.Property<string>("Output");
|
||||
|
||||
b.Property<long>("RevisionInformationId");
|
||||
@@ -161,6 +163,8 @@ namespace Tgstation.Server.Host.Models.Migrations
|
||||
|
||||
b.Property<int>("ApiValidationPort");
|
||||
|
||||
b.Property<int>("ApiValidationSecurityLevel");
|
||||
|
||||
b.Property<long>("InstanceId");
|
||||
|
||||
b.Property<string>("ProjectName");
|
||||
|
||||
Reference in New Issue
Block a user