mirror of
https://github.com/Jackett/Jackett
synced 2025-02-28 08:55:39 +00:00
Add Authorization
This commit is contained in:
parent
615794a4bf
commit
ce84264490
8 changed files with 100 additions and 62 deletions
|
@ -1,6 +1,7 @@
|
|||
using Jackett.Common.Models.Config;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
|
@ -11,7 +12,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Jackett.Server.Controllers
|
||||
{
|
||||
//[AllowAnonymous]
|
||||
[AllowAnonymous]
|
||||
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
[Route("bh/{indexerID}")]
|
||||
public class BlackholeController : Controller
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using Jackett.Common.Models.Config;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using NLog;
|
||||
|
@ -11,7 +12,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Jackett.Server.Controllers
|
||||
{
|
||||
//[AllowAnonymous]
|
||||
[AllowAnonymous]
|
||||
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
[Route("dl/{indexerID}")]
|
||||
public class DownloadController : Controller
|
||||
|
|
|
@ -54,7 +54,6 @@ namespace Jackett.Server.Controllers
|
|||
}
|
||||
|
||||
[Route("api/v2.0/indexers")]
|
||||
//[JackettAuthorized]
|
||||
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public class IndexerApiController : Controller, IIndexerController
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ using Jackett.Common.Models;
|
|||
using Jackett.Common.Models.DTO;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Common.Utils;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using NLog;
|
||||
|
@ -155,7 +156,7 @@ namespace Jackett.Server.Controllers
|
|||
TorznabQuery CurrentQuery { get; set; }
|
||||
}
|
||||
|
||||
//[AllowAnonymous]
|
||||
[AllowAnonymous]
|
||||
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
[Route("api/v2.0/indexers/{indexerId}/results")]
|
||||
[TypeFilter(typeof(RequiresApiKey))]
|
||||
|
@ -166,6 +167,9 @@ namespace Jackett.Server.Controllers
|
|||
public IIndexerManagerService IndexerService { get; private set; }
|
||||
public IIndexer CurrentIndexer { 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)
|
||||
{
|
||||
|
@ -481,8 +485,5 @@ namespace Jackett.Server.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
private Logger logger;
|
||||
private IServerService serverService;
|
||||
private ICacheService cacheService;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ using System.Linq;
|
|||
namespace Jackett.Server.Controllers
|
||||
{
|
||||
[Route("api/v2.0/server/[action]")]
|
||||
//[JackettAuthorized]
|
||||
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public class ServerConfigurationController : Controller
|
||||
{
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
using Jackett.Common.Models.Config;
|
||||
using Jackett.Common.Services.Interfaces;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MimeMapping;
|
||||
using NLog;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.Server.Controllers
|
||||
{
|
||||
[Route("UI/[action]")]
|
||||
//[JackettAuthorized]
|
||||
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public class WebUIController : Controller
|
||||
{
|
||||
|
@ -29,66 +30,76 @@ namespace Jackett.Server.Controllers
|
|||
logger = l;
|
||||
}
|
||||
|
||||
private HttpResponseMessage GetFile(string path)
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Login()
|
||||
{
|
||||
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
||||
var mappedPath = Path.Combine(config.GetContentFolder(), path);
|
||||
var stream = new FileStream(mappedPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
result.Content = new StreamContent(stream);
|
||||
result.Content.Headers.ContentType = new MediaTypeHeaderValue(MimeUtility.GetMimeMapping(mappedPath));
|
||||
if (string.IsNullOrEmpty(serverConfig.AdminPassword))
|
||||
{
|
||||
await MakeUserAuthenticated();
|
||||
}
|
||||
|
||||
return result;
|
||||
if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
return Redirect("Dashboard");
|
||||
}
|
||||
|
||||
return new PhysicalFileResult(config.GetContentFolder() + "/login.html", "text/html"); ;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
//[AllowAnonymous]
|
||||
public IActionResult Logout()
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Logout()
|
||||
{
|
||||
var ctx = Request.HttpContext;
|
||||
//TODO
|
||||
//var authManager = ctx.Authentication;
|
||||
//authManager.SignOut("ApplicationCookie");
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
return Redirect("Login");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Dashboard([FromForm] string password)
|
||||
{
|
||||
if (password != null && securityService.HashPassword(password) == serverConfig.AdminPassword)
|
||||
{
|
||||
await MakeUserAuthenticated();
|
||||
}
|
||||
|
||||
return Redirect("Dashboard");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[HttpPost]
|
||||
//[AllowAnonymous]
|
||||
public IActionResult Dashboard()
|
||||
{
|
||||
var result = new PhysicalFileResult(config.GetContentFolder() + "/index.html", "text/html");
|
||||
return result;
|
||||
bool logout = HttpContext.Request.Query.Where(x => String.Equals(x.Key, "logout", StringComparison.OrdinalIgnoreCase)
|
||||
&& String.Equals(x.Value, "true", StringComparison.OrdinalIgnoreCase)).Any();
|
||||
|
||||
if (logout)
|
||||
{
|
||||
return Redirect("Logout");
|
||||
}
|
||||
|
||||
//if (Request.Path != null && Request.Path.ToString().Contains("logout"))
|
||||
//{
|
||||
// var file = GetFile("login.html");
|
||||
// securityService.Logout(file);
|
||||
// return file;
|
||||
//}
|
||||
return new PhysicalFileResult(config.GetContentFolder() + "/index.html", "text/html");
|
||||
}
|
||||
|
||||
//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))
|
||||
//{
|
||||
//return GetFile("index.html");
|
||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// var formData = await Request.ReadFormAsync();
|
||||
|
||||
// if (formData != null && securityService.HashPassword(formData["password"]) == serverConfig.AdminPassword)
|
||||
// {
|
||||
// var file = GetFile("index.html");
|
||||
// securityService.Login(file);
|
||||
// return file;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return GetFile("login.html");
|
||||
// }
|
||||
//}
|
||||
await HttpContext.SignInAsync(
|
||||
CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
new ClaimsPrincipal(claimsIdentity),
|
||||
new AuthenticationProperties
|
||||
{
|
||||
ExpiresUtc = DateTime.UtcNow.AddMinutes(20),
|
||||
IsPersistent = false,
|
||||
AllowRefresh = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Rewrite;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using System;
|
||||
|
||||
namespace Jackett.Server.Middleware
|
||||
{
|
||||
|
@ -8,9 +9,10 @@ namespace Jackett.Server.Middleware
|
|||
{
|
||||
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
|
||||
var redir = Initialisation.ServerService.BasePath() + "/UI/Dashboard";
|
||||
|
|
|
@ -5,8 +5,12 @@ using Jackett.Common.Plumbing;
|
|||
using Jackett.Common.Services.Interfaces;
|
||||
using Jackett.Server.Middleware;
|
||||
using Jackett.Server.Services;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.AspNetCore.Rewrite;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
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.
|
||||
public IServiceProvider ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.AddMvc()
|
||||
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver()); //Web app uses Pascal Case JSON
|
||||
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
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();
|
||||
Configuration.GetSection("RuntimeSettings").Bind(runtimeSettings);
|
||||
|
@ -77,6 +99,8 @@ namespace Jackett.Server
|
|||
EnableDirectoryBrowsing = false
|
||||
});
|
||||
|
||||
app.UseAuthentication();
|
||||
|
||||
app.UseMvc();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue