mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-26 22:48:20 +01:00
Add a dedicated action and permission for granting instance user permissions on an instance
This commit is contained in:
@@ -61,6 +61,11 @@ namespace Tgstation.Server.Api.Rights
|
||||
/// <summary>
|
||||
/// User can change <see cref="Models.Instance.ChatBotLimit"/>.
|
||||
/// </summary>
|
||||
SetChatBotLimit = 512
|
||||
SetChatBotLimit = 512,
|
||||
|
||||
/// <summary>
|
||||
/// User can give themselves full <see cref="Models.InstanceUser"/> rights on instances.
|
||||
/// </summary>
|
||||
GrantPermissions = 1024,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,6 +235,9 @@ namespace Tgstation.Server.Client
|
||||
/// <inheritdoc />
|
||||
public Task<TResult> Update<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken) => RunRequest<TResult>(route, body, HttpMethod.Post, null, false, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task Patch(string route, CancellationToken cancellationToken) => RunRequest<object>(route, null, HttpMethod.Patch, null, false, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task Update<TBody>(string route, TBody body, CancellationToken cancellationToken) => RunRequest<object>(route, body, HttpMethod.Post, null, false, cancellationToken);
|
||||
|
||||
|
||||
@@ -90,6 +90,14 @@ namespace Tgstation.Server.Client
|
||||
/// <returns>A <see cref="Task"/> representing the running operation</returns>
|
||||
Task Update<TBody>(string route, TBody body, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Run an HTTP PATCH request.
|
||||
/// </summary>
|
||||
/// <param name="route">The server route to make the request to.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task Patch(string route, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Run an HTTP DELETE request
|
||||
/// </summary>
|
||||
|
||||
@@ -50,6 +50,14 @@ namespace Tgstation.Server.Client
|
||||
/// <returns>A <see cref="Task"/> representing the running operation</returns>
|
||||
Task Detach(Instance instance, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gives the user full permissions on an <paramref name="instance"/>.
|
||||
/// </summary>
|
||||
/// <param name="instance">The <see cref="Instance"/> to grant permissions on.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task GrantPermissions(Instance instance, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Create an <see cref="IInstanceClient"/> for a given <see cref="Instance"/>
|
||||
/// </summary>
|
||||
|
||||
@@ -47,6 +47,9 @@ namespace Tgstation.Server.Client
|
||||
/// <inheritdoc />
|
||||
public Task<Instance> GetId(Instance instance, CancellationToken cancellationToken) => apiClient.Read<Instance>(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task GrantPermissions(Instance instance, CancellationToken cancellationToken) => apiClient.Patch(Routes.SetID(Routes.InstanceManager, instance?.Id ?? throw new ArgumentNullException(nameof(instance))), cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public IInstanceClient CreateClient(Instance instance)
|
||||
{
|
||||
|
||||
@@ -114,17 +114,22 @@ namespace Tgstation.Server.Host.Controllers
|
||||
return path;
|
||||
}
|
||||
|
||||
Models.InstanceUser InstanceAdminUser() => new Models.InstanceUser
|
||||
Models.InstanceUser InstanceAdminUser(Models.InstanceUser userToModify)
|
||||
{
|
||||
ByondRights = (ByondRights)~0U,
|
||||
ChatBotRights = (ChatBotRights)~0U,
|
||||
ConfigurationRights = (ConfigurationRights)~0U,
|
||||
DreamDaemonRights = (DreamDaemonRights)~0U,
|
||||
DreamMakerRights = (DreamMakerRights)~0U,
|
||||
RepositoryRights = (RepositoryRights)~0U,
|
||||
InstanceUserRights = (InstanceUserRights)~0U,
|
||||
UserId = AuthenticationContext.User.Id
|
||||
};
|
||||
if (userToModify == null)
|
||||
userToModify = new Models.InstanceUser()
|
||||
{
|
||||
UserId = AuthenticationContext.User.Id
|
||||
};
|
||||
userToModify.ByondRights = RightsHelper.AllRights<ByondRights>();
|
||||
userToModify.ChatBotRights = RightsHelper.AllRights<ChatBotRights>();
|
||||
userToModify.ConfigurationRights = RightsHelper.AllRights<ConfigurationRights>();
|
||||
userToModify.DreamDaemonRights = RightsHelper.AllRights<DreamDaemonRights>();
|
||||
userToModify.DreamMakerRights = RightsHelper.AllRights<DreamMakerRights>();
|
||||
userToModify.RepositoryRights = RightsHelper.AllRights<RepositoryRights>();
|
||||
userToModify.InstanceUserRights = RightsHelper.AllRights<InstanceUserRights>();
|
||||
return userToModify;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create or attach an <see cref="Api.Models.Instance"/>.
|
||||
@@ -267,7 +272,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
},
|
||||
InstanceUsers = new List<Models.InstanceUser> // give this user full privileges on the instance
|
||||
{
|
||||
InstanceAdminUser()
|
||||
InstanceAdminUser(null)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -458,21 +463,6 @@ namespace Tgstation.Server.Host.Controllers
|
||||
return Conflict(new ErrorMessage(ErrorCode.ChatBotMax));
|
||||
}
|
||||
|
||||
// ensure the current user has write privilege on the instance
|
||||
var usersInstanceUser = await InstanceQuery()
|
||||
.SelectMany(x => x.InstanceUsers)
|
||||
.Where(x => x.UserId == AuthenticationContext.User.Id)
|
||||
.FirstOrDefaultAsync(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
if (usersInstanceUser == default)
|
||||
{
|
||||
var instanceAdminUser = InstanceAdminUser();
|
||||
instanceAdminUser.InstanceId = originalModel.Id;
|
||||
DatabaseContext.InstanceUsers.Add(instanceAdminUser);
|
||||
}
|
||||
else
|
||||
usersInstanceUser.InstanceUserRights |= InstanceUserRights.WriteUsers;
|
||||
|
||||
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (renamed)
|
||||
@@ -634,5 +624,40 @@ namespace Tgstation.Server.Host.Controllers
|
||||
api.MoveJob = moveJob?.ToApi();
|
||||
return Json(api);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gives the current user full permissions on a given instance <paramref name="id"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">The instance <see cref="EntityId.Id"/> to give permissions on.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> of the request.</returns>
|
||||
/// <response code="204">Granted permissions successfully.</response>
|
||||
[HttpPatch("{id}")]
|
||||
[TgsAuthorize(InstanceManagerRights.GrantPermissions)]
|
||||
[ProducesResponseType(204)]
|
||||
public async Task<IActionResult> GrantPermissions(long id, CancellationToken cancellationToken)
|
||||
{
|
||||
// ensure the current user has write privilege on the instance
|
||||
var usersInstanceUser = await DatabaseContext
|
||||
.Instances
|
||||
.AsQueryable()
|
||||
.Where(x => x.Id == id)
|
||||
.SelectMany(x => x.InstanceUsers)
|
||||
.Where(x => x.UserId == AuthenticationContext.User.Id)
|
||||
.FirstOrDefaultAsync(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
if (usersInstanceUser == default)
|
||||
{
|
||||
var instanceAdminUser = InstanceAdminUser(null);
|
||||
instanceAdminUser.InstanceId = id;
|
||||
DatabaseContext.InstanceUsers.Add(instanceAdminUser);
|
||||
}
|
||||
else
|
||||
InstanceAdminUser(usersInstanceUser);
|
||||
|
||||
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"General": {
|
||||
"ApiPort": 5000,
|
||||
"MinimumPasswordLength": 15,
|
||||
"GitHubAccessToken": null,
|
||||
"SetupWizardMode": "AutoDetect",
|
||||
@@ -33,6 +32,13 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Kestrel": {
|
||||
"EndPoints": {
|
||||
"Http": {
|
||||
"Url": "http://0.0.0.0:80"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ControlPanel": {
|
||||
"Enable": false,
|
||||
"AllowAnyOrigin": false,
|
||||
|
||||
Reference in New Issue
Block a user