Merge branch 'dev'

This commit is contained in:
JonnyWong16 2016-05-22 15:04:25 -07:00
commit 36e81f44cb
9 changed files with 61 additions and 15 deletions

View file

@ -1,5 +1,12 @@
# Changelog # Changelog
## v1.4.2 (2016-05-22)
* New: Option to use HTTP basic authentication instead of the HTML login form.
* Fix: Unable to save settings when enabling the HTTP proxy setting.
* Change: Match the PMS port when retrieving the PMS url.
## v1.4.1 (2016-05-20) ## v1.4.1 (2016-05-20)
* New: HTTP Proxy checkbox in the settings. Enable this if using an SSL enabled reverse proxy in front of PlexPy. * New: HTTP Proxy checkbox in the settings. Enable this if using an SSL enabled reverse proxy in front of PlexPy.

View file

@ -1,10 +1,10 @@
<!--- <!---
Reporting Issues: Reporting Issues:
* To ensure that a develpoer has enough information to work with please include all of the information below. * To ensure that a developer has enough information to work with please include all of the information below.
Please provide as much detail as possible. Screenshots can be very useful to see the problem. Please provide as much detail as possible. Screenshots can be very useful to see the problem.
* Use proper markdown syntax to structure your post (i.e. code/log in code blocks). * Use proper markdown syntax to structure your post (i.e. code/log in code blocks).
See: https://help.github.com/articles/basic-writing-and-formatting-syntax/ See: https://help.github.com/articles/basic-writing-and-formatting-syntax/
* Iclude a link to your **FULL** log file that has the error(not just a few lines!). * Include a link to your **FULL** log file that has the error(not just a few lines!).
Please use [Gist](http://gist.github.com) or [Pastebin](http://pastebin.com/). Please use [Gist](http://gist.github.com) or [Pastebin](http://pastebin.com/).
Feature Requests: Feature Requests:

View file

@ -214,6 +214,7 @@ def main():
'https_key': plexpy.CONFIG.HTTPS_KEY, 'https_key': plexpy.CONFIG.HTTPS_KEY,
'http_username': plexpy.CONFIG.HTTP_USERNAME, 'http_username': plexpy.CONFIG.HTTP_USERNAME,
'http_password': plexpy.CONFIG.HTTP_PASSWORD, 'http_password': plexpy.CONFIG.HTTP_PASSWORD,
'http_basic_auth': plexpy.CONFIG.HTTP_BASIC_AUTH
} }
webstart.initialize(web_config) webstart.initialize(web_config)

View file

