diff --git a/PlexPy.py b/PlexPy.py index 5ea68130..82a91808 100755 --- a/PlexPy.py +++ b/PlexPy.py @@ -214,6 +214,7 @@ def main(): 'https_key': plexpy.CONFIG.HTTPS_KEY, 'http_username': plexpy.CONFIG.HTTP_USERNAME, 'http_password': plexpy.CONFIG.HTTP_PASSWORD, + 'http_basic_auth': plexpy.CONFIG.HTTP_BASIC_AUTH } webstart.initialize(web_config) diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 169ab3d6..a6cedf9a 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -528,10 +528,17 @@ +
Store a hashed password in the config file.
Warning: Your password cannot be recovered if forgotten!
Use basic HTTP authentication instead of the HTML login form.
+Current API key:
${config['api_key']}
Current API key: ${config['api_key']}
@@ -2570,7 +2577,11 @@ $(document).ready(function() { }); 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("checked", false); $("#allowGuestCheck").html("You must set an admin password above to allow guest access."); @@ -2581,18 +2592,30 @@ $(document).ready(function() { } allowGuestAccessCheck(); - $('#http_username, #http_password').change(function () { + $('#http_username, #http_password, #http_basic_auth').change(function () { allowGuestAccessCheck(); }); - - $("#http_hash_password").click(function(){ + function hashPasswordCheck () { + 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() == " ") { $("#http_hashed_password").val(-1); } else if ($("#http_hash_password").is(":checked") && $("#http_hashed_password").val() == "-1" && $("#http_password").val() == " ") { $("#http_hashed_password").val(1); $("#http_hash_password_error").html(""); } + } + hashPasswordCheck(); + + $('#http_password, #http_hash_password, #http_basic_auth').change(function () { + hashPasswordCheck(); }); $('#http_password').change(function () { diff --git a/plexpy/config.py b/plexpy/config.py index 02a89c4d..e1b70d53 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -185,6 +185,7 @@ _CONFIG_DEFINITIONS = { 'HTTPS_KEY': (str, 'General', ''), 'HTTPS_DOMAIN': (str, 'General', 'localhost'), 'HTTPS_IP': (str, 'General', '127.0.0.1'), + 'HTTP_BASIC_AUTH': (int, 'General', 0), 'HTTP_ENVIRONMENT': (str, 'General', 'production'), 'HTTP_HASH_PASSWORD': (int, 'General', 0), 'HTTP_HASHED_PASSWORD': (int, 'General', 0), diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 008ee775..d5cbcb00 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -2247,6 +2247,7 @@ class WebInterface(object): config = { "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_hashed_password": plexpy.CONFIG.HTTP_HASHED_PASSWORD, "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", "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", - "allow_guest_access", "cache_images", "http_proxy" + "allow_guest_access", "cache_images", "http_proxy", "http_basic_auth" ] for checked_config in checked_configs: if checked_config not in kwargs: diff --git a/plexpy/webstart.py b/plexpy/webstart.py index d9197d39..e498ce29 100644 --- a/plexpy/webstart.py +++ b/plexpy/webstart.py @@ -66,8 +66,13 @@ def initialize(options): if options['http_password']: 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 - cherrypy.tools.auth = cherrypy.Tool('before_handler', webauth.check_auth) + if options['http_basic_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: auth_enabled = session_enabled = False @@ -88,7 +93,14 @@ def initialize(options): 'application/javascript'], 'tools.auth.on': auth_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': { 'tools.staticdir.on': True, @@ -199,7 +211,7 @@ def initialize(options): 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.auth.on': False, 'tools.sessions.on': False - }, + } } # Prevent time-outs