Commit b3ca7065 authored by echel0n's avatar echel0n
Browse files

Minor updates to login handler

Added ability to unlink account from app
Fixed issue with scheduler view and empty show runtime
Replaced all no16 and yes16 with font awesome equivalents
parent 5136f53d
# Changelog
- * 9f445ab - 2018-06-25: Release v9.3.47
- * e2158f9 - 2018-06-26: Minor updates to login handler Added ability to unlink account from app Fixed issue with scheduler view and empty show runtime Replaced all no16 and yes16 with font awesome equivalents
- * ecf829f - 2018-06-25: Release v9.3.47
- * 713cec3 - 2018-06-25: Updated requirements.txt to resolve Synology issues
- * 40ffc7a - 2018-06-25: Release v9.3.46
- * d272697 - 2018-06-25: Fixed token refresh issues for API
......
......@@ -47,7 +47,7 @@ from sickrage.core.common import SD, SKIPPED, WANTED
from sickrage.core.config import Config
from sickrage.core.databases.cache import CacheDB
from sickrage.core.databases.main import MainDB
from sickrage.core.helpers import findCertainShow, generateCookieSecret, makeDir, get_lan_ip, restoreSR, \
from sickrage.core.helpers import findCertainShow, generate_secret, makeDir, get_lan_ip, restoreSR, \
getDiskSpaceUsage, getFreeSpace, launch_browser, torrent_webui_url
from sickrage.core.helpers.encoding import get_sys_encoding, ek, patch_modules
from sickrage.core.logger import Logger
......@@ -295,7 +295,7 @@ class Core(object):
self.config.web_port = 8081
if not self.config.web_cookie_secret:
self.config.web_cookie_secret = generateCookieSecret()
self.config.web_cookie_secret = generate_secret()
# attempt to help prevent users from breaking links by using a bad url
if not self.config.anon_redirect.endswith('?'):
......
......@@ -46,6 +46,9 @@ class API(object):
def register_appid(self, appid):
self._request('POST', 'register-appid', json={'appid': appid})
def unregister_appid(self, appid):
self._request('POST', 'unregister-appid', json={'appid': appid})
def _request(self, method, url, **kwargs):
try:
resp = self.session.request(method, urljoin(self.api_url, url), timeout=30,
......
......@@ -37,7 +37,7 @@ from configobj import ConfigObj
import sickrage
from sickrage.core.common import SD, WANTED, SKIPPED, Quality
from sickrage.core.helpers import makeDir, generateCookieSecret, auto_type, get_lan_ip, \
from sickrage.core.helpers import makeDir, generate_secret, auto_type, get_lan_ip, \
extract_zipfile, try_int, checkbox_to_value, generateApiKey, backupVersionedFile
from sickrage.core.websession import WebSession
......@@ -703,9 +703,9 @@ class Config(object):
'api_key': generateApiKey(),
'check_propers_interval': 'daily',
'nzb_method': 'blackhole',
'web_cookie_secret': generateCookieSecret(),
'web_cookie_secret': generate_secret(),
'ssl_verify': True,
'encryption_secret': generateCookieSecret(),
'encryption_secret': generate_secret(),
'enable_upnp': True,
'version_notify': True,
'web_root': '',
......
......@@ -1153,7 +1153,7 @@ def remove_article(text=''):
return re.sub(r'(?i)^(?:(?:A(?!\s+to)n?)|The)\s(\w)', r'\1', text)
def generateCookieSecret():
def generate_secret():
"""Generate a new cookie secret"""
return base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes)
......
# Author: echel0n <[email protected]>
# URL: http://www.github.com/sickragetv/sickrage/
#
# This file is part of SickRage.
#
# SickRage is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SickRage is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
......@@ -36,7 +36,7 @@ from concurrent.futures import ThreadPoolExecutor
from mako.exceptions import RichTraceback
from mako.lookup import TemplateLookup
from tornado.concurrent import run_on_executor
from tornado.escape import json_encode, recursive_unicode
from tornado.escape import json_encode, recursive_unicode, json_decode
from tornado.gen import coroutine
from tornado.process import cpu_count
from tornado.web import RequestHandler, authenticated
......@@ -147,14 +147,10 @@ class BaseHandler(RequestHandler):
request=request_info,
webroot=sickrage.app.config.web_root))
def set_current_user(self, user, remember_me=False):
self.set_secure_cookie('sickrage_user', user, expires_days=30 if remember_me else None)
def get_current_user(self):
return self.get_secure_cookie('sickrage_user')
def clear_current_user(self):
self.clear_cookie('sickrage_user')
user = self.get_secure_cookie('sr_user')
if user:
return json_decode(user)
def render_string(self, template_name, **kwargs):
template_kwargs = {
......@@ -256,9 +252,11 @@ class LoginHandler(BaseHandler):
API().token = sickrage.app.oidc_client.authorization_code(code, redirect_uri)
try:
user = sickrage.app.oidc_client.userinfo(API().token['access_token'])
API().register_appid(sickrage.app.config.app_id)
self.set_current_user(json_encode(API().userinfo), True)
except Exception:
self.set_secure_cookie('sr_user', json_encode(user))
self.set_secure_cookie('sr_refresh_token', API().token['refresh_token'])
except Exception as e:
return self.redirect('/logout')
redirect_page = self.get_argument('next', "/{}/".format(sickrage.app.config.default_page))
......@@ -274,10 +272,10 @@ class LogoutHandler(BaseHandler):
super(LogoutHandler, self).__init__(*args, **kwargs)
def prepare(self, *args, **kwargs):
if API().token:
sickrage.app.oidc_client.logout(API().token['refresh_token'])
if self.get_secure_cookie('sr_refresh_token'):
sickrage.app.oidc_client.logout(self.get_secure_cookie('sr_refresh_token'))
self.clear_current_user()
self.clear_all_cookies()
return self.redirect('/login/')
......@@ -508,6 +506,10 @@ class WebRoot(WebHandler):
def getIndexerImage(self, indexerid):
return indexerImage(id=indexerid, which="poster_thumb")
def unlink(self):
API().unregister_appid(sickrage.app.config.app_id)
return self.redirect('/logout/')
@Route('/ui(/?.*)')
class UI(WebHandler):
......
......@@ -159,7 +159,7 @@
% if show.network and show.airs:
<tr>
<td class="showLegend">${_('Originally Airs:')}</td>
<td>${show.airs} ${("<font color='#FF0000'><b>(invalid Timeformat)</b></font> ", "")[tz_updater.test_timeformat(show.airs)]}
<td>${show.airs} ${("<span style='color: red;'><b>(invalid Timeformat)</b></span> ", "")[tz_updater.test_timeformat(show.airs)]}
on ${show.network}</td>
</tr>
% elif show.network:
......@@ -170,7 +170,7 @@
% elif show.airs:
<tr>
<td class="showLegend">${_('Originally Airs:')}</td>
<td>${show.airs} ${("<font color='#FF0000'><b>(invalid Timeformat)</b></font>", "")[tz_updater.test_timeformat(show.airs)]}</td>
<td>${show.airs} ${("<span style='color: red;'><b>(invalid Timeformat)</b></span>", "")[tz_updater.test_timeformat(show.airs)]}</td>
</tr>
% endif
<tr>
......@@ -182,7 +182,13 @@
<tr>
<td class="showLegend">${_('Runtime:')}</td>
<td>
<span>${show.runtime} ${_('minutes')}</span>
<span>
% if show.runtime:
${show.runtime} ${_('minutes')}
% else:
<span style="color: red;"><b>${_('UNKNOWN')}</b></span>
% endif
</span>
</td>
</tr>
<tr>
......@@ -247,17 +253,12 @@
<td class="showLegend">${_('Default EP Status:')}</td>
<td>${statusStrings[show.default_ep_status]}</td>
</tr>
<tr>
<td class="showLegend">${_('Location:')}</td>
% if os.path.isdir(showLoc):
<tr>
<td class="showLegend">${_('Location:')}</td>
<td>${showLoc}</td>
</tr>
<td>${showLoc}</td>
% else:
<tr>
<td class="showLegend"><span style="color: red;">${_('Location:')} </span>
</td>
<td><span style="color: red;">${showLoc}</span> (${_('Missing')})</td>
</tr>
<td><span style="color: red;">${showLoc}</span> (${_('Missing')})</td>
% endif
% if os.path.isdir(showLoc):
<tr>
......@@ -318,70 +319,44 @@
% if sickrage.app.config.use_subtitles:
<tr>
<td class="showLegend">${_('Subtitles:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.subtitles)]}"
alt="${("N", "Y")[bool(show.subtitles)]}" width="16" height="16"/>
</td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.subtitles)]}"></i></td>
</tr>
% endif
<tr>
<td class="showLegend">${_('Subtitles Metadata:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.subtitles_sr_metadata)]}"
alt="${("N", "Y")[bool(show.subtitles_sr_metadata)]}" width="16"
height="16"/>
</td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.subtitles_sr_metadata)]}"></i></td>
</tr>
<tr>
<td class="showLegend">${_('Season Folders:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(not show.flatten_folders or sickrage.app.config.naming_force_folders)]}"
alt=="${("N", "Y")[bool(not show.flatten_folders or sickrage.app.config.naming_force_folders)]}"
width="16" height="16"/></td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(not show.flatten_folders or sickrage.app.config.naming_force_folders)]}"></i></td>
</tr>
<tr>
<td class="showLegend">${_('Paused:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.paused)]}"
alt="${("N", "Y")[bool(show.paused)]}" width="16" height="16"/></td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.paused)]}"></i></td>
</tr>
<tr>
<td class="showLegend">${_('Air-by-Date:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.air_by_date)]}"
alt="${("N", "Y")[bool(show.air_by_date)]}" width="16" height="16"/>
</td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.air_by_date)]}"></i></td>
</tr>
<tr>
<td class="showLegend">${_('Sports:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.is_sports)]}"
alt="${("N", "Y")[bool(show.is_sports)]}" width="16" height="16"/></td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.is_sports)]}"></i></td>
</tr>
<tr>
<td class="showLegend">${_('Anime:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.is_anime)]}"
alt="${("N", "Y")[bool(show.is_anime)]}" width="16" height="16"/></td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.is_anime)]}"></i></td>
</tr>
<tr>
<td class="showLegend">${_('DVD Order:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.dvdorder)]}"
alt="${("N", "Y")[bool(show.dvdorder)]}" width="16" height="16"/></td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.dvdorder)]}"></i></td>
</tr>
<tr>
<td class="showLegend">${_('Scene Numbering:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.scene)]}"
alt="${("N", "Y")[bool(show.scene)]}" width="16" height="16"/></td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.scene)]}"></i></td>
</tr>
<tr>
<td class="showLegend">${_('Skip Downloaded:')}</td>
<td><img
src="${srWebRoot}/images/${("no16.png", "yes16.png")[bool(show.skip_downloaded)]}"
alt="${("N", "Y")[bool(show.skip_downloaded)]}" width="16"
height="16"/></td>
<td><i class="fa ${("fa-times red-text", "fa-check green-text")[bool(show.skip_downloaded)]}"></i></td>
</tr>
</table>
</div>
......
......@@ -465,8 +465,7 @@
<td align="center">
<% paused = int(curShow.paused) == 0 and curShow.status == 'Continuing' %>
<img src="${srWebRoot}/images/${('no16.png', 'yes16.png')[bool(paused)]}"
alt="${(_('No'), _('Yes'))[bool(paused)]}" width="16" height="16"/>
<i class="fa ${("fa-times red-text", "fa-check green-text")[bool(paused)]}"></i>
</td>
<td align="center">
......
......@@ -352,6 +352,11 @@
</a>
</li>
% if current_user != True:
<li>
<a href="${srWebRoot}/unlink" class="confirm logout">
<i class="fa fa-unlink"></i>&nbsp;${_('Unlink Account')}
</a>
</li>
<li>
<a href="${srWebRoot}/logout" class="confirm logout">
<i class="fa fa-sign-out"></i>&nbsp;${_('Logout')}
......
......@@ -75,32 +75,25 @@
</td>
<td align="center">${renderQualityPill(curShow.quality, showTitle=True)}</td>
<td align="center">
<img src="${srWebRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[bool(curShow.is_sports)]}"
width="16" height="16"/>
<i class="fa ${("fa-times red-text", "fa-check green-text")[bool(curShow.is_sports)]}"></i>
</td>
<td align="center">
<img src="${srWebRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[bool(curShow.is_scene)]}"
width="16" height="16"/>
<i class="fa ${("fa-times red-text", "fa-check green-text")[bool(curShow.is_scene)]}"></i>
</td>
<td align="center">
<img src="${srWebRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[bool(curShow.is_anime)]}"
width="16" height="16"/>
<i class="fa ${("fa-times red-text", "fa-check green-text")[bool(curShow.is_anime)]}"></i>
</td>
<td align="center">
<img src="${srWebRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[not bool(curShow.flatten_folders)]}"
width="16" height="16"/>
<i class="fa ${("fa-times red-text", "fa-check green-text")[not bool(curShow.flatten_folders)]}"></i>
</td>
<td align="center">
<img src="${srWebRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[bool(curShow.skip_downloaded)]}"
width="16" height="16"/>
<i class="fa ${("fa-times red-text", "fa-check green-text")[bool(curShow.skip_downloaded)]}"></i>
</td>
<td align="center">
<img src="${srWebRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[bool(curShow.paused)]}"
width="16" height="16"/>
<i class="fa ${("fa-times red-text", "fa-check green-text")[bool(curShow.paused)]}"></i>
</td>
<td align="center">
<img src="${srWebRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[bool(curShow.subtitles)]}"
width="16" height="16"/>
<i class="fa ${("fa-times red-text", "fa-check green-text")[bool(curShow.subtitles)]}"></i>
</td>
<td align="center">${statusStrings[curShow.default_ep_status]}</td>
<td align="center">${curShow.status}</td>
......
......@@ -107,7 +107,7 @@
% if not int(cur_result['paused']) or sickrage.app.config.coming_eps_display_paused:
<%
cur_indexer = int(cur_result['indexer'])
run_time = int(cur_result['runtime'])
run_time = int(cur_result['runtime'] or 0)
cur_ep_airdate = cur_result['localtime'].date()
cur_ep_enddate = cur_result['localtime']
......@@ -235,7 +235,7 @@
<%
cur_indexer = int(cur_result['indexer'])
run_time = int(cur_result['runtime'])
run_time = int(cur_result['runtime'] or 0)
cur_ep_airdate = cur_result['localtime'].date()
if run_time:
......@@ -441,7 +441,7 @@
% if not int(cur_result['paused']) or sickrage.app.config.coming_eps_display_paused:
<% cur_indexer = int(cur_result['indexer']) %>
<% run_time = int(cur_result['runtime']) %>
<% run_time = int(cur_result['runtime'] or 0) %>
<% airday = cur_result['localtime'].date() %>
% if airday == day:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment