diff --git a/docs/API.dox b/docs/API.dox
index 5361caf7db..af9deb1ebe 100644
--- a/docs/API.dox
+++ b/docs/API.dox
@@ -212,11 +212,15 @@ Some requests return @ref Tgstation.Server.Api.Models.Job objects. These are lon
To list all jobs in an Instance use the following request
-I GET "/Job" => Array of @ref Tgstation.Server.Api.Models.Job
+I GET "/Job/List" => Array of @ref Tgstation.Server.Api.Models.Job
Note that the response for this request will only have the @ref Tgstation.Server.Api.Models.Job.Id field populated
-To get full details of a job use the following request:
+To get full details of _active_ jobs use the following request:
+
+I GET "/Job" => Array of @ref Tgstation.Server.Api.Models.Job
+
+To get full details of a specific job use the following request:
I GET "/Job/{JobId}" => @ref Tgstation.Server.Api.Models.Job
diff --git a/src/Tgstation.Server.Api/Rights/AdministrationRights.cs b/src/Tgstation.Server.Api/Rights/AdministrationRights.cs
index 6f546020aa..84c93c4cb3 100644
--- a/src/Tgstation.Server.Api/Rights/AdministrationRights.cs
+++ b/src/Tgstation.Server.Api/Rights/AdministrationRights.cs
@@ -13,9 +13,9 @@ namespace Tgstation.Server.Api.Rights
///
None = 0,
///
- /// User can edit themself and other s
+ /// User can edit themself and other s and also create others
///
- EditUsers = 1,
+ WriteUsers = 1,
///
/// User can gracefully restart the host
///
@@ -27,6 +27,10 @@ namespace Tgstation.Server.Api.Rights
///
/// User can change their password
///
- EditPassword = 8,
+ EditOwnPassword = 8,
+ ///
+ /// User can read info and rights of other users
+ ///
+ ReadUsers = 16
}
}
diff --git a/src/Tgstation.Server.Api/Rights/DreamMakerRights.cs b/src/Tgstation.Server.Api/Rights/DreamMakerRights.cs
index 884a42a475..439a13d81c 100644
--- a/src/Tgstation.Server.Api/Rights/DreamMakerRights.cs
+++ b/src/Tgstation.Server.Api/Rights/DreamMakerRights.cs
@@ -35,6 +35,6 @@ namespace Tgstation.Server.Api.Rights
///
/// User may list and read all s
///
- List = 32
+ CompileJobs = 32
}
}
diff --git a/src/Tgstation.Server.Api/Rights/InstanceManagerRights.cs b/src/Tgstation.Server.Api/Rights/InstanceManagerRights.cs
index c424d4ac95..552af89b45 100644
--- a/src/Tgstation.Server.Api/Rights/InstanceManagerRights.cs
+++ b/src/Tgstation.Server.Api/Rights/InstanceManagerRights.cs
@@ -47,10 +47,6 @@ namespace Tgstation.Server.Api.Rights
///
/// User can change
///
- SetAutoUpdate = 256,
- ///
- /// User can cancel move operations
- ///
- CancelMove = 512,
+ SetAutoUpdate = 256
}
}
diff --git a/src/Tgstation.Server.Api/Rights/InstanceUserRights.cs b/src/Tgstation.Server.Api/Rights/InstanceUserRights.cs
index 841e39fa64..b3860cc36d 100644
--- a/src/Tgstation.Server.Api/Rights/InstanceUserRights.cs
+++ b/src/Tgstation.Server.Api/Rights/InstanceUserRights.cs
@@ -17,8 +17,12 @@ namespace Tgstation.Server.Api.Rights
///
ReadUsers = 1,
///
- /// Allow write access to for the
+ /// Allow write and delete access to for the
///
- WriteUsers = 2
+ WriteUsers = 2,
+ ///
+ /// Allow adding additional to the
+ ///
+ CreateUsers = 4
}
}
diff --git a/src/Tgstation.Server.Api/Rights/RepositoryRights.cs b/src/Tgstation.Server.Api/Rights/RepositoryRights.cs
index 83968e7adb..2729f72ae0 100644
--- a/src/Tgstation.Server.Api/Rights/RepositoryRights.cs
+++ b/src/Tgstation.Server.Api/Rights/RepositoryRights.cs
@@ -13,6 +13,10 @@ namespace Tgstation.Server.Api.Rights
///
None = 0,
///
+ /// User may cancel synchronize operations
+ ///
+ CancelPendingChanges = 1,
+ ///
/// User may create the if it does not exist
///
SetOrigin = 2,
@@ -59,10 +63,6 @@ namespace Tgstation.Server.Api.Rights
///
/// User may cancel clone operations
///
- CancelClone = 4096,
- ///
- /// User may cancel synchronize operations
- ///
- CancelPendingChanges = 8192
+ CancelClone = 4096
}
}
diff --git a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
index cd29816873..235cd27951 100644
--- a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
+++ b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
@@ -17,7 +17,7 @@
4.0.0.0
json web api tgstation-server tgstation ss13 byond
Prototype release
- 4.0.0.0-preview3
+ 4.0.0.0-preview4
@@ -35,7 +35,10 @@
-
+
+ all
+ compile; build; native; contentfiles; analyzers
+
diff --git a/src/Tgstation.Server.Client/AdministrationClient.cs b/src/Tgstation.Server.Client/AdministrationClient.cs
index 617a925e4e..1e7b290168 100644
--- a/src/Tgstation.Server.Client/AdministrationClient.cs
+++ b/src/Tgstation.Server.Client/AdministrationClient.cs
@@ -1,4 +1,5 @@
-using System.Threading;
+using System;
+using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api;
using Tgstation.Server.Api.Models;
@@ -26,7 +27,7 @@ namespace Tgstation.Server.Client
public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.Administration, cancellationToken);
///
- public Task Update(Administration administration, CancellationToken cancellationToken) => apiClient.Update(Routes.Administration, administration, cancellationToken);
+ public Task Update(Administration administration, CancellationToken cancellationToken) => apiClient.Update(Routes.Administration, administration ?? throw new ArgumentNullException(nameof(administration)), cancellationToken);
///
public Task Restart(CancellationToken cancellationToken) => apiClient.Delete(Routes.Administration, cancellationToken);
diff --git a/src/Tgstation.Server.Client/Components/ByondClient.cs b/src/Tgstation.Server.Client/Components/ByondClient.cs
index ec311873c7..e75c47110c 100644
--- a/src/Tgstation.Server.Client/Components/ByondClient.cs
+++ b/src/Tgstation.Server.Client/Components/ByondClient.cs
@@ -33,6 +33,6 @@ namespace Tgstation.Server.Client.Components
public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.Byond, instance.Id, cancellationToken);
///
- public Task Update(Byond byond, CancellationToken cancellationToken) => apiClient.Update(Routes.Byond, byond, instance.Id, cancellationToken);
+ public Task Update(Byond byond, CancellationToken cancellationToken) => apiClient.Update(Routes.Byond, byond ?? throw new ArgumentNullException(nameof(byond)), instance.Id, cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/Components/ChatBotsClient.cs b/src/Tgstation.Server.Client/Components/ChatBotsClient.cs
index b9fc623102..73cdd02680 100644
--- a/src/Tgstation.Server.Client/Components/ChatBotsClient.cs
+++ b/src/Tgstation.Server.Client/Components/ChatBotsClient.cs
@@ -31,15 +31,15 @@ namespace Tgstation.Server.Client.Components
}
///
- public Task Create(ChatBot settings, CancellationToken cancellationToken) => apiClient.Create(Routes.Chat, settings, instance.Id, cancellationToken);
+ public Task Create(ChatBot settings, CancellationToken cancellationToken) => apiClient.Create(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id, cancellationToken);
///
- public Task Delete(ChatBot settings, CancellationToken cancellationToken) => apiClient.Delete(Routes.SetID(Routes.Chat, settings.Id), instance.Id, cancellationToken);
+ public Task Delete(ChatBot settings, CancellationToken cancellationToken) => apiClient.Delete(Routes.SetID(Routes.Chat, settings?.Id ?? throw new ArgumentNullException(nameof(settings))), instance.Id, cancellationToken);
///
public Task> List(CancellationToken cancellationToken) => apiClient.Create>(Routes.List(Routes.Chat), instance.Id, cancellationToken);
///
- public Task Update(ChatBot settings, CancellationToken cancellationToken) => apiClient.Update(Routes.Chat, settings, instance.Id, cancellationToken);
+ public Task Update(ChatBot settings, CancellationToken cancellationToken) => apiClient.Update(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id, cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/Components/ConfigurationClient.cs b/src/Tgstation.Server.Client/Components/ConfigurationClient.cs
index 6eac9582bc..4f35d86321 100644
--- a/src/Tgstation.Server.Client/Components/ConfigurationClient.cs
+++ b/src/Tgstation.Server.Client/Components/ConfigurationClient.cs
@@ -47,6 +47,6 @@ namespace Tgstation.Server.Client.Components
}
///
- public Task Write(ConfigurationFile file, CancellationToken cancellationToken) => apiClient.Update(Routes.Configuration, file, instance.Id, cancellationToken);
+ public Task Write(ConfigurationFile file, CancellationToken cancellationToken) => apiClient.Update(Routes.Configuration, file ?? throw new ArgumentNullException(nameof(file)), instance.Id, cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/Components/DreamDaemonClient.cs b/src/Tgstation.Server.Client/Components/DreamDaemonClient.cs
index d776c09f69..e0815a873b 100644
--- a/src/Tgstation.Server.Client/Components/DreamDaemonClient.cs
+++ b/src/Tgstation.Server.Client/Components/DreamDaemonClient.cs
@@ -39,6 +39,6 @@ namespace Tgstation.Server.Client.Components
public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.DreamDaemon, instance.Id, cancellationToken);
///
- public Task Update(DreamDaemon dreamDaemon, CancellationToken cancellationToken) => apiClient.Update(Routes.DreamDaemon, dreamDaemon, instance.Id, cancellationToken);
+ public Task Update(DreamDaemon dreamDaemon, CancellationToken cancellationToken) => apiClient.Update(Routes.DreamDaemon, dreamDaemon ?? throw new ArgumentNullException(nameof(dreamDaemon)), instance.Id, cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/Components/DreamMakerClient.cs b/src/Tgstation.Server.Client/Components/DreamMakerClient.cs
index ae331617e2..5e8d2af1b9 100644
--- a/src/Tgstation.Server.Client/Components/DreamMakerClient.cs
+++ b/src/Tgstation.Server.Client/Components/DreamMakerClient.cs
@@ -36,6 +36,6 @@ namespace Tgstation.Server.Client.Components
public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.DreamMaker, instance.Id, cancellationToken);
///
- public Task Update(DreamMaker dreamMaker, CancellationToken cancellationToken) => apiClient.Update(Routes.DreamMaker, dreamMaker, instance.Id, cancellationToken);
+ public Task Update(DreamMaker dreamMaker, CancellationToken cancellationToken) => apiClient.Update(Routes.DreamMaker, dreamMaker ?? throw new ArgumentNullException(nameof(dreamMaker)), instance.Id, cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/Components/IInstanceUserClient.cs b/src/Tgstation.Server.Client/Components/IInstanceUserClient.cs
index 5d73e4f2ee..3d1d54e8d7 100644
--- a/src/Tgstation.Server.Client/Components/IInstanceUserClient.cs
+++ b/src/Tgstation.Server.Client/Components/IInstanceUserClient.cs
@@ -17,6 +17,14 @@ namespace Tgstation.Server.Client.Components
/// A resulting in the associated with the logged on user
Task Read(CancellationToken cancellationToken);
+ ///
+ /// Get a specific
+ ///
+ /// The to get
+ /// The for the operation
+ /// A resulting in the requested
+ Task GetId(InstanceUser instanceUser, CancellationToken cancellationToken);
+
///
/// Get the s in the
///
diff --git a/src/Tgstation.Server.Client/Components/IJobsClient.cs b/src/Tgstation.Server.Client/Components/IJobsClient.cs
index 0b659841e9..c59dc7a8ba 100644
--- a/src/Tgstation.Server.Client/Components/IJobsClient.cs
+++ b/src/Tgstation.Server.Client/Components/IJobsClient.cs
@@ -18,13 +18,20 @@ namespace Tgstation.Server.Client.Components
/// A resulting in a of the s in the
Task> List(CancellationToken cancellationToken);
+ ///
+ /// List the active s in the
+ ///
+ /// The for the operation
+ /// A resulting in a of the active s in the
+ Task> ListActive(CancellationToken cancellationToken);
+
///
/// Get a
///
/// The to get
/// The for the operation
/// A resulting in the
- Task Read(Job job, CancellationToken cancellationToken);
+ Task GetId(Job job, CancellationToken cancellationToken);
///
/// Cancels a
@@ -40,7 +47,7 @@ namespace Tgstation.Server.Client.Components
/// The to create a for
/// The rate in to poll the server for results
/// A to run with 0-100 progress
- /// The which will trigger the cancellation of the
+ /// The for the operation. This does not cancel the
/// A resulting in a complete
Task CreateTaskFromJob(Job job, TimeSpan requeryRate, Action progressCallback, CancellationToken cancellationToken);
}
diff --git a/src/Tgstation.Server.Client/Components/InstanceUserClient.cs b/src/Tgstation.Server.Client/Components/InstanceUserClient.cs
index a45453a1fd..c3ceeca108 100644
--- a/src/Tgstation.Server.Client/Components/InstanceUserClient.cs
+++ b/src/Tgstation.Server.Client/Components/InstanceUserClient.cs
@@ -31,7 +31,7 @@ namespace Tgstation.Server.Client.Components
}
///
- public Task Create(InstanceUser user, CancellationToken cancellationToken) => apiClient.Create(Routes.InstanceUser, user, instance.Id, cancellationToken);
+ public Task Create(InstanceUser instanceUser, CancellationToken cancellationToken) => apiClient.Create(Routes.InstanceUser, instanceUser ?? throw new ArgumentNullException(nameof(instanceUser)), instance.Id, cancellationToken);
public Task Delete(InstanceUser instanceUser, CancellationToken cancellationToken) => apiClient.Delete(Routes.SetID(Routes.InstanceUser, instanceUser.UserId.Value), instance.Id, cancellationToken);
@@ -39,9 +39,12 @@ namespace Tgstation.Server.Client.Components
public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.InstanceUser, instance.Id, cancellationToken);
///
- public Task Update(InstanceUser user, CancellationToken cancellationToken) => apiClient.Update(Routes.InstanceUser, user, instance.Id, cancellationToken);
+ public Task Update(InstanceUser instanceUser, CancellationToken cancellationToken) => apiClient.Update(Routes.InstanceUser, instanceUser ?? throw new ArgumentNullException(nameof(instanceUser)), instance.Id, cancellationToken);
///
public Task> List(CancellationToken cancellationToken) => apiClient.Read>(Routes.List(Routes.InstanceUser), instance.Id, cancellationToken);
+
+ ///
+ public Task GetId(InstanceUser instanceUser, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.InstanceUser, instanceUser?.UserId ?? throw new ArgumentNullException(nameof(instanceUser))), instance.Id, cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/Components/JobsClient.cs b/src/Tgstation.Server.Client/Components/JobsClient.cs
index c4f08dca91..7f9bf1cfa5 100644
--- a/src/Tgstation.Server.Client/Components/JobsClient.cs
+++ b/src/Tgstation.Server.Client/Components/JobsClient.cs
@@ -31,25 +31,30 @@ namespace Tgstation.Server.Client.Components
}
///
- public Task Cancel(Job job, CancellationToken cancellationToken) => apiClient.Delete(Routes.SetID(Routes.Jobs, job.Id), instance.Id, cancellationToken);
+ public Task Cancel(Job job, CancellationToken cancellationToken) => apiClient.Delete(Routes.SetID(Routes.Jobs, job?.Id ?? throw new ArgumentNullException(nameof(job))), instance.Id, cancellationToken);
///
public Task> List(CancellationToken cancellationToken) => apiClient.Read>(Routes.List(Routes.Jobs), instance.Id, cancellationToken);
///
- public Task Read(Job job, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.Jobs, job.Id), instance.Id, cancellationToken);
+ public Task> ListActive(CancellationToken cancellationToken) => apiClient.Read>(Routes.Jobs, instance.Id, cancellationToken);
+
+ ///
+ public Task GetId(Job job, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.Jobs, job?.Id ?? throw new ArgumentNullException(nameof(job))), instance.Id, cancellationToken);
///
public async Task CreateTaskFromJob(Job job, TimeSpan requeryRate, Action progressCallback, CancellationToken cancellationToken)
{
if (job == null)
throw new ArgumentNullException(nameof(job));
+ if (progressCallback == null)
+ throw new ArgumentNullException(nameof(progressCallback));
int? lastProgress = null;
while (!job.StoppedAt.HasValue)
{
await Task.Delay(requeryRate, cancellationToken).ConfigureAwait(false);
- job = await Read(job, cancellationToken).ConfigureAwait(false);
+ job = await GetId(job, cancellationToken).ConfigureAwait(false);
if (job.Progress.HasValue && job.Progress != lastProgress)
{
progressCallback(job.Progress.Value);
diff --git a/src/Tgstation.Server.Client/Components/RepositoryClient.cs b/src/Tgstation.Server.Client/Components/RepositoryClient.cs
index 7b52a0cc1c..9232a323c9 100644
--- a/src/Tgstation.Server.Client/Components/RepositoryClient.cs
+++ b/src/Tgstation.Server.Client/Components/RepositoryClient.cs
@@ -1,4 +1,5 @@
-using System.Threading;
+using System;
+using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api;
using Tgstation.Server.Api.Models;
@@ -35,6 +36,6 @@ namespace Tgstation.Server.Client.Components
public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.Repository, instance.Id, cancellationToken);
///
- public Task Update(Repository repository, CancellationToken cancellationToken) => apiClient.Update(Routes.Repository, repository, instance.Id, cancellationToken);
+ public Task Update(Repository repository, CancellationToken cancellationToken) => apiClient.Update(Routes.Repository, repository ?? throw new ArgumentNullException(nameof(repository)), instance.Id, cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Client/InstanceManagerClient.cs b/src/Tgstation.Server.Client/InstanceManagerClient.cs
index 63b78d47af..f8343c5c91 100644
--- a/src/Tgstation.Server.Client/InstanceManagerClient.cs
+++ b/src/Tgstation.Server.Client/InstanceManagerClient.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api;
@@ -26,30 +27,30 @@ namespace Tgstation.Server.Client
///
public InstanceManagerClient(IApiClient apiClient)
{
- this.apiClient = apiClient;
+ this.apiClient = apiClient ?? throw new ArgumentNullException(nameof(apiClient));
cachedClients = new Dictionary();
}
///
- public Task Create(Instance instance, CancellationToken cancellationToken) => apiClient.Create(Routes.InstanceManager, instance, cancellationToken);
+ public Task Create(Instance instance, CancellationToken cancellationToken) => apiClient.Create(Routes.InstanceManager, instance ?? throw new ArgumentNullException(nameof(instance)), cancellationToken);
///
- public Task Delete(Instance instance, CancellationToken cancellationToken) => apiClient.Delete(Routes.SetID(Routes.InstanceManager, instance.Id), cancellationToken);
+ public Task Delete(Instance instance, CancellationToken cancellationToken) => apiClient.Delete(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken);
///
public Task> List(CancellationToken cancellationToken) => apiClient.Read>(Routes.List(Routes.InstanceManager), cancellationToken);
///
- public Task Update(Instance instance, CancellationToken cancellationToken) => apiClient.Update(Routes.InstanceManager, instance, cancellationToken);
+ public Task Update(Instance instance, CancellationToken cancellationToken) => apiClient.Update(Routes.InstanceManager, instance ?? throw new ArgumentNullException(nameof(instance)), cancellationToken);
///
- public Task GetId(Instance instance, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.InstanceManager, instance.Id), cancellationToken);
+ public Task GetId(Instance instance, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken);
///
public IInstanceClient CreateClient(Instance instance)
{
- if (!cachedClients.TryGetValue(instance.Id, out var client))
+ if (!cachedClients.TryGetValue(instance?.Id ?? throw new ArgumentNullException(nameof(instance)), out var client))
{
client = new InstanceClient(apiClient, instance);
cachedClients.Add(instance.Id, client);
diff --git a/src/Tgstation.Server.Client/ServerClientFactory.cs b/src/Tgstation.Server.Client/ServerClientFactory.cs
index 9e7286d1a7..b0a7d3b547 100644
--- a/src/Tgstation.Server.Client/ServerClientFactory.cs
+++ b/src/Tgstation.Server.Client/ServerClientFactory.cs
@@ -38,8 +38,6 @@ namespace Tgstation.Server.Client
throw new ArgumentNullException(nameof(username));
if (password == null)
throw new ArgumentNullException(nameof(password));
- if (timeout == null)
- throw new ArgumentNullException(nameof(timeout));
Token token;
using (var api = apiClientFactory.CreateApiClient(host, new ApiHeaders(productHeaderValue, username, password)))
diff --git a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
index 40ffb4c446..3ac3042fca 100644
--- a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
+++ b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
@@ -3,7 +3,7 @@
netstandard2.0
Full
- 4.0.0.0-preview8
+ 4.0.0.0-preview9
true
Cyberboss
/tg/station 13
@@ -31,6 +31,10 @@
+
+ all
+ compile; build; native; contentfiles; analyzers
+
diff --git a/src/Tgstation.Server.Client/UsersClient.cs b/src/Tgstation.Server.Client/UsersClient.cs
index 3578731509..1e6c5fd45e 100644
--- a/src/Tgstation.Server.Client/UsersClient.cs
+++ b/src/Tgstation.Server.Client/UsersClient.cs
@@ -25,10 +25,10 @@ namespace Tgstation.Server.Client
}
///
- public Task Create(UserUpdate user, CancellationToken cancellationToken) => apiClient.Create(Routes.User, user, cancellationToken);
+ public Task Create(UserUpdate user, CancellationToken cancellationToken) => apiClient.Create(Routes.User, user ?? throw new ArgumentNullException(nameof(user)), cancellationToken);
///
- public Task GetId(User user, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.User, user.Id), cancellationToken);
+ public Task GetId(User user, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.User, user?.Id ?? throw new ArgumentNullException(nameof(user))), cancellationToken);
///
public Task> List(CancellationToken cancellationToken) => apiClient.Read>(Routes.List(Routes.User), cancellationToken);
@@ -37,6 +37,6 @@ namespace Tgstation.Server.Client
public Task Read(CancellationToken cancellationToken) => apiClient.Read(Routes.User, cancellationToken);
///
- public Task Update(UserUpdate user, CancellationToken cancellationToken) => apiClient.Update(Routes.User, user, cancellationToken);
+ public Task Update(UserUpdate user, CancellationToken cancellationToken) => apiClient.Update(Routes.User, user ?? throw new ArgumentNullException(nameof(user)), cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj b/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
index cb7add9153..dbaae93de8 100644
--- a/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
+++ b/src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj
@@ -4,6 +4,7 @@
Exe
netcoreapp2.0
Full
+ 4.0.0.0
@@ -18,6 +19,10 @@
+
+ all
+ compile; build; native; contentfiles; analyzers
+
diff --git a/src/Tgstation.Server.Host.Service/Properties/AssemblyInfo.cs b/src/Tgstation.Server.Host.Service/Properties/AssemblyInfo.cs
index 295c7cb2a0..32e1197c31 100644
--- a/src/Tgstation.Server.Host.Service/Properties/AssemblyInfo.cs
+++ b/src/Tgstation.Server.Host.Service/Properties/AssemblyInfo.cs
@@ -9,4 +9,3 @@ using System.Runtime.InteropServices;
[assembly: AssemblyVersion("4.0.0.0")]
[assembly: AssemblyFileVersion("4.0.0.0")]
-[assembly: AssemblyInformationalVersion("4.0.0.0")]
diff --git a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
index 77dd44b935..b1d14c9e0b 100644
--- a/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
+++ b/src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
@@ -94,6 +94,10 @@
2.2.5
+
+ all
+ compile; build; native; contentfiles; analyzers
+
2.1.1
diff --git a/src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj b/src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj
index f6c9dce932..607abe220f 100644
--- a/src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj
+++ b/src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj
@@ -4,6 +4,8 @@
netstandard2.0
Full
false
+ 4.0.0.0
+ 4.0.0.0
@@ -18,7 +20,10 @@
-
+
+ all
+ compile; build; native; contentfiles; analyzers
+
diff --git a/src/Tgstation.Server.Host/Components/ReattachInfoHandler.cs b/src/Tgstation.Server.Host/Components/ReattachInfoHandler.cs
index de9f8c19ce..0aba902d06 100644
--- a/src/Tgstation.Server.Host/Components/ReattachInfoHandler.cs
+++ b/src/Tgstation.Server.Host/Components/ReattachInfoHandler.cs
@@ -79,8 +79,12 @@ namespace Tgstation.Server.Host.Components
{
Models.WatchdogReattachInformation result = null;
await databaseContextFactory.UseContext(async (db) =>
- result = await db.Instances.Where(x => x.Id == metadata.Id).Select(x => x.WatchdogReattachInformation).FirstAsync(cancellationToken).ConfigureAwait(false)
+ result = await db.Instances.Where(x => x.Id == metadata.Id).Select(x => x.WatchdogReattachInformation).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false)
).ConfigureAwait(false);
+
+ if (result == default)
+ throw new JobException("Unable to load reattach information!");
+
var bravoDmbTask = dmbFactory.FromCompileJob(result.Bravo.CompileJob, cancellationToken);
return new WatchdogReattachInformation(result, await dmbFactory.FromCompileJob(result.Alpha.CompileJob, cancellationToken).ConfigureAwait(false), await bravoDmbTask.ConfigureAwait(false));
}
diff --git a/src/Tgstation.Server.Host/Controllers/ChatController.cs b/src/Tgstation.Server.Host/Controllers/ChatController.cs
index 40c1aa5ec2..7a2d765a54 100644
--- a/src/Tgstation.Server.Host/Controllers/ChatController.cs
+++ b/src/Tgstation.Server.Host/Controllers/ChatController.cs
@@ -163,7 +163,7 @@ namespace Tgstation.Server.Host.Controllers
var results = await query.FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
if (results == default)
- return NotFound();
+ return StatusCode((int)HttpStatusCode.Gone);
var connectionStrings = (AuthenticationContext.GetRight(RightsType.ChatBots) & (ulong)ChatBotRights.ReadConnectionString) != 0;
diff --git a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs
index 7f7a8281c6..59dfd9016b 100644
--- a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs
+++ b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs
@@ -96,7 +96,12 @@ namespace Tgstation.Server.Host.Controllers
var revision = (AuthenticationContext.GetRight(RightsType.DreamDaemon) & (ulong)DreamDaemonRights.ReadRevision) != 0;
if (settings == null)
- settings = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstAsync(cancellationToken).ConfigureAwait(false);
+ {
+ settings = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
+ if (settings == default)
+ return StatusCode((int)HttpStatusCode.Gone);
+ }
+
var result = new DreamDaemon();
if (metadata)
{
@@ -145,7 +150,10 @@ namespace Tgstation.Server.Host.Controllers
throw new ArgumentNullException(nameof(model));
//alias for changing DD settings
- var current = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstAsync(cancellationToken).ConfigureAwait(false);
+ var current = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
+
+ if (current == default)
+ return StatusCode((int)HttpStatusCode.Gone);
var userRights = (DreamDaemonRights)AuthenticationContext.GetRight(RightsType.DreamDaemon);
diff --git a/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs b/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs
index c77d3a458d..9341fd8dd3 100644
--- a/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs
+++ b/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs
@@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
+using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api;
@@ -58,7 +59,7 @@ namespace Tgstation.Server.Host.Controllers
}
///
- [TgsAuthorize(DreamMakerRights.List)]
+ [TgsAuthorize(DreamMakerRights.CompileJobs)]
public override async Task GetId(long id, CancellationToken cancellationToken)
{
var compileJob = await DatabaseContext.CompileJobs
@@ -73,11 +74,14 @@ namespace Tgstation.Server.Host.Controllers
}
///
- [TgsAuthorize(DreamMakerRights.List)]
+ [TgsAuthorize(DreamMakerRights.CompileJobs)]
public override async Task List(CancellationToken cancellationToken)
{
- var compileJobs = await DatabaseContext.CompileJobs.Where(x => x.Job.Instance.Id == Instance.Id).ToListAsync(cancellationToken).ConfigureAwait(false);
- return Json(compileJobs.Select(x => x.ToApi()));
+ var compileJobs = await DatabaseContext.CompileJobs.Where(x => x.Job.Instance.Id == Instance.Id).OrderByDescending(x => x.Job.StartedAt).Select(x => new Api.Models.CompileJob
+ {
+ Id = x.Id
+ }).ToListAsync(cancellationToken).ConfigureAwait(false);
+ return Json(compileJobs);
}
///
@@ -100,12 +104,9 @@ namespace Tgstation.Server.Host.Controllers
[TgsAuthorize(DreamMakerRights.SetDme | DreamMakerRights.SetApiValidationPort)]
public override async Task Update([FromBody] Api.Models.DreamMaker model, CancellationToken cancellationToken)
{
- var hostModel = new DreamMakerSettings
- {
- InstanceId = Instance.Id
- };
-
- DatabaseContext.DreamMakerSettings.Attach(hostModel);
+ var hostModel = await DatabaseContext.DreamMakerSettings.Where(x => x.InstanceId == Instance.Id).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
+ if (hostModel == null)
+ return StatusCode((int)HttpStatusCode.Gone);
if (model.ProjectName != null)
{
@@ -145,9 +146,15 @@ namespace Tgstation.Server.Host.Controllers
{
StartupTimeout = x.StartupTimeout,
SecurityLevel = x.SecurityLevel
- }).FirstAsync(cancellationToken);
+ }).FirstOrDefaultAsync(cancellationToken);
+
+
var dreamMakerSettings = await databaseContext.DreamMakerSettings.Where(x => x.InstanceId == instanceModel.Id).FirstAsync(cancellationToken).ConfigureAwait(false);
+ if (dreamMakerSettings == default)
+ throw new JobException("Missing DreamMakerSettings in DB!");
var ddSettings = await ddSettingsTask.ConfigureAwait(false);
+ if (ddSettings == default)
+ throw new JobException("Missing DreamDaemonSettings in DB!");
var instance = instanceManager.GetInstance(instanceModel);
@@ -156,10 +163,8 @@ namespace Tgstation.Server.Host.Controllers
using (var repo = await instance.RepositoryManager.LoadRepository(cancellationToken).ConfigureAwait(false))
{
if (repo == null)
- {
- job.ExceptionDetails = "Missing repository!";
- return;
- }
+ throw new JobException("Missing Repository!");
+
var repoSha = repo.Head;
revInfo = await databaseContext.RevisionInformations.Where(x => x.CommitSha == repoSha).Include(x => x.ActiveTestMerges).ThenInclude(x => x.TestMerge).FirstOrDefaultAsync().ConfigureAwait(false);
diff --git a/src/Tgstation.Server.Host/Controllers/InstanceController.cs b/src/Tgstation.Server.Host/Controllers/InstanceController.cs
index 30f111dede..eae5142ff3 100644
--- a/src/Tgstation.Server.Host/Controllers/InstanceController.cs
+++ b/src/Tgstation.Server.Host/Controllers/InstanceController.cs
@@ -199,8 +199,8 @@ namespace Tgstation.Server.Host.Controllers
.Include(x => x.WatchdogReattachInformation)
.Include(x => x.WatchdogReattachInformation.Alpha)
.Include(x => x.WatchdogReattachInformation.Bravo)
- .FirstAsync(cancellationToken).ConfigureAwait(false);
- if (originalModel == default(Models.Instance))
+ .FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
+ if (originalModel == default)
return StatusCode((int)HttpStatusCode.Gone);
if (originalModel.WatchdogReattachInformation != null)
@@ -324,7 +324,7 @@ namespace Tgstation.Server.Host.Controllers
Description = String.Format(CultureInfo.InvariantCulture, "Move instance ID {0} from {1} to {2}", Instance.Id, Instance.Path, rawPath),
Instance = Instance,
CancelRightsType = RightsType.InstanceManager,
- CancelRight = (ulong)InstanceManagerRights.CancelMove,
+ CancelRight = (ulong)InstanceManagerRights.Relocate,
StartedBy = AuthenticationContext.User
};
diff --git a/src/Tgstation.Server.Host/Controllers/InstanceUserController.cs b/src/Tgstation.Server.Host/Controllers/InstanceUserController.cs
index 26412f7509..aa9a8c8bf7 100644
--- a/src/Tgstation.Server.Host/Controllers/InstanceUserController.cs
+++ b/src/Tgstation.Server.Host/Controllers/InstanceUserController.cs
@@ -47,7 +47,7 @@ namespace Tgstation.Server.Host.Controllers
}
///
- [TgsAuthorize(InstanceUserRights.WriteUsers)]
+ [TgsAuthorize(InstanceUserRights.CreateUsers)]
public override async Task Create([FromBody] Api.Models.InstanceUser model, CancellationToken cancellationToken)
{
var test = StandardModelChecks(model);
@@ -114,7 +114,7 @@ namespace Tgstation.Server.Host.Controllers
//this functions as userId
var user = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).SelectMany(x => x.InstanceUsers).Where(x => x.UserId == id).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
if (user == default)
- return NotFound();
+ return StatusCode((int)HttpStatusCode.Gone);
return Json(user.ToApi());
}
diff --git a/src/Tgstation.Server.Host/Controllers/JobController.cs b/src/Tgstation.Server.Host/Controllers/JobController.cs
index b48033ef4e..07c54687cc 100644
--- a/src/Tgstation.Server.Host/Controllers/JobController.cs
+++ b/src/Tgstation.Server.Host/Controllers/JobController.cs
@@ -40,10 +40,8 @@ namespace Tgstation.Server.Host.Controllers
[TgsAuthorize]
public override async Task Read(CancellationToken cancellationToken)
{
- var result = await DatabaseContext.Jobs.Where(x => x.Instance.Id == Instance.Id).OrderByDescending(x => x.StartedAt).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
- if (result == null)
- return StatusCode((int)HttpStatusCode.Gone);
- return Json(result);
+ var result = await DatabaseContext.Jobs.Where(x => x.Instance.Id == Instance.Id && !x.StoppedAt.HasValue).OrderByDescending(x => x.StartedAt).ToListAsync(cancellationToken).ConfigureAwait(false);
+ return Json(result.Select(x => x.ToApi()));
}
///
diff --git a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs
index 3cdf397055..735bc19e6d 100644
--- a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs
+++ b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs
@@ -224,8 +224,11 @@ namespace Tgstation.Server.Host.Controllers
using (var repo = await instanceManager.GetInstance(Instance).RepositoryManager.LoadRepository(cancellationToken).ConfigureAwait(false))
{
if (repo != null && await PopulateApi(api, repo, DatabaseContext, Instance, null, null, cancellationToken).ConfigureAwait(false))
+ {
//user may have fucked with the repo without telling us, do what we can
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
+ return StatusCode((int)HttpStatusCode.Created, api);
+ }
return Json(api);
}
}
diff --git a/src/Tgstation.Server.Host/Controllers/UserController.cs b/src/Tgstation.Server.Host/Controllers/UserController.cs
index 7a389b3b1d..241b08a02f 100644
--- a/src/Tgstation.Server.Host/Controllers/UserController.cs
+++ b/src/Tgstation.Server.Host/Controllers/UserController.cs
@@ -62,7 +62,7 @@ namespace Tgstation.Server.Host.Controllers
}
///
- [TgsAuthorize(AdministrationRights.EditUsers)]
+ [TgsAuthorize(AdministrationRights.WriteUsers)]
public override async Task Create([FromBody] UserUpdate model, CancellationToken cancellationToken)
{
if (model == null)
@@ -122,17 +122,17 @@ namespace Tgstation.Server.Host.Controllers
}
///
- [TgsAuthorize(AdministrationRights.EditUsers | AdministrationRights.EditPassword)]
+ [TgsAuthorize(AdministrationRights.WriteUsers | AdministrationRights.EditOwnPassword)]
public override async Task Update([FromBody] UserUpdate model, CancellationToken cancellationToken)
{
if (model == null)
throw new ArgumentNullException(nameof(model));
- var passwordEditOnly = !AuthenticationContext.User.AdministrationRights.Value.HasFlag(AdministrationRights.EditUsers);
+ var passwordEditOnly = !AuthenticationContext.User.AdministrationRights.Value.HasFlag(AdministrationRights.WriteUsers);
var originalUser = passwordEditOnly ? AuthenticationContext.User : await DatabaseContext.Users.Where(x => x.Id == model.Id).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
if (originalUser == default)
- return StatusCode((int)HttpStatusCode.Gone);
+ return NotFound();
if (passwordEditOnly && (model.Id != originalUser.Id || model.InstanceManagerRights.HasValue || model.AdministrationRights.HasValue || model.Enabled.HasValue || model.SystemIdentifier != null || model.Name != null))
return Forbid();
@@ -164,7 +164,7 @@ namespace Tgstation.Server.Host.Controllers
public override Task Read(CancellationToken cancellationToken) => Task.FromResult(Json(AuthenticationContext.User.ToApi(true)));
///
- [TgsAuthorize(AdministrationRights.EditUsers)]
+ [TgsAuthorize(AdministrationRights.ReadUsers)]
public override async Task List(CancellationToken cancellationToken)
{
var users = await DatabaseContext.Users.ToListAsync(cancellationToken).ConfigureAwait(false);
@@ -178,7 +178,7 @@ namespace Tgstation.Server.Host.Controllers
if (id == AuthenticationContext.User.Id)
return await Read(cancellationToken).ConfigureAwait(false);
- if (!((AdministrationRights)AuthenticationContext.GetRight(RightsType.Administration)).HasFlag(AdministrationRights.EditUsers))
+ if (!((AdministrationRights)AuthenticationContext.GetRight(RightsType.Administration)).HasFlag(AdministrationRights.ReadUsers))
return Forbid();
var user = await DatabaseContext.Users.Where(x => x.Id == id).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
index fa8a4573ea..68e70510d1 100644
--- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
+++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
@@ -4,6 +4,8 @@
netcoreapp2.0
Full
4.0.0.0
+ 4.0.0.0
+ 1.0.0
@@ -29,6 +31,10 @@
+
+ all
+ compile; build; native; contentfiles; analyzers
+
diff --git a/tests/Tgstation.Server.Host.Tests/Security/TestAuthenticationContext.cs b/tests/Tgstation.Server.Host.Tests/Security/TestAuthenticationContext.cs
index 0c2291bfe1..0208a1bdc1 100644
--- a/tests/Tgstation.Server.Host.Tests/Security/TestAuthenticationContext.cs
+++ b/tests/Tgstation.Server.Host.Tests/Security/TestAuthenticationContext.cs
@@ -42,7 +42,7 @@ namespace Tgstation.Server.Host.Security.Tests
var instanceUser = new InstanceUser();
var authContext = new AuthenticationContext(null, user, instanceUser);
- user.AdministrationRights = AdministrationRights.EditUsers;
+ user.AdministrationRights = AdministrationRights.WriteUsers;
instanceUser.ByondRights = ByondRights.ChangeVersion | ByondRights.ReadActive;
Assert.AreEqual((ulong)user.AdministrationRights, authContext.GetRight(RightsType.Administration));
Assert.AreEqual((ulong)instanceUser.ByondRights, authContext.GetRight(RightsType.Byond));
diff --git a/v4_prototype_TODO.txt b/v4_prototype_TODO.txt
index 9e7ad3777f..4efbf08945 100644
--- a/v4_prototype_TODO.txt
+++ b/v4_prototype_TODO.txt
@@ -1,3 +1,12 @@
Verify the byond cache folder location on linux
Test watchdog
-Test chat channel tagging
+
+UNIT test watchdog
+
+Test chat channel tagging and full stack
+
+Test reattachment
+
+Test auto update
+
+Test auto start