@ -434,7 +434,7 @@
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" name="http_proxy http-settings" id="http_proxy" value="1" ${config['http_proxy']}> Enable HTTP Proxy <input type="checkbox" class="http-settings" name="http_proxy" id="http_proxy" value="1" ${config['http_proxy']}> Enable HTTP Proxy
</label> </label>
<p class="help-block">Respect the X-Forwarded-Proto header. Used for reverse proxies with SSL.</p> <p class="help-block">Respect the X-Forwarded-Proto header. Used for reverse proxies with SSL.</p>
</div> </div>
@ -528,10 +528,17 @@
<label> <label>
<input type="checkbox" name="http_hash_password" id="http_hash_password" value="1" ${config['http_hash_password']} data-parsley-trigger="change"> Hash Password in the Config File <input type="checkbox" name="http_hash_password" id="http_hash_password" value="1" ${config['http_hash_password']} data-parsley-trigger="change"> Hash Password in the Config File
</label> </label>
<span id="hashPasswordCheck" style="color: #eb8600; padding-left: 10px;"></span>
<p class="help-block">Store a hashed password in the config file.<br />Warning: Your password cannot be recovered if forgotten!</p> <p class="help-block">Store a hashed password in the config file.<br />Warning: Your password cannot be recovered if forgotten!</p>
</div> </div>
<input type="text" id="http_hashed_password" name="http_hashed_password" value="${config['http_hashed_password']}" style="display: none;" data-parsley-trigger="change" data-parsley-type="integer" data-parsley-range="[0, 1]" <input type="text" id="http_hashed_password" name="http_hashed_password" value="${config['http_hashed_password']}" style="display: none;" data-parsley-trigger="change" data-parsley-type="integer" data-parsley-range="[0, 1]"
data-parsley-errors-container="#http_hash_password_error" data-parsley-error-message="Cannot un-hash password, please set a new password." data-parsley-no-focus required> data-parsley-errors-container="#http_hash_password_error" data-parsley-error-message="Cannot un-hash password, please set a new password." data-parsley-no-focus required>
<div class="checkbox">
<label>
<input type="checkbox" class="auth-settings" name="http_basic_auth" id="http_basic_auth" value="1" ${config['http_basic_auth']} data-parsley-trigger="change"> Use Basic Authentication
</label>
<p class="help-block">Use basic HTTP authentication instead of the HTML login form.</p>
</div>
<div class="padded-header"> <div class="padded-header">
@ -566,7 +573,7 @@
</div> </div>
</div> </div>
</div> </div>
<p class="help-block">Current API key: <strong><br/>${config['api_key']}</strong></p> <p class="help-block">Current API key: <strong> ${config['api_key']}</strong></p>
</div> </div>
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p> <p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
@ -2570,7 +2577,11 @@ $(document).ready(function() {
}); });
function allowGuestAccessCheck () { function allowGuestAccessCheck () {
if ($('#http_username').val() == '' || $('#http_password').val() == '') { if ($("#http_basic_auth").is(":checked")) {
$("#allow_guest_access").attr("disabled", true);
$("#allow_guest_access").attr("checked", false);
$("#allowGuestCheck").html("Guest access cannot be enabled with basic authentication.");
} else if ($('#http_username').val() == '' || $('#http_password').val() == '') {
$("#allow_guest_access").attr("disabled", true); $("#allow_guest_access").attr("disabled", true);
$("#allow_guest_access").attr("checked", false); $("#allow_guest_access").attr("checked", false);
$("#allowGuestCheck").html("You must set an admin password above to allow guest access."); $("#allowGuestCheck").html("You must set an admin password above to allow guest access.");
@ -2581,18 +2592,30 @@ $(document).ready(function() {
} }
allowGuestAccessCheck(); allowGuestAccessCheck();
$('#http_username, #http_password').change(function () { $('#http_username, #http_password, #http_basic_auth').change(function () {
allowGuestAccessCheck(); allowGuestAccessCheck();
}); });
function hashPasswordCheck () {
$("#http_hash_password").click(function(){ if ($("#http_basic_auth").is(":checked")) {
$("#http_hash_password").attr("checked", false);
$("#http_hash_password").attr("disabled", true);
$("#hashPasswordCheck").html("Password cannot be hashed with basic authentication.");
} else {
$("#http_hash_password").attr("disabled", false);
$("#hashPasswordCheck").html("");
}
if (!($("#http_hash_password").is(":checked")) && $("#http_hashed_password").val() == "1" && $("#http_password").val() == " ") { if (!($("#http_hash_password").is(":checked")) && $("#http_hashed_password").val() == "1" && $("#http_password").val() == " ") {
$("#http_hashed_password").val(-1); $("#http_hashed_password").val(-1);
} else if ($("#http_hash_password").is(":checked") && $("#http_hashed_password").val() == "-1" && $("#http_password").val() == " ") { } else if ($("#http_hash_password").is(":checked") && $("#http_hashed_password").val() == "-1" && $("#http_password").val() == " ") {
$("#http_hashed_password").val(1); $("#http_hashed_password").val(1);
$("#http_hash_password_error").html(""); $("#http_hash_password_error").html("");
} }
}
hashPasswordCheck();
$('#http_password, #http_hash_password, #http_basic_auth').change(function () {
hashPasswordCheck();
}); });
$('#http_password').change(function () { $('#http_password').change(function () {

View file

@ -185,6 +185,7 @@ _CONFIG_DEFINITIONS = {
'HTTPS_KEY': (str, 'General', ''), 'HTTPS_KEY': (str, 'General', ''),
'HTTPS_DOMAIN': (str, 'General', 'localhost'), 'HTTPS_DOMAIN': (str, 'General', 'localhost'),
'HTTPS_IP': (str, 'General', '127.0.0.1'), 'HTTPS_IP': (str, 'General', '127.0.0.1'),
'HTTP_BASIC_AUTH': (int, 'General', 0),
'HTTP_ENVIRONMENT': (str, 'General', 'production'), 'HTTP_ENVIRONMENT': (str, 'General', 'production'),
'HTTP_HASH_PASSWORD': (int, 'General', 0), 'HTTP_HASH_PASSWORD': (int, 'General', 0),
'HTTP_HASHED_PASSWORD': (int, 'General', 0), 'HTTP_HASHED_PASSWORD': (int, 'General', 0),

View file

@ -108,7 +108,8 @@ def get_real_pms_url():
if connections: if connections:
# Get connection with matching address, otherwise return first connection # Get connection with matching address, otherwise return first connection
conn = next((c for c in connections if c['address'] == plexpy.CONFIG.PMS_IP), connections[0]) conn = next((c for c in connections if c['address'] == plexpy.CONFIG.PMS_IP
and c['port'] == plexpy.CONFIG.PMS_PORT), connections[0])
plexpy.CONFIG.__setattr__('PMS_URL', conn['uri']) plexpy.CONFIG.__setattr__('PMS_URL', conn['uri'])
plexpy.CONFIG.write() plexpy.CONFIG.write()
logger.info(u"PlexPy PlexTV :: Server URL retrieved.") logger.info(u"PlexPy PlexTV :: Server URL retrieved.")

View file

@ -1,2 +1,2 @@
PLEXPY_VERSION = "master" PLEXPY_VERSION = "master"
PLEXPY_RELEASE_VERSION = "1.4.1" PLEXPY_RELEASE_VERSION = "1.4.2"

View file

@ -2247,6 +2247,7 @@ class WebInterface(object):
config = { config = {
"allow_guest_access": checked(plexpy.CONFIG.ALLOW_GUEST_ACCESS), "allow_guest_access": checked(plexpy.CONFIG.ALLOW_GUEST_ACCESS),
"http_basic_auth": checked(plexpy.CONFIG.HTTP_BASIC_AUTH),
"http_hash_password": checked(plexpy.CONFIG.HTTP_HASH_PASSWORD), "http_hash_password": checked(plexpy.CONFIG.HTTP_HASH_PASSWORD),
"http_hashed_password": plexpy.CONFIG.HTTP_HASHED_PASSWORD, "http_hashed_password": plexpy.CONFIG.HTTP_HASHED_PASSWORD,
"http_host": plexpy.CONFIG.HTTP_HOST, "http_host": plexpy.CONFIG.HTTP_HOST,
@ -2367,7 +2368,7 @@ class WebInterface(object):
"ip_logging_enable", "movie_logging_enable", "tv_logging_enable", "music_logging_enable", "ip_logging_enable", "movie_logging_enable", "tv_logging_enable", "music_logging_enable",
"notify_consecutive", "notify_upload_posters", "notify_recently_added", "notify_recently_added_grandparent", "notify_consecutive", "notify_upload_posters", "notify_recently_added", "notify_recently_added_grandparent",
"monitor_pms_updates", "monitor_remote_access", "get_file_sizes", "log_blacklist", "http_hash_password", "monitor_pms_updates", "monitor_remote_access", "get_file_sizes", "log_blacklist", "http_hash_password",
"allow_guest_access", "cache_images", "http_proxy" "allow_guest_access", "cache_images", "http_proxy", "http_basic_auth"
] ]
for checked_config in checked_configs: for checked_config in checked_configs:
if checked_config not in kwargs: if checked_config not in kwargs:

View file

@ -66,8 +66,13 @@ def initialize(options):
if options['http_password']: if options['http_password']:
logger.info(u"PlexPy WebStart :: Web server authentication is enabled, username is '%s'", options['http_username']) logger.info(u"PlexPy WebStart :: Web server authentication is enabled, username is '%s'", options['http_username'])
options_dict['tools.sessions.on'] = auth_enabled = session_enabled = True if options['http_basic_auth']:
cherrypy.tools.auth = cherrypy.Tool('before_handler', webauth.check_auth) auth_enabled = session_enabled = False
basic_auth_enabled = True
else:
options_dict['tools.sessions.on'] = auth_enabled = session_enabled = True
basic_auth_enabled = False
cherrypy.tools.auth = cherrypy.Tool('before_handler', webauth.check_auth)
else: else:
auth_enabled = session_enabled = False auth_enabled = session_enabled = False
@ -88,7 +93,14 @@ def initialize(options):
'application/javascript'], 'application/javascript'],
'tools.auth.on': auth_enabled, 'tools.auth.on': auth_enabled,
'tools.sessions.on': session_enabled, 'tools.sessions.on': session_enabled,
'tools.sessions.timeout': 30 * 24 * 60 # 30 days 'tools.sessions.timeout': 30 * 24 * 60, # 30 days
'tools.auth_basic.on': basic_auth_enabled,
'tools.auth_basic.realm': 'PlexPy web server',
'tools.auth_basic.checkpassword': cherrypy.lib.auth_basic.checkpassword_dict({
options['http_username']: options['http_password']})
},
'/api': {
'tools.auth_basic.on': False
}, },
'/interfaces': { '/interfaces': {
'tools.staticdir.on': True, 'tools.staticdir.on': True,
@ -199,7 +211,7 @@ def initialize(options):
'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days
'tools.auth.on': False, 'tools.auth.on': False,
'tools.sessions.on': False 'tools.sessions.on': False
}, }
} }
# Prevent time-outs # Prevent time-outs