1
0
Fork 0
mirror of https://github.com/Jackett/Jackett synced 2025-02-28 17:05:40 +00:00

Add Authorization

This commit is contained in:
flightlevel 2018-05-12 12:44:47 +10:00
parent 615794a4bf
commit ce84264490
8 changed files with 100 additions and 62 deletions

View file

@ -1,6 +1,7 @@
using Jackett.Common.Models.Config; using Jackett.Common.Models.Config;
using Jackett.Common.Services.Interfaces; using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils; using Jackett.Common.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using NLog; using NLog;
@ -11,7 +12,7 @@ using System.Threading.Tasks;
namespace Jackett.Server.Controllers namespace Jackett.Server.Controllers
{ {
//[AllowAnonymous] [AllowAnonymous]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
[Route("bh/{indexerID}")] [Route("bh/{indexerID}")]
public class BlackholeController : Controller public class BlackholeController : Controller

View file

@ -2,6 +2,7 @@
using Jackett.Common.Models.Config; using Jackett.Common.Models.Config;
using Jackett.Common.Services.Interfaces; using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils; using Jackett.Common.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using NLog; using NLog;
@ -11,7 +12,7 @@ using System.Threading.Tasks;
namespace Jackett.Server.Controllers namespace Jackett.Server.Controllers
{ {
//[AllowAnonymous] [AllowAnonymous]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
[Route("dl/{indexerID}")] [Route("dl/{indexerID}")]
public class DownloadController : Controller public class DownloadController : Controller

View file

@ -54,7 +54,6 @@ namespace Jackett.Server.Controllers
} }
[Route("api/v2.0/indexers")] [Route("api/v2.0/indexers")]
//[JackettAuthorized]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public class IndexerApiController : Controller, IIndexerController public class IndexerApiController : Controller, IIndexerController
{ {

View file

@ -5,6 +5,7 @@ using Jackett.Common.Models;
using Jackett.Common.Models.DTO; using Jackett.Common.Models.DTO;
using Jackett.Common.Services.Interfaces; using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils; using Jackett.Common.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using NLog; using NLog;
@ -155,7 +156,7 @@ namespace Jackett.Server.Controllers
TorznabQuery CurrentQuery { get; set; } TorznabQuery CurrentQuery { get; set; }
} }
//[AllowAnonymous] [AllowAnonymous]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
[Route("api/v2.0/indexers/{indexerId}/results")] [Route("api/v2.0/indexers/{indexerId}/results")]
[TypeFilter(typeof(RequiresApiKey))] [TypeFilter(typeof(RequiresApiKey))]
@ -166,6 +167,9 @@ namespace Jackett.Server.Controllers
public IIndexerManagerService IndexerService { get; private set; } public IIndexerManagerService IndexerService { get; private set; }
public IIndexer CurrentIndexer { get; set; } public IIndexer CurrentIndexer { get; set; }
public TorznabQuery CurrentQuery { get; set; } public TorznabQuery CurrentQuery { get; set; }
private Logger logger;
private IServerService serverService;
private ICacheService cacheService;
public ResultsController(IIndexerManagerService indexerManagerService, IServerService ss, ICacheService c, Logger logger) public ResultsController(IIndexerManagerService indexerManagerService, IServerService ss, ICacheService c, Logger logger)
{ {
@ -481,8 +485,5 @@ namespace Jackett.Server.Controllers
} }
} }
private Logger logger;
private IServerService serverService;
private ICacheService cacheService;
} }
} }

View file

