mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Web auth
This commit is contained in:
@@ -53,6 +53,9 @@
|
|||||||
<Reference Include="Autofac.Integration.WebApi.Owin">
|
<Reference Include="Autofac.Integration.WebApi.Owin">
|
||||||
<HintPath>..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
|
<HintPath>..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.AspNet.Identity.Core">
|
||||||
|
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@@ -65,10 +68,19 @@
|
|||||||
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.2.0.2\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.2.0.2\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Owin.Host.SystemWeb">
|
||||||
|
<HintPath>..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Owin.Hosting">
|
<Reference Include="Microsoft.Owin.Hosting">
|
||||||
<HintPath>..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Owin.Security">
|
||||||
|
<HintPath>..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Owin.Security.Cookies">
|
||||||
|
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
<package id="Autofac.Owin" version="3.1.0" targetFramework="net452" userInstalled="true" />
|
<package id="Autofac.Owin" version="3.1.0" targetFramework="net452" userInstalled="true" />
|
||||||
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net452" userInstalled="true" />
|
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net452" userInstalled="true" />
|
||||||
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net452" userInstalled="true" />
|
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net452" userInstalled="true" />
|
||||||
|
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net452" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" userInstalled="true" />
|
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" userInstalled="true" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" userInstalled="true" />
|
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" userInstalled="true" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" userInstalled="true" />
|
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" userInstalled="true" />
|
||||||
@@ -12,7 +13,10 @@
|
|||||||
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" userInstalled="true" />
|
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" userInstalled="true" />
|
||||||
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net452" userInstalled="true" />
|
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net452" userInstalled="true" />
|
||||||
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net452" userInstalled="true" />
|
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net452" userInstalled="true" />
|
||||||
|
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net452" />
|
||||||
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net452" userInstalled="true" />
|
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net452" userInstalled="true" />
|
||||||
|
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net452" />
|
||||||
|
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net452" />
|
||||||
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net452" userInstalled="true" />
|
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net452" userInstalled="true" />
|
||||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net452" userInstalled="true" />
|
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net452" userInstalled="true" />
|
||||||
<package id="NLog" version="4.0.1" targetFramework="net452" />
|
<package id="NLog" version="4.0.1" targetFramework="net452" />
|
||||||
|
@@ -5,15 +5,22 @@ loadJackettSettings();
|
|||||||
|
|
||||||
function loadJackettSettings() {
|
function loadJackettSettings() {
|
||||||
getJackettConfig(function (data) {
|
getJackettConfig(function (data) {
|
||||||
|
|
||||||
|
$("#api-key-input").val(data.config.api_key);
|
||||||
|
$("#app-version").html(data.app_version);
|
||||||
$("#jackett-port").val(data.config.port);
|
$("#jackett-port").val(data.config.port);
|
||||||
|
var password = data.config.password;
|
||||||
|
$("#jackett-adminpwd").val(password);
|
||||||
|
if (password != null && password != '') {
|
||||||
|
$("#logoutBtn").show();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#change-jackett-port").click(function () {
|
$("#change-jackett-port").click(function () {
|
||||||
var jackett_port = $("#jackett-port").val();
|
var jackett_port = $("#jackett-port").val();
|
||||||
var jsonObject = JSON.parse('{"port":"' + jackett_port + '"}');
|
var jsonObject = { port: jackett_port};
|
||||||
|
var jqxhr = $.post("/admin/apply_jackett_config", JSON.stringify(jsonObject), function (data) {
|
||||||
var jqxhr = $.post("admin/apply_jackett_config", JSON.stringify(jsonObject), function (data) {
|
|
||||||
|
|
||||||
if (data.result == "error") {
|
if (data.result == "error") {
|
||||||
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
|
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
|
||||||
@@ -34,8 +41,30 @@ $("#change-jackett-port").click(function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#change-jackett-password").click(function () {
|
||||||
|
var password = $("#jackett-adminpwd").val();
|
||||||
|
var jsonObject = { password: password };
|
||||||
|
|
||||||
|
var jqxhr = $.post("/admin/set_admin_password", JSON.stringify(jsonObject), function (data) {
|
||||||
|
|
||||||
|
if (data.result == "error") {
|
||||||
|
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
doNotify("Admin password has been set.", "success", "glyphicon glyphicon-ok");
|
||||||
|
|
||||||
|
window.setTimeout(function () {
|
||||||
|
window.location = window.location.pathname;
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
}).fail(function () {
|
||||||
|
doNotify("Request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function getJackettConfig(callback) {
|
function getJackettConfig(callback) {
|
||||||
var jqxhr = $.get("admin/get_jackett_config", function (data) {
|
var jqxhr = $.get("/admin/get_jackett_config", function (data) {
|
||||||
|
|
||||||
callback(data);
|
callback(data);
|
||||||
}).fail(function () {
|
}).fail(function () {
|
||||||
@@ -47,9 +76,7 @@ function reloadIndexers() {
|
|||||||
$('#indexers').hide();
|
$('#indexers').hide();
|
||||||
$('#indexers > .indexer').remove();
|
$('#indexers > .indexer').remove();
|
||||||
$('#unconfigured-indexers').empty();
|
$('#unconfigured-indexers').empty();
|
||||||
var jqxhr = $.get("admin/get_indexers", function (data) {
|
var jqxhr = $.get("/admin/get_indexers", function (data) {
|
||||||
$("#api-key-input").val(data.api_key);
|
|
||||||
$("#app-version").html(data.app_version);
|
|
||||||
displayIndexers(data.items);
|
displayIndexers(data.items);
|
||||||
}).fail(function () {
|
}).fail(function () {
|
||||||
doNotify("Error loading indexers, request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
|
doNotify("Error loading indexers, request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
|
||||||
@@ -82,7 +109,7 @@ function prepareDeleteButtons() {
|
|||||||
var $btn = $(btn);
|
var $btn = $(btn);
|
||||||
var id = $btn.data("id");
|
var id = $btn.data("id");
|
||||||
$btn.click(function () {
|
$btn.click(function () {
|
||||||
var jqxhr = $.post("admin/delete_indexer", JSON.stringify({ indexer: id }), function (data) {
|
var jqxhr = $.post("/admin/delete_indexer", JSON.stringify({ indexer: id }), function (data) {
|
||||||
if (data.result == "error") {
|
if (data.result == "error") {
|
||||||
doNotify("Delete error for " + id + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
|
doNotify("Delete error for " + id + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
|
||||||
}
|
}
|
||||||
@@ -114,7 +141,7 @@ function prepareTestButtons() {
|
|||||||
var id = $btn.data("id");
|
var id = $btn.data("id");
|
||||||
$btn.click(function () {
|
$btn.click(function () {
|
||||||
doNotify("Test started for " + id, "info", "glyphicon glyphicon-transfer");
|
doNotify("Test started for " + id, "info", "glyphicon glyphicon-transfer");
|
||||||
var jqxhr = $.post("admin/test_indexer", JSON.stringify({ indexer: id }), function (data) {
|
var jqxhr = $.post("/admin/test_indexer", JSON.stringify({ indexer: id }), function (data) {
|
||||||
if (data.result == "error") {
|
if (data.result == "error") {
|
||||||
doNotify("Test failed for " + data.name + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
|
doNotify("Test failed for " + data.name + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
|
||||||
}
|
}
|
||||||
@@ -130,7 +157,7 @@ function prepareTestButtons() {
|
|||||||
|
|
||||||
function displayIndexerSetup(id) {
|
function displayIndexerSetup(id) {
|
||||||
|
|
||||||
var jqxhr = $.post("admin/get_config_form", JSON.stringify({ indexer: id }), function (data) {
|
var jqxhr = $.post("/admin/get_config_form", JSON.stringify({ indexer: id }), function (data) {
|
||||||
if (data.result == "error") {
|
if (data.result == "error") {
|
||||||
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
|
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
|
||||||
return;
|
return;
|
||||||
@@ -200,7 +227,7 @@ function populateSetupForm(indexerId, name, config) {
|
|||||||
$goButton.prop('disabled', true);
|
$goButton.prop('disabled', true);
|
||||||
$goButton.html($('#templates > .spinner')[0].outerHTML);
|
$goButton.html($('#templates > .spinner')[0].outerHTML);
|
||||||
|
|
||||||
var jqxhr = $.post("admin/configure_indexer", JSON.stringify(data), function (data) {
|
var jqxhr = $.post("/admin/configure_indexer", JSON.stringify(data), function (data) {
|
||||||
if (data.result == "error") {
|
if (data.result == "error") {
|
||||||
if (data.config) {
|
if (data.config) {
|
||||||
populateConfigItems(configForm, data.config);
|
populateConfigItems(configForm, data.config);
|
||||||
|
@@ -6,21 +6,21 @@
|
|||||||
|
|
||||||
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
|
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
|
||||||
|
|
||||||
<script src="jquery-2.1.3.min.js"></script>
|
<script src="/jquery-2.1.3.min.js"></script>
|
||||||
<script src="handlebars-v3.0.1.js"></script>
|
<script src="/handlebars-v3.0.1.js"></script>
|
||||||
<script src="bootstrap/bootstrap.min.js"></script>
|
<script src="/bootstrap/bootstrap.min.js"></script>
|
||||||
<script src="bootstrap-notify.js"></script>
|
<script src="/bootstrap-notify.js"></script>
|
||||||
|
|
||||||
<link href="bootstrap/bootstrap.min.css" rel="stylesheet">
|
<link href="/bootstrap/bootstrap.min.css" rel="stylesheet">
|
||||||
<link href="animate.css" rel="stylesheet">
|
<link href="/animate.css" rel="stylesheet">
|
||||||
<link href="custom.css" rel="stylesheet">
|
<link href="/custom.css" rel="stylesheet">
|
||||||
|
|
||||||
<title>Jackett</title>
|
<title>Jackett</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
|
|
||||||
<img id="logo" src="jacket_medium.png" /><span id="header-title">Jackett</span>
|
<img id="logo" src="/jacket_medium.png" /><span id="header-title">Jackett</span>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
@@ -35,6 +35,16 @@
|
|||||||
<span class="input-header">Jackett API Key: </span>
|
<span class="input-header">Jackett API Key: </span>
|
||||||
<input id="api-key-input" class="form-control input-right" type="text" value="" placeholder="API Key" readonly="">
|
<input id="api-key-input" class="form-control input-right" type="text" value="" placeholder="API Key" readonly="">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="input-area">
|
||||||
|
<span class="input-header">Admin Password: </span>
|
||||||
|
<input id="jackett-adminpwd" class="form-control input-right" type="password" value="" placeholder="Blank to disable">
|
||||||
|
<button id="change-jackett-password" class="btn btn-primary btn-sm">
|
||||||
|
Set <span class="glyphicon glyphicon-ok-wrench" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<a href="Dashboard?logout=true" id="logoutBtn" style="display:none" class="btn btn-danger btn-sm">
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="input-area">
|
<div class="input-area">
|
||||||
<span class="input-header">Jackett port: </span>
|
<span class="input-header">Jackett port: </span>
|
||||||
@@ -101,7 +111,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="configured-indexer indexer card">
|
<div class="configured-indexer indexer card">
|
||||||
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="logos/{{id}}.png" /></div>
|
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
|
||||||
<div class="indexer-buttons">
|
<div class="indexer-buttons">
|
||||||
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}">
|
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}">
|
||||||
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
||||||
@@ -123,7 +133,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="unconfigured-indexer card">
|
<div class="unconfigured-indexer card">
|
||||||
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="logos/{{id}}.png" /></div>
|
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
|
||||||
<div class="indexer-buttons">
|
<div class="indexer-buttons">
|
||||||
<a class="btn btn-info" target="_blank" href="{{site_link}}">Visit <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a>
|
<a class="btn btn-info" target="_blank" href="{{site_link}}">Visit <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a>
|
||||||
<button class="indexer-setup btn btn-success" data-id="{{id}}">Setup <span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
|
<button class="indexer-setup btn btn-success" data-id="{{id}}">Setup <span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
|
||||||
@@ -153,7 +163,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script src="custom.js"></script>
|
<script src="/custom.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
38
src/Jackett/Content/login.html
Normal file
38
src/Jackett/Content/login.html
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
|
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
|
||||||
|
|
||||||
|
<script src="/jquery-2.1.3.min.js"></script>
|
||||||
|
<script src="/handlebars-v3.0.1.js"></script>
|
||||||
|
<script src="/bootstrap/bootstrap.min.js"></script>
|
||||||
|
<script src="/bootstrap-notify.js"></script>
|
||||||
|
|
||||||
|
<link href="/bootstrap/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="/animate.css" rel="stylesheet">
|
||||||
|
<link href="/custom.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<title>Jackett</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="page">
|
||||||
|
|
||||||
|
<img id="logo" src="/jacket_medium.png" /><span id="header-title">Jackett</span>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h1>Login</h1>
|
||||||
|
<form action="/Admin/Dashboard" method="post">
|
||||||
|
<div class="input-area">
|
||||||
|
<span class="input-header">Admin password</span>
|
||||||
|
<input id="password" name="password" class="form-control input-right" type="password">
|
||||||
|
</div>
|
||||||
|
<div class="input-area">
|
||||||
|
<input type="submit" value="Login" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -1,30 +1,40 @@
|
|||||||
using Autofac;
|
using Autofac;
|
||||||
using Jackett.Models;
|
using Jackett.Models;
|
||||||
using Jackett.Services;
|
using Jackett.Services;
|
||||||
|
using Jackett.Utils;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
|
using System.Web.Http.Results;
|
||||||
|
using System.Web.Security;
|
||||||
|
|
||||||
namespace Jackett.Controllers
|
namespace Jackett.Controllers
|
||||||
{
|
{
|
||||||
[RoutePrefix("admin")]
|
[RoutePrefix("admin")]
|
||||||
|
[JackettAuthorized]
|
||||||
public class AdminController : ApiController
|
public class AdminController : ApiController
|
||||||
{
|
{
|
||||||
private IConfigurationService config;
|
private IConfigurationService config;
|
||||||
private IIndexerManagerService indexerService;
|
private IIndexerManagerService indexerService;
|
||||||
private IServerService serverService;
|
private IServerService serverService;
|
||||||
|
private ISecuityService securityService;
|
||||||
|
|
||||||
public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss)
|
public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss, ISecuityService s)
|
||||||
{
|
{
|
||||||
this.config = config;
|
this.config = config;
|
||||||
indexerService = i;
|
indexerService = i;
|
||||||
serverService = ss;
|
serverService = ss;
|
||||||
|
securityService = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<JToken> ReadPostDataJson()
|
private async Task<JToken> ReadPostDataJson()
|
||||||
@@ -33,6 +43,91 @@ namespace Jackett.Controllers
|
|||||||
return JObject.Parse(content);
|
return JObject.Parse(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private HttpResponseMessage GetFile(string path)
|
||||||
|
{
|
||||||
|
var result = new HttpResponseMessage(HttpStatusCode.OK);
|
||||||
|
var mappedPath = Path.Combine(config.GetContentFolder(), path);
|
||||||
|
var stream = new FileStream(mappedPath, FileMode.Open);
|
||||||
|
result.Content = new StreamContent(stream);
|
||||||
|
result.Content.Headers.ContentType =
|
||||||
|
new MediaTypeHeaderValue(MimeMapping.GetMimeMapping(mappedPath));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public RedirectResult Logout()
|
||||||
|
{
|
||||||
|
var ctx = Request.GetOwinContext();
|
||||||
|
var authManager = ctx.Authentication;
|
||||||
|
authManager.SignOut("ApplicationCookie");
|
||||||
|
return Redirect("/Admin/Dashboard");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[HttpPost]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<HttpResponseMessage> Dashboard()
|
||||||
|
{
|
||||||
|
if(Request.RequestUri.Query!=null && Request.RequestUri.Query.Contains("logout"))
|
||||||
|
{
|
||||||
|
var file = GetFile("login.html");
|
||||||
|
securityService.Logout(file);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (securityService.CheckAuthorised(Request))
|
||||||
|
{
|
||||||
|
return GetFile("index.html");
|
||||||
|
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
var formData = await Request.Content.ReadAsFormDataAsync();
|
||||||
|
|
||||||
|
if (formData!=null && securityService.HashPassword(formData["password"]) == serverService.Config.AdminPassword)
|
||||||
|
{
|
||||||
|
var file = GetFile("index.html");
|
||||||
|
securityService.Login(file);
|
||||||
|
return file;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return GetFile("login.html");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("set_admin_password")]
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IHttpActionResult> SetAdminPassword()
|
||||||
|
{
|
||||||
|
var jsonReply = new JObject();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var postData = await ReadPostDataJson();
|
||||||
|
var password = (string)postData["password"];
|
||||||
|
if (string.IsNullOrEmpty(password))
|
||||||
|
{
|
||||||
|
serverService.Config.AdminPassword = string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serverService.Config.AdminPassword = securityService.HashPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
serverService.SaveConfig();
|
||||||
|
jsonReply["result"] = "success";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
jsonReply["result"] = "error";
|
||||||
|
jsonReply["error"] = ex.Message;
|
||||||
|
}
|
||||||
|
return Json(jsonReply);
|
||||||
|
}
|
||||||
|
|
||||||
[Route("get_config_form")]
|
[Route("get_config_form")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IHttpActionResult> GetConfigForm()
|
public async Task<IHttpActionResult> GetConfigForm()
|
||||||
@@ -92,8 +187,6 @@ namespace Jackett.Controllers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
jsonReply["result"] = "success";
|
jsonReply["result"] = "success";
|
||||||
jsonReply["api_key"] = serverService.Config.APIKey;
|
|
||||||
jsonReply["app_version"] = config.GetVersion();
|
|
||||||
JArray items = new JArray();
|
JArray items = new JArray();
|
||||||
|
|
||||||
foreach (var indexer in indexerService.GetAllIndexers())
|
foreach (var indexer in indexerService.GetAllIndexers())
|
||||||
@@ -163,7 +256,13 @@ namespace Jackett.Controllers
|
|||||||
var jsonReply = new JObject();
|
var jsonReply = new JObject();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
jsonReply["config"] = config.ReadServerSettingsFile();
|
var cfg = new JObject();
|
||||||
|
cfg["port"] = serverService.Config.Port;
|
||||||
|
cfg["api_key"] = serverService.Config.APIKey;
|
||||||
|
cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword )? string.Empty:serverService.Config.AdminPassword.Substring(0,10);
|
||||||
|
|
||||||
|
jsonReply["config"] = cfg;
|
||||||
|
jsonReply["app_version"] = config.GetVersion();
|
||||||
jsonReply["result"] = "success";
|
jsonReply["result"] = "success";
|
||||||
}
|
}
|
||||||
catch (CustomException ex)
|
catch (CustomException ex)
|
||||||
|
@@ -94,6 +94,15 @@ namespace Jackett
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ISecuityService SecurityService
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return container.Resolve<ISecuityService>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void SetupLogging(ContainerBuilder builder)
|
private static void SetupLogging(ContainerBuilder builder)
|
||||||
{
|
{
|
||||||
var logConfig = new LoggingConfiguration();
|
var logConfig = new LoggingConfiguration();
|
||||||
|
@@ -73,6 +73,9 @@
|
|||||||
<Reference Include="CsQuery">
|
<Reference Include="CsQuery">
|
||||||
<HintPath>..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll</HintPath>
|
<HintPath>..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.AspNet.Identity.Core">
|
||||||
|
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@@ -85,10 +88,19 @@
|
|||||||
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.2.0.2\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.2.0.2\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Owin.Host.SystemWeb">
|
||||||
|
<HintPath>..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Owin.Hosting, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Owin.Hosting, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Owin.Security">
|
||||||
|
<HintPath>..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Owin.Security.Cookies">
|
||||||
|
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@@ -146,6 +158,7 @@
|
|||||||
<Compile Include="Indexers\SpeedCD.cs" />
|
<Compile Include="Indexers\SpeedCD.cs" />
|
||||||
<Compile Include="Models\Config\ServerConfig.cs" />
|
<Compile Include="Models\Config\ServerConfig.cs" />
|
||||||
<Compile Include="Services\ProcessService.cs" />
|
<Compile Include="Services\ProcessService.cs" />
|
||||||
|
<Compile Include="Services\SecuityService.cs" />
|
||||||
<Compile Include="Services\SerializeService.cs" />
|
<Compile Include="Services\SerializeService.cs" />
|
||||||
<Compile Include="Services\ServiceConfigService.cs" />
|
<Compile Include="Services\ServiceConfigService.cs" />
|
||||||
<Compile Include="Services\SpinService.cs" />
|
<Compile Include="Services\SpinService.cs" />
|
||||||
@@ -184,6 +197,7 @@
|
|||||||
<Compile Include="Indexers\Torrentz.cs" />
|
<Compile Include="Indexers\Torrentz.cs" />
|
||||||
<Compile Include="JackettModule.cs" />
|
<Compile Include="JackettModule.cs" />
|
||||||
<Compile Include="Utils\DateTimeUtil.cs" />
|
<Compile Include="Utils\DateTimeUtil.cs" />
|
||||||
|
<Compile Include="Utils\JackettAuthorizedAttribute.cs" />
|
||||||
<Compile Include="Utils\ParseUtil.cs" />
|
<Compile Include="Utils\ParseUtil.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
@@ -202,6 +216,7 @@
|
|||||||
<Compile Include="CurlHelper.cs" />
|
<Compile Include="CurlHelper.cs" />
|
||||||
<Compile Include="Indexers\AlphaRatio.cs" />
|
<Compile Include="Indexers\AlphaRatio.cs" />
|
||||||
<Compile Include="Utils\StringUtil.cs" />
|
<Compile Include="Utils\StringUtil.cs" />
|
||||||
|
<Compile Include="Utils\WebApiRootRedirectMiddleware.cs" />
|
||||||
<Compile Include="Utils\WebAPIRequestLogger.cs" />
|
<Compile Include="Utils\WebAPIRequestLogger.cs" />
|
||||||
<Compile Include="Utils\WebAPIToNLogTracer.cs" />
|
<Compile Include="Utils\WebAPIToNLogTracer.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -240,6 +255,9 @@
|
|||||||
<Content Include="Content\fonts\glyphicons-halflings-regular.svg">
|
<Content Include="Content\fonts\glyphicons-halflings-regular.svg">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Content\login.html">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Content\logos\animebytes.png">
|
<Content Include="Content\logos\animebytes.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@@ -17,6 +17,7 @@ namespace Jackett.Models.Config
|
|||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
public bool AllowExternal { get; set; }
|
public bool AllowExternal { get; set; }
|
||||||
public string APIKey { get; set; }
|
public string APIKey { get; set; }
|
||||||
|
public string AdminPassword { get; set; }
|
||||||
|
|
||||||
public string GetListenAddress(bool? external = null)
|
public string GetListenAddress(bool? external = null)
|
||||||
{
|
{
|
||||||
|
@@ -18,7 +18,6 @@ namespace Jackett.Services
|
|||||||
string GetVersion();
|
string GetVersion();
|
||||||
string GetIndexerConfigDir();
|
string GetIndexerConfigDir();
|
||||||
string GetAppDataFolder();
|
string GetAppDataFolder();
|
||||||
JObject ReadServerSettingsFile();
|
|
||||||
string GetSonarrConfigFile();
|
string GetSonarrConfigFile();
|
||||||
T GetConfig<T>();
|
T GetConfig<T>();
|
||||||
void SaveConfig<T>(T config);
|
void SaveConfig<T>(T config);
|
||||||
@@ -168,24 +167,5 @@ namespace Jackett.Services
|
|||||||
{
|
{
|
||||||
return Path.Combine(GetAppDataFolder(), "sonarr_api.json");
|
return Path.Combine(GetAppDataFolder(), "sonarr_api.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public JObject ReadServerSettingsFile()
|
|
||||||
{
|
|
||||||
var path = GetConfigFile();
|
|
||||||
JObject jsonReply = new JObject();
|
|
||||||
if (File.Exists(path))
|
|
||||||
{
|
|
||||||
jsonReply = JObject.Parse(File.ReadAllText(path));
|
|
||||||
// Port = (int)jsonReply["port"];
|
|
||||||
// ListenPublic = (bool)jsonReply["public"];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// jsonReply["port"] = Port;
|
|
||||||
// jsonReply["public"] = ListenPublic;
|
|
||||||
}
|
|
||||||
return jsonReply;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
80
src/Jackett/Services/SecuityService.cs
Normal file
80
src/Jackett/Services/SecuityService.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace Jackett.Services
|
||||||
|
{
|
||||||
|
public interface ISecuityService
|
||||||
|
{
|
||||||
|
bool CheckAuthorised(HttpRequestMessage request);
|
||||||
|
string HashPassword(string input);
|
||||||
|
void Login(HttpResponseMessage request);
|
||||||
|
void Logout(HttpResponseMessage request);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SecuityService : ISecuityService
|
||||||
|
{
|
||||||
|
private const string COOKIENAME = "JACKETT";
|
||||||
|
private IServerService serverService;
|
||||||
|
|
||||||
|
public SecuityService(IServerService ss)
|
||||||
|
{
|
||||||
|
serverService = ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string HashPassword(string input)
|
||||||
|
{
|
||||||
|
// Append key as salt
|
||||||
|
input += serverService.Config.APIKey;
|
||||||
|
|
||||||
|
UnicodeEncoding UE = new UnicodeEncoding();
|
||||||
|
byte[] hashValue;
|
||||||
|
byte[] message = UE.GetBytes(input);
|
||||||
|
|
||||||
|
SHA512Managed hashString = new SHA512Managed();
|
||||||
|
string hex = "";
|
||||||
|
|
||||||
|
hashValue = hashString.ComputeHash(message);
|
||||||
|
foreach (byte x in hashValue)
|
||||||
|
{
|
||||||
|
hex += String.Format("{0:x2}", x);
|
||||||
|
}
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Login(HttpResponseMessage response)
|
||||||
|
{
|
||||||
|
// Login
|
||||||
|
response.Headers.Add("Set-Cookie", COOKIENAME + "=" + serverService.Config.AdminPassword + "; path=/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Logout(HttpResponseMessage response)
|
||||||
|
{
|
||||||
|
// Logout
|
||||||
|
response.Headers.Add("Set-Cookie", COOKIENAME + "=; path=/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckAuthorised(HttpRequestMessage request)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(Engine.Server.Config.AdminPassword))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cookie = request.Headers.GetCookies(COOKIENAME).FirstOrDefault();
|
||||||
|
if (cookie != null)
|
||||||
|
{
|
||||||
|
return cookie[COOKIENAME].Value == serverService.Config.AdminPassword;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -26,6 +26,7 @@ namespace Jackett.Services
|
|||||||
void Stop();
|
void Stop();
|
||||||
void ReserveUrls(bool doInstall = true);
|
void ReserveUrls(bool doInstall = true);
|
||||||
ServerConfig Config { get; }
|
ServerConfig Config { get; }
|
||||||
|
void SaveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServerService : IServerService
|
public class ServerService : IServerService
|
||||||
@@ -94,6 +95,11 @@ namespace Jackett.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveConfig()
|
||||||
|
{
|
||||||
|
configService.SaveConfig<ServerConfig>(config);
|
||||||
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
|
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
|
||||||
|
@@ -15,6 +15,8 @@ using Autofac;
|
|||||||
using Jackett.Services;
|
using Jackett.Services;
|
||||||
using System.Web.Http.Tracing;
|
using System.Web.Http.Tracing;
|
||||||
using Jackett.Utils;
|
using Jackett.Utils;
|
||||||
|
using Microsoft.Owin.Security.Cookies;
|
||||||
|
using Microsoft.AspNet.Identity;
|
||||||
|
|
||||||
[assembly: OwinStartup(typeof(Startup))]
|
[assembly: OwinStartup(typeof(Startup))]
|
||||||
namespace Jackett
|
namespace Jackett
|
||||||
@@ -25,6 +27,9 @@ namespace Jackett
|
|||||||
{
|
{
|
||||||
// Configure Web API for self-host.
|
// Configure Web API for self-host.
|
||||||
var config = new HttpConfiguration();
|
var config = new HttpConfiguration();
|
||||||
|
|
||||||
|
appBuilder.Use<WebApiRootRedirectMiddleware>();
|
||||||
|
|
||||||
// Setup tracing if enabled
|
// Setup tracing if enabled
|
||||||
if (Engine.TracingEnabled)
|
if (Engine.TracingEnabled)
|
||||||
{
|
{
|
||||||
@@ -63,11 +68,18 @@ namespace Jackett
|
|||||||
defaults: new { controller = "Download", action = "Download" }
|
defaults: new { controller = "Download", action = "Download" }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
|
||||||
|
LoginPath = new PathString("/Admin/Login")
|
||||||
|
});
|
||||||
|
|
||||||
appBuilder.UseFileServer(new FileServerOptions
|
appBuilder.UseFileServer(new FileServerOptions
|
||||||
{
|
{
|
||||||
RequestPath = new PathString(string.Empty),
|
RequestPath = new PathString(string.Empty),
|
||||||
FileSystem = new PhysicalFileSystem(Engine.ConfigService.GetContentFolder()),
|
FileSystem = new PhysicalFileSystem(Engine.ConfigService.GetContentFolder()),
|
||||||
EnableDirectoryBrowsing = true,
|
EnableDirectoryBrowsing = false,
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
appBuilder.UseWebApi(config);
|
appBuilder.UseWebApi(config);
|
||||||
|
44
src/Jackett/Utils/JackettAuthorizedAttribute.cs
Normal file
44
src/Jackett/Utils/JackettAuthorizedAttribute.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Web.Http.Controllers;
|
||||||
|
using System.Web.Http.Filters;
|
||||||
|
|
||||||
|
namespace Jackett.Utils
|
||||||
|
{
|
||||||
|
public class JackettAuthorizedAttribute : AuthorizationFilterAttribute
|
||||||
|
{
|
||||||
|
public override void OnAuthorization(HttpActionContext actionContext)
|
||||||
|
{
|
||||||
|
// Skip authorisation on blank passwords
|
||||||
|
if (string.IsNullOrEmpty(Engine.Server.Config.AdminPassword))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Engine.SecurityService.CheckAuthorised(actionContext.Request))
|
||||||
|
{
|
||||||
|
if(actionContext.ControllerContext.ControllerDescriptor.ControllerType.GetCustomAttributes(true).Where(a => a.GetType() == typeof(AllowAnonymousAttribute)).Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actionContext.ControllerContext.ControllerDescriptor.ControllerType.GetMethod(actionContext.ActionDescriptor.ActionName).GetCustomAttributes(true).Where(a => a.GetType() == typeof(AllowAnonymousAttribute)).Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode
|
||||||
|
.Unauthorized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -24,11 +24,13 @@ namespace Jackett.Utils
|
|||||||
return await base.SendAsync(request, cancellationToken)
|
return await base.SendAsync(request, cancellationToken)
|
||||||
.ContinueWith(task =>
|
.ContinueWith(task =>
|
||||||
{
|
{
|
||||||
//once response is ready, log it
|
if (null != task.Result.Content)
|
||||||
var responseBody = task.Result.Content.ReadAsStringAsync().Result;
|
{
|
||||||
Trace.WriteLine(responseBody);
|
//once response is ready, log it
|
||||||
Engine.Logger.Debug("Response: " + responseBody);
|
var responseBody = task.Result.Content.ReadAsStringAsync().Result;
|
||||||
|
Trace.WriteLine(responseBody);
|
||||||
|
Engine.Logger.Debug("Response: " + responseBody);
|
||||||
|
}
|
||||||
return task.Result;
|
return task.Result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
32
src/Jackett/Utils/WebApiRootRedirectMiddleware.cs
Normal file
32
src/Jackett/Utils/WebApiRootRedirectMiddleware.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Microsoft.Owin;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Jackett.Utils
|
||||||
|
{
|
||||||
|
public class WebApiRootRedirectMiddleware : OwinMiddleware
|
||||||
|
{
|
||||||
|
public WebApiRootRedirectMiddleware(OwinMiddleware next)
|
||||||
|
: base(next)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public async override Task Invoke(IOwinContext context)
|
||||||
|
{
|
||||||
|
var url = context.Request.Uri;
|
||||||
|
if (string.IsNullOrWhiteSpace(url.AbsolutePath) || url.AbsolutePath == "/")
|
||||||
|
{
|
||||||
|
// 301 is the status code of permanent redirect
|
||||||
|
context.Response.StatusCode = 301;
|
||||||
|
context.Response.Headers.Set("Location", "/Admin/Dashboard");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Next.Invoke(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,6 +6,7 @@
|
|||||||
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net451" userInstalled="true" />
|
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net451" userInstalled="true" />
|
||||||
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net451" userInstalled="true" />
|
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net451" userInstalled="true" />
|
||||||
<package id="CsQuery" version="1.3.4" targetFramework="net451" userInstalled="true" />
|
<package id="CsQuery" version="1.3.4" targetFramework="net451" userInstalled="true" />
|
||||||
|
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net451" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net451" userInstalled="true" />
|
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net451" userInstalled="true" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net451" userInstalled="true" />
|
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net451" userInstalled="true" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net451" userInstalled="true" />
|
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net451" userInstalled="true" />
|
||||||
@@ -14,7 +15,10 @@
|
|||||||
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net451" userInstalled="true" />
|
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net451" userInstalled="true" />
|
||||||
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net451" userInstalled="true" />
|
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net451" userInstalled="true" />
|
||||||
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net451" userInstalled="true" />
|
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net451" userInstalled="true" />
|
||||||
|
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net451" />
|
||||||
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net451" userInstalled="true" />
|
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net451" userInstalled="true" />
|
||||||
|
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net451" />
|
||||||
|
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net451" />
|
||||||
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net451" userInstalled="true" />
|
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net451" userInstalled="true" />
|
||||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net451" userInstalled="true" />
|
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net451" userInstalled="true" />
|
||||||
<package id="NLog" version="4.0.1" targetFramework="net451" userInstalled="true" />
|
<package id="NLog" version="4.0.1" targetFramework="net451" userInstalled="true" />
|
||||||
|
Reference in New Issue
Block a user