From 513b821b60a9057e15ca8325bcf1d84346223f1c Mon Sep 17 00:00:00 2001 From: JustArchi Date: Thu, 11 Apr 2019 22:47:21 +0200 Subject: [PATCH] IPC controllers cleanup --- .../CatController.cs | 2 +- .../IPC/Controllers/Api/ASFController.cs | 12 ++- .../IPC/Controllers/Api/ArchiController.cs | 9 +- .../IPC/Controllers/Api/BotController.cs | 92 +++++++++++-------- .../IPC/Controllers/Api/CommandController.cs | 14 +-- .../IPC/Controllers/Api/NLogController.cs | 4 +- .../Controllers/Api/StructureController.cs | 12 ++- .../IPC/Controllers/Api/TypeController.cs | 10 +- .../IPC/Controllers/Api/WWWController.cs | 53 +++++------ 9 files changed, 119 insertions(+), 89 deletions(-) diff --git a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatController.cs b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatController.cs index bdf909406..d00350090 100644 --- a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatController.cs +++ b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatController.cs @@ -37,7 +37,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin { [HttpGet] [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.ServiceUnavailable)] - public async Task>> CatGet() { + public async Task> CatGet() { string link = await CatAPI.GetRandomCatURL(ASF.WebBrowser).ConfigureAwait(false); return !string.IsNullOrEmpty(link) ? Ok(new GenericResponse(link)) : StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false)); diff --git a/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs b/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs index 9da4b3b6d..f25be92ca 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Threading.Tasks; using ArchiSteamFarm.IPC.Requests; using ArchiSteamFarm.IPC.Responses; @@ -36,7 +37,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Fetches common info related to ASF as a whole. /// [HttpGet] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] public ActionResult> ASFGet() { uint memoryUsage = (uint) GC.GetTotalMemory(false) / 1024; @@ -50,7 +51,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// [Consumes("application/json")] [HttpPost] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task> ASFPost([FromBody] ASFRequest request) { if (request == null) { ASF.ArchiLogger.LogNullError(nameof(request)); @@ -100,7 +102,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Makes ASF shutdown itself. /// [HttpPost("Exit")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] public ActionResult ExitPost() { (bool success, string message) = Actions.Exit(); @@ -111,7 +113,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Makes ASF restart itself. /// [HttpPost("Restart")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] public ActionResult RestartPost() { (bool success, string message) = Actions.Restart(); @@ -122,7 +124,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Makes ASF update itself. /// [HttpPost("Update")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] public async Task>> UpdatePost() { (bool success, string message, Version version) = await Actions.Update().ConfigureAwait(false); diff --git a/ArchiSteamFarm/IPC/Controllers/Api/ArchiController.cs b/ArchiSteamFarm/IPC/Controllers/Api/ArchiController.cs index cb5e7e07c..0ccb0a982 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/ArchiController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/ArchiController.cs @@ -19,6 +19,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System.Net; using ArchiSteamFarm.IPC.Responses; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; @@ -26,8 +27,10 @@ using Swashbuckle.AspNetCore.Annotations; namespace ArchiSteamFarm.IPC.Controllers.Api { [ApiController] [Produces("application/json")] - [SwaggerResponse(400, "The request has failed, check " + nameof(GenericResponse.Message) + " from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))] - [SwaggerResponse(401, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set, but you've failed to authenticate. See " + SharedInfo.ProjectURL + "/wiki/IPC#authentication.")] - [SwaggerResponse(403, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set and you've failed to authenticate too many times, try again in an hour. See " + SharedInfo.ProjectURL + "/wiki/IPC#authentication.")] + [SwaggerResponse((int) HttpStatusCode.BadRequest, "The request has failed, check " + nameof(GenericResponse.Message) + " from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))] + [SwaggerResponse((int) HttpStatusCode.Unauthorized, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set, but you've failed to authenticate. See " + SharedInfo.ProjectURL + "/wiki/IPC#authentication.")] + [SwaggerResponse((int) HttpStatusCode.Forbidden, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set and you've failed to authenticate too many times, try again in an hour. See " + SharedInfo.ProjectURL + "/wiki/IPC#authentication.")] + [SwaggerResponse((int) HttpStatusCode.InternalServerError, "ASF has encountered an unexpected error while serving the request. The log may include extra info related to this issue.")] + [SwaggerResponse((int) HttpStatusCode.ServiceUnavailable, "ASF has encountered an error while requesting a third-party resource. Try again later.")] public abstract class ArchiController : ControllerBase { } } diff --git a/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs b/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs index 96dbe3fc5..994d11be2 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; +using System.Net; using System.Threading.Tasks; using ArchiSteamFarm.IPC.Requests; using ArchiSteamFarm.IPC.Responses; @@ -37,7 +38,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Deletes all files related to given bots. /// [HttpDelete("{botNames:required}")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task> BotDelete(string botNames) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); @@ -60,18 +62,19 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Fetches common info related to given bots. /// [HttpGet("{botNames:required}")] - [ProducesResponseType(typeof(GenericResponse>), 200)] - public ActionResult>> BotGet(string botNames) { + [ProducesResponseType(typeof(GenericResponse>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public ActionResult BotGet(string botNames) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames)))); } HashSet bots = Bot.GetBots(botNames); if (bots == null) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsInvalid, nameof(bots)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, nameof(bots)))); } return Ok(new GenericResponse>(bots.ToDictionary(bot => bot.BotName, bot => bot, Bot.BotsComparer))); @@ -82,18 +85,19 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// [Consumes("application/json")] [HttpPost("{botNames:required}")] - [ProducesResponseType(typeof(GenericResponse>), 200)] - public async Task>>> BotPost(string botNames, [FromBody] BotRequest request) { + [ProducesResponseType(typeof(GenericResponse>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public async Task> BotPost(string botNames, [FromBody] BotRequest request) { if (string.IsNullOrEmpty(botNames) || (request == null)) { ASF.ArchiLogger.LogNullError(nameof(botNames) + " || " + nameof(request)); - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames) + " || " + nameof(request)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames) + " || " + nameof(request)))); } (bool valid, string errorMessage) = request.BotConfig.CheckValidation(); if (!valid) { - return BadRequest(new GenericResponse>(false, errorMessage)); + return BadRequest(new GenericResponse(false, errorMessage)); } request.BotConfig.ShouldSerializeEverything = false; @@ -135,7 +139,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { if (string.IsNullOrEmpty(filePath)) { ASF.ArchiLogger.LogNullError(filePath); - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsInvalid, nameof(filePath)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, nameof(filePath)))); } result[botName] = await BotConfig.Write(filePath, request.BotConfig).ConfigureAwait(false); @@ -148,7 +152,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Removes BGR output files of given bots. /// [HttpDelete("{botNames:required}/GamesToRedeemInBackground")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task> GamesToRedeemInBackgroundDelete(string botNames) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); @@ -171,18 +176,19 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Fetches BGR output files of given bots. /// [HttpGet("{botNames:required}/GamesToRedeemInBackground")] - [ProducesResponseType(typeof(GenericResponse>), 200)] - public async Task>>> GamesToRedeemInBackgroundGet(string botNames) { + [ProducesResponseType(typeof(GenericResponse>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public async Task> GamesToRedeemInBackgroundGet(string botNames) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames)))); } HashSet bots = Bot.GetBots(botNames); if ((bots == null) || (bots.Count == 0)) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.BotNotFound, botNames))); + return BadRequest(new GenericResponse(false, string.Format(Strings.BotNotFound, botNames))); } IList<(Dictionary UnusedKeys, Dictionary UsedKeys)> results = await Utilities.InParallel(bots.Select(bot => bot.GetUsedAndUnusedKeys())).ConfigureAwait(false); @@ -202,28 +208,29 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// [Consumes("application/json")] [HttpPost("{botNames:required}/GamesToRedeemInBackground")] - [ProducesResponseType(typeof(GenericResponse>), 200)] - public async Task>>> GamesToRedeemInBackgroundPost(string botNames, [FromBody] BotGamesToRedeemInBackgroundRequest request) { + [ProducesResponseType(typeof(GenericResponse>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public async Task> GamesToRedeemInBackgroundPost(string botNames, [FromBody] BotGamesToRedeemInBackgroundRequest request) { if (string.IsNullOrEmpty(botNames) || (request == null)) { ASF.ArchiLogger.LogNullError(nameof(botNames) + " || " + nameof(request)); - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames) + " || " + nameof(request)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames) + " || " + nameof(request)))); } if (request.GamesToRedeemInBackground.Count == 0) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(request.GamesToRedeemInBackground)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(request.GamesToRedeemInBackground)))); } HashSet bots = Bot.GetBots(botNames); if ((bots == null) || (bots.Count == 0)) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.BotNotFound, botNames))); + return BadRequest(new GenericResponse(false, string.Format(Strings.BotNotFound, botNames))); } IOrderedDictionary validGamesToRedeemInBackground = Bot.ValidateGamesToRedeemInBackground(request.GamesToRedeemInBackground); if ((validGamesToRedeemInBackground == null) || (validGamesToRedeemInBackground.Count == 0)) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(validGamesToRedeemInBackground)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(validGamesToRedeemInBackground)))); } await Utilities.InParallel(bots.Select(bot => bot.AddGamesToRedeemInBackground(validGamesToRedeemInBackground))).ConfigureAwait(false); @@ -242,7 +249,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// [Consumes("application/json")] [HttpPost("{botNames:required}/Pause")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task> PausePost(string botNames, [FromBody] BotPauseRequest request) { if (string.IsNullOrEmpty(botNames) || (request == null)) { ASF.ArchiLogger.LogNullError(nameof(botNames) + " || " + nameof(request)); @@ -270,22 +278,23 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// [Consumes("application/json")] [HttpPost("{botNames:required}/Redeem")] - [ProducesResponseType(typeof(GenericResponse>>), 200)] - public async Task>>>> RedeemPost(string botNames, [FromBody] BotRedeemRequest request) { + [ProducesResponseType(typeof(GenericResponse>>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public async Task> RedeemPost(string botNames, [FromBody] BotRedeemRequest request) { if (string.IsNullOrEmpty(botNames) || (request == null)) { ASF.ArchiLogger.LogNullError(nameof(botNames) + " || " + nameof(request)); - return BadRequest(new GenericResponse>>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames) + " || " + nameof(request)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames) + " || " + nameof(request)))); } if (request.KeysToRedeem.Count == 0) { - return BadRequest(new GenericResponse>>(false, string.Format(Strings.ErrorIsEmpty, nameof(request.KeysToRedeem)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(request.KeysToRedeem)))); } HashSet bots = Bot.GetBots(botNames); if ((bots == null) || (bots.Count == 0)) { - return BadRequest(new GenericResponse>>(false, string.Format(Strings.BotNotFound, botNames))); + return BadRequest(new GenericResponse(false, string.Format(Strings.BotNotFound, botNames))); } IList results = await Utilities.InParallel(bots.Select(bot => request.KeysToRedeem.Select(key => bot.Actions.RedeemKey(key))).SelectMany(task => task)).ConfigureAwait(false); @@ -311,7 +320,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// [Consumes("application/json")] [HttpPost("{botName:required}/Rename")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task> RenamePost(string botName, [FromBody] BotRenameRequest request) { if (string.IsNullOrEmpty(botName) || (request == null)) { ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(request)); @@ -336,7 +346,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Resumes given bots. /// [HttpPost("{botNames:required}/Resume")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task> ResumePost(string botNames) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); @@ -359,7 +370,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Starts given bots. /// [HttpPost("{botNames:required}/Start")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task> StartPost(string botNames) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); @@ -382,7 +394,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Stops given bots. /// [HttpPost("{botNames:required}/Stop")] - [ProducesResponseType(typeof(GenericResponse), 200)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task> StopPost(string botNames) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); @@ -405,22 +418,25 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Accepts 2FA confirmations of given bots, requires ASF 2FA module to be active on them. /// [HttpPost("{botNames:required}/TwoFactorAuthentication/Confirmations/Accept")] - [ProducesResponseType(typeof(GenericResponse>), 200)] - public async Task>>> TwoFactorAuthenticationConfirmationsAcceptPost(string botNames) => await TwoFactorAuthenticationConfirmationsPost(botNames, true).ConfigureAwait(false); + [ProducesResponseType(typeof(GenericResponse>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public async Task> TwoFactorAuthenticationConfirmationsAcceptPost(string botNames) => await TwoFactorAuthenticationConfirmationsPost(botNames, true).ConfigureAwait(false); /// /// Denies 2FA confirmations of given bots, requires ASF 2FA module to be active on them. /// [HttpPost("{botNames:required}/TwoFactorAuthentication/Confirmations/Cancel")] - [ProducesResponseType(typeof(GenericResponse>), 200)] - public async Task>>> TwoFactorAuthenticationConfirmationsCancelPost(string botNames) => await TwoFactorAuthenticationConfirmationsPost(botNames, false).ConfigureAwait(false); + [ProducesResponseType(typeof(GenericResponse>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public async Task> TwoFactorAuthenticationConfirmationsCancelPost(string botNames) => await TwoFactorAuthenticationConfirmationsPost(botNames, false).ConfigureAwait(false); /// /// Fetches 2FA tokens of given bots, requires ASF 2FA module to be active on them. /// [HttpGet("{botNames:required}/TwoFactorAuthentication/Token")] - [ProducesResponseType(typeof(GenericResponse>>), 200)] - public async Task>>>> TwoFactorAuthenticationTokenGet(string botNames) { + [ProducesResponseType(typeof(GenericResponse>>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public async Task> TwoFactorAuthenticationTokenGet(string botNames) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); @@ -445,7 +461,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return Ok(new GenericResponse>>(result)); } - private async Task>>> TwoFactorAuthenticationConfirmationsPost(string botNames, bool accept) { + private async Task> TwoFactorAuthenticationConfirmationsPost(string botNames, bool accept) { if (string.IsNullOrEmpty(botNames)) { ASF.ArchiLogger.LogNullError(nameof(botNames)); diff --git a/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs b/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs index ee1176178..b8be77da2 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs @@ -21,6 +21,7 @@ using System; using System.Linq; +using System.Net; using System.Threading.Tasks; using ArchiSteamFarm.IPC.Responses; using ArchiSteamFarm.Localization; @@ -37,29 +38,30 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// You should use "given bot" commands when executing this endpoint, omitting targets of the command will cause the command to be executed on first defined bot /// [HttpPost("{command:required}")] - [ProducesResponseType(typeof(GenericResponse), 200)] - public async Task>> CommandPost(string command) { + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public async Task> CommandPost(string command) { if (string.IsNullOrEmpty(command)) { ASF.ArchiLogger.LogNullError(nameof(command)); - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(command)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(command)))); } if (ASF.GlobalConfig.SteamOwnerID == 0) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, nameof(ASF.GlobalConfig.SteamOwnerID)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, nameof(ASF.GlobalConfig.SteamOwnerID)))); } Bot targetBot = Bot.Bots.OrderBy(bot => bot.Key, Bot.BotsComparer).Select(bot => bot.Value).FirstOrDefault(); if (targetBot == null) { - return BadRequest(new GenericResponse(false, Strings.ErrorNoBotsDefined)); + return BadRequest(new GenericResponse(false, Strings.ErrorNoBotsDefined)); } if (!string.IsNullOrEmpty(ASF.GlobalConfig.CommandPrefix) && command.StartsWith(ASF.GlobalConfig.CommandPrefix, StringComparison.Ordinal)) { command = command.Substring(ASF.GlobalConfig.CommandPrefix.Length); if (string.IsNullOrEmpty(command)) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(command)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(command)))); } } diff --git a/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs b/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs index 1a1bdfdb8..a03ae30fb 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs @@ -22,6 +22,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Net.WebSockets; using System.Text; using System.Threading; @@ -44,7 +45,8 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// This API endpoint requires a websocket connection. /// [HttpGet] - [ProducesResponseType(typeof(IEnumerable>), 200)] + [ProducesResponseType(typeof(IEnumerable>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] public async Task NLogGet() { if (!HttpContext.WebSockets.IsWebSocketRequest) { return BadRequest(new GenericResponse(false, string.Format(Strings.WarningFailedWithError, nameof(HttpContext.WebSockets.IsWebSocketRequest) + ": " + HttpContext.WebSockets.IsWebSocketRequest))); diff --git a/ArchiSteamFarm/IPC/Controllers/Api/StructureController.cs b/ArchiSteamFarm/IPC/Controllers/Api/StructureController.cs index e4b565aa4..4e5f1845d 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/StructureController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/StructureController.cs @@ -20,6 +20,7 @@ // limitations under the License. using System; +using System.Net; using ArchiSteamFarm.IPC.Responses; using ArchiSteamFarm.Localization; using Microsoft.AspNetCore.Mvc; @@ -34,18 +35,19 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Structure is defined as a representation of given object in its default state. /// [HttpGet("{structure:required}")] - [ProducesResponseType(typeof(GenericResponse), 200)] - public ActionResult> StructureGet(string structure) { + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public ActionResult StructureGet(string structure) { if (string.IsNullOrEmpty(structure)) { ASF.ArchiLogger.LogNullError(nameof(structure)); - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(structure)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(structure)))); } Type targetType = WebUtilities.ParseType(structure); if (targetType == null) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, structure))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, structure))); } object obj; @@ -53,7 +55,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { try { obj = Activator.CreateInstance(targetType, true); } catch (Exception e) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorParsingObject, nameof(targetType)) + Environment.NewLine + e)); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorParsingObject, nameof(targetType)) + Environment.NewLine + e)); } return Ok(new GenericResponse(obj)); diff --git a/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs b/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs index e47ec96a9..0408b4c14 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Reflection; using ArchiSteamFarm.IPC.Responses; using ArchiSteamFarm.Localization; @@ -38,18 +39,19 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// Type info is defined as a representation of given object with its fields and properties being assigned to a string value that defines their type. /// [HttpGet("{type:required}")] - [ProducesResponseType(typeof(GenericResponse), 200)] - public ActionResult> TypeGet(string type) { + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + public ActionResult TypeGet(string type) { if (string.IsNullOrEmpty(type)) { ASF.ArchiLogger.LogNullError(nameof(type)); - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(type)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(type)))); } Type targetType = WebUtilities.ParseType(type); if (targetType == null) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, type))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, type))); } string baseType = targetType.BaseType?.GetUnifiedName(); diff --git a/ArchiSteamFarm/IPC/Controllers/Api/WWWController.cs b/ArchiSteamFarm/IPC/Controllers/Api/WWWController.cs index ad17d00cd..cbe894c48 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/WWWController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/WWWController.cs @@ -24,6 +24,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.IO; using System.Linq; +using System.Net; using System.Threading.Tasks; using ArchiSteamFarm.IPC.Requests; using ArchiSteamFarm.IPC.Responses; @@ -40,18 +41,20 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime. /// [HttpGet("Directory/{directory:required}")] - [ProducesResponseType(typeof(GenericResponse>), 200)] - public ActionResult>> DirectoryGet(string directory) { + [ProducesResponseType(typeof(GenericResponse>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.InternalServerError)] + public ActionResult DirectoryGet(string directory) { if (string.IsNullOrEmpty(directory)) { ASF.ArchiLogger.LogNullError(nameof(directory)); - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(directory)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(directory)))); } string directoryPath = Path.Combine(ArchiKestrel.WebsiteDirectory, directory); if (!Directory.Exists(directoryPath)) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsInvalid, directory))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, directory))); } string[] files; @@ -59,7 +62,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { try { files = Directory.GetFiles(directoryPath); } catch (Exception e) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorParsingObject, nameof(files)) + Environment.NewLine + e)); + return StatusCode((int) HttpStatusCode.InternalServerError, new GenericResponse(false, string.Format(Strings.ErrorParsingObject, nameof(files)) + Environment.NewLine + e)); } HashSet result = files.Select(Path.GetFileName).ToHashSet(); @@ -74,16 +77,18 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime. /// [HttpGet("GitHub/Releases")] - [ProducesResponseType(typeof(GenericResponse>), 200)] - public async Task>>> GitHubReleasesGet([FromQuery] byte count = 10) { + [ProducesResponseType(typeof(GenericResponse>), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.ServiceUnavailable)] + public async Task> GitHubReleasesGet([FromQuery] byte count = 10) { if (count == 0) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(count)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(count)))); } ImmutableList response = await GitHub.GetReleases(count).ConfigureAwait(false); if ((response == null) || (response.Count == 0)) { - return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries))); + return StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false, string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries))); } List result = response.Select(singleResponse => new GitHubReleaseResponse(singleResponse)).ToList(); @@ -98,19 +103,17 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime. /// [HttpGet("GitHub/Releases/{version:required}")] - [ProducesResponseType(typeof(GenericResponse), 200)] - public async Task>> GitHubReleasesGet(string version) { + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.ServiceUnavailable)] + public async Task> GitHubReleasesGet(string version) { if (string.IsNullOrEmpty(version)) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(version)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(version)))); } GitHub.ReleaseResponse releaseResponse = await GitHub.GetRelease(version).ConfigureAwait(false); - if (releaseResponse == null) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries))); - } - - return Ok(new GenericResponse(new GitHubReleaseResponse(releaseResponse))); + return releaseResponse != null ? Ok(new GenericResponse(new GitHubReleaseResponse(releaseResponse))) : StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false, string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries))); } /// @@ -121,25 +124,23 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { /// [Consumes("application/json")] [HttpPost("Send")] - [ProducesResponseType(typeof(GenericResponse), 200)] - public async Task>> SendPost([FromBody] WWWSendRequest request) { + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] + [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.ServiceUnavailable)] + public async Task> SendPost([FromBody] WWWSendRequest request) { if (request == null) { ASF.ArchiLogger.LogNullError(nameof(request)); - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(request)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(request)))); } if (string.IsNullOrEmpty(request.URL) || !Uri.TryCreate(request.URL, UriKind.Absolute, out Uri uri) || !uri.Scheme.Equals(Uri.UriSchemeHttps)) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, nameof(request.URL)))); + return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsInvalid, nameof(request.URL)))); } WebBrowser.StringResponse urlResponse = await ASF.WebBrowser.UrlGetToString(request.URL).ConfigureAwait(false); - if (urlResponse?.Content == null) { - return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries))); - } - - return Ok(new GenericResponse(urlResponse.Content)); + return urlResponse?.Content != null ? Ok(new GenericResponse(urlResponse.Content)) : StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false, string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries))); } } }