From ad5bb5b49af49c4668fd30fb2a0e606dcefe4ec0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Oct 2017 19:39:13 -0400 Subject: proxy Pastebin requests through our API instead of third parties, improve error-handling (#358) --- .../Framework/ConfigModels/LogParserConfig.cs | 18 ++++++++++++++++++ .../Framework/ConfigModels/ModUpdateCheckConfig.cs | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs (limited to 'src/SMAPI.Web/Framework/ConfigModels') diff --git a/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs new file mode 100644 index 00000000..5cb0cf95 --- /dev/null +++ b/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs @@ -0,0 +1,18 @@ +namespace StardewModdingAPI.Web.Framework.ConfigModels +{ + /// The config settings for the log parser. + internal class LogParserConfig + { + /********* + ** Accessors + *********/ + /// The base URL for the Pastebin API. + public string PastebinBaseUrl { get; set; } + + /// The user agent for the Pastebin API client, where {0} is the SMAPI version. + public string PastebinUserAgent { get; set; } + + /// The developer key used to authenticate with the Pastebin API. + public string PastebinDevKey { get; set; } + } +} diff --git a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs index 03de639e..2fb5b97e 100644 --- a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs +++ b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs @@ -1,7 +1,7 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels { /// The config settings for mod update checks. - public class ModUpdateCheckConfig + internal class ModUpdateCheckConfig { /********* ** Accessors -- cgit From 3f43ebcc0e31db523fa82a163374cebf2f577cde Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Oct 2017 21:10:36 -0400 Subject: fix issues with subdomain routing in log UI (#358) --- src/SMAPI.Web/Controllers/LogParserController.cs | 12 ++++++---- .../Framework/ConfigModels/LogParserConfig.cs | 3 +++ src/SMAPI.Web/Framework/RewriteSubdomainRule.cs | 22 ++++++++++++++++-- src/SMAPI.Web/Startup.cs | 9 +++++++- src/SMAPI.Web/ViewModels/LogParserModel.cs | 26 ++++++++++++++++++++++ src/SMAPI.Web/Views/LogParser/Index.cshtml | 6 +++++ src/SMAPI.Web/appsettings.Development.json | 5 ++++- src/SMAPI.Web/appsettings.json | 1 + src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 9 ++++---- 9 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 src/SMAPI.Web/ViewModels/LogParserModel.cs (limited to 'src/SMAPI.Web/Framework/ConfigModels') diff --git a/src/SMAPI.Web/Controllers/LogParserController.cs b/src/SMAPI.Web/Controllers/LogParserController.cs index 893d9a52..ee1d51cd 100644 --- a/src/SMAPI.Web/Controllers/LogParserController.cs +++ b/src/SMAPI.Web/Controllers/LogParserController.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Options; using StardewModdingAPI.Web.Framework; using StardewModdingAPI.Web.Framework.ConfigModels; using StardewModdingAPI.Web.Framework.LogParser; +using StardewModdingAPI.Web.ViewModels; namespace StardewModdingAPI.Web.Controllers { @@ -13,6 +14,9 @@ namespace StardewModdingAPI.Web.Controllers /********* ** Properties *********/ + /// The log parser config settings. + private readonly LogParserConfig Config; + /// The underlying Pastebin client. private readonly PastebinClient PastebinClient; @@ -28,10 +32,10 @@ namespace StardewModdingAPI.Web.Controllers public LogParserController(IOptions configProvider) { // init Pastebin client - LogParserConfig config = configProvider.Value; + this.Config = configProvider.Value; string version = this.GetType().Assembly.GetName().Version.ToString(3); - string userAgent = string.Format(config.PastebinUserAgent, version); - this.PastebinClient = new PastebinClient(config.PastebinBaseUrl, userAgent, config.PastebinDevKey); + string userAgent = string.Format(this.Config.PastebinUserAgent, version); + this.PastebinClient = new PastebinClient(this.Config.PastebinBaseUrl, userAgent, this.Config.PastebinDevKey); } /*** @@ -42,7 +46,7 @@ namespace StardewModdingAPI.Web.Controllers [Route("log")] public ViewResult Index() { - return this.View("Index"); + return this.View("Index", new LogParserModel(this.Config.SectionUrl)); } /*** diff --git a/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs index 5cb0cf95..18d8ff05 100644 --- a/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs +++ b/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs @@ -6,6 +6,9 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels /********* ** Accessors *********/ + /// The root URL for the log parser controller. + public string SectionUrl { get; set; } + /// The base URL for the Pastebin API. public string PastebinBaseUrl { get; set; } diff --git a/src/SMAPI.Web/Framework/RewriteSubdomainRule.cs b/src/SMAPI.Web/Framework/RewriteSubdomainRule.cs index 5a56844f..cc183fe3 100644 --- a/src/SMAPI.Web/Framework/RewriteSubdomainRule.cs +++ b/src/SMAPI.Web/Framework/RewriteSubdomainRule.cs @@ -1,4 +1,7 @@ using System; +using System.Linq; +using System.Text.RegularExpressions; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Rewrite; namespace StardewModdingAPI.Web.Framework @@ -7,14 +10,29 @@ namespace StardewModdingAPI.Web.Framework /// Derived from . internal class RewriteSubdomainRule : IRule { + /********* + ** Accessors + *********/ + /// The paths (excluding the hostname portion) to not rewrite. + public Regex[] ExceptPaths { get; set; } + + + /********* + ** Public methods + *********/ /// Applies the rule. Implementations of ApplyRule should set the value for (defaults to RuleResult.ContinueRules). /// The rewrite context. public void ApplyRule(RewriteContext context) { context.Result = RuleResult.ContinueRules; + HttpRequest request = context.HttpContext.Request; + + // check ignores + if (this.ExceptPaths?.Any(pattern => pattern.IsMatch(request.Path)) == true) + return; // get host parts - string host = context.HttpContext.Request.Host.Host; + string host = request.Host.Host; string[] parts = host.Split('.'); // validate @@ -24,7 +42,7 @@ namespace StardewModdingAPI.Web.Framework return; // prepend to path - context.HttpContext.Request.Path = $"/{parts[0]}{context.HttpContext.Request.Path}"; + request.Path = $"/{parts[0]}{request.Path}"; } } } diff --git a/src/SMAPI.Web/Startup.cs b/src/SMAPI.Web/Startup.cs index c0ea90da..e19593c7 100644 --- a/src/SMAPI.Web/Startup.cs +++ b/src/SMAPI.Web/Startup.cs @@ -1,3 +1,4 @@ +using System.Text.RegularExpressions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Rewrite; @@ -64,7 +65,13 @@ namespace StardewModdingAPI.Web loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app - .UseRewriter(new RewriteOptions().Add(new RewriteSubdomainRule())) // convert subdomain.smapi.io => smapi.io/subdomain for routing + .UseRewriter( + new RewriteOptions() + .Add(new RewriteSubdomainRule + { + ExceptPaths = new[] { new Regex("^/Content", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase) } + }) + ) // convert subdomain.smapi.io => smapi.io/subdomain for routing .UseStaticFiles() // wwwroot folder .UseMvc(); } diff --git a/src/SMAPI.Web/ViewModels/LogParserModel.cs b/src/SMAPI.Web/ViewModels/LogParserModel.cs new file mode 100644 index 00000000..ba31db87 --- /dev/null +++ b/src/SMAPI.Web/ViewModels/LogParserModel.cs @@ -0,0 +1,26 @@ +namespace StardewModdingAPI.Web.ViewModels +{ + /// The view model for the log parser page. + public class LogParserModel + { + /********* + ** Accessors + *********/ + /// The root URL for the log parser controller. + public string SectionUrl { get; set; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + public LogParserModel() { } + + /// Construct an instance. + /// The root URL for the log parser controller. + public LogParserModel(string sectionUrl) + { + this.SectionUrl = sectionUrl; + } + } +} diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index 87a3962b..bd47f2ff 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -1,12 +1,18 @@ @{ ViewData["Title"] = "SMAPI log parser"; } +@model StardewModdingAPI.Web.ViewModels.LogParserModel @section Head { + } @********* diff --git a/src/SMAPI.Web/appsettings.Development.json b/src/SMAPI.Web/appsettings.Development.json index fa8ce71a..e49eabb7 100644 --- a/src/SMAPI.Web/appsettings.Development.json +++ b/src/SMAPI.Web/appsettings.Development.json @@ -1,4 +1,4 @@ -{ +{ "Logging": { "IncludeScopes": false, "LogLevel": { @@ -6,5 +6,8 @@ "System": "Information", "Microsoft": "Information" } + }, + "LogParser": { + "SectionUrl": "http://localhost:59482/log/" } } diff --git a/src/SMAPI.Web/appsettings.json b/src/SMAPI.Web/appsettings.json index ca1299ce..1b5c35cd 100644 --- a/src/SMAPI.Web/appsettings.json +++ b/src/SMAPI.Web/appsettings.json @@ -28,6 +28,7 @@ "NexusModUrlFormat": "mods/{0}" }, "LogParser": { + "SectionUrl": "https://log.smapi.io/", "PastebinBaseUrl": "https://pastebin.com/", "PastebinUserAgent": "SMAPI/{0} (+https://github.com/Pathoschild/SMAPI)", "PastebinDevKey": "b8219d942109d1e60ebb14fbb45f06f9" diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index b1f8f5c6..3949fabe 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -1,6 +1,7 @@ /* globals $, LZString */ -$(function() { +var smapi = smapi || {}; +smapi.logParser = function(sectionUrl) { /********* ** Initialisation *********/ @@ -75,7 +76,7 @@ $(function() { $ .ajax({ type: "POST", - url: "/log/save", + url: sectionUrl + "/save", data: JSON.stringify(paste), contentType: "application/json" // sent to API }) @@ -273,7 +274,7 @@ $(function() { function getData() { $("#uploader").attr("data-text", "Loading..."); $("#uploader").fadeIn(); - $.get("/log/fetch/" + location.search.substring(1), function(data) { + $.get(sectionUrl + "/fetch/" + location.search.substring(1), function(data) { if (data.success) { $("#input").val(LZString.decompressFromUTF16(data.content) || data.content); loadData(); @@ -284,4 +285,4 @@ $(function() { $("#uploader").fadeOut(); }); } -}); +}; -- cgit From 790a62920b15f1f948724f5b2a70a937829355dd Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 28 Oct 2017 14:05:29 -0400 Subject: link pastes to Pastebin account & tweak paste options (#358) --- src/SMAPI.Web/Controllers/LogParserController.cs | 2 +- src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs | 3 +++ src/SMAPI.Web/Framework/LogParser/PastebinClient.cs | 17 ++++++++++++----- src/SMAPI.Web/appsettings.Development.json | 1 + src/SMAPI.Web/appsettings.json | 1 + 5 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/SMAPI.Web/Framework/ConfigModels') diff --git a/src/SMAPI.Web/Controllers/LogParserController.cs b/src/SMAPI.Web/Controllers/LogParserController.cs index f9943707..8e986196 100644 --- a/src/SMAPI.Web/Controllers/LogParserController.cs +++ b/src/SMAPI.Web/Controllers/LogParserController.cs @@ -35,7 +35,7 @@ namespace StardewModdingAPI.Web.Controllers this.Config = configProvider.Value; string version = this.GetType().Assembly.GetName().Version.ToString(3); string userAgent = string.Format(this.Config.PastebinUserAgent, version); - this.PastebinClient = new PastebinClient(this.Config.PastebinBaseUrl, userAgent, this.Config.PastebinDevKey); + this.PastebinClient = new PastebinClient(this.Config.PastebinBaseUrl, userAgent, this.Config.PastebinUserKey, this.Config.PastebinDevKey); } /*** diff --git a/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs index 18d8ff05..df5d605d 100644 --- a/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs +++ b/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs @@ -15,6 +15,9 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels /// The user agent for the Pastebin API client, where {0} is the SMAPI version. public string PastebinUserAgent { get; set; } + /// The user key used to authenticate with the Pastebin API. + public string PastebinUserKey { get; set; } + /// The developer key used to authenticate with the Pastebin API. public string PastebinDevKey { get; set; } } diff --git a/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs b/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs index e45a9eed..738330d3 100644 --- a/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs +++ b/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs @@ -17,6 +17,9 @@ namespace StardewModdingAPI.Web.Framework.LogParser /// The underlying HTTP client. private readonly IClient Client; + /// The user key used to authenticate with the Pastebin API. + private readonly string UserKey; + /// The developer key used to authenticate with the Pastebin API. private readonly string DevKey; @@ -27,10 +30,12 @@ namespace StardewModdingAPI.Web.Framework.LogParser /// Construct an instance. /// The base URL for the Pastebin API. /// The user agent for the API client. + /// The user key used to authenticate with the Pastebin API. /// The developer key used to authenticate with the Pastebin API. - public PastebinClient(string baseUrl, string userAgent, string devKey) + public PastebinClient(string baseUrl, string userAgent, string userKey, string devKey) { this.Client = new FluentClient(baseUrl).SetUserAgent(userAgent); + this.UserKey = userKey; this.DevKey = devKey; } @@ -75,11 +80,13 @@ namespace StardewModdingAPI.Web.Framework.LogParser .PostAsync("api/api_post.php") .WithBodyContent(new FormUrlEncodedContent(new Dictionary { - ["api_dev_key"] = this.DevKey, ["api_option"] = "paste", - ["api_paste_private"] = "1", - ["api_paste_code"] = content, - ["api_paste_expire_date"] = "1W" + ["api_user_key"] = this.UserKey, + ["api_dev_key"] = this.DevKey, + ["api_paste_private"] = "1", // unlisted + ["api_paste_name"] = $"SMAPI log {DateTime.UtcNow:s}", + ["api_paste_expire_date"] = "1W", // one week + ["api_paste_code"] = content })) .AsString(); diff --git a/src/SMAPI.Web/appsettings.Development.json b/src/SMAPI.Web/appsettings.Development.json index 1080ee00..87c35ca9 100644 --- a/src/SMAPI.Web/appsettings.Development.json +++ b/src/SMAPI.Web/appsettings.Development.json @@ -22,6 +22,7 @@ }, "LogParser": { "SectionUrl": "http://localhost:59482/log/", + "PastebinUserKey": null, "PastebinDevKey": null } } diff --git a/src/SMAPI.Web/appsettings.json b/src/SMAPI.Web/appsettings.json index 397765eb..eb6ecc9b 100644 --- a/src/SMAPI.Web/appsettings.json +++ b/src/SMAPI.Web/appsettings.json @@ -39,6 +39,7 @@ "SectionUrl": null, // see top note "PastebinBaseUrl": "https://pastebin.com/", "PastebinUserAgent": "SMAPI/{0} (+https://github.com/Pathoschild/SMAPI)", + "PastebinUserKey": null, // see top note "PastebinDevKey": null // see top note } } -- cgit