OPDS Authentication, Cleanup, and Config Fixes

This commit is contained in:
DarkSir23 2017-10-31 12:57:26 -04:00 committed by evilhero
parent 9f739d8246
commit e1f4cabc0b
6 changed files with 127 additions and 32 deletions

View File

@ -240,6 +240,10 @@ def main():
'https_chain': mylar.CONFIG.HTTPS_CHAIN,
'http_username': mylar.CONFIG.HTTP_USERNAME,
'http_password': mylar.CONFIG.HTTP_PASSWORD,
'opds_enable': mylar.CONFIG.OPDS_ENABLE,
'opds_authentication': mylar.CONFIG.OPDS_AUTHENTICATION,
'opds_username': mylar.CONFIG.OPDS_USERNAME,
'opds_password': mylar.CONFIG.OPDS_PASSWORD,
}
# Try to start the server.

View File

@ -204,6 +204,34 @@
</div>
</div>
</fieldset>
<fieldset>
<legend>OPDS</legend>
<div class="row">
<div class="row_checkbox">
<input id="opds_enable" type="checkbox" name="opds_enable" value="1" ${config['opds_enable']} /><label>Enable OPDS</label>
</div>
<div id="opdsoptions">
<div class="row_checkbox">
<input id="opds_authentication" type="checkbox" name="opds_authentication" value="1" ${config['opds_authentication']} /><label>OPDS Requires Credentials</label>
<%
opds_notes = "Require authentication for OPDS. If checked\nyou will need to provide a username/password.\nThe service user name will work (if set). Additionally,\nyou can provide a user with only OPDS access below.\nNOTE: If this is not checked, OPDS will be available\nwithout a password."
%>
<a href="#" title="${opds_notes}"><img src="interfaces/default/images/info32.png" height="16" alt="" /></a>
<div id="opdscredentials">
<div class="row">
<label>OPDS Username</label>
<input type="text" name="opds_username" value="${config['opds_username']}" size="30">
</div>
<div class="row">
<label>OPDS Password</label>
<input type="password" name="opds_password" value="${config['opds_password']| h}" size="30">
</div>
</div>
</div>
</div>
</div>
</fieldset>
<fieldset>
<legend>Interval</legend>
<div class="row">
@ -1366,7 +1394,45 @@
$("#apioptions").slideUp();
}
});
if ($("#opds_enable").is(":checked"))
{
$("#opdsoptions").show();
}
else
{
$("#opdsoptions").hide();
}
$("#opds_enable").click(function(){
if ($("#opds_enable").is(":checked"))
{
$("#opdsoptions").slideDown();
}
else
{
$("#opdsoptions").slideUp();
}
});
if ($("#opds_authentication").is(":checked"))
{
$("#opdscredentials").show();
}
else
{
$("#opdscredentials").hide();
}
$("#opds_authentication").click(function(){
if ($("#opds_authentication").is(":checked"))
{
$("#opdscredentials").slideDown();
}
else
{
$("#opdscredentials").slideUp();
}
});
if ($("#cbr2cbz").is(":checked"))
{

View File

@ -44,8 +44,8 @@ _CONFIG_DEFINITIONS = OrderedDict({
'CORRECT_METADATA': (bool, 'General', False),
'MOVE_FILES': (bool, 'General', False),
'RENAME_FILES': (bool, 'General', False),
'FOLDER_FORMAT': (str, 'General', None),
'FILE_FORMAT': (str, 'General', None),
'FOLDER_FORMAT': (str, 'General', '$Series ($Year)'),
'FILE_FORMAT': (str, 'General', '$Series $Annual $Issue ($Year)'),
'REPLACE_SPACES': (bool, 'General', False),
'REPLACE_CHAR': (str, 'General', None),
'ZERO_LEVEL': (bool, 'General', False),
@ -104,7 +104,7 @@ _CONFIG_DEFINITIONS = OrderedDict({
'CV_VERIFY': (bool, 'CV', True),
'CV_ONLY': (bool, 'CV', True),
'CV_ONETIMER': (bool, 'CV', True),
'CVINFO': (bool, 'CV', True),
'CVINFO': (bool, 'CV', False),
'LOG_DIR' : (str, 'Logs', None),
'MAX_LOGSIZE' : (int, 'Logs', 10000000),
@ -320,9 +320,9 @@ _CONFIG_DEFINITIONS = OrderedDict({
'QBITTORRENT_STARTONLOAD': (bool, 'qBittorrent', False),
'OPDS_ENABLE': (bool, 'OPDS', False),
'OPDS_READONLYUSER': (bool, 'OPDS', False),
'OPDS_READONLYUSERNAME': (str, 'OPDS', None),
'OPDS_READONLYPASSWORD': (str, 'OPDS', None),
'OPDS_AUTHENTICATION': (bool, 'OPDS', False),
'OPDS_USERNAME': (str, 'OPDS', None),
'OPDS_PASSWORD': (str, 'OPDS', None),
})

View File

@ -20,7 +20,6 @@ import mylar
from mylar import db, mb, importer, search, PostProcessor, versioncheck, logger
import simplejson as simplejson
import cherrypy
from lxml import etree
import os
import urllib2
import cache
@ -81,12 +80,9 @@ class OPDS(object):
return self.data
def _error_with_message(self, message):
feed = etree.Element("feed")
error = etree.SubElement(feed,'error')
error.text = message
error = '<feed><error>%s</error></feed>' % message
cherrypy.response.headers['Content-Type'] = "text/xml"
return etree.tostring(feed)
return error
def _root(self, **kwargs):
myDB = db.DBConnection()
@ -96,23 +92,9 @@ class OPDS(object):
feed['updated'] = mylar.helpers.now()
links = []
entries=[]
links.append({
'href': '/opds',
'type': 'application/atom+xml;profile=opds-catalog;kind=navigation',
'rel': 'start',
'title': 'Home'
})
links.append({
'href': '/opds',
'type': 'application/atom+xml;profile=opds-catalog;kind=navigation',
'rel': 'self',
})
links.append({
'href': '/opds?cmd=search',
'type': 'application/opensearchdescription+xml',
'rel': 'search',
'title': 'Search',
})
links.append(getLink(href='/opds',type='application/atom+xml;profile=opds-catalog;kind=navigation', rel='start', title='Home'))
links.append(getLink(href='/opds',type='application/atom+xml;profile=opds-catalog;kind=navigation',rel='self'))
links.append(getLink(href='/opds?cmd=search', type='application/opensearchdescription+xml',rel='search',title='Search'))
publishers = myDB.select("SELECT ComicPublisher from comics GROUP BY ComicPublisher")
if len(publishers) > 0:
count = len(publishers)
@ -142,7 +124,33 @@ class OPDS(object):
'kind': 'navigation'
}
)
storyArcs = mylar.helpers.listStoryArcs()
logger.debug(storyArcs)
if len(storyArcs) > 0:
entries.append(
{
'title': 'Story Arcs (%s)' % len(storyArcs),
'id': 'StoryArcs',
'updated': mylar.helpers.now(),
'content': 'List of Story Arcs',
'href': '/opds?cmd=StoryArcs',
'kind': 'navigation'
}
)
feed['links'] = links
feed['entries'] = entries
self.data = feed
return
return
def getLink(href=None, type=None, rel=None, title=None):
link = {}
if href:
link['href'] = href
if type:
link['type'] = type
if rel:
link['rel'] = rel
if title:
link['title'] = title
return link

View File

@ -4353,7 +4353,11 @@ class WebInterface(object):
"config_file": mylar.CONFIG_FILE,
"branch_history": 'None',
# "branch_history" : br_hist,
"log_dir": mylar.CONFIG.LOG_DIR
"log_dir": mylar.CONFIG.LOG_DIR,
"opds_enable": helpers.checked(mylar.CONFIG.OPDS_ENABLE),
"opds_authentication": helpers.checked(mylar.CONFIG.OPDS_AUTHENTICATION),
"opds_username": mylar.CONFIG.OPDS_USERNAME,
"opds_password": mylar.CONFIG.OPDS_PASSWORD,
}
return serve_template(templatename="config.html", title="Settings", config=config, comicinfo=comicinfo)
config.exposed = True
@ -4570,7 +4574,8 @@ class WebInterface(object):
'enable_meta', 'cbr2cbz_only', 'ct_tag_cr', 'ct_tag_cbl', 'ct_cbz_overwrite', 'rename_files', 'replace_spaces', 'zero_level',
'lowercase_filenames', 'autowant_upcoming', 'autowant_all', 'comic_cover_local', 'cvinfo', 'snatchedtorrent_notify',
'prowl_enabled', 'prowl_onsnatch', 'nma_enabled', 'nma_onsnatch', 'pushover_enabled', 'pushover_onsnatch', 'boxcar_enabled',
'boxcar_onsnatch', 'pushbullet_enabled', 'pushbullet_onsnatch', 'telegram_enabled', 'telegram_onsnatch', 'slack_enabled', 'slack_onsnatch' ]
'boxcar_onsnatch', 'pushbullet_enabled', 'pushbullet_onsnatch', 'telegram_enabled', 'telegram_onsnatch', 'slack_enabled', 'slack_onsnatch',
'opds_enable', 'opds_authentication']
for checked_config in checked_configs:
if checked_config not in kwargs:

View File

@ -125,6 +125,18 @@ def initialize(options):
})
conf['/api'] = {'tools.auth_basic.on': False}
if options['opds_authentication']:
user_list = {}
if len(options['opds_username']) > 0:
user_list[options['opds_username']] = options['opds_password']
if options['http_password'] is not None and options['http_username'] != options['opds_username']:
user_list[options['http_username']] = options['http_password']
conf['/opds'] = {'tools.auth_basic.on': True,
'tools.auth_basic.realm': 'Mylar OPDS',
'tools.auth_basic.checkpassword': cherrypy.lib.auth_basic.checkpassword_dict(user_list)}
else:
conf['/opds'] = {'tools.auth_basic.on': False}
# Prevent time-outs
cherrypy.engine.timeout_monitor.unsubscribe()