Start refactoring to base api controller
This commit is contained in:
parent
7f47fa6753
commit
e78c0d8746
145
ChaosBot/WebServer/App/ApiControllers/BaseApiController.cs
Normal file
145
ChaosBot/WebServer/App/ApiControllers/BaseApiController.cs
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Dynamic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ChaosBot.Models;
|
||||||
|
using ChaosBot.WebServer.Services;
|
||||||
|
using FlexLabs.EntityFrameworkCore.Upsert;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace ChaosBot.WebServer.App.ApiControllers
|
||||||
|
{
|
||||||
|
public abstract class BaseApiController<T, TDeleteParameter> : Controller where T : class, new()
|
||||||
|
{
|
||||||
|
protected readonly AccessTokenCache AccessTokenCache;
|
||||||
|
|
||||||
|
protected BaseApiController(
|
||||||
|
AccessTokenCache accessTokenCache
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AccessTokenCache = accessTokenCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> Index(ulong guildId)
|
||||||
|
{
|
||||||
|
if (!CheckPermissions.GetResult(AccessTokenCache, Request, guildId, out IActionResult result))
|
||||||
|
return result;
|
||||||
|
|
||||||
|
await using ChaosbotContext dbContext = new ChaosbotContext();
|
||||||
|
|
||||||
|
IQueryable<T> query = GetBasicQuery(dbContext);
|
||||||
|
List<T> list = ApplyFilterForCurrentGuild(query, guildId).ToList();
|
||||||
|
|
||||||
|
LoggingFacade.Info("Received request");
|
||||||
|
List<dynamic> response = list.Select(element =>
|
||||||
|
{
|
||||||
|
Dictionary<string, object> responseDict = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
foreach (string field in GetIndexFields())
|
||||||
|
{
|
||||||
|
responseDict.Add(field, element.GetType().GetProperty(field)?.GetValue(element, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic dynamicResponseElement = new DynamicResponse(responseDict);
|
||||||
|
return dynamicResponseElement;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
return Content(JsonConvert.SerializeObject(response), new MediaTypeHeaderValue("application/json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> Upsert(ulong guildId, dynamic requestBody)
|
||||||
|
{
|
||||||
|
if (!CheckPermissions.GetResult(AccessTokenCache, Request, guildId, out IActionResult result))
|
||||||
|
return result;
|
||||||
|
|
||||||
|
await using ChaosbotContext dbContext = new ChaosbotContext();
|
||||||
|
|
||||||
|
T databaseObject = new T();
|
||||||
|
|
||||||
|
foreach (string key in GetValidationRules().Keys)
|
||||||
|
{
|
||||||
|
databaseObject
|
||||||
|
.GetType()
|
||||||
|
.GetProperty(key)
|
||||||
|
?.SetValue(databaseObject, requestBody.GetType().GetProperty(key)?.GetValue(requestBody, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
await ApplyFilterForUpsert(GetBasicQuery(dbContext).Upsert(databaseObject)).RunAsync();
|
||||||
|
await dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> Delete(ulong guildId, TDeleteParameter deleteParameter)
|
||||||
|
{
|
||||||
|
if (!CheckPermissions.GetResult(AccessTokenCache, Request, guildId, out IActionResult result))
|
||||||
|
return result;
|
||||||
|
|
||||||
|
await using ChaosbotContext dbContext = new ChaosbotContext();
|
||||||
|
|
||||||
|
IQueryable<T> query = GetBasicQuery(dbContext);
|
||||||
|
List<T> toDelete = FilterQueryMultipleForDeletion(query, guildId, deleteParameter);
|
||||||
|
toDelete.Add(FilterQueryForDeletion(query, guildId, deleteParameter));
|
||||||
|
|
||||||
|
if (toDelete.Count == 0)
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
foreach (T obj in toDelete)
|
||||||
|
{
|
||||||
|
GetBasicQuery(dbContext).Remove(obj);
|
||||||
|
}
|
||||||
|
await dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract DbSet<T> GetBasicQuery(ChaosbotContext context);
|
||||||
|
protected abstract IQueryable<T> ApplyFilterForCurrentGuild(IQueryable<T> query, ulong guildId);
|
||||||
|
protected abstract List<string> GetIndexFields();
|
||||||
|
protected abstract Dictionary<string, List<string>> GetValidationRules();
|
||||||
|
protected abstract UpsertCommandBuilder<T> ApplyFilterForUpsert(UpsertCommandBuilder<T> builder);
|
||||||
|
protected abstract T FilterQueryForDeletion(IQueryable<T> query, ulong guildId, TDeleteParameter deleteParameter);
|
||||||
|
protected abstract List<T> FilterQueryMultipleForDeletion(IQueryable<T> query, ulong guildId, TDeleteParameter deleteParameter);
|
||||||
|
|
||||||
|
private class DynamicResponse : DynamicObject
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, object> _properties;
|
||||||
|
|
||||||
|
public DynamicResponse(Dictionary<string, object> properties)
|
||||||
|
{
|
||||||
|
_properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetDynamicMemberNames()
|
||||||
|
{
|
||||||
|
return _properties.Keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||||
|
{
|
||||||
|
if (_properties.ContainsKey(binder.Name))
|
||||||
|
{
|
||||||
|
result = _properties[binder.Name];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||||
|
{
|
||||||
|
if (_properties.ContainsKey(binder.Name))
|
||||||
|
{
|
||||||
|
_properties[binder.Name] = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ChaosBot.Models;
|
||||||
|
using ChaosBot.WebServer.Models;
|
||||||
|
using ChaosBot.WebServer.Services;
|
||||||
|
using FlexLabs.EntityFrameworkCore.Upsert;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace ChaosBot.WebServer.App.ApiControllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("/api/custom-commands")]
|
||||||
|
public class CustomCommandController : BaseApiController<CustomCommand, string>
|
||||||
|
{
|
||||||
|
public CustomCommandController(
|
||||||
|
AccessTokenCache accessTokenCache
|
||||||
|
) : base(
|
||||||
|
accessTokenCache
|
||||||
|
) {}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("{guildId}")]
|
||||||
|
public async Task<IActionResult> IndexAction(ulong guildId)
|
||||||
|
{
|
||||||
|
return await Index(guildId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("{guildId}")]
|
||||||
|
public async Task<IActionResult> UpsertAction(
|
||||||
|
[FromRoute] ulong guildId,
|
||||||
|
[FromBody] dynamic requestBody)
|
||||||
|
{
|
||||||
|
return await Upsert(guildId, requestBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("{guildId}/{command}")]
|
||||||
|
public async Task<IActionResult> DeleteAction([FromRoute]ulong guildId, [FromRoute]string command)
|
||||||
|
{
|
||||||
|
return await Delete(guildId, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DbSet<CustomCommand> GetBasicQuery(ChaosbotContext context)
|
||||||
|
{
|
||||||
|
return context.CustomCommands;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IQueryable<CustomCommand> ApplyFilterForCurrentGuild(IQueryable<CustomCommand> query, ulong guildId)
|
||||||
|
{
|
||||||
|
return query.Where(e => e.DiscordGuildId == guildId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override List<string> GetIndexFields() {
|
||||||
|
return new List<string>
|
||||||
|
{
|
||||||
|
"Command",
|
||||||
|
"Type",
|
||||||
|
"Content"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Dictionary<string, List<string>> GetValidationRules()
|
||||||
|
{
|
||||||
|
return new Dictionary<string, List<string>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override UpsertCommandBuilder<CustomCommand> ApplyFilterForUpsert(
|
||||||
|
UpsertCommandBuilder<CustomCommand> builder)
|
||||||
|
{
|
||||||
|
return builder.On(cc => new {cc.DiscordGuildId, cc.Command});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override CustomCommand FilterQueryForDeletion(IQueryable<CustomCommand> query, ulong guildId, string deleteParameter)
|
||||||
|
{
|
||||||
|
return query
|
||||||
|
.Where(cc => cc.DiscordGuildId == guildId)
|
||||||
|
.First(cc => cc.Command == deleteParameter)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override List<CustomCommand> FilterQueryMultipleForDeletion(IQueryable<CustomCommand> query, ulong guildId, string deleteParameter)
|
||||||
|
{
|
||||||
|
return new List<CustomCommand>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,93 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using ChaosBot.Discord;
|
|
||||||
using ChaosBot.Models;
|
|
||||||
using ChaosBot.WebServer.Models;
|
|
||||||
using ChaosBot.WebServer.Services;
|
|
||||||
using Discord.WebSocket;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace ChaosBot.WebServer.App
|
|
||||||
{
|
|
||||||
[ApiController]
|
|
||||||
[Route("/api/custom-commands")]
|
|
||||||
public class CustomCommandController : Controller
|
|
||||||
{
|
|
||||||
private readonly AccessTokenCache _accessTokenCache;
|
|
||||||
|
|
||||||
public CustomCommandController(
|
|
||||||
AccessTokenCache accessTokenCache
|
|
||||||
)
|
|
||||||
{
|
|
||||||
_accessTokenCache = accessTokenCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[Route("{guildId}")]
|
|
||||||
public async Task<IActionResult> GetCustomCommands([FromRoute]ulong guildId)
|
|
||||||
{
|
|
||||||
if (!CheckPermissions.GetResult(_accessTokenCache, Request, guildId, out IActionResult result))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
await using ChaosbotContext dbContext = new ChaosbotContext();
|
|
||||||
|
|
||||||
IQueryable<CustomCommand> customCommandsQuery = dbContext.CustomCommands;
|
|
||||||
List<CustomCommand> customCommands = customCommandsQuery
|
|
||||||
.Where(cc => cc.DiscordGuildId == guildId)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
List<CustomCommandResponse> response = customCommands.Select(e => new CustomCommandResponse(e)).ToList();
|
|
||||||
|
|
||||||
return Json(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[Route("{guildId}")]
|
|
||||||
public async Task<IActionResult> UpsertCustomCommands([FromRoute]ulong guildId, [FromBody]CustomCommandRequest customCommandRequest)
|
|
||||||
{
|
|
||||||
if (!CheckPermissions.GetResult(_accessTokenCache, Request, guildId, out IActionResult result))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
await using ChaosbotContext dbContext = new ChaosbotContext();
|
|
||||||
|
|
||||||
CustomCommand customCommand = new CustomCommand
|
|
||||||
{
|
|
||||||
DiscordGuildId = guildId,
|
|
||||||
Command = customCommandRequest.Command,
|
|
||||||
Type = customCommandRequest.Type,
|
|
||||||
Content = customCommandRequest.Content
|
|
||||||
};
|
|
||||||
await dbContext.CustomCommands.Upsert(customCommand)
|
|
||||||
.On(cc => new {cc.DiscordGuildId, cc.Command}).RunAsync();
|
|
||||||
await dbContext.SaveChangesAsync();
|
|
||||||
|
|
||||||
return NoContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpDelete]
|
|
||||||
[Route("{guildId}/{command}")]
|
|
||||||
public async Task<IActionResult> DeleteCustomCommands([FromRoute]ulong guildId, [FromRoute]string command)
|
|
||||||
{
|
|
||||||
if (!CheckPermissions.GetResult(_accessTokenCache, Request, guildId, out IActionResult result))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
await using ChaosbotContext dbContext = new ChaosbotContext();
|
|
||||||
|
|
||||||
IQueryable<CustomCommand> customCommandQuery = dbContext.CustomCommands;
|
|
||||||
CustomCommand customCommand = customCommandQuery
|
|
||||||
.Where(cc => cc.DiscordGuildId == guildId)
|
|
||||||
.First(cc => cc.Command == command);
|
|
||||||
|
|
||||||
if (customCommand == null)
|
|
||||||
return NotFound();
|
|
||||||
|
|
||||||
dbContext.CustomCommands.Remove(customCommand);
|
|
||||||
await dbContext.SaveChangesAsync();
|
|
||||||
|
|
||||||
return NoContent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user