@ -12,7 +12,6 @@ using System.Linq;
namespace Jackett.Server.Controllers namespace Jackett.Server.Controllers
{ {
[Route("api/v2.0/server/[action]")] [Route("api/v2.0/server/[action]")]
//[JackettAuthorized]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public class ServerConfigurationController : Controller public class ServerConfigurationController : Controller
{ {

View file

@ -1,18 +1,19 @@
using Jackett.Common.Models.Config; using Jackett.Common.Models.Config;
using Jackett.Common.Services.Interfaces; using Jackett.Common.Services.Interfaces;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MimeMapping;
using NLog; using NLog;
using System.IO; using System;
using System.Net; using System.Collections.Generic;
using System.Net.Http; using System.Linq;
using System.Net.Http.Headers; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jackett.Server.Controllers namespace Jackett.Server.Controllers
{ {
[Route("UI/[action]")] [Route("UI/[action]")]
//[JackettAuthorized]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public class WebUIController : Controller public class WebUIController : Controller
{ {
@ -29,66 +30,76 @@ namespace Jackett.Server.Controllers
logger = l; logger = l;
} }
private HttpResponseMessage GetFile(string path) [HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login()
{ {
var result = new HttpResponseMessage(HttpStatusCode.OK); if (string.IsNullOrEmpty(serverConfig.AdminPassword))
var mappedPath = Path.Combine(config.GetContentFolder(), path); {
var stream = new FileStream(mappedPath, FileMode.Open, FileAccess.Read, FileShare.Read); await MakeUserAuthenticated();
result.Content = new StreamContent(stream); }
result.Content.Headers.ContentType = new MediaTypeHeaderValue(MimeUtility.GetMimeMapping(mappedPath));
return result; if (User.Identity.IsAuthenticated)
{
return Redirect("Dashboard");
}
return new PhysicalFileResult(config.GetContentFolder() + "/login.html", "text/html"); ;
} }
[HttpGet] [HttpGet]
//[AllowAnonymous] [AllowAnonymous]
public IActionResult Logout() public async Task<IActionResult> Logout()
{ {
var ctx = Request.HttpContext; await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
//TODO return Redirect("Login");
//var authManager = ctx.Authentication; }
//authManager.SignOut("ApplicationCookie");
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Dashboard([FromForm] string password)
{
if (password != null && securityService.HashPassword(password) == serverConfig.AdminPassword)
{
await MakeUserAuthenticated();
}
return Redirect("Dashboard"); return Redirect("Dashboard");
} }
[HttpGet] [HttpGet]
[HttpPost]
//[AllowAnonymous]
public IActionResult Dashboard() public IActionResult Dashboard()
{ {
var result = new PhysicalFileResult(config.GetContentFolder() + "/index.html", "text/html"); bool logout = HttpContext.Request.Query.Where(x => String.Equals(x.Key, "logout", StringComparison.OrdinalIgnoreCase)
return result; && String.Equals(x.Value, "true", StringComparison.OrdinalIgnoreCase)).Any();
if (logout)
{
return Redirect("Logout");
}
//if (Request.Path != null && Request.Path.ToString().Contains("logout")) return new PhysicalFileResult(config.GetContentFolder() + "/index.html", "text/html");
//{ }
// var file = GetFile("login.html");
// securityService.Logout(file);
// return file;
//}
//TODO //TODO: Move this to security service once off Mono
private async Task MakeUserAuthenticated()
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "Jackett", ClaimValueTypes.String)
};
//if (securityService.CheckAuthorised(Request)) var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
//{
//return GetFile("index.html");
//} await HttpContext.SignInAsync(
//else CookieAuthenticationDefaults.AuthenticationScheme,
//{ new ClaimsPrincipal(claimsIdentity),
// var formData = await Request.ReadFormAsync(); new AuthenticationProperties
{
// if (formData != null && securityService.HashPassword(formData["password"]) == serverConfig.AdminPassword) ExpiresUtc = DateTime.UtcNow.AddMinutes(20),
// { IsPersistent = false,
// var file = GetFile("index.html"); AllowRefresh = true
// securityService.Login(file); });
// return file;
// }
// else
// {
// return GetFile("login.html");
// }
//}
} }
} }
} }

View file

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite; using Microsoft.AspNetCore.Rewrite;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using System;
namespace Jackett.Server.Middleware namespace Jackett.Server.Middleware
{ {
@ -8,9 +9,10 @@ namespace Jackett.Server.Middleware
{ {
public static void RedirectToDashboard(RewriteContext context) public static void RedirectToDashboard(RewriteContext context)
{ {
var request = context.HttpContext.Request; HttpRequest request = context.HttpContext.Request;
if (request.Path == null || string.IsNullOrWhiteSpace(request.Path.ToString()) || request.Path.ToString() == "/") if (request.Path == null || string.IsNullOrWhiteSpace(request.Path.ToString()) || request.Path.ToString() == "/"
|| request.Path.ToString().Equals("/index.html", StringComparison.OrdinalIgnoreCase))
{ {
// 301 is the status code of permanent redirect // 301 is the status code of permanent redirect
var redir = Initialisation.ServerService.BasePath() + "/UI/Dashboard"; var redir = Initialisation.ServerService.BasePath() + "/UI/Dashboard";

View file

@ -5,8 +5,12 @@ using Jackett.Common.Plumbing;
using Jackett.Common.Services.Interfaces; using Jackett.Common.Services.Interfaces;
using Jackett.Server.Middleware; using Jackett.Server.Middleware;
using Jackett.Server.Services; using Jackett.Server.Services;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Rewrite; using Microsoft.AspNetCore.Rewrite;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -29,9 +33,27 @@ namespace Jackett.Server
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services) public IServiceProvider ConfigureServices(IServiceCollection services)
{ {
services services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddMvc() .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver()); //Web app uses Pascal Case JSON options =>
{
options.LoginPath = new PathString("/UI/Login");
options.AccessDeniedPath = new PathString("/UI/Login");
options.LogoutPath = new PathString("/UI/Logout");
options.Cookie.Name = "Jackett";
});
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
})
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver(); //Web app uses Pascal Case JSON
});
RuntimeSettings runtimeSettings = new RuntimeSettings(); RuntimeSettings runtimeSettings = new RuntimeSettings();
Configuration.GetSection("RuntimeSettings").Bind(runtimeSettings); Configuration.GetSection("RuntimeSettings").Bind(runtimeSettings);
@ -77,6 +99,8 @@ namespace Jackett.Server
EnableDirectoryBrowsing = false EnableDirectoryBrowsing = false
}); });
app.UseAuthentication();
app.UseMvc(); app.UseMvc();
} }
} }