From f8048a01a6b71233282c9d76c985932a846eaa25 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Wed, 5 Jan 2022 15:52:09 -0800 Subject: [PATCH] Validate settings when saving config --- plexpy/config.py | 109 ++++++++++++++++++++++++++++++++ plexpy/webserve.py | 151 ++++++--------------------------------------- 2 files changed, 127 insertions(+), 133 deletions(-) diff --git a/plexpy/config.py b/plexpy/config.py index 5806c9e9..b3d904da 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -224,6 +224,115 @@ _DO_NOT_IMPORT_KEYS_DOCKER = [ IS_IMPORTING = False IMPORT_THREAD = None +SETTINGS = [ + 'ANON_REDIRECT', + 'API_KEY', + 'BACKUP_DAYS', + 'BACKUP_DIR', + 'BACKUP_INTERVAL', + 'BUFFER_THRESHOLD', + 'BUFFER_WAIT', + 'CACHE_DIR', + 'CHECK_GITHUB_INTERVAL', + 'CLOUDINARY_API_KEY', + 'CLOUDINARY_API_SECRET', + 'CLOUDINARY_CLOUD_NAME', + 'DATE_FORMAT', + 'EXPORT_DIR', + 'GIT_BRANCH', + 'GIT_PATH', + 'GIT_REMOTE', + 'GIT_TOKEN', + 'HOME_LIBRARY_CARDS', + 'HOME_REFRESH_INTERVAL', + 'HOME_SECTIONS', + 'HOME_STATS_CARDS', + 'HTTPS_CERT', + 'HTTPS_CERT_CHAIN', + 'HTTPS_DOMAIN', + 'HTTPS_IP', + 'HTTPS_KEY', + 'HTTP_BASE_URL', + 'HTTP_PASSWORD', + 'HTTP_PORT', + 'HTTP_ROOT', + 'HTTP_USERNAME', + 'IMGUR_CLIENT_ID', + 'LOGGING_IGNORE_INTERVAL', + 'LOG_DIR', + 'MOVIE_WATCHED_PERCENT', + 'MUSIC_WATCHED_PERCENT', + 'NEWSLETTER_AUTH', + 'NEWSLETTER_CUSTOM_DIR', + 'NEWSLETTER_DIR', + 'NEWSLETTER_PASSWORD', + 'NOTIFY_CONCURRENT_THRESHOLD', + 'NOTIFY_CONTINUED_SESSION_THRESHOLD', + 'NOTIFY_RECENTLY_ADDED_DELAY', + 'NOTIFY_REMOTE_ACCESS_THRESHOLD', + 'NOTIFY_SERVER_CONNECTION_THRESHOLD', + 'NOTIFY_UPLOAD_POSTERS', + 'PMS_CLIENT_ID', + 'PMS_IDENTIFIER', + 'PMS_IP', + 'PMS_IS_CLOUD', + 'PMS_IS_REMOTE', + 'PMS_LOGS_FOLDER', + 'PMS_NAME', + 'PMS_PORT', + 'PMS_SSL', + 'PMS_UPDATE_CHANNEL', + 'PMS_UPDATE_CHECK_INTERVAL', + 'PMS_UPDATE_DISTRO', + 'PMS_UPDATE_DISTRO_BUILD', + 'PMS_URL', + 'PMS_VERSION', + 'PMS_WEB_URL', + 'REFRESH_LIBRARIES_INTERVAL', + 'REFRESH_USERS_INTERVAL', + 'SHOW_ADVANCED_SETTINGS', + 'TIME_FORMAT', + 'TV_WATCHED_PERCENT' +] + +CHECKED_SETTINGS = [ + 'ALLOW_GUEST_ACCESS', + 'ANON_REDIRECT_DYNAMIC', + 'API_ENABLED', + 'CACHE_IMAGES', + 'CHECK_GITHUB', + 'ENABLE_HTTPS', + 'GET_FILE_SIZES', + 'GROUP_HISTORY_TABLES', + 'HISTORY_TABLE_ACTIVITY', + 'HTTPS_CREATE_CERT', + 'HTTP_PLEX_ADMIN', + 'HTTP_PROXY', + 'LAUNCH_BROWSER', + 'LAUNCH_STARTUP', + 'LOG_BLACKLIST', + 'MONITOR_PMS_UPDATES', + 'MUSICBRAINZ_LOOKUP', + 'NEWSLETTER_INLINE_STYLES', + 'NEWSLETTER_SELF_HOSTED', + 'NOTIFY_CONCURRENT_BY_IP', + 'NOTIFY_CONSECUTIVE', + 'NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT', + 'NOTIFY_GROUP_RECENTLY_ADDED_PARENT', + 'NOTIFY_NEW_DEVICE_INITIAL_ONLY', + 'NOTIFY_PLEXPY_UPDATE_REPEAT', + 'NOTIFY_RECENTLY_ADDED_UPGRADE', + 'NOTIFY_SERVER_UPDATE_REPEAT', + 'PLEXPY_AUTO_UPDATE', + 'PMS_URL_MANUAL', + 'REFRESH_LIBRARIES_ON_STARTUP', + 'REFRESH_USERS_ON_STARTUP', + 'SYS_TRAY_ICON', + 'THEMOVIEDB_LOOKUP', + 'TVMAZE_LOOKUP', + 'WEEK_START_MONDAY', +] + def set_is_importing(value): global IS_IMPORTING diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 668d2426..441e87d2 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -3131,126 +3131,25 @@ class WebInterface(object): @cherrypy.expose @requireAuth(member_of("admin")) def settings(self, **kwargs): - interface_dir = os.path.join(plexpy.PROG_DIR, 'data/interfaces/') - interface_list = [name for name in os.listdir(interface_dir) if - os.path.isdir(os.path.join(interface_dir, name))] + settings_dict = {} + + for setting in config.SETTINGS: + settings_dict[setting.lower()] = plexpy.CONFIG.__getattr__(setting) + + for setting in config.CHECKED_SETTINGS: + settings_dict[setting.lower()] = checked(plexpy.CONFIG.__getattr__(setting)) # Initialise blank passwords so we do not expose them in the html forms # but users are still able to clear them if plexpy.CONFIG.HTTP_PASSWORD != '': - http_password = ' ' + settings_dict['http_password'] = ' ' else: - http_password = '' + settings_dict['http_password'] = '' - config = { - "allow_guest_access": checked(plexpy.CONFIG.ALLOW_GUEST_ACCESS), - "history_table_activity": checked(plexpy.CONFIG.HISTORY_TABLE_ACTIVITY), - "http_host": plexpy.CONFIG.HTTP_HOST, - "http_username": plexpy.CONFIG.HTTP_USERNAME, - "http_port": plexpy.CONFIG.HTTP_PORT, - "http_password": http_password, - "http_root": plexpy.CONFIG.HTTP_ROOT, - "http_proxy": checked(plexpy.CONFIG.HTTP_PROXY), - "http_plex_admin": checked(plexpy.CONFIG.HTTP_PLEX_ADMIN), - "launch_browser": checked(plexpy.CONFIG.LAUNCH_BROWSER), - "launch_startup": checked(plexpy.CONFIG.LAUNCH_STARTUP), - "enable_https": checked(plexpy.CONFIG.ENABLE_HTTPS), - "https_create_cert": checked(plexpy.CONFIG.HTTPS_CREATE_CERT), - "https_cert": plexpy.CONFIG.HTTPS_CERT, - "https_cert_chain": plexpy.CONFIG.HTTPS_CERT_CHAIN, - "https_key": plexpy.CONFIG.HTTPS_KEY, - "https_domain": plexpy.CONFIG.HTTPS_DOMAIN, - "https_ip": plexpy.CONFIG.HTTPS_IP, - "http_base_url": plexpy.CONFIG.HTTP_BASE_URL, - "anon_redirect": plexpy.CONFIG.ANON_REDIRECT, - "anon_redirect_dynamic": checked(plexpy.CONFIG.ANON_REDIRECT_DYNAMIC), - "api_enabled": checked(plexpy.CONFIG.API_ENABLED), - "api_key": plexpy.CONFIG.API_KEY, - "update_db_interval": plexpy.CONFIG.UPDATE_DB_INTERVAL, - "freeze_db": checked(plexpy.CONFIG.FREEZE_DB), - "backup_days": plexpy.CONFIG.BACKUP_DAYS, - "backup_dir": plexpy.CONFIG.BACKUP_DIR, - "backup_interval": plexpy.CONFIG.BACKUP_INTERVAL, - "cache_dir": plexpy.CONFIG.CACHE_DIR, - "export_dir": plexpy.CONFIG.EXPORT_DIR, - "log_dir": plexpy.CONFIG.LOG_DIR, - "log_blacklist": checked(plexpy.CONFIG.LOG_BLACKLIST), - "check_github": checked(plexpy.CONFIG.CHECK_GITHUB), - "check_github_interval": plexpy.CONFIG.CHECK_GITHUB_INTERVAL, - "interface_list": interface_list, - "cache_sizemb": plexpy.CONFIG.CACHE_SIZEMB, - "pms_client_id": plexpy.CONFIG.PMS_CLIENT_ID, - "pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER, - "pms_ip": plexpy.CONFIG.PMS_IP, - "pms_logs_folder": plexpy.CONFIG.PMS_LOGS_FOLDER, - "pms_port": plexpy.CONFIG.PMS_PORT, - "pms_ssl": plexpy.CONFIG.PMS_SSL, - "pms_is_remote": plexpy.CONFIG.PMS_IS_REMOTE, - "pms_is_cloud": plexpy.CONFIG.PMS_IS_CLOUD, - "pms_url": plexpy.CONFIG.PMS_URL, - "pms_url_manual": checked(plexpy.CONFIG.PMS_URL_MANUAL), - "pms_web_url": plexpy.CONFIG.PMS_WEB_URL, - "pms_name": plexpy.CONFIG.PMS_NAME, - "pms_update_check_interval": plexpy.CONFIG.PMS_UPDATE_CHECK_INTERVAL, - "date_format": plexpy.CONFIG.DATE_FORMAT, - "time_format": plexpy.CONFIG.TIME_FORMAT, - "week_start_monday": checked(plexpy.CONFIG.WEEK_START_MONDAY), - "get_file_sizes": checked(plexpy.CONFIG.GET_FILE_SIZES), - "monitor_pms_updates": checked(plexpy.CONFIG.MONITOR_PMS_UPDATES), - "refresh_libraries_interval": plexpy.CONFIG.REFRESH_LIBRARIES_INTERVAL, - "refresh_libraries_on_startup": checked(plexpy.CONFIG.REFRESH_LIBRARIES_ON_STARTUP), - "refresh_users_interval": plexpy.CONFIG.REFRESH_USERS_INTERVAL, - "refresh_users_on_startup": checked(plexpy.CONFIG.REFRESH_USERS_ON_STARTUP), - "logging_ignore_interval": plexpy.CONFIG.LOGGING_IGNORE_INTERVAL, - "notify_consecutive": checked(plexpy.CONFIG.NOTIFY_CONSECUTIVE), - "notify_upload_posters": plexpy.CONFIG.NOTIFY_UPLOAD_POSTERS, - "notify_recently_added_upgrade": checked(plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_UPGRADE), - "notify_group_recently_added_grandparent": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT), - "notify_group_recently_added_parent": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT), - "notify_recently_added_delay": plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_DELAY, - "notify_remote_access_threshold": plexpy.CONFIG.NOTIFY_REMOTE_ACCESS_THRESHOLD, - "notify_concurrent_by_ip": checked(plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP), - "notify_concurrent_threshold": plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD, - "notify_continued_session_threshold": plexpy.CONFIG.NOTIFY_CONTINUED_SESSION_THRESHOLD, - "notify_new_device_initial_only": checked(plexpy.CONFIG.NOTIFY_NEW_DEVICE_INITIAL_ONLY), - "notify_server_connection_threshold": plexpy.CONFIG.NOTIFY_SERVER_CONNECTION_THRESHOLD, - "notify_server_update_repeat": checked(plexpy.CONFIG.NOTIFY_SERVER_UPDATE_REPEAT), - "notify_plexpy_update_repeat": checked(plexpy.CONFIG.NOTIFY_PLEXPY_UPDATE_REPEAT), - "home_sections": json.dumps(plexpy.CONFIG.HOME_SECTIONS), - "home_stats_cards": json.dumps(plexpy.CONFIG.HOME_STATS_CARDS), - "home_library_cards": json.dumps(plexpy.CONFIG.HOME_LIBRARY_CARDS), - "home_refresh_interval": plexpy.CONFIG.HOME_REFRESH_INTERVAL, - "buffer_threshold": plexpy.CONFIG.BUFFER_THRESHOLD, - "buffer_wait": plexpy.CONFIG.BUFFER_WAIT, - "group_history_tables": checked(plexpy.CONFIG.GROUP_HISTORY_TABLES), - "git_token": plexpy.CONFIG.GIT_TOKEN, - "imgur_client_id": plexpy.CONFIG.IMGUR_CLIENT_ID, - "cloudinary_cloud_name": plexpy.CONFIG.CLOUDINARY_CLOUD_NAME, - "cloudinary_api_key": plexpy.CONFIG.CLOUDINARY_API_KEY, - "cloudinary_api_secret": plexpy.CONFIG.CLOUDINARY_API_SECRET, - "cache_images": checked(plexpy.CONFIG.CACHE_IMAGES), - "pms_version": plexpy.CONFIG.PMS_VERSION, - "plexpy_auto_update": checked(plexpy.CONFIG.PLEXPY_AUTO_UPDATE), - "git_branch": plexpy.CONFIG.GIT_BRANCH, - "git_path": plexpy.CONFIG.GIT_PATH, - "git_remote": plexpy.CONFIG.GIT_REMOTE, - "movie_watched_percent": plexpy.CONFIG.MOVIE_WATCHED_PERCENT, - "tv_watched_percent": plexpy.CONFIG.TV_WATCHED_PERCENT, - "music_watched_percent": plexpy.CONFIG.MUSIC_WATCHED_PERCENT, - "themoviedb_lookup": checked(plexpy.CONFIG.THEMOVIEDB_LOOKUP), - "tvmaze_lookup": checked(plexpy.CONFIG.TVMAZE_LOOKUP), - "musicbrainz_lookup": checked(plexpy.CONFIG.MUSICBRAINZ_LOOKUP), - "show_advanced_settings": plexpy.CONFIG.SHOW_ADVANCED_SETTINGS, - "newsletter_dir": plexpy.CONFIG.NEWSLETTER_DIR, - "newsletter_self_hosted": checked(plexpy.CONFIG.NEWSLETTER_SELF_HOSTED), - "newsletter_auth": plexpy.CONFIG.NEWSLETTER_AUTH, - "newsletter_password": plexpy.CONFIG.NEWSLETTER_PASSWORD, - "newsletter_inline_styles": checked(plexpy.CONFIG.NEWSLETTER_INLINE_STYLES), - "newsletter_custom_dir": plexpy.CONFIG.NEWSLETTER_CUSTOM_DIR, - "sys_tray_icon": checked(plexpy.CONFIG.SYS_TRAY_ICON) - } + for key in ('home_sections', 'home_stats_cards', 'home_library_cards'): + settings_dict[key] = json.dumps(settings_dict[key]) - return serve_template(templatename="settings.html", title="Settings", config=config, kwargs=kwargs) + return serve_template(templatename="settings.html", title="Settings", config=settings_dict) @cherrypy.expose @cherrypy.tools.json_out() @@ -3271,24 +3170,8 @@ class WebInterface(object): if kwargs.pop('first_run', None): first_run = True - checked_configs = [ - "launch_browser", "launch_startup", "enable_https", "https_create_cert", - "api_enabled", "freeze_db", "check_github", - "group_history_tables", - "pms_url_manual", "week_start_monday", - "refresh_libraries_on_startup", "refresh_users_on_startup", - "notify_consecutive", "notify_recently_added_upgrade", - "notify_group_recently_added_grandparent", "notify_group_recently_added_parent", - "notify_new_device_initial_only", - "notify_server_update_repeat", "notify_plexpy_update_repeat", - "monitor_pms_updates", "get_file_sizes", "log_blacklist", - "allow_guest_access", "cache_images", "http_proxy", "notify_concurrent_by_ip", - "history_table_activity", "plexpy_auto_update", - "themoviedb_lookup", "tvmaze_lookup", "musicbrainz_lookup", "http_plex_admin", - "newsletter_self_hosted", "newsletter_inline_styles", "sys_tray_icon", - "anon_redirect_dynamic" - ] - for checked_config in checked_configs: + for checked_config in config.CHECKED_SETTINGS: + checked_config = checked_config.lower() if checked_config not in kwargs: # checked items should be zero or one. if they were not sent then the item was not checked kwargs[checked_config] = 0 @@ -3297,9 +3180,9 @@ class WebInterface(object): # If http password exists in config, do not overwrite when blank value received if kwargs.get('http_password') == ' ': - kwargs['http_password'] = plexpy.CONFIG.HTTP_PASSWORD + del kwargs['http_password'] else: - if kwargs['http_password'] != '': + if kwargs.get('http_password', '') != '': kwargs['http_password'] = make_hash(kwargs['http_password']) # Flag to refresh JWT uuid to log out clients kwargs['jwt_update_secret'] = True and not first_run @@ -3374,6 +3257,8 @@ class WebInterface(object): if kwargs.pop('auth_changed', None): refresh_users = True + all_settings = config.SETTINGS + config.CHECKED_SETTINGS + kwargs = {k: v for k, v in kwargs.items() if k.upper() in all_settings} plexpy.CONFIG.process_kwargs(kwargs) # Write the config