diff --git a/src/Ombi/Startup.cs b/src/Ombi/Startup.cs index 6a9c8c4eb..09b5f382b 100644 --- a/src/Ombi/Startup.cs +++ b/src/Ombi/Startup.cs @@ -1,7 +1,10 @@ using System; using System.IO; +using System.Linq; +using System.Net; using System.Security.Principal; using System.Text; +using System.Threading.Tasks; using AutoMapper; using AutoMapper.EquivalencyExpression; using Hangfire; @@ -27,11 +30,13 @@ using Microsoft.Extensions.PlatformAbstractions; using Microsoft.IdentityModel.Tokens; using Ombi.Config; using Ombi.Core.Claims; +using Ombi.Core.Settings; using Ombi.DependencyInjection; using Ombi.Helpers; using Ombi.Mapping; using Ombi.Models.Identity; using Ombi.Schedule; +using Ombi.Settings.Settings.Models; using Ombi.Store.Context; using Ombi.Store.Entities; using Serilog; @@ -63,7 +68,7 @@ namespace Ombi if (env.IsProduction()) { Log.Logger = new LoggerConfiguration() - .MinimumLevel.Information() + .MinimumLevel.Debug() .WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "Logs", "log-{Date}.txt")) .WriteTo.SQLite("Ombi.db", "Logs", LogEventLevel.Debug) .CreateLogger(); @@ -245,6 +250,8 @@ namespace Ombi app.UseAuthentication(); + //ApiKeyMiddlewear(app, serviceProvider); + app.UseMvc(routes => { routes.MapRoute( @@ -256,6 +263,50 @@ namespace Ombi defaults: new { controller = "Home", action = "Index" }); }); } + + private static void ApiKeyMiddlewear(IApplicationBuilder app, IServiceProvider serviceProvider) + { + app.Use(async (context, next) => + { + if (context.Request.Path.StartsWithSegments(new PathString("/api"))) + { + // Let's check if this is an API Call + if (context.Request.Headers["ApiKey"].Any()) + { + // validate the supplied API key + // Validate it + var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault(); + var settingsProvider = serviceProvider.GetService>(); + var ombiSettings = settingsProvider.GetSettings(); + var valid = ombiSettings.ApiKey.Equals(headerKey, StringComparison.CurrentCultureIgnoreCase); + if (!valid) + { + context.Response.StatusCode = (int) HttpStatusCode.Unauthorized; + await context.Response.WriteAsync("Invalid API Key"); + } + else + { + var identity = new GenericIdentity("API"); + identity.AddClaim(new System.Security.Claims.Claim("Origin", "Api")); + identity.AddClaim(new System.Security.Claims.Claim("role", "Admin")); + + var principal = new GenericPrincipal(identity, new[] {"ApiUser"}); + // TODO need to think about if I require a JWT Token here. + context.User = principal; + await next(); + } + } + else + { + await next(); + } + } + else + { + await next(); + } + }); + } } public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter diff --git a/src/Ombi/package-lock.json b/src/Ombi/package-lock.json index 3f1ffa300..62dcd0404 100644 --- a/src/Ombi/package-lock.json +++ b/src/Ombi/package-lock.json @@ -4972,7 +4972,6 @@ "resolved": "https://registry.npmjs.org/npm/-/npm-5.4.2.tgz", "integrity": "sha512-F6LLCAHriKyKQ9Ff03UKCjkXZoRBp281I42K42+VeHfjAXZ3TJdg3RccinzoCFV1kDxCedVm7AstIpb1Uf5UkQ==", "requires": { - "JSONStream": "1.3.1", "abbrev": "1.1.0", "ansi-regex": "3.0.0", "ansicolors": "0.3.2", @@ -5002,6 +5001,7 @@ "inherits": "2.0.3", "ini": "1.3.4", "init-package-json": "1.10.1", + "JSONStream": "1.3.1", "lazy-property": "1.0.0", "libnpx": "9.6.0", "lockfile": "1.0.3", @@ -5072,24 +5072,6 @@ "write-file-atomic": "2.1.0" }, "dependencies": { - "JSONStream": { - "version": "1.3.1", - "bundled": true, - "requires": { - "jsonparse": "1.3.1", - "through": "2.3.8" - }, - "dependencies": { - "jsonparse": { - "version": "1.3.1", - "bundled": true - }, - "through": { - "version": "2.3.8", - "bundled": true - } - } - }, "abbrev": { "version": "1.1.0", "bundled": true @@ -5389,6 +5371,24 @@ } } }, + "JSONStream": { + "version": "1.3.1", + "bundled": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + }, + "dependencies": { + "jsonparse": { + "version": "1.3.1", + "bundled": true + }, + "through": { + "version": "2.3.8", + "bundled": true + } + } + }, "lazy-property": { "version": "1.0.0", "bundled": true @@ -10036,6 +10036,14 @@ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -10046,14 +10054,6 @@ "strip-ansi": "3.0.1" } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",