2019-04-14 11:55:05 -04:00
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
2019-03-30 23:04:15 -04:00
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
2019-12-02 16:52:36 -05:00
|
|
|
|
using SharedLibraryCore;
|
2019-04-11 21:43:05 -04:00
|
|
|
|
using SharedLibraryCore.Configuration;
|
2020-01-17 18:31:53 -05:00
|
|
|
|
using SharedLibraryCore.Configuration.Attributes;
|
|
|
|
|
using SharedLibraryCore.Configuration.Validation;
|
2019-12-02 16:52:36 -05:00
|
|
|
|
using SharedLibraryCore.Interfaces;
|
2019-04-14 11:55:05 -04:00
|
|
|
|
using System.Linq;
|
2020-01-17 18:31:53 -05:00
|
|
|
|
using System.Reflection;
|
2019-04-14 11:55:05 -04:00
|
|
|
|
using System.Threading.Tasks;
|
2019-04-11 21:43:05 -04:00
|
|
|
|
using WebfrontCore.ViewModels;
|
2019-03-30 23:04:15 -04:00
|
|
|
|
|
|
|
|
|
namespace WebfrontCore.Controllers
|
|
|
|
|
{
|
2019-04-14 11:55:05 -04:00
|
|
|
|
[Authorize]
|
2019-03-30 23:04:15 -04:00
|
|
|
|
public class ConfigurationController : BaseController
|
|
|
|
|
{
|
2020-01-17 18:31:53 -05:00
|
|
|
|
private readonly ApplicationConfigurationValidator _validator;
|
2019-12-02 16:52:36 -05:00
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
public ConfigurationController(IManager manager) : base(manager)
|
|
|
|
|
{
|
|
|
|
|
_validator = new ApplicationConfigurationValidator();
|
2019-12-02 16:52:36 -05:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Endpoint to get the current configuration view
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2019-03-30 23:04:15 -04:00
|
|
|
|
public IActionResult Edit()
|
|
|
|
|
{
|
2019-07-27 09:18:49 -04:00
|
|
|
|
if (Client.Level < SharedLibraryCore.Database.Models.EFClient.Permission.Owner)
|
2019-04-16 12:32:42 -04:00
|
|
|
|
{
|
|
|
|
|
return Unauthorized();
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-30 23:04:15 -04:00
|
|
|
|
return View("Index", Manager.GetApplicationSettings().Configuration());
|
|
|
|
|
}
|
2019-04-11 21:43:05 -04:00
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Endpoint for the save action
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="newConfiguration">bound configuration</param>
|
|
|
|
|
/// <returns></returns>
|
2019-04-11 21:43:05 -04:00
|
|
|
|
[HttpPost]
|
2020-01-17 18:31:53 -05:00
|
|
|
|
public async Task<IActionResult> Save(ApplicationConfiguration newConfiguration)
|
2019-04-11 21:43:05 -04:00
|
|
|
|
{
|
2020-01-17 18:31:53 -05:00
|
|
|
|
// todo: make this authorization middleware instead of these checks
|
2019-07-27 09:18:49 -04:00
|
|
|
|
if (Client.Level < SharedLibraryCore.Database.Models.EFClient.Permission.Owner)
|
2019-04-16 12:32:42 -04:00
|
|
|
|
{
|
|
|
|
|
return Unauthorized();
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
CleanConfiguration(newConfiguration);
|
|
|
|
|
var validationResult = _validator.Validate(newConfiguration);
|
|
|
|
|
|
|
|
|
|
if (validationResult.IsValid)
|
2019-04-12 23:25:18 -04:00
|
|
|
|
{
|
2019-04-14 11:55:05 -04:00
|
|
|
|
var currentConfiguration = Manager.GetApplicationSettings().Configuration();
|
2020-01-17 18:31:53 -05:00
|
|
|
|
CopyConfiguration(newConfiguration, currentConfiguration);
|
|
|
|
|
await Manager.GetApplicationSettings().Save();
|
|
|
|
|
return Ok(new { message = new[] { Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CONFIGURATION_SAVED"] } });
|
|
|
|
|
}
|
2019-04-12 23:25:18 -04:00
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return BadRequest(new { message = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CONFIGURATION_SAVE_FAILED"], errors = new[] { validationResult.Errors.Select(_error => _error.ErrorMessage) } });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Cleans the configuration by removing empty items from from the array
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="newConfiguration"></param>
|
|
|
|
|
private void CleanConfiguration(ApplicationConfiguration newConfiguration)
|
|
|
|
|
{
|
|
|
|
|
void cleanProperties(object config)
|
|
|
|
|
{
|
|
|
|
|
foreach (var property in config.GetType()
|
|
|
|
|
.GetProperties().Where(_prop => _prop.CanWrite))
|
2019-04-12 23:25:18 -04:00
|
|
|
|
{
|
2020-01-17 18:31:53 -05:00
|
|
|
|
var newPropValue = property.GetValue(config);
|
2019-04-14 11:55:05 -04:00
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
if (newPropValue is ServerConfiguration[] serverConfig)
|
2019-04-14 11:55:05 -04:00
|
|
|
|
{
|
2020-01-17 18:31:53 -05:00
|
|
|
|
foreach (var c in serverConfig)
|
|
|
|
|
{
|
|
|
|
|
cleanProperties(c);
|
|
|
|
|
}
|
2019-04-14 11:55:05 -04:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
// this clears out any null or empty items in the string array
|
|
|
|
|
if (newPropValue is string[] configArray)
|
|
|
|
|
{
|
|
|
|
|
newPropValue = configArray.Where(_str => !string.IsNullOrWhiteSpace(_str)).ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
property.SetValue(config, newPropValue);
|
|
|
|
|
}
|
2019-04-12 23:25:18 -04:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
cleanProperties(newConfiguration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Copies required config fields from new to old
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="newConfiguration">Source config</param>
|
|
|
|
|
/// <param name="oldConfiguration">Destination config</param>
|
|
|
|
|
private void CopyConfiguration(ApplicationConfiguration newConfiguration, ApplicationConfiguration oldConfiguration)
|
|
|
|
|
{
|
|
|
|
|
foreach (var property in newConfiguration.GetType()
|
|
|
|
|
.GetProperties().Where(_prop => _prop.CanWrite))
|
2019-04-14 11:55:05 -04:00
|
|
|
|
{
|
2020-01-17 18:31:53 -05:00
|
|
|
|
var newPropValue = property.GetValue(newConfiguration);
|
|
|
|
|
bool isPropNullArray = property.PropertyType.IsArray && newPropValue == null;
|
2019-04-14 11:55:05 -04:00
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
// this prevents us from setting a null array as that could screw reading up
|
|
|
|
|
if (!ShouldIgnoreProperty(property) && !isPropNullArray)
|
|
|
|
|
{
|
|
|
|
|
property.SetValue(oldConfiguration, newPropValue);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-11 21:43:05 -04:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Generates the partial view for a new list item
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="propertyName">name of the property the input element is generated for</param>
|
|
|
|
|
/// <param name="itemCount">how many items exist already</param>
|
|
|
|
|
/// <param name="serverIndex">if it's a server property, which one</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public IActionResult GetNewListItem(string propertyName, int itemCount, int serverIndex = -1)
|
2019-04-11 21:43:05 -04:00
|
|
|
|
{
|
2020-01-17 18:31:53 -05:00
|
|
|
|
if (Client.Level < SharedLibraryCore.Database.Models.EFClient.Permission.Owner)
|
2019-04-16 12:32:42 -04:00
|
|
|
|
{
|
|
|
|
|
return Unauthorized();
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
// todo: maybe make this cleaner in the future
|
|
|
|
|
if (propertyName.StartsWith("Servers") && serverIndex < 0)
|
2019-04-11 21:43:05 -04:00
|
|
|
|
{
|
2020-01-17 18:31:53 -05:00
|
|
|
|
return PartialView("_ServerItem", new ApplicationConfiguration()
|
|
|
|
|
{
|
|
|
|
|
Servers = Enumerable.Repeat(new ServerConfiguration(), itemCount + 1).ToArray()
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var model = new BindingHelper()
|
|
|
|
|
{
|
|
|
|
|
Properties = propertyName.Split("."),
|
|
|
|
|
ItemIndex = itemCount,
|
|
|
|
|
ParentItemIndex = serverIndex
|
2019-04-11 21:43:05 -04:00
|
|
|
|
};
|
|
|
|
|
|
2020-01-17 18:31:53 -05:00
|
|
|
|
return PartialView("_ListItem", model);
|
2019-04-11 21:43:05 -04:00
|
|
|
|
}
|
2020-01-17 18:31:53 -05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Indicates if the property should be ignored when cleaning/copying from one config to another
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="info">property info of the current property</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private bool ShouldIgnoreProperty(PropertyInfo info) => (info.GetCustomAttributes(false)
|
|
|
|
|
.Where(_attr => _attr.GetType() == typeof(ConfigurationIgnore))
|
|
|
|
|
.FirstOrDefault() as ConfigurationIgnore) != null;
|
2019-03-30 23:04:15 -04:00
|
|
|
|
}
|
|
|
|
|
}
|