From 7c53e1e5f6cf729ef664024f4d53d222ff645e98 Mon Sep 17 00:00:00 2001 From: JackDandy Date: Tue, 3 Apr 2018 13:05:37 +0100 Subject: [PATCH] Change remove redundant xsrf handling for POSTs that don't use web and API. --- CHANGES.md | 1 + .../_devenv.py | 22 ----- sickbeard/webapi.py | 3 + sickbeard/webserve.py | 94 ++++++++++++++-------- sickbeard/webserveInit.py | 1 + 5 files changed, 66 insertions(+), 55 deletions(-) delete mode 100644 sickbeard/clients/kodi/service.sickgear.watchedstate.updater/_devenv.py diff --git a/CHANGES.md b/CHANGES.md index 534fd63..653c204 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -31,6 +31,7 @@ [develop changelog] * Change pick up the stragglers late to the more security party +* Change remove redundant xsrf handling for POSTs that don't use web and API ### 0.15.4 (2018-04-03 16:10:00 UTC) diff --git a/sickbeard/clients/kodi/service.sickgear.watchedstate.updater/_devenv.py b/sickbeard/clients/kodi/service.sickgear.watchedstate.updater/_devenv.py deleted file mode 100644 index 1312da3..0000000 --- a/sickbeard/clients/kodi/service.sickgear.watchedstate.updater/_devenv.py +++ /dev/null @@ -1,22 +0,0 @@ -# /tests/_devenv.py -# -# To trigger dev env -# -# import _devenv as devenv -# - -__remotedebug__ = True - -if __remotedebug__: - import sys - sys.path.append('C:\Program Files\JetBrains\PyCharm 2017.2.1\debug-eggs\pycharm-debug.egg') - import pydevd - - - def setup_devenv(state): - pydevd.settrace('localhost', port=(65001, 65000)[bool(state)], stdoutToServer=True, stderrToServer=True, - suspend=False) - - -def stop(): - pydevd.stoptrace() diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py index 979de40..2e1825d 100644 --- a/sickbeard/webapi.py +++ b/sickbeard/webapi.py @@ -97,6 +97,9 @@ class Api(webserve.BaseHandler): version = 10 # use an int since float-point is unpredictible intent = 4 + def check_xsrf_cookie(self): + pass + def set_default_headers(self): self.set_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0') self.set_header('X-Robots-Tag', 'noindex, nofollow, noarchive, nocache, noodp, noydir, noimageindex, nosnippet') diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 9e6e7be..c930101 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -91,7 +91,7 @@ class PageTemplate(Template): def __init__(self, web_handler, *args, **kwargs): headers = web_handler.request.headers - self.xsrf_form_html = '' % web_handler.xsrf_token + self.xsrf_form_html = re.sub('\s*/>$', '>', web_handler.xsrf_form_html()) self.sbHost = headers.get('X-Forwarded-Host') if None is self.sbHost: sbHost = headers.get('Host') or 'localhost' @@ -545,6 +545,66 @@ class RepoHandler(BaseStaticFileHandler): return zip_data +class NoXSRFHandler(RequestHandler): + def __init__(self, *arg, **kwargs): + + super(NoXSRFHandler, self).__init__(*arg, **kwargs) + self.lock = threading.Lock() + + def check_xsrf_cookie(self): + pass + + @gen.coroutine + def post(self, route, *args, **kwargs): + route = route.strip('/') + try: + method = getattr(self, route) + except (StandardError, Exception): + self.finish() + else: + kwargss = {k: v if not (isinstance(v, list) and 1 == len(v)) else v[0] + for k, v in self.request.arguments.iteritems()} + result = method(**kwargss) + if result: + self.finish(result) + + @staticmethod + def update_watched_state_kodi(payload=None, as_json=True): + data = {} + try: + data = json.loads(payload) + except (StandardError, Exception): + pass + + mapped = 0 + mapping = None + maps = [x.split('=') for x in sickbeard.KODI_PARENT_MAPS.split(',') if any(x)] + for k, d in data.iteritems(): + try: + d['label'] = '%s%s{Kodi}' % (d['label'], bool(d['label']) and ' ' or '') + except (StandardError, Exception): + return + try: + d['played'] = 100 * int(d['played']) + except (StandardError, Exception): + d['played'] = 0 + + for m in maps: + result, change = helpers.path_mapper(m[0], m[1], d['path_file']) + if change: + if not mapping: + mapping = (states[idx]['path_file'], result) + mapped += 1 + states[idx]['path_file'] = result + break + + if mapping: + logger.log('Folder mappings used, the first of %s is [%s] in Kodi is [%s] in SickGear' % + (mapped, mapping[0], mapping[1])) + + return MainHandler.update_watched_state(data, as_json) + + class IsAliveHandler(BaseHandler): def get(self, *args, **kwargs): kwargs = self.request.arguments @@ -870,38 +930,6 @@ class MainHandler(WebHandler): sickbeard.save_config() - def update_watched_state_kodi(self, payload=None, as_json=True): - - data = {} - try: - data = json.loads(payload) - except (StandardError, Exception): - pass - - mapped = 0 - mapping = None - maps = [x.split('=') for x in sickbeard.KODI_PARENT_MAPS.split(',') if any(x)] - for k, d in data.iteritems(): - d['label'] = '%s%s{Kodi}' % (d['label'], bool(d['label']) and ' ' or '') - try: - d['played'] = 100 * int(d['played']) - except (StandardError, Exception): - d['played'] = 0 - - for m in maps: - result, change = helpers.path_mapper(m[0], m[1], d['path_file']) - if change: - if not mapping: - mapping = (states[idx]['path_file'], result) - mapped += 1 - states[idx]['path_file'] = result - break - - if mapping: - logger.log('Folder mappings used, the first of %s is [%s] in Kodi is [%s] in SickGear' % - (mapped, mapping[0], mapping[1])) - - return self.update_watched_state(data, as_json) @staticmethod def getFooterTime(change_layout=True, json_dump=True, *args, **kwargs): diff --git a/sickbeard/webserveInit.py b/sickbeard/webserveInit.py index ecb8945..aebe4f1 100644 --- a/sickbeard/webserveInit.py +++ b/sickbeard/webserveInit.py @@ -143,6 +143,7 @@ class WebServer(threading.Thread): (r'%s/manage/(/?.*)' % self.options['web_root'], webserve.Manage), (r'%s/ui(/?.*)' % self.options['web_root'], webserve.UI), (r'%s/browser(/?.*)' % self.options['web_root'], webserve.WebFileBrowser), + (r'%s(/?update_watched_state_kodi/?)' % self.options['web_root'], webserve.NoXSRFHandler), (r'%s(/?.*)' % self.options['web_root'], webserve.MainHandler), ])