diff --git a/src/Tgstation.Server.Api/Models/Internal/ChatSettings.cs b/src/Tgstation.Server.Api/Models/Internal/ChatSettings.cs
index db9ba2db13..2a23052ad8 100644
--- a/src/Tgstation.Server.Api/Models/Internal/ChatSettings.cs
+++ b/src/Tgstation.Server.Api/Models/Internal/ChatSettings.cs
@@ -26,13 +26,13 @@ namespace Tgstation.Server.Api.Models.Internal
/// If the connection is enabled
///
[Permissions(WriteRight = ChatSettingsRights.WriteEnabled)]
- public bool Enabled { get; set; }
+ public bool? Enabled { get; set; }
///
/// The used for the connection
///
[Permissions(WriteRight = ChatSettingsRights.WriteProvider)]
- public ChatProvider Provider { get; set; }
+ public ChatProvider? Provider { get; set; }
///
/// The information used to connect to the
diff --git a/src/Tgstation.Server.Host/Components/Chat/Chat.cs b/src/Tgstation.Server.Host/Components/Chat/Chat.cs
index 862096ae44..07a29865c9 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Chat.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Chat.cs
@@ -171,7 +171,7 @@ namespace Tgstation.Server.Host.Components.Chat
providers.Remove(newSettings.Id);
provider.Dispose();
}
- if (newSettings.Enabled)
+ if (newSettings.Enabled.Value)
{
provider = providerFactory.CreateProvider(newSettings);
providers.Add(newSettings.Id, provider);
@@ -180,7 +180,7 @@ namespace Tgstation.Server.Host.Components.Chat
lock (mappedChannels)
foreach (var channelId in mappedChannels.Where(x => x.Value.ProviderId == newSettings.Id).Select(x => x.Key))
mappedChannels.Remove(channelId);
- if (newSettings.Enabled && started)
+ if (newSettings.Enabled.Value && started)
await provider.Connect(cancellationToken).ConfigureAwait(false);
}
diff --git a/src/Tgstation.Server.Host/Controllers/ChatController.cs b/src/Tgstation.Server.Host/Controllers/ChatController.cs
index 3288e5d7f7..2a19a797e3 100644
--- a/src/Tgstation.Server.Host/Controllers/ChatController.cs
+++ b/src/Tgstation.Server.Host/Controllers/ChatController.cs
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Linq.Expressions;
+using System.Net;
+using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
@@ -36,6 +39,14 @@ namespace Tgstation.Server.Host.Controllers
this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
}
+ static Models.ChatChannel ConvertApiChatChannel(Api.Models.ChatChannel api) => new Models.ChatChannel
+ {
+ DiscordChannelId = api.DiscordChannelId,
+ IrcChannel = api.IrcChannel,
+ IsAdminChannel = api.IsAdminChannel,
+ IsWatchdogChannel = api.IsWatchdogChannel
+ };
+
///
[TgsAuthorize(ChatSettingsRights.Create)]
public override async Task Create([FromBody] Api.Models.ChatSettings model, CancellationToken cancellationToken)
@@ -44,10 +55,16 @@ namespace Tgstation.Server.Host.Controllers
throw new ArgumentNullException(nameof(model));
if (String.IsNullOrWhiteSpace(model.Name))
- return BadRequest(new { message = "Name cannot be null or whitespace!" });
+ return BadRequest(new { message = "name cannot be null or whitespace!" });
if (String.IsNullOrWhiteSpace(model.ConnectionString))
- return BadRequest(new { message = "ConnectionString cannot be null or whitespace!" });
+ return BadRequest(new { message = "connection_string cannot be null or whitespace!" });
+
+ if (!model.Provider.HasValue)
+ return BadRequest(new { message = "provider cannot be null!" });
+
+ if (!model.Enabled.HasValue)
+ return BadRequest(new { message = "enabled cannot be null!" });
//try to update das db first
var dbModel = new Models.ChatSettings
@@ -55,13 +72,7 @@ namespace Tgstation.Server.Host.Controllers
Name = model.Name,
ConnectionString = model.ConnectionString,
Enabled = model.Enabled,
- Channels = model.Channels?.Select(x => new Models.ChatChannel
- {
- DiscordChannelId = x.DiscordChannelId,
- IrcChannel = x.IrcChannel,
- IsAdminChannel = x.IsAdminChannel,
- IsWatchdogChannel = x.IsWatchdogChannel
- }).ToList() ?? new List(),
+ Channels = model.Channels?.Select(x => ConvertApiChatChannel(x)).ToList() ?? new List(),
InstanceId = Instance.Id,
Provider = model.Provider,
};
@@ -124,5 +135,70 @@ namespace Tgstation.Server.Host.Controllers
return Json(results);
}
+
+ ///
+ [TgsAuthorize(ChatSettingsRights.WriteChannels | ChatSettingsRights.WriteConnectionString | ChatSettingsRights.WriteEnabled | ChatSettingsRights.WriteName | ChatSettingsRights.WriteProvider)]
+ public override async Task Update([FromBody] Api.Models.ChatSettings model, CancellationToken cancellationToken)
+ {
+ if (model == null)
+ throw new ArgumentNullException(nameof(model));
+
+ var query = DatabaseContext.ChatSettings.Where(x => x.InstanceId == Instance.Id && x.Id == model.Id).Include(x => x.Channels);
+
+ var current = await query.FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
+
+ if (current == default)
+ return StatusCode((int)HttpStatusCode.Gone);
+
+ var userRights = (ChatSettingsRights)AuthenticationContext.GetRight(RightsType.ChatSettings);
+
+ bool anySettingsModified = false;
+
+ bool CheckModified(Expression> expression, ChatSettingsRights requiredRight)
+ {
+ var memberSelectorExpression = (MemberExpression)expression.Body;
+ var property = (PropertyInfo)memberSelectorExpression.Member;
+
+ var newVal = property.GetValue(model);
+ if (newVal == null)
+ return false;
+ if (!userRights.HasFlag(requiredRight) && property.GetValue(current) != newVal)
+ return true;
+
+ property.SetValue(current, newVal);
+ anySettingsModified = true;
+ return false;
+ };
+
+ if (!CheckModified(x => x.ConnectionString, ChatSettingsRights.WriteConnectionString)
+ || !CheckModified(x => x.Enabled, ChatSettingsRights.WriteEnabled)
+ || !CheckModified(x => x.Name, ChatSettingsRights.WriteName)
+ || !CheckModified(x => x.Provider, ChatSettingsRights.WriteProvider)
+ || (model.Channels != null && !userRights.HasFlag(ChatSettingsRights.WriteChannels)))
+ return Forbid();
+
+ if (model.Channels != null)
+ {
+ DatabaseContext.ChatChannels.RemoveRange(current.Channels);
+ var dbChannels = model.Channels.Select(x => ConvertApiChatChannel(x)).ToList();
+ DatabaseContext.ChatChannels.AddRange(dbChannels);
+ current.Channels = dbChannels;
+ }
+
+ await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
+
+ var chat = instanceManager.GetInstance(Instance).Chat;
+
+ if (anySettingsModified)
+ //have to rebuild the thing first
+ await chat.ChangeSettings(current, cancellationToken).ConfigureAwait(false);
+
+ if (model.Channels != null)
+ await chat.ChangeChannels(current.Id, current.Channels, cancellationToken).ConfigureAwait(false);
+
+ if(userRights.HasFlag(ChatSettingsRights.Read))
+ return Json(current);
+ return Ok();
+ }
}
}