1
0
Fork 0
mirror of https://github.com/Jackett/Jackett synced 2025-02-24 23:22:46 +00:00

Implement recaptcha for torrentday (This will only work for localhost)

This commit is contained in:
KZ 2015-08-08 00:15:42 +01:00
parent 6ea759aeab
commit d1ff05ac13
7 changed files with 172 additions and 100 deletions

View file

@ -197,8 +197,8 @@ function reloadIndexers() {
} }
function displayIndexers(items) { function displayIndexers(items) {
var indexerTemplate = Handlebars.compile($("#templates > .configured-indexer")[0].outerHTML); var indexerTemplate = Handlebars.compile($("#configured-indexer").html());
var unconfiguredIndexerTemplate = Handlebars.compile($("#templates > .unconfigured-indexer")[0].outerHTML); var unconfiguredIndexerTemplate = Handlebars.compile($("#unconfigured-indexer").html());
for (var i = 0; i < items.length; i++) { for (var i = 0; i < items.length; i++) {
var item = items[i]; var item = items[i];
item.torznab_host = resolveUrl("/torznab/" + item.id); item.torznab_host = resolveUrl("/torznab/" + item.id);
@ -209,7 +209,7 @@ function displayIndexers(items) {
$('#unconfigured-indexers').append($(unconfiguredIndexerTemplate(item))); $('#unconfigured-indexers').append($(unconfiguredIndexerTemplate(item)));
} }
var addIndexerButton = $("#templates > .add-indexer")[0].outerHTML; var addIndexerButton = $('#add-indexer').html();
$('#indexers').append(addIndexerButton); $('#indexers').append(addIndexerButton);
$('#indexers').fadeIn(); $('#indexers').fadeIn();
@ -293,12 +293,22 @@ function populateConfigItems(configForm, config) {
} }
var $formItemContainer = configForm.find(".config-setup-form"); var $formItemContainer = configForm.find(".config-setup-form");
$formItemContainer.empty(); $formItemContainer.empty();
var setupItemTemplate = Handlebars.compile($("#templates > .setup-item")[0].outerHTML); var setupItemTemplate = Handlebars.compile($("#setup-item").html());
for (var i = 0; i < config.length; i++) { for (var i = 0; i < config.length; i++) {
var item = config[i]; var item = config[i];
var setupValueTemplate = Handlebars.compile($("#templates > .setup-item-" + item.type)[0].outerHTML); var setupValueTemplate = Handlebars.compile($("#setup-item-" + item.type).html());
item.value_element = setupValueTemplate(item); item.value_element = setupValueTemplate(item);
$formItemContainer.append(setupItemTemplate(item)); var template = setupItemTemplate(item);
$formItemContainer.append(template);
if (item.type === 'recaptcha') {
grecaptcha.render($('.jackettrecaptcha')[0], {
'sitekey': item.sitekey
});
}
} }
} }
@ -327,6 +337,9 @@ function getConfigModalJson(configForm) {
case "inputbool": case "inputbool":
itemEntry.value = $el.find(".setup-item-inputbool input").is(":checked"); itemEntry.value = $el.find(".setup-item-inputbool input").is(":checked");
break; break;
case "recaptcha":
itemEntry.value = $('.g-recaptcha-response').val();
break;
} }
configJson.push(itemEntry) configJson.push(itemEntry)
}); });
@ -342,7 +355,7 @@ function populateSetupForm(indexerId, name, config, caps) {
var originalBtnText = $goButton.html(); var originalBtnText = $goButton.html();
$goButton.prop('disabled', true); $goButton.prop('disabled', true);
$goButton.html($('#templates > .spinner')[0].outerHTML); $goButton.html($('#spinner').html());
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") {

View file

@ -13,6 +13,7 @@
<script src="/libs/handlebarsmoment.js"></script> <script src="/libs/handlebarsmoment.js"></script>
<script src="/bootstrap/bootstrap.min.js"></script> <script src="/bootstrap/bootstrap.min.js"></script>
<script src="/libs/bootstrap-notify.js"></script> <script src="/libs/bootstrap-notify.js"></script>
<script src='https://www.google.com/recaptcha/api.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">
@ -20,6 +21,85 @@
<link href="/css/jquery.dataTables.css" rel="stylesheet"> <link href="/css/jquery.dataTables.css" rel="stylesheet">
<link rel="stylesheet" href="/css/font-awesome.min.css"> <link rel="stylesheet" href="/css/font-awesome.min.css">
<script id="setup-item" type="text/x-handlebars-template">
<div class="setup-item form-group" data-id="{{id}}" data-value="{{value}}" data-type="{{type}}">
<div class="setup-item-label">{{name}}</div>
<div class="setup-item-value">{{{value_element}}}</div>
</div>
</script>
<script id="setup-item-inputstring" type="text/x-handlebars-template">
<div class="setup-item-inputstring">
{{#if ispassword}}
<input class="form-control" type="password" value="{{{value}}}" />
{{else}}
<input class="form-control" type="text" value="{{{value}}}" />
{{/if}}
</div>
</script>
<script id="setup-item-inputbool" type="text/x-handlebars-template">
<div class="setup-item-inputbool">
{{#if value}}
<input type="checkbox" data-id="{{id}}" class="form-control" checked />
{{else}}
<input type="checkbox" data-id="{{id}}" class="form-control" />
{{/if}}
</div>
</script>
<script id="setup-item-recaptcha" type="text/x-handlebars-template">
<div class="jackettrecaptcha">
</div>
</script>
<script id="setup-item-displayimage" type="text/x-handlebars-template">
<img class="setup-item-displayimage" src="{{{value}}}" />
</script>
<script id="setup-item-displayinfo" type="text/x-handlebars-template">
<div class="setup-item-displayinfo alert alert-info" role="alert">{{{value}}}</div>
</script>
<script id="setup-item-hiddendata" type="text/x-handlebars-template">
<div class="setup-item-hiddendata">
<input class="form-control" type="text" value="{{{value}}}" />
</div>
</script>
<script id="configured-indexer" type="text/x-handlebars-template">
<div class="configured-indexer indexer card">
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
<div class="indexer-buttons">
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}">
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
</button>
<button class="btn btn-danger btn-sm indexer-button-delete" data-id="{{id}}">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
<a class="btn btn-info btn-sm" target="_blank" href="{{site_link}}">
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
</a>
<button class="btn btn-warning btn-sm indexer-button-test" data-id="{{id}}">
Test <span class="glyphicon glyphicon-screenshot" aria-hidden="true"></span>
</button>
</div>
<div class="indexer-host">
<b>Torznab Host:</b>
<input class="form-control" type="text" value="{{torznab_host}}" placeholder="Torznab Host" readonly="">
<b>CouchPotato Host:</b>
{{#if potatoenabled}}
<input class="form-control" type="text" value="{{potato_host}}" placeholder="Torznab Host" readonly="">
{{else}}
<input class="form-control" type="text" value="Not availible" placeholder="Torznab Host" readonly="">
{{/if}}
</div>
</div>
</script>
<script id="unconfigured-indexer" type="text/x-handlebars-template">
<div class="unconfigured-indexer card">
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
<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>
<button class="indexer-setup btn btn-success" data-id="{{id}}">Setup <span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
</div>
</div>
</script>
<script id="jackett-releases" type="text/x-handlebars-template"> <script id="jackett-releases" type="text/x-handlebars-template">
<div id="select-indexer-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true"> <div id="select-indexer-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg modal-fillwidth"> <div class="modal-dialog modal-lg modal-fillwidth">
@ -164,6 +244,17 @@
</div> </div>
</div> </div>
</script> </script>
<script id="add-indexer" type="text/x-handlebars-template">
<button class="indexer card add-indexer" data-toggle="modal" data-target="#select-indexer-modal">
<div class="indexer-add-content">
<span class="glyphicon glyphicon glyphicon-plus" aria-hidden="true"></span>
<div class="light-text">Add</div>
</div>
</button>
</script>
<script id="spinner" type="text/x-handlebars-template">
<span class="spinner glyphicon glyphicon-refresh"></span>
</script>
<title>Jackett</title> <title>Jackett</title>
</head> </head>
@ -248,85 +339,6 @@
</div> </div>
<div id="modals"></div> <div id="modals"></div>
<div id="templates">
<button class="indexer card add-indexer" data-toggle="modal" data-target="#select-indexer-modal">
<div class="indexer-add-content">
<span class="glyphicon glyphicon glyphicon-plus" aria-hidden="true"></span>
<div class="light-text">Add</div>
</div>
</button>
<div class="configured-indexer indexer card">
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
<div class="indexer-buttons">
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}">
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
</button>
<button class="btn btn-danger btn-sm indexer-button-delete" data-id="{{id}}">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
<a class="btn btn-info btn-sm" target="_blank" href="{{site_link}}">
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
</a>
<button class="btn btn-warning btn-sm indexer-button-test" data-id="{{id}}">
Test <span class="glyphicon glyphicon-screenshot" aria-hidden="true"></span>
</button>
</div>
<div class="indexer-host">
<b>Torznab Host:</b>
<input class="form-control" type="text" value="{{torznab_host}}" placeholder="Torznab Host" readonly="">
<b>CouchPotato Host:</b>
{{#if potatoenabled}}
<input class="form-control" type="text" value="{{potato_host}}" placeholder="Torznab Host" readonly="">
{{else}}
<input class="form-control" type="text" value="Not availible" placeholder="Torznab Host" readonly="">
{{/if}}
</div>
</div>
<div class="unconfigured-indexer card">
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
<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>
<button class="indexer-setup btn btn-success" data-id="{{id}}">Setup <span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
</div>
</div>
<div class="setup-item form-group" data-id="{{id}}" data-value="{{value}}" data-type="{{type}}">
<div class="setup-item-label">{{name}}</div>
<div class="setup-item-value">{{{value_element}}}</div>
</div>
<div class="setup-item-inputstring">
{{#if ispassword}}
<input class="form-control" type="password" value="{{{value}}}" />
{{else}}
<input class="form-control" type="text" value="{{{value}}}" />
{{/if}}
</div>
<div class="setup-item-inputbool">
{{#if value}}
<input type="checkbox" data-id="{{id}}" class="form-control" checked />
{{else}}
<input type="checkbox" data-id="{{id}}" class="form-control" />
{{/if}}
</div>
<img class="setup-item-displayimage" src="{{{value}}}" />
<div class="setup-item-displayinfo alert alert-info" role="alert">{{{value}}}</div>
<div class="setup-item-hiddendata">
<input class="form-control" type="text" value="{{{value}}}" />
</div>
<span class="spinner glyphicon glyphicon-refresh"></span>
</div>
<script src="/custom.js"></script> <script src="/custom.js"></script>
</body> </body>
</html> </html>

View file

@ -31,4 +31,3 @@ Handlebars.registerHelper('jacketTimespan', function (context, block) {
var years = timeSpan.asYears(); var years = timeSpan.asYears();
return Math.round(years) + 'y ago'; return Math.round(years) + 'y ago';
}); });

View file

@ -25,9 +25,9 @@ namespace Jackett.Indexers
private string LoginUrl { get { return SiteLink + "tak3login.php"; } } private string LoginUrl { get { return SiteLink + "tak3login.php"; } }
private string SearchUrl { get { return SiteLink + "browse.php"; } } private string SearchUrl { get { return SiteLink + "browse.php"; } }
new ConfigurationDataBasicLogin configData new ConfigurationDataRecaptchaLogin configData
{ {
get { return (ConfigurationDataBasicLogin)base.configData; } get { return (ConfigurationDataRecaptchaLogin)base.configData; }
set { base.configData = value; } set { base.configData = value; }
} }
@ -40,7 +40,7 @@ namespace Jackett.Indexers
client: wc, client: wc,
logger: l, logger: l,
p: ps, p: ps,
configData: new ConfigurationDataBasicLogin()) configData: new ConfigurationDataRecaptchaLogin())
{ {
AddCategoryMapping(29, TorznabCatType.Anime); AddCategoryMapping(29, TorznabCatType.Anime);
@ -84,19 +84,26 @@ namespace Jackett.Indexers
AddCategoryMapping(15, TorznabCatType.XXX); AddCategoryMapping(15, TorznabCatType.XXX);
} }
public override async Task<ConfigurationData> GetConfigurationForSetup()
{
var loginPage = await RequestStringWithCookies(StartPageUrl, string.Empty);
CQ cq = loginPage.Content;
var result = new ConfigurationDataRecaptchaLogin();
result.CookieHeader.Value = loginPage.Cookies;
result.Captcha.SiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
return result;
}
public async Task ApplyConfiguration(JToken configJson) public async Task ApplyConfiguration(JToken configJson)
{ {
configData.LoadValuesFromJson(configJson); configData.LoadValuesFromJson(configJson);
var startMessage = await RequestStringWithCookies(StartPageUrl, string.Empty);
var pairs = new Dictionary<string, string> { var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value }, { "username", configData.Username.Value },
{ "password", configData.Password.Value } { "password", configData.Password.Value },
{ "g-recaptcha-response", configData.Captcha.Value }
}; };
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SiteLink, LoginUrl); var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, SiteLink, LoginUrl);
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () => await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
{ {
CQ dom = result.Content; CQ dom = result.Content;

View file

@ -213,6 +213,7 @@
<Compile Include="Models\CachedLog.cs" /> <Compile Include="Models\CachedLog.cs" />
<Compile Include="Models\CachedResult.cs" /> <Compile Include="Models\CachedResult.cs" />
<Compile Include="Models\CategoryMapping.cs" /> <Compile Include="Models\CategoryMapping.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataRecaptchaLogin.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataLoginTokin.cs" /> <Compile Include="Models\IndexerConfig\ConfigurationDataLoginTokin.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataNCore.cs" /> <Compile Include="Models\IndexerConfig\ConfigurationDataNCore.cs" />
<Compile Include="Models\IndexerConfig\ConfigurationDataCaptchaLogin.cs" /> <Compile Include="Models\IndexerConfig\ConfigurationDataCaptchaLogin.cs" />

View file

@ -20,7 +20,8 @@ namespace Jackett.Models.IndexerConfig
InputBool, InputBool,
DisplayImage, DisplayImage,
DisplayInfo, DisplayInfo,
HiddenData HiddenData,
Recaptcha
} }
public HiddenItem CookieHeader { get; private set; } = new HiddenItem { Name = "CookieHeader" }; public HiddenItem CookieHeader { get; private set; } = new HiddenItem { Name = "CookieHeader" };
@ -69,6 +70,9 @@ namespace Jackett.Models.IndexerConfig
case ItemType.InputBool: case ItemType.InputBool:
((BoolItem)item).Value = arrItem.Value<bool>("value"); ((BoolItem)item).Value = arrItem.Value<bool>("value");
break; break;
case ItemType.Recaptcha:
((RecaptchaItem)item).Value = arrItem.Value<string>("value");
break;
} }
} }
} }
@ -85,6 +89,9 @@ namespace Jackett.Models.IndexerConfig
jObject["name"] = item.Name; jObject["name"] = item.Name;
switch (item.ItemType) switch (item.ItemType)
{ {
case ItemType.Recaptcha:
jObject["sitekey"] = ((RecaptchaItem)item).SiteKey;
break;
case ItemType.InputString: case ItemType.InputString:
case ItemType.HiddenData: case ItemType.HiddenData:
case ItemType.DisplayInfo: case ItemType.DisplayInfo:
@ -98,7 +105,6 @@ namespace Jackett.Models.IndexerConfig
else if (ps != null) else if (ps != null)
value = ps.Protect(value); value = ps.Protect(value);
} }
jObject["value"] = value; jObject["value"] = value;
break; break;
case ItemType.InputBool: case ItemType.InputBool:
@ -125,7 +131,7 @@ namespace Jackett.Models.IndexerConfig
if (!forDisplay) if (!forDisplay)
{ {
properties = properties properties = properties
.Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString) .Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString || p.ItemType == ItemType.Recaptcha)
.ToArray(); .ToArray();
} }
@ -159,6 +165,7 @@ namespace Jackett.Models.IndexerConfig
public class StringItem : Item public class StringItem : Item
{ {
public string SiteKey { get; set; }
public string Value { get; set; } public string Value { get; set; }
public StringItem() public StringItem()
{ {
@ -166,6 +173,14 @@ namespace Jackett.Models.IndexerConfig
} }
} }
public class RecaptchaItem : StringItem
{
public RecaptchaItem()
{
ItemType = ConfigurationData.ItemType.Recaptcha;
}
}
public class BoolItem : Item public class BoolItem : Item
{ {
public bool Value { get; set; } public bool Value { get; set; }

View file

@ -0,0 +1,25 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett.Models.IndexerConfig
{
public class ConfigurationDataRecaptchaLogin : ConfigurationData
{
public StringItem Username { get; private set; }
public StringItem Password { get; private set; }
public RecaptchaItem Captcha { get; private set; }
public ConfigurationDataRecaptchaLogin()
{
Username = new StringItem { Name = "Username" };
Password = new StringItem { Name = "Password" };
Captcha = new RecaptchaItem() { Name = "Recaptcha" };
}
}
}