mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Refactor controllers for ASP.NET Core (Authentication disabled for now)
This commit is contained in:
@@ -1,39 +1,37 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
using Jackett.Common.Models.Config;
|
||||||
|
using Jackett.Common.Services.Interfaces;
|
||||||
|
using Jackett.Common.Utils;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
|
||||||
using System.Web.Http;
|
|
||||||
using Jackett.Common.Models.Config;
|
|
||||||
using Jackett.Common.Services.Interfaces;
|
|
||||||
using Jackett.Common.Utils;
|
|
||||||
|
|
||||||
namespace Jackett.Controllers
|
namespace Jackett.Server.Controllers
|
||||||
{
|
{
|
||||||
[AllowAnonymous]
|
//[AllowAnonymous]
|
||||||
[JackettAPINoCache]
|
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public class BlackholeController : ApiController
|
[Route("bh/{indexerID}")]
|
||||||
|
public class BlackholeController : Controller
|
||||||
{
|
{
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
private IIndexerManagerService indexerService;
|
private IIndexerManagerService indexerService;
|
||||||
private readonly ServerConfig serverConfig;
|
private readonly ServerConfig serverConfig;
|
||||||
IProtectionService protectionService;
|
private IProtectionService protectionService;
|
||||||
|
|
||||||
public BlackholeController(IIndexerManagerService i, Logger l, ServerConfig config, IProtectionService ps)
|
public BlackholeController(IIndexerManagerService i, Logger l, ServerConfig config, IProtectionService ps)
|
||||||
{
|
{
|
||||||
logger = l;
|
logger = l;
|
||||||
indexerService = i;
|
indexerService = i;
|
||||||
serverConfig = config;
|
serverConfig = config;
|
||||||
|
|
||||||
protectionService = ps;
|
protectionService = ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IHttpActionResult> Blackhole(string indexerID, string path, string jackett_apikey, string file)
|
public async Task<IActionResult> Blackhole(string indexerID, string path, string jackett_apikey, string file)
|
||||||
{
|
{
|
||||||
|
|
||||||
var jsonReply = new JObject();
|
var jsonReply = new JObject();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -47,7 +45,7 @@ namespace Jackett.Controllers
|
|||||||
if (serverConfig.APIKey != jackett_apikey)
|
if (serverConfig.APIKey != jackett_apikey)
|
||||||
throw new Exception("Incorrect API key");
|
throw new Exception("Incorrect API key");
|
||||||
|
|
||||||
path = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
path = WebUtility.UrlDecode(path);
|
||||||
path = protectionService.UnProtect(path);
|
path = protectionService.UnProtect(path);
|
||||||
var remoteFile = new Uri(path, UriKind.RelativeOrAbsolute);
|
var remoteFile = new Uri(path, UriKind.RelativeOrAbsolute);
|
||||||
var fileExtension = ".torrent";
|
var fileExtension = ".torrent";
|
||||||
@@ -81,9 +79,9 @@ namespace Jackett.Controllers
|
|||||||
if (string.IsNullOrWhiteSpace(file))
|
if (string.IsNullOrWhiteSpace(file))
|
||||||
fileName += fileExtension;
|
fileName += fileExtension;
|
||||||
else
|
else
|
||||||
fileName += "-"+StringUtil.MakeValidFileName(file + fileExtension, '_', false); // call MakeValidFileName() again to avoid any possibility of path traversal attacks
|
fileName += "-" + StringUtil.MakeValidFileName(file + fileExtension, '_', false); // call MakeValidFileName() again to avoid any possibility of path traversal attacks
|
||||||
|
|
||||||
File.WriteAllBytes(Path.Combine(serverConfig.BlackholeDir, fileName), downloadBytes);
|
System.IO.File.WriteAllBytes(Path.Combine(serverConfig.BlackholeDir, fileName), downloadBytes);
|
||||||
jsonReply["result"] = "success";
|
jsonReply["result"] = "success";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@@ -1,26 +1,24 @@
|
|||||||
using System;
|
using BencodeNET.Parsing;
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Web;
|
|
||||||
using System.Web.Http;
|
|
||||||
using BencodeNET.Parsing;
|
|
||||||
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.Mvc;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Jackett.Controllers
|
namespace Jackett.Server.Controllers
|
||||||
{
|
{
|
||||||
[AllowAnonymous]
|
//[AllowAnonymous]
|
||||||
[JackettAPINoCache]
|
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public class DownloadController : ApiController
|
[Route("dl/{indexerID}")]
|
||||||
|
public class DownloadController : Controller
|
||||||
{
|
{
|
||||||
private ServerConfig config;
|
private ServerConfig config;
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
private IIndexerManagerService indexerService;
|
private IIndexerManagerService indexerService;
|
||||||
private IProtectionService protectionService;
|
private IProtectionService protectionService;
|
||||||
|
|
||||||
public DownloadController(IIndexerManagerService i, Logger l, IProtectionService ps, ServerConfig serverConfig)
|
public DownloadController(IIndexerManagerService i, Logger l, IProtectionService ps, ServerConfig serverConfig)
|
||||||
@@ -32,7 +30,7 @@ namespace Jackett.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<HttpResponseMessage> Download(string indexerID, string path, string jackett_apikey, string file)
|
public async Task<IActionResult> Download(string indexerID, string path, string jackett_apikey, string file)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -41,14 +39,14 @@ namespace Jackett.Controllers
|
|||||||
if (!indexer.IsConfigured)
|
if (!indexer.IsConfigured)
|
||||||
{
|
{
|
||||||
logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName));
|
logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName));
|
||||||
return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.");
|
return Forbid("This indexer is not configured.");
|
||||||
}
|
}
|
||||||
|
|
||||||
path = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(path));
|
path = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(path));
|
||||||
path = protectionService.UnProtect(path);
|
path = protectionService.UnProtect(path);
|
||||||
|
|
||||||
if (config.APIKey != jackett_apikey)
|
if (config.APIKey != jackett_apikey)
|
||||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
return Unauthorized();
|
||||||
|
|
||||||
var target = new Uri(path, UriKind.RelativeOrAbsolute);
|
var target = new Uri(path, UriKind.RelativeOrAbsolute);
|
||||||
var downloadBytes = await indexer.Download(target);
|
var downloadBytes = await indexer.Download(target);
|
||||||
@@ -65,9 +63,7 @@ namespace Jackett.Controllers
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
var magneturi = Encoding.UTF8.GetString(downloadBytes);
|
var magneturi = Encoding.UTF8.GetString(downloadBytes);
|
||||||
var response = Request.CreateResponse(HttpStatusCode.Moved);
|
return Redirect(new Uri(magneturi).ToString());
|
||||||
response.Headers.Location = new Uri(magneturi);
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will fix torrents where the keys are not sorted, and thereby not supported by Sonarr.
|
// This will fix torrents where the keys are not sorted, and thereby not supported by Sonarr.
|
||||||
@@ -75,19 +71,14 @@ namespace Jackett.Controllers
|
|||||||
var torrentDictionary = parser.Parse(downloadBytes);
|
var torrentDictionary = parser.Parse(downloadBytes);
|
||||||
byte[] sortedDownloadBytes = torrentDictionary.EncodeAsBytes();
|
byte[] sortedDownloadBytes = torrentDictionary.EncodeAsBytes();
|
||||||
|
|
||||||
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
string fileName = StringUtil.MakeValidFileName(file, '_', false) + ".torrent"; // call MakeValidFileName again to avoid any kind of injection attack
|
||||||
result.Content = new ByteArrayContent(sortedDownloadBytes);
|
|
||||||
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-bittorrent");
|
return File(sortedDownloadBytes, "application/x-bittorrent", fileName);
|
||||||
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
|
||||||
{
|
|
||||||
FileName = StringUtil.MakeValidFileName(file, '_', false) + ".torrent" // call MakeValidFileName again to avoid any kind of injection attack
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.Error(e, "Error downloading " + indexerID + " " + path);
|
logger.Error(e, "Error downloading " + indexerID + " " + path);
|
||||||
return new HttpResponseMessage(HttpStatusCode.NotFound);
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,21 +1,18 @@
|
|||||||
using System;
|
using Jackett.Common.Indexers;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Web.Http;
|
|
||||||
using System.Web.Http.Controllers;
|
|
||||||
using System.Web.Http.Filters;
|
|
||||||
using Jackett.Common;
|
|
||||||
using Jackett.Common.Indexers;
|
|
||||||
using Jackett.Common.Models;
|
using Jackett.Common.Models;
|
||||||
using Jackett.Common.Services.Interfaces;
|
using Jackett.Common.Services.Interfaces;
|
||||||
using Jackett.Common.Utils;
|
using Jackett.Common.Utils;
|
||||||
using Jackett.Utils;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Jackett.Controllers
|
namespace Jackett.Server.Controllers
|
||||||
{
|
{
|
||||||
public interface IIndexerController
|
public interface IIndexerController
|
||||||
{
|
{
|
||||||
@@ -23,19 +20,17 @@ namespace Jackett.Controllers
|
|||||||
IIndexer CurrentIndexer { get; set; }
|
IIndexer CurrentIndexer { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RequiresIndexerAttribute : ActionFilterAttribute
|
public class RequiresIndexer : IActionFilter
|
||||||
{
|
{
|
||||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
public void OnActionExecuting(ActionExecutingContext context)
|
||||||
{
|
{
|
||||||
base.OnActionExecuting(actionContext);
|
var controller = context.Controller;
|
||||||
|
|
||||||
var controller = actionContext.ControllerContext.Controller;
|
|
||||||
if (!(controller is IIndexerController))
|
if (!(controller is IIndexerController))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var indexerController = controller as IIndexerController;
|
var indexerController = controller as IIndexerController;
|
||||||
|
|
||||||
var parameters = actionContext.RequestContext.RouteData.Values;
|
var parameters = context.RouteData.Values;
|
||||||
|
|
||||||
if (!parameters.ContainsKey("indexerId"))
|
if (!parameters.ContainsKey("indexerId"))
|
||||||
{
|
{
|
||||||
@@ -51,15 +46,23 @@ namespace Jackett.Controllers
|
|||||||
var indexer = indexerService.GetIndexer(indexerId);
|
var indexer = indexerService.GetIndexer(indexerId);
|
||||||
indexerController.CurrentIndexer = indexer;
|
indexerController.CurrentIndexer = indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
// do something after the action executes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[RoutePrefix("api/v2.0/indexers")]
|
[Route("api/v2.0/indexers")]
|
||||||
[JackettAuthorized]
|
//[JackettAuthorized]
|
||||||
[JackettAPINoCache]
|
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public class IndexerApiController : ApiController, IIndexerController
|
public class IndexerApiController : Controller, IIndexerController
|
||||||
{
|
{
|
||||||
public IIndexerManagerService IndexerService { get; private set; }
|
public IIndexerManagerService IndexerService { get; private set; }
|
||||||
public IIndexer CurrentIndexer { get; set; }
|
public IIndexer CurrentIndexer { get; set; }
|
||||||
|
private Logger logger;
|
||||||
|
private IServerService serverService;
|
||||||
|
private ICacheService cacheService;
|
||||||
|
|
||||||
public IndexerApiController(IIndexerManagerService indexerManagerService, IServerService ss, ICacheService c, Logger logger)
|
public IndexerApiController(IIndexerManagerService indexerManagerService, IServerService ss, ICacheService c, Logger logger)
|
||||||
{
|
{
|
||||||
@@ -70,16 +73,17 @@ namespace Jackett.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[RequiresIndexer]
|
[TypeFilter(typeof(RequiresIndexer))]
|
||||||
public async Task<IHttpActionResult> Config()
|
[Route("{indexerId?}/Config")]
|
||||||
|
public async Task<IActionResult> Config()
|
||||||
{
|
{
|
||||||
var config = await CurrentIndexer.GetConfigurationForSetup();
|
var config = await CurrentIndexer.GetConfigurationForSetup();
|
||||||
return Ok(config.ToJson(null));
|
return Ok(config.ToJson(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ActionName("Config")]
|
[Route("{indexerId?}/Config")]
|
||||||
[RequiresIndexer]
|
[TypeFilter(typeof(RequiresIndexer))]
|
||||||
public async Task UpdateConfig([FromBody]Common.Models.DTO.ConfigItem[] config)
|
public async Task UpdateConfig([FromBody]Common.Models.DTO.ConfigItem[] config)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -111,14 +115,16 @@ namespace Jackett.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[RequiresIndexer]
|
[Route("{indexerid}/[action]")]
|
||||||
public async Task Test()
|
[TypeFilter(typeof(RequiresIndexer))]
|
||||||
|
public async Task<IActionResult> Test()
|
||||||
{
|
{
|
||||||
JToken jsonReply = new JObject();
|
JToken jsonReply = new JObject();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await IndexerService.TestIndexer(CurrentIndexer.ID);
|
await IndexerService.TestIndexer(CurrentIndexer.ID);
|
||||||
CurrentIndexer.LastError = null;
|
CurrentIndexer.LastError = null;
|
||||||
|
return NoContent();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -134,8 +140,8 @@ namespace Jackett.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
[RequiresIndexer]
|
[TypeFilter(typeof(RequiresIndexer))]
|
||||||
[Route("{indexerId}")]
|
[Route("{indexerid}")]
|
||||||
public void Delete()
|
public void Delete()
|
||||||
{
|
{
|
||||||
IndexerService.DeleteIndexer(CurrentIndexer.ID);
|
IndexerService.DeleteIndexer(CurrentIndexer.ID);
|
||||||
@@ -160,14 +166,10 @@ namespace Jackett.Controllers
|
|||||||
var link = result.Link;
|
var link = result.Link;
|
||||||
var file = StringUtil.MakeValidFileName(result.Title, '_', false);
|
var file = StringUtil.MakeValidFileName(result.Title, '_', false);
|
||||||
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
||||||
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.ServerConfig.BlackholeDir))
|
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(serverService.GetBlackholeDirectory()))
|
||||||
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Logger logger;
|
|
||||||
private IServerService serverService;
|
|
||||||
private ICacheService cacheService;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,59 +1,73 @@
|
|||||||
using System;
|
using Jackett.Common;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Web.Http;
|
|
||||||
using System.Web.Http.Controllers;
|
|
||||||
using System.Web.Http.Filters;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using Jackett.Common;
|
|
||||||
using Jackett.Common.Indexers;
|
using Jackett.Common.Indexers;
|
||||||
using Jackett.Common.Indexers.Meta;
|
using Jackett.Common.Indexers.Meta;
|
||||||
using Jackett.Common.Models;
|
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.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Jackett.Controllers
|
namespace Jackett.Server.Controllers
|
||||||
{
|
{
|
||||||
public class RequiresApiKeyAttribute : AuthorizationFilterAttribute
|
public class RequiresApiKey : IActionFilter
|
||||||
{
|
{
|
||||||
public override void OnAuthorization(HttpActionContext actionContext)
|
public IServerService serverService;
|
||||||
|
|
||||||
|
public RequiresApiKey(IServerService ss)
|
||||||
{
|
{
|
||||||
var validApiKey = Engine.ServerConfig.APIKey;
|
serverService = ss;
|
||||||
var queryParams = actionContext.Request.GetQueryNameValuePairs();
|
}
|
||||||
|
|
||||||
|
public void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
var validApiKey = serverService.GetApiKey();
|
||||||
|
var queryParams = context.HttpContext.Request.Query;
|
||||||
var queryApiKey = queryParams.Where(x => x.Key == "apikey" || x.Key == "passkey").Select(x => x.Value).FirstOrDefault();
|
var queryApiKey = queryParams.Where(x => x.Key == "apikey" || x.Key == "passkey").Select(x => x.Value).FirstOrDefault();
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (Debugger.IsAttached)
|
if (Debugger.IsAttached)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (queryApiKey != validApiKey)
|
if (queryApiKey != validApiKey)
|
||||||
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
|
{
|
||||||
|
context.Result = new UnauthorizedResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
// do something after the action executes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RequiresConfiguredIndexerAttribute : ActionFilterAttribute
|
public class RequiresConfiguredIndexer : IActionFilter
|
||||||
{
|
{
|
||||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
public void OnActionExecuting(ActionExecutingContext context)
|
||||||
{
|
{
|
||||||
var controller = actionContext.ControllerContext.Controller;
|
var controller = context.Controller;
|
||||||
if (!(controller is IIndexerController))
|
if (!(controller is IIndexerController))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var indexerController = controller as IIndexerController;
|
var indexerController = controller as IIndexerController;
|
||||||
|
|
||||||
var parameters = actionContext.RequestContext.RouteData.Values;
|
var parameters = context.RouteData.Values;
|
||||||
|
|
||||||
if (!parameters.ContainsKey("indexerId"))
|
if (!parameters.ContainsKey("indexerId"))
|
||||||
{
|
{
|
||||||
indexerController.CurrentIndexer = null;
|
indexerController.CurrentIndexer = null;
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
context.Result = new UnauthorizedResult();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +75,7 @@ namespace Jackett.Controllers
|
|||||||
if (indexerId.IsNullOrEmptyOrWhitespace())
|
if (indexerId.IsNullOrEmptyOrWhitespace())
|
||||||
{
|
{
|
||||||
indexerController.CurrentIndexer = null;
|
indexerController.CurrentIndexer = null;
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
context.Result = new UnauthorizedResult();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,63 +85,68 @@ namespace Jackett.Controllers
|
|||||||
if (indexer == null)
|
if (indexer == null)
|
||||||
{
|
{
|
||||||
indexerController.CurrentIndexer = null;
|
indexerController.CurrentIndexer = null;
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
context.Result = new UnauthorizedResult();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!indexer.IsConfigured)
|
if (!indexer.IsConfigured)
|
||||||
{
|
{
|
||||||
indexerController.CurrentIndexer = null;
|
indexerController.CurrentIndexer = null;
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Indexer is not configured");
|
context.Result = new UnauthorizedResult();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexerController.CurrentIndexer = indexer;
|
indexerController.CurrentIndexer = indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
// do something after the action executes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RequiresValidQueryAttribute : RequiresConfiguredIndexerAttribute
|
public class RequiresValidQuery : IActionFilter
|
||||||
{
|
{
|
||||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
public void OnActionExecuting(ActionExecutingContext context)
|
||||||
{
|
{
|
||||||
base.OnActionExecuting(actionContext);
|
//TODO: Not sure what this is meant to do
|
||||||
if (actionContext.Response != null)
|
//if (context.HttpContext.Response != null)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
var controller = actionContext.ControllerContext.Controller;
|
var controller = context.Controller;
|
||||||
if (!(controller is IResultController))
|
if (!(controller is IResultController))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var resultController = controller as IResultController;
|
var resultController = controller as IResultController;
|
||||||
|
|
||||||
var query = actionContext.ActionArguments.First().Value;
|
var query = context.ActionArguments.First().Value;
|
||||||
var queryType = query.GetType();
|
var queryType = query.GetType();
|
||||||
var converter = queryType.GetMethod("ToTorznabQuery", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
var converter = queryType.GetMethod("ToTorznabQuery", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
||||||
if (converter == null)
|
if (converter == null)
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "");
|
{
|
||||||
|
context.Result = new BadRequestResult();
|
||||||
|
}
|
||||||
|
|
||||||
var converted = converter.Invoke(null, new object[] { query });
|
var converted = converter.Invoke(null, new object[] { query });
|
||||||
var torznabQuery = converted as TorznabQuery;
|
var torznabQuery = converted as TorznabQuery;
|
||||||
resultController.CurrentQuery = torznabQuery;
|
resultController.CurrentQuery = torznabQuery;
|
||||||
|
|
||||||
if (queryType == typeof(ApiSearch)) // Skip CanHandleQuery() check for manual search (CurrentIndexer isn't used during manul search)
|
if (queryType == typeof(ApiSearch)) // Skip CanHandleQuery() check for manual search (CurrentIndexer isn't used during manul search)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery))
|
if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery))
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, $"{resultController.CurrentIndexer.ID} does not support the requested query. Please check the capabilities (t=caps) and make sure the search mode and categories are supported.");
|
{
|
||||||
|
context.Result = new BadRequestObjectResult($"{resultController.CurrentIndexer.ID} does not support the requested query. Please check the capabilities (t=caps) and make sure the search mode and categories are supported.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class JsonResponseAttribute : ActionFilterAttribute
|
public void OnActionExecuted(ActionExecutedContext context)
|
||||||
{
|
|
||||||
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
|
|
||||||
{
|
{
|
||||||
base.OnActionExecuted(actionExecutedContext);
|
// do something after the action executes
|
||||||
|
|
||||||
if (actionExecutedContext.Exception != null)
|
|
||||||
throw new Exception("Error while executing request", actionExecutedContext.Exception);
|
|
||||||
|
|
||||||
var content = actionExecutedContext.Response.Content as ObjectContent;
|
|
||||||
actionExecutedContext.Response.Content = new JsonContent(content.Value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,12 +155,13 @@ namespace Jackett.Controllers
|
|||||||
TorznabQuery CurrentQuery { get; set; }
|
TorznabQuery CurrentQuery { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
//[AllowAnonymous]
|
||||||
[JackettAPINoCache]
|
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
[RoutePrefix("api/v2.0/indexers")]
|
[Route("api/v2.0/indexers/{indexerId}/results")]
|
||||||
[RequiresApiKey]
|
[TypeFilter(typeof(RequiresApiKey))]
|
||||||
[RequiresValidQuery]
|
[TypeFilter(typeof(RequiresConfiguredIndexer))]
|
||||||
public class ResultsController : ApiController, IResultController
|
[TypeFilter(typeof(RequiresValidQuery))]
|
||||||
|
public class ResultsController : Controller, IResultController
|
||||||
{
|
{
|
||||||
public IIndexerManagerService IndexerService { get; private set; }
|
public IIndexerManagerService IndexerService { get; private set; }
|
||||||
public IIndexer CurrentIndexer { get; set; }
|
public IIndexer CurrentIndexer { get; set; }
|
||||||
@@ -155,13 +175,39 @@ namespace Jackett.Controllers
|
|||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<ManualSearchResult> Results([FromUri]ApiSearch request)
|
public async Task<IActionResult> Results([FromQuery] ApiSearch requestt)
|
||||||
{
|
{
|
||||||
|
//TODO: Better way to parse querystring
|
||||||
|
|
||||||
|
ApiSearch request = new ApiSearch();
|
||||||
|
|
||||||
|
foreach (var t in Request.Query)
|
||||||
|
{
|
||||||
|
if (t.Key == "Tracker[]")
|
||||||
|
{
|
||||||
|
request.Tracker = t.Value.ToString().Split(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t.Key == "Category[]")
|
||||||
|
{
|
||||||
|
request.Category = t.Value.ToString().Split(",").Select(Int32.Parse).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t.Key == "query")
|
||||||
|
{
|
||||||
|
request.Query = t.Value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var manualResult = new ManualSearchResult();
|
var manualResult = new ManualSearchResult();
|
||||||
var trackers = IndexerService.GetAllIndexers().Where(t => t.IsConfigured);
|
var trackers = IndexerService.GetAllIndexers().ToList().Where(t => t.IsConfigured);
|
||||||
if (request.Tracker != null)
|
if (request.Tracker != null)
|
||||||
|
{
|
||||||
trackers = trackers.Where(t => request.Tracker.Contains(t.ID));
|
trackers = trackers.Where(t => request.Tracker.Contains(t.ID));
|
||||||
|
}
|
||||||
|
|
||||||
trackers = trackers.Where(t => t.CanHandleQuery(CurrentQuery));
|
trackers = trackers.Where(t => t.CanHandleQuery(CurrentQuery));
|
||||||
|
|
||||||
var tasks = trackers.ToList().Select(t => t.ResultsForQuery(CurrentQuery)).ToList();
|
var tasks = trackers.ToList().Select(t => t.ResultsForQuery(CurrentQuery)).ToList();
|
||||||
@@ -235,18 +281,16 @@ namespace Jackett.Controllers
|
|||||||
ConfigureCacheResults(manualResult.Results);
|
ConfigureCacheResults(manualResult.Results);
|
||||||
|
|
||||||
logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", CurrentQuery.SanitizedSearchTerm, string.Join(", ", manualResult.Indexers.Select(i => i.ID)), manualResult.Results.Count()));
|
logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", CurrentQuery.SanitizedSearchTerm, string.Join(", ", manualResult.Indexers.Select(i => i.ID)), manualResult.Results.Count()));
|
||||||
return manualResult;
|
return Json(manualResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("[action]/{ignored?}")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IHttpActionResult> Torznab([FromUri]Common.Models.DTO.TorznabRequest request)
|
public async Task<IActionResult> Torznab([FromQuery]TorznabRequest request)
|
||||||
{
|
{
|
||||||
if (string.Equals(CurrentQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase))
|
if (string.Equals(CurrentQuery.QueryType, "caps", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
return ResponseMessage(new HttpResponseMessage()
|
return Content(CurrentIndexer.TorznabCaps.ToXml(), "application/rss+xml", Encoding.UTF8);
|
||||||
{
|
|
||||||
Content = new StringContent(CurrentIndexer.TorznabCaps.ToXml(), Encoding.UTF8, "application/xml")
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// indexers - returns a list of all included indexers (meta indexers only)
|
// indexers - returns a list of all included indexers (meta indexers only)
|
||||||
@@ -254,7 +298,7 @@ namespace Jackett.Controllers
|
|||||||
{
|
{
|
||||||
if (!(CurrentIndexer is BaseMetaIndexer)) // shouldn't be needed because CanHandleQuery should return false
|
if (!(CurrentIndexer is BaseMetaIndexer)) // shouldn't be needed because CanHandleQuery should return false
|
||||||
{
|
{
|
||||||
logger.Warn($"A search request with t=indexers from {Request.GetOwinContext().Request.RemoteIpAddress} was made but the indexer {CurrentIndexer.DisplayName} isn't a meta indexer.");
|
logger.Warn($"A search request with t=indexers from {Request.HttpContext.Connection.RemoteIpAddress} was made but the indexer {CurrentIndexer.DisplayName} isn't a meta indexer.");
|
||||||
return GetErrorXML(203, "Function Not Available: this isn't a meta indexer");
|
return GetErrorXML(203, "Function Not Available: this isn't a meta indexer");
|
||||||
}
|
}
|
||||||
var CurrentBaseMetaIndexer = (BaseMetaIndexer)CurrentIndexer;
|
var CurrentBaseMetaIndexer = (BaseMetaIndexer)CurrentIndexer;
|
||||||
@@ -281,30 +325,27 @@ namespace Jackett.Controllers
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return ResponseMessage(new HttpResponseMessage()
|
return Content(xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString(), "application/xml", Encoding.UTF8);
|
||||||
{
|
|
||||||
Content = new StringContent(xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString(), Encoding.UTF8, "application/xml")
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentQuery.ImdbID != null)
|
if (CurrentQuery.ImdbID != null)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(CurrentQuery.SearchTerm))
|
if (!string.IsNullOrEmpty(CurrentQuery.SearchTerm))
|
||||||
{
|
{
|
||||||
logger.Warn($"A search request from {Request.GetOwinContext().Request.RemoteIpAddress} was made containing q and imdbid.");
|
logger.Warn($"A search request from {Request.HttpContext.Connection.RemoteIpAddress} was made containing q and imdbid.");
|
||||||
return GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q");
|
return GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q");
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentQuery.ImdbID = ParseUtil.GetFullImdbID(CurrentQuery.ImdbID); // normalize ImdbID
|
CurrentQuery.ImdbID = ParseUtil.GetFullImdbID(CurrentQuery.ImdbID); // normalize ImdbID
|
||||||
if (CurrentQuery.ImdbID == null)
|
if (CurrentQuery.ImdbID == null)
|
||||||
{
|
{
|
||||||
logger.Warn($"A search request from {Request.GetOwinContext().Request.RemoteIpAddress} was made with an invalid imdbid.");
|
logger.Warn($"A search request from {Request.HttpContext.Connection.RemoteIpAddress} was made with an invalid imdbid.");
|
||||||
return GetErrorXML(201, "Incorrect parameter: invalid imdbid format");
|
return GetErrorXML(201, "Incorrect parameter: invalid imdbid format");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CurrentIndexer.TorznabCaps.SupportsImdbSearch)
|
if (!CurrentIndexer.TorznabCaps.SupportsImdbSearch)
|
||||||
{
|
{
|
||||||
logger.Warn($"A search request with imdbid from {Request.GetOwinContext().Request.RemoteIpAddress} was made but the indexer {CurrentIndexer.DisplayName} doesn't support it.");
|
logger.Warn($"A search request with imdbid from {Request.HttpContext.Connection.RemoteIpAddress} was made but the indexer {CurrentIndexer.DisplayName} doesn't support it.");
|
||||||
return GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer");
|
return GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,13 +402,12 @@ namespace Jackett.Controllers
|
|||||||
|
|
||||||
var xml = resultPage.ToXml(new Uri(serverUrl));
|
var xml = resultPage.ToXml(new Uri(serverUrl));
|
||||||
// Force the return as XML
|
// Force the return as XML
|
||||||
return ResponseMessage(new HttpResponseMessage()
|
|
||||||
{
|
return Content(xml, "application/rss+xml", Encoding.UTF8);
|
||||||
Content = new StringContent(xml, Encoding.UTF8, "application/rss+xml")
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHttpActionResult GetErrorXML(int code, string description)
|
[Route("[action]/{ignored?}")]
|
||||||
|
public IActionResult GetErrorXML(int code, string description)
|
||||||
{
|
{
|
||||||
var xdoc = new XDocument(
|
var xdoc = new XDocument(
|
||||||
new XDeclaration("1.0", "UTF-8", null),
|
new XDeclaration("1.0", "UTF-8", null),
|
||||||
@@ -378,16 +418,12 @@ namespace Jackett.Controllers
|
|||||||
);
|
);
|
||||||
|
|
||||||
var xml = xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString();
|
var xml = xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString();
|
||||||
|
return Content(xml, "application/xml", Encoding.UTF8);
|
||||||
return ResponseMessage(new HttpResponseMessage()
|
|
||||||
{
|
|
||||||
Content = new StringContent(xml, Encoding.UTF8, "application/xml")
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("[action]/{ignored?}")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[JsonResponse]
|
public async Task<TorrentPotatoResponse> Potato([FromQuery]TorrentPotatoRequest request)
|
||||||
public async Task<TorrentPotatoResponse> Potato([FromUri]TorrentPotatoRequest request)
|
|
||||||
{
|
{
|
||||||
var result = await CurrentIndexer.ResultsForQuery(CurrentQuery);
|
var result = await CurrentIndexer.ResultsForQuery(CurrentQuery);
|
||||||
|
|
||||||
@@ -431,6 +467,7 @@ namespace Jackett.Controllers
|
|||||||
return potatoResponse;
|
return potatoResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("[action]/{ignored?}")]
|
||||||
private void ConfigureCacheResults(IEnumerable<TrackerCacheResult> results)
|
private void ConfigureCacheResults(IEnumerable<TrackerCacheResult> results)
|
||||||
{
|
{
|
||||||
var serverUrl = serverService.GetServerUrl(Request);
|
var serverUrl = serverService.GetServerUrl(Request);
|
||||||
@@ -439,9 +476,8 @@ namespace Jackett.Controllers
|
|||||||
var link = result.Link;
|
var link = result.Link;
|
||||||
var file = StringUtil.MakeValidFileName(result.Title, '_', false);
|
var file = StringUtil.MakeValidFileName(result.Title, '_', false);
|
||||||
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", file);
|
||||||
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.ServerConfig.BlackholeDir))
|
if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(serverService.GetBlackholeDirectory()))
|
||||||
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", file);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,23 +1,20 @@
|
|||||||
using System;
|
using Jackett.Common.Models;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Web.Http;
|
|
||||||
using Jackett.Common;
|
|
||||||
using Jackett.Common.Models;
|
|
||||||
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 Jackett.Utils;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Jackett.Controllers
|
namespace Jackett.Server.Controllers
|
||||||
{
|
{
|
||||||
[RoutePrefix("api/v2.0/server")]
|
[Route("api/v2.0/server/[action]")]
|
||||||
[JackettAuthorized]
|
//[JackettAuthorized]
|
||||||
[JackettAPINoCache]
|
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public class ServerConfigurationController : ApiController
|
public class ServerConfigurationController : Controller
|
||||||
{
|
{
|
||||||
private readonly IConfigurationService configService;
|
private readonly IConfigurationService configService;
|
||||||
private ServerConfig serverConfig;
|
private ServerConfig serverConfig;
|
||||||
@@ -29,7 +26,7 @@ namespace Jackett.Controllers
|
|||||||
private ILogCacheService logCache;
|
private ILogCacheService logCache;
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
|
|
||||||
public ServerConfigurationController(IConfigurationService c, IServerService s, IProcessService p, IIndexerManagerService i, ISecuityService ss, IUpdateService u, ILogCacheService lc, Logger l, ServerConfig sc)
|
public ServerConfigurationController(IConfigurationService c, IServerService s, IProcessService p, IIndexerManagerService i, ISecuityService ss, IUpdateService u, ILogCacheService lc, Logger l, ServerConfig sc)
|
||||||
{
|
{
|
||||||
configService = c;
|
configService = c;
|
||||||
serverConfig = sc;
|
serverConfig = sc;
|
||||||
@@ -65,14 +62,13 @@ namespace Jackett.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
public Common.Models.DTO.ServerConfig Config()
|
public Common.Models.DTO.ServerConfig Config()
|
||||||
{
|
{
|
||||||
|
|
||||||
var dto = new Common.Models.DTO.ServerConfig(serverService.notices, serverConfig, configService.GetVersion());
|
var dto = new Common.Models.DTO.ServerConfig(serverService.notices, serverConfig, configService.GetVersion());
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
[ActionName("Config")]
|
[ActionName("Config")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public void UpdateConfig([FromBody]Common.Models.DTO.ServerConfig config)
|
public IActionResult UpdateConfig([FromBody]Common.Models.DTO.ServerConfig config)
|
||||||
{
|
{
|
||||||
var originalPort = serverConfig.Port;
|
var originalPort = serverConfig.Port;
|
||||||
var originalAllowExternal = serverConfig.AllowExternal;
|
var originalAllowExternal = serverConfig.AllowExternal;
|
||||||
@@ -95,16 +91,16 @@ namespace Jackett.Controllers
|
|||||||
serverConfig.UpdateDisabled = updateDisabled;
|
serverConfig.UpdateDisabled = updateDisabled;
|
||||||
serverConfig.UpdatePrerelease = preRelease;
|
serverConfig.UpdatePrerelease = preRelease;
|
||||||
serverConfig.BasePathOverride = basePathOverride;
|
serverConfig.BasePathOverride = basePathOverride;
|
||||||
serverConfig.RuntimeSettings.BasePath = Engine.Server.BasePath();
|
serverConfig.RuntimeSettings.BasePath = serverService.BasePath();
|
||||||
configService.SaveConfig(serverConfig);
|
configService.SaveConfig(serverConfig);
|
||||||
|
|
||||||
Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
|
Initialisation.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
|
||||||
serverConfig.RuntimeSettings.TracingEnabled = logging;
|
serverConfig.RuntimeSettings.TracingEnabled = logging;
|
||||||
|
|
||||||
if (omdbApiKey != serverConfig.OmdbApiKey)
|
if (omdbApiKey != serverConfig.OmdbApiKey)
|
||||||
{
|
{
|
||||||
serverConfig.OmdbApiKey = omdbApiKey;
|
serverConfig.OmdbApiKey = omdbApiKey;
|
||||||
configService.SaveConfig(serverConfig);
|
configService.SaveConfig(serverConfig);
|
||||||
// HACK
|
// HACK
|
||||||
indexerService.InitAggregateIndexer();
|
indexerService.InitAggregateIndexer();
|
||||||
}
|
}
|
||||||
@@ -128,7 +124,6 @@ namespace Jackett.Controllers
|
|||||||
|
|
||||||
if (port != serverConfig.Port || external != serverConfig.AllowExternal)
|
if (port != serverConfig.Port || external != serverConfig.AllowExternal)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ServerUtil.RestrictedPorts.Contains(port))
|
if (ServerUtil.RestrictedPorts.Contains(port))
|
||||||
throw new Exception("The port you have selected is restricted, try a different one.");
|
throw new Exception("The port you have selected is restricted, try a different one.");
|
||||||
|
|
||||||
@@ -147,7 +142,8 @@ namespace Jackett.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
processService.StartProcessAndLog(System.Windows.Forms.Application.ExecutablePath, "--ReserveUrls", true);
|
//TODO
|
||||||
|
//processService.StartProcessAndLog(System.Windows.Forms.Application.ExecutablePath, "--ReserveUrls", true);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -163,15 +159,15 @@ namespace Jackett.Controllers
|
|||||||
serverService.ReserveUrls(true);
|
serverService.ReserveUrls(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//TODO
|
||||||
(new Thread(() =>
|
//(new Thread(() =>
|
||||||
{
|
//{
|
||||||
Thread.Sleep(500);
|
// Thread.Sleep(500);
|
||||||
serverService.Stop();
|
// serverService.Stop();
|
||||||
Engine.BuildContainer(serverConfig.RuntimeSettings, new WebApi2Module());
|
// Engine.BuildContainer(serverConfig.RuntimeSettings, new WebApi2Module());
|
||||||
Engine.Server.Initalize();
|
// Engine.Server.Initalize();
|
||||||
Engine.Server.Start();
|
// Engine.Server.Start();
|
||||||
})).Start();
|
//})).Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (saveDir != serverConfig.BlackholeDir)
|
if (saveDir != serverConfig.BlackholeDir)
|
||||||
@@ -187,8 +183,10 @@ namespace Jackett.Controllers
|
|||||||
serverConfig.BlackholeDir = saveDir;
|
serverConfig.BlackholeDir = saveDir;
|
||||||
configService.SaveConfig(serverConfig);
|
configService.SaveConfig(serverConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
serverConfig.ConfigChanged();
|
serverConfig.ConfigChanged();
|
||||||
|
|
||||||
|
return Json(serverConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -196,7 +194,5 @@ namespace Jackett.Controllers
|
|||||||
{
|
{
|
||||||
return logCache.Logs;
|
return logCache.Logs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,21 +1,20 @@
|
|||||||
using System.IO;
|
using Jackett.Common.Models.Config;
|
||||||
|
using Jackett.Common.Services.Interfaces;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MimeMapping;
|
||||||
|
using NLog;
|
||||||
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web.Http;
|
|
||||||
using Jackett.Common.Models.Config;
|
|
||||||
using Jackett.Common.Services.Interfaces;
|
|
||||||
using Jackett.Utils;
|
|
||||||
using MimeMapping;
|
|
||||||
using NLog;
|
|
||||||
|
|
||||||
namespace Jackett.Controllers
|
namespace Jackett.Server.Controllers
|
||||||
{
|
{
|
||||||
[RoutePrefix("UI")]
|
[Route("UI/[action]")]
|
||||||
[JackettAuthorized]
|
//[JackettAuthorized]
|
||||||
[JackettAPINoCache]
|
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public class WebUIController : ApiController
|
public class WebUIController : Controller
|
||||||
{
|
{
|
||||||
private IConfigurationService config;
|
private IConfigurationService config;
|
||||||
private ServerConfig serverConfig;
|
private ServerConfig serverConfig;
|
||||||
@@ -42,50 +41,50 @@ namespace Jackett.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[AllowAnonymous]
|
//[AllowAnonymous]
|
||||||
public IHttpActionResult Logout()
|
public IActionResult Logout()
|
||||||
{
|
{
|
||||||
var ctx = Request.GetOwinContext();
|
var ctx = Request.HttpContext;
|
||||||
var authManager = ctx.Authentication;
|
//TODO
|
||||||
authManager.SignOut("ApplicationCookie");
|
//var authManager = ctx.Authentication;
|
||||||
return Redirect("UI/Dashboard");
|
//authManager.SignOut("ApplicationCookie");
|
||||||
|
return Redirect("Dashboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[AllowAnonymous]
|
//[AllowAnonymous]
|
||||||
public async Task<HttpResponseMessage> Dashboard()
|
public async Task<HttpResponseMessage> Dashboard()
|
||||||
{
|
{
|
||||||
if (Request.RequestUri.Query != null && Request.RequestUri.Query.Contains("logout"))
|
if (Request.Path != null && Request.Path.ToString().Contains("logout"))
|
||||||
{
|
{
|
||||||
var file = GetFile("login.html");
|
var file = GetFile("login.html");
|
||||||
securityService.Logout(file);
|
securityService.Logout(file);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
|
||||||
if (securityService.CheckAuthorised(Request))
|
//if (securityService.CheckAuthorised(Request))
|
||||||
{
|
//{
|
||||||
return GetFile("index.html");
|
return GetFile("index.html");
|
||||||
|
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
var formData = await Request.Content.ReadAsFormDataAsync();
|
// var formData = await Request.ReadFormAsync();
|
||||||
|
|
||||||
if (formData != null && securityService.HashPassword(formData["password"]) == serverConfig.AdminPassword)
|
// if (formData != null && securityService.HashPassword(formData["password"]) == serverConfig.AdminPassword)
|
||||||
{
|
// {
|
||||||
var file = GetFile("index.html");
|
// var file = GetFile("index.html");
|
||||||
securityService.Login(file);
|
// securityService.Login(file);
|
||||||
return file;
|
// return file;
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
return GetFile("login.html");
|
// return GetFile("login.html");
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,44 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Jackett.Server.Controllers
|
|
||||||
{
|
|
||||||
[Route("api/[controller]")]
|
|
||||||
public class ValuesController : Controller
|
|
||||||
{
|
|
||||||
// GET api/values
|
|
||||||
[HttpGet]
|
|
||||||
public IEnumerable<string> Get()
|
|
||||||
{
|
|
||||||
return new string[] { "value1", "value2" };
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET api/values/5
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public string Get(int id)
|
|
||||||
{
|
|
||||||
return "value";
|
|
||||||
}
|
|
||||||
|
|
||||||
// POST api/values
|
|
||||||
[HttpPost]
|
|
||||||
public void Post([FromBody]string value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUT api/values/5
|
|
||||||
[HttpPut("{id}")]
|
|
||||||
public void Put(int id, [FromBody]string value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// DELETE api/values/5
|
|
||||||
[HttpDelete("{id}")]
|
|
||||||
public void Delete(int id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user