Require authentication for all endpoints except API

* And more minor UI changes
This commit is contained in:
JonnyWong16 2016-04-23 01:02:37 -07:00
parent d8ad9adabd
commit e99bc73e46
5 changed files with 147 additions and 22 deletions

View file

@ -212,6 +212,8 @@ from plexpy.helpers import anon_url
% endif % endif
<a href="settings" class="dropdown-toggle disabled" aria-haspopup="true" data-toggle="dropdown" data-hover="dropdown"><i class="fa fa-lg fa-cogs"></i> <span class="caret"></span></a> <a href="settings" class="dropdown-toggle disabled" aria-haspopup="true" data-toggle="dropdown" data-hover="dropdown"><i class="fa fa-lg fa-cogs"></i> <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="settings"><i class="fa fa-cogs"></i> Settings</a></li>
<li role="separator" class="divider"></li>
<li><a href="logs"><i class="fa fa-list-alt"></i> View Logs</a></li> <li><a href="logs"><i class="fa fa-list-alt"></i> View Logs</a></li>
<li role="separator" class="divider"></li> <li role="separator" class="divider"></li>
% if plexpy.CONFIG.CHECK_GITHUB: % if plexpy.CONFIG.CHECK_GITHUB:
@ -219,7 +221,9 @@ from plexpy.helpers import anon_url
% endif % endif
<li><a href="#" id="nav-restart"><i class="fa fa-refresh"></i> Restart</a></li> <li><a href="#" id="nav-restart"><i class="fa fa-refresh"></i> Restart</a></li>
<li><a href="#" id="nav-shutdown"><i class="fa fa-power-off"></i> Shutdown</a></li> <li><a href="#" id="nav-shutdown"><i class="fa fa-power-off"></i> Shutdown</a></li>
<li><a href="${http_root}auth/login"><i class="fa fa-sign-out"></i> Logout</a></li> % if plexpy.CONFIG.HTTP_PASSWORD:
<li><a href="${http_root}auth/logout"><i class="fa fa-sign-out"></i> Logout</a></li>
% endif
</ul> </ul>
</li> </li>
</ul> </ul>

View file

@ -132,7 +132,7 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<td><a class="no-highlight" href="${anon_url('https://gitter.im/drzoidberg33/plexpy')}" target="_blank">https://gitter.im/drzoidberg33/plexpy</a></td> <td><a class="no-highlight" href="${anon_url('https://gitter.im/drzoidberg33/plexpy')}" target="_blank">https://gitter.im/drzoidberg33/plexpy</a></td>
</tr> </tr>
<tr> <tr>
<td>Donations:</td> <td>Support PlexPy:</td>
<td><a class="no-highlight" href="${anon_url('https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DG783BMSCU3V4')}" target="_blank">Paypal</a> | <td><a class="no-highlight" href="${anon_url('https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DG783BMSCU3V4')}" target="_blank">Paypal</a> |
<a class="no-highlight" href="${anon_url('http://swiftpanda16.tip.me/')}" target="_blank">Bitcoin</a></td> <a class="no-highlight" href="${anon_url('http://swiftpanda16.tip.me/')}" target="_blank">Bitcoin</a></td>
</tr> </tr>
@ -236,12 +236,11 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<div role="tabpanel" class="tab-pane" id="tabs-2"> <div role="tabpanel" class="tab-pane" id="tabs-2">
<div class="padded-header"> <div class="padded-header">
<h3>Homepage</h3> <h3>Sections</h3>
</div> </div>
<label for="sortable_home_stats_cards">Sections</label>
<p class="help-block"> <p class="help-block">
Select the sections to show on the homepage.<br> Select the sections to show on the homepage.
Drag the items below to reorder your homepage content. Drag the items below to reorder your homepage content.
</p> </p>
<div class="row"> <div class="row">
@ -281,7 +280,6 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="sortable_home_stats_cards">Cards</label>
<p class="help-block"> <p class="help-block">
Select the cards to show in the watch statistics on the home page. Select the cards to show in the watch statistics on the home page.
Drag the items below to reorder your homepage content. Drag the items below to reorder your homepage content.
@ -386,7 +384,6 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="home_library_cards">Cards</label>
<p class="help-block"> <p class="help-block">
Select the cards to show in the library statistics on the home page. Select the cards to show in the library statistics on the home page.
Drag the items below to reorder your homepage content. Drag the items below to reorder your homepage content.
@ -433,7 +430,7 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<input type="text" class="form-control http-settings" id="http_root" name="http_root" value="${config['http_root']}" data-parsley-trigger="change"> <input type="text" class="form-control http-settings" id="http_root" name="http_root" value="${config['http_root']}" data-parsley-trigger="change">
</div> </div>
</div> </div>
<p class="help-block">The base URL for the web server. Used for reverse proxies.</p> <p class="help-block">The base URL of the web server used for reverse proxies.</p>
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label> <label>

View file

@ -62,7 +62,7 @@ def check_auth(*args, **kwargs):
else: else:
raise cherrypy.HTTPRedirect("auth/login") raise cherrypy.HTTPRedirect("auth/login")
def require(*conditions): def requireAuth(*conditions):
"""A decorator that appends conditions to the auth.require config """A decorator that appends conditions to the auth.require config
variable.""" variable."""
def decorate(f): def decorate(f):
@ -133,8 +133,15 @@ class AuthController(object):
return serve_template(templatename="login.html", title="Login", username=username, msg=msg) return serve_template(templatename="login.html", title="Login", username=username, msg=msg)
@cherrypy.expose
def index(self):
raise cherrypy.HTTPRedirect("login")
@cherrypy.expose @cherrypy.expose
def login(self, username=None, password=None, remember_me=0): def login(self, username=None, password=None, remember_me=0):
if not plexpy.CONFIG.HTTP_PASSWORD:
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
if username is None or password is None: if username is None or password is None:
return self.get_loginform() return self.get_loginform()
@ -151,6 +158,9 @@ class AuthController(object):
@cherrypy.expose @cherrypy.expose
def logout(self): def logout(self):
if not plexpy.CONFIG.HTTP_PASSWORD:
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
sess = cherrypy.session sess = cherrypy.session
username = sess.get(SESSION_KEY, None) username = sess.get(SESSION_KEY, None)
sess[SESSION_KEY] = None sess[SESSION_KEY] = None

View file

@ -16,7 +16,7 @@
from plexpy import logger, notifiers, plextv, pmsconnect, common, log_reader, \ from plexpy import logger, notifiers, plextv, pmsconnect, common, log_reader, \
datafactory, graphs, users, libraries, database, web_socket datafactory, graphs, users, libraries, database, web_socket
from plexpy.helpers import checked, addtoapi, get_ip, create_https_certificates from plexpy.helpers import checked, addtoapi, get_ip, create_https_certificates
from plexpy.webauth import AuthController, require, member_of, name_is from plexpy.webauth import AuthController, requireAuth, member_of, name_is
from mako.lookup import TemplateLookup from mako.lookup import TemplateLookup
from mako import exceptions from mako import exceptions
@ -64,7 +64,7 @@ class WebInterface(object):
self.interface_dir = os.path.join(str(plexpy.PROG_DIR), 'data/') self.interface_dir = os.path.join(str(plexpy.PROG_DIR), 'data/')
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def index(self): def index(self):
if plexpy.CONFIG.FIRST_RUN_COMPLETE: if plexpy.CONFIG.FIRST_RUN_COMPLETE:
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
@ -75,6 +75,7 @@ class WebInterface(object):
##### Welcome ##### ##### Welcome #####
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def welcome(self, **kwargs): def welcome(self, **kwargs):
config = { config = {
"launch_browser": checked(plexpy.CONFIG.LAUNCH_BROWSER), "launch_browser": checked(plexpy.CONFIG.LAUNCH_BROWSER),
@ -108,6 +109,7 @@ class WebInterface(object):
return serve_template(templatename="welcome.html", title="Welcome", config=config) return serve_template(templatename="welcome.html", title="Welcome", config=config)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def discover(self, token): def discover(self, token):
""" Gets all your servers that are published to plextv """ Gets all your servers that are published to plextv
@ -147,7 +149,7 @@ class WebInterface(object):
##### Home ##### ##### Home #####
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def home(self): def home(self):
config = { config = {
"home_sections": plexpy.CONFIG.HOME_SECTIONS, "home_sections": plexpy.CONFIG.HOME_SECTIONS,
@ -160,6 +162,7 @@ class WebInterface(object):
return serve_template(templatename="index.html", title="Home", config=config) return serve_template(templatename="index.html", title="Home", config=config)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_date_formats(self): def get_date_formats(self):
""" Get the date and time formats used by plexpy """ """ Get the date and time formats used by plexpy """
@ -180,6 +183,7 @@ class WebInterface(object):
return json.dumps(formats) return json.dumps(formats)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_current_activity(self, **kwargs): def get_current_activity(self, **kwargs):
try: try:
@ -202,6 +206,7 @@ class WebInterface(object):
return serve_template(templatename="current_activity.html", data=None) return serve_template(templatename="current_activity.html", data=None)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_current_activity_header(self, **kwargs): def get_current_activity_header(self, **kwargs):
try: try:
@ -217,6 +222,7 @@ class WebInterface(object):
return serve_template(templatename="current_activity_header.html", data=None) return serve_template(templatename="current_activity_header.html", data=None)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def home_stats(self, **kwargs): def home_stats(self, **kwargs):
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
@ -237,6 +243,7 @@ class WebInterface(object):
return serve_template(templatename="home_stats.html", title="Stats", data=stats_data) return serve_template(templatename="home_stats.html", title="Stats", data=stats_data)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def library_stats(self, **kwargs): def library_stats(self, **kwargs):
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
@ -247,6 +254,7 @@ class WebInterface(object):
return serve_template(templatename="library_stats.html", title="Library Stats", data=stats_data) return serve_template(templatename="library_stats.html", title="Library Stats", data=stats_data)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_recently_added(self, count='0', **kwargs): def get_recently_added(self, count='0', **kwargs):
try: try:
@ -262,6 +270,7 @@ class WebInterface(object):
return serve_template(templatename="recently_added.html", data=None) return serve_template(templatename="recently_added.html", data=None)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def delete_temp_sessions(self): def delete_temp_sessions(self):
result = database.delete_sessions() result = database.delete_sessions()
@ -277,7 +286,7 @@ class WebInterface(object):
##### Libraries ##### ##### Libraries #####
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def libraries(self): def libraries(self):
config = { config = {
"update_section_ids": plexpy.CONFIG.UPDATE_SECTION_IDS "update_section_ids": plexpy.CONFIG.UPDATE_SECTION_IDS
@ -286,6 +295,7 @@ class WebInterface(object):
return serve_template(templatename="libraries.html", title="Libraries", config=config) return serve_template(templatename="libraries.html", title="Libraries", config=config)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_library_list(self, **kwargs): def get_library_list(self, **kwargs):
@ -296,6 +306,7 @@ class WebInterface(object):
return json.dumps(library_list) return json.dumps(library_list)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_library_sections(self, **kwargs): def get_library_sections(self, **kwargs):
""" Get the library sections from pms """ Get the library sections from pms
@ -321,6 +332,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_library_sections.") logger.warn(u"Unable to retrieve data for get_library_sections.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() # should be added manually @addtoapi() # should be added manually
def refresh_libraries_list(self, **kwargs): def refresh_libraries_list(self, **kwargs):
threading.Thread(target=pmsconnect.refresh_libraries).start() threading.Thread(target=pmsconnect.refresh_libraries).start()
@ -328,6 +340,7 @@ class WebInterface(object):
return True return True
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def library(self, section_id=None): def library(self, section_id=None):
config = { config = {
"get_file_sizes": plexpy.CONFIG.GET_FILE_SIZES, "get_file_sizes": plexpy.CONFIG.GET_FILE_SIZES,
@ -348,6 +361,7 @@ class WebInterface(object):
return serve_template(templatename="library.html", title="Library", data=library_details, config=config) return serve_template(templatename="library.html", title="Library", data=library_details, config=config)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def edit_library_dialog(self, section_id=None, **kwargs): def edit_library_dialog(self, section_id=None, **kwargs):
library_data = libraries.Libraries() library_data = libraries.Libraries()
if section_id: if section_id:
@ -360,6 +374,7 @@ class WebInterface(object):
return serve_template(templatename="edit_library.html", title="Edit Library", data=result, status_message=status_message) return serve_template(templatename="edit_library.html", title="Edit Library", data=result, status_message=status_message)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def edit_library(self, section_id=None, **kwargs): def edit_library(self, section_id=None, **kwargs):
custom_thumb = kwargs.get('custom_thumb', '') custom_thumb = kwargs.get('custom_thumb', '')
@ -383,6 +398,7 @@ class WebInterface(object):
return status_message return status_message
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_library_watch_time_stats(self, section_id=None, **kwargs): def get_library_watch_time_stats(self, section_id=None, **kwargs):
if section_id: if section_id:
library_data = libraries.Libraries() library_data = libraries.Libraries()
@ -397,6 +413,7 @@ class WebInterface(object):
return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats") return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_library_user_stats(self, section_id=None, **kwargs): def get_library_user_stats(self, section_id=None, **kwargs):
if section_id: if section_id:
library_data = libraries.Libraries() library_data = libraries.Libraries()
@ -411,6 +428,7 @@ class WebInterface(object):
return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats") return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_library_recently_watched(self, section_id=None, limit='10', **kwargs): def get_library_recently_watched(self, section_id=None, limit='10', **kwargs):
if section_id: if section_id:
library_data = libraries.Libraries() library_data = libraries.Libraries()
@ -425,6 +443,7 @@ class WebInterface(object):
return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched") return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_library_recently_added(self, section_id=None, limit='10', **kwargs): def get_library_recently_added(self, section_id=None, limit='10', **kwargs):
if section_id: if section_id:
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
@ -439,6 +458,7 @@ class WebInterface(object):
return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added") return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_library_media_info(self, section_id=None, section_type=None, rating_key=None, refresh='', **kwargs): def get_library_media_info(self, section_id=None, section_type=None, rating_key=None, refresh='', **kwargs):
@ -458,6 +478,7 @@ class WebInterface(object):
return json.dumps(result) return json.dumps(result)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_media_info_file_sizes(self, section_id=None, rating_key=None): def get_media_info_file_sizes(self, section_id=None, rating_key=None):
get_file_sizes_hold = plexpy.CONFIG.GET_FILE_SIZES_HOLD get_file_sizes_hold = plexpy.CONFIG.GET_FILE_SIZES_HOLD
@ -487,6 +508,7 @@ class WebInterface(object):
return json.dumps({'success': result}) return json.dumps({'success': result})
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def delete_all_library_history(self, section_id, **kwargs): def delete_all_library_history(self, section_id, **kwargs):
library_data = libraries.Libraries() library_data = libraries.Libraries()
@ -502,6 +524,7 @@ class WebInterface(object):
return json.dumps({'message': 'no data received'}) return json.dumps({'message': 'no data received'})
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def delete_library(self, section_id, **kwargs): def delete_library(self, section_id, **kwargs):
library_data = libraries.Libraries() library_data = libraries.Libraries()
@ -517,6 +540,7 @@ class WebInterface(object):
return json.dumps({'message': 'no data received'}) return json.dumps({'message': 'no data received'})
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def undelete_library(self, section_id=None, section_name=None, **kwargs): def undelete_library(self, section_id=None, section_name=None, **kwargs):
library_data = libraries.Libraries() library_data = libraries.Libraries()
@ -538,6 +562,7 @@ class WebInterface(object):
return json.dumps({'message': 'no data received'}) return json.dumps({'message': 'no data received'})
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def update_section_ids(self, **kwargs): def update_section_ids(self, **kwargs):
@ -551,6 +576,7 @@ class WebInterface(object):
return "Unable to update section_id's in database. See logs for details." return "Unable to update section_id's in database. See logs for details."
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def delete_datatable_media_info_cache(self, section_id, **kwargs): def delete_datatable_media_info_cache(self, section_id, **kwargs):
get_file_sizes_hold = plexpy.CONFIG.GET_FILE_SIZES_HOLD get_file_sizes_hold = plexpy.CONFIG.GET_FILE_SIZES_HOLD
@ -571,6 +597,7 @@ class WebInterface(object):
return json.dumps({'message': 'Cannot refresh library while getting file sizes.'}) return json.dumps({'message': 'Cannot refresh library while getting file sizes.'})
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def delete_duplicate_libraries(self): def delete_duplicate_libraries(self):
library_data = libraries.Libraries() library_data = libraries.Libraries()
@ -586,11 +613,12 @@ class WebInterface(object):
##### Users ##### ##### Users #####
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def users(self): def users(self):
return serve_template(templatename="users.html", title="Users") return serve_template(templatename="users.html", title="Users")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_user_list(self, **kwargs): def get_user_list(self, **kwargs):
@ -601,6 +629,7 @@ class WebInterface(object):
return json.dumps(user_list) return json.dumps(user_list)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def refresh_users_list(self, **kwargs): def refresh_users_list(self, **kwargs):
""" Refresh a users list in a own thread """ """ Refresh a users list in a own thread """
@ -609,6 +638,7 @@ class WebInterface(object):
return True return True
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def user(self, user_id=None): def user(self, user_id=None):
user_data = users.Users() user_data = users.Users()
if user_id: if user_id:
@ -624,6 +654,7 @@ class WebInterface(object):
return serve_template(templatename="user.html", title="User", data=user_details) return serve_template(templatename="user.html", title="User", data=user_details)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def edit_user_dialog(self, user=None, user_id=None, **kwargs): def edit_user_dialog(self, user=None, user_id=None, **kwargs):
user_data = users.Users() user_data = users.Users()
if user_id: if user_id:
@ -636,6 +667,7 @@ class WebInterface(object):
return serve_template(templatename="edit_user.html", title="Edit User", data=result, status_message=status_message) return serve_template(templatename="edit_user.html", title="Edit User", data=result, status_message=status_message)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def edit_user(self, user_id=None, **kwargs): def edit_user(self, user_id=None, **kwargs):
friendly_name = kwargs.get('friendly_name', '') friendly_name = kwargs.get('friendly_name', '')
custom_thumb = kwargs.get('custom_thumb', '') custom_thumb = kwargs.get('custom_thumb', '')
@ -657,6 +689,7 @@ class WebInterface(object):
return status_message return status_message
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_user_watch_time_stats(self, user=None, user_id=None, **kwargs): def get_user_watch_time_stats(self, user=None, user_id=None, **kwargs):
if user_id or user: if user_id or user:
user_data = users.Users() user_data = users.Users()
@ -671,6 +704,7 @@ class WebInterface(object):
return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats") return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_user_player_stats(self, user=None, user_id=None, **kwargs): def get_user_player_stats(self, user=None, user_id=None, **kwargs):
if user_id or user: if user_id or user:
user_data = users.Users() user_data = users.Users()
@ -685,6 +719,7 @@ class WebInterface(object):
return serve_template(templatename="user_player_stats.html", data=None, title="Player Stats") return serve_template(templatename="user_player_stats.html", data=None, title="Player Stats")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_user_recently_watched(self, user=None, user_id=None, limit='10', **kwargs): def get_user_recently_watched(self, user=None, user_id=None, limit='10', **kwargs):
if user_id or user: if user_id or user:
user_data = users.Users() user_data = users.Users()
@ -699,6 +734,7 @@ class WebInterface(object):
return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched") return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_user_ips(self, user_id=None, **kwargs): def get_user_ips(self, user_id=None, **kwargs):
user_data = users.Users() user_data = users.Users()
@ -708,6 +744,7 @@ class WebInterface(object):
return json.dumps(history) return json.dumps(history)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def delete_all_user_history(self, user_id, **kwargs): def delete_all_user_history(self, user_id, **kwargs):
user_data = users.Users() user_data = users.Users()
@ -721,6 +758,7 @@ class WebInterface(object):
return json.dumps({'message': 'no data received'}) return json.dumps({'message': 'no data received'})
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def delete_user(self, user_id, **kwargs): def delete_user(self, user_id, **kwargs):
user_data = users.Users() user_data = users.Users()
@ -735,6 +773,7 @@ class WebInterface(object):
return json.dumps({'message': 'no data received'}) return json.dumps({'message': 'no data received'})
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def undelete_user(self, user_id=None, username=None, **kwargs): def undelete_user(self, user_id=None, username=None, **kwargs):
user_data = users.Users() user_data = users.Users()
@ -758,11 +797,12 @@ class WebInterface(object):
##### History ##### ##### History #####
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def history(self): def history(self):
return serve_template(templatename="history.html", title="History") return serve_template(templatename="history.html", title="History")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_history(self, user=None, user_id=None, grouping=0, **kwargs): def get_history(self, user=None, user_id=None, grouping=0, **kwargs):
if grouping == 'false': if grouping == 'false':
@ -811,6 +851,7 @@ class WebInterface(object):
return json.dumps(history) return json.dumps(history)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_stream_data(self, row_id=None, user=None, **kwargs): def get_stream_data(self, row_id=None, user=None, **kwargs):
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
@ -819,6 +860,7 @@ class WebInterface(object):
return serve_template(templatename="stream_data.html", title="Stream Data", data=stream_data, user=user) return serve_template(templatename="stream_data.html", title="Stream Data", data=stream_data, user=user)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_ip_address_details(self, ip_address=None, **kwargs): def get_ip_address_details(self, ip_address=None, **kwargs):
import socket import socket
@ -830,6 +872,7 @@ class WebInterface(object):
return serve_template(templatename="ip_address_modal.html", title="IP Address Details", data=ip_address) return serve_template(templatename="ip_address_modal.html", title="IP Address Details", data=ip_address)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def delete_history_rows(self, row_id, **kwargs): def delete_history_rows(self, row_id, **kwargs):
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
@ -847,7 +890,7 @@ class WebInterface(object):
##### Graphs ##### ##### Graphs #####
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def graphs(self): def graphs(self):
config = { config = {
@ -860,6 +903,7 @@ class WebInterface(object):
return serve_template(templatename="graphs.html", title="Graphs", config=config) return serve_template(templatename="graphs.html", title="Graphs", config=config)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def set_graph_config(self, graph_type=None, graph_days=None, graph_tab=None): def set_graph_config(self, graph_type=None, graph_days=None, graph_tab=None):
if graph_type: if graph_type:
plexpy.CONFIG.__setattr__('GRAPH_TYPE', graph_type) plexpy.CONFIG.__setattr__('GRAPH_TYPE', graph_type)
@ -884,6 +928,7 @@ class WebInterface(object):
return json.dumps(user_names) return json.dumps(user_names)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_by_date(self, time_range='30', user_id=None, y_axis='plays', **kwargs): def get_plays_by_date(self, time_range='30', user_id=None, y_axis='plays', **kwargs):
@ -897,6 +942,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_by_date.") logger.warn(u"Unable to retrieve data for get_plays_by_date.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_by_dayofweek(self, time_range='30', user_id=None, y_axis='plays', **kwargs): def get_plays_by_dayofweek(self, time_range='30', user_id=None, y_axis='plays', **kwargs):
@ -910,6 +956,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_by_dayofweek.") logger.warn(u"Unable to retrieve data for get_plays_by_dayofweek.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_by_hourofday(self, time_range='30', user_id=None, y_axis='plays', **kwargs): def get_plays_by_hourofday(self, time_range='30', user_id=None, y_axis='plays', **kwargs):
@ -923,6 +970,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_by_hourofday.") logger.warn(u"Unable to retrieve data for get_plays_by_hourofday.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_per_month(self, y_axis='plays', user_id=None, **kwargs): def get_plays_per_month(self, y_axis='plays', user_id=None, **kwargs):
@ -936,6 +984,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_per_month.") logger.warn(u"Unable to retrieve data for get_plays_per_month.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_by_top_10_platforms(self, time_range='30', y_axis='plays', user_id=None, **kwargs): def get_plays_by_top_10_platforms(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
@ -949,6 +998,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_by_top_10_platforms.") logger.warn(u"Unable to retrieve data for get_plays_by_top_10_platforms.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_by_top_10_users(self, time_range='30', y_axis='plays', user_id=None, **kwargs): def get_plays_by_top_10_users(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
@ -962,6 +1012,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_by_top_10_users.") logger.warn(u"Unable to retrieve data for get_plays_by_top_10_users.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_by_stream_type(self, time_range='30', y_axis='plays', user_id=None, **kwargs): def get_plays_by_stream_type(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
@ -975,6 +1026,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_by_stream_type.") logger.warn(u"Unable to retrieve data for get_plays_by_stream_type.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_by_source_resolution(self, time_range='30', y_axis='plays', user_id=None, **kwargs): def get_plays_by_source_resolution(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
@ -988,6 +1040,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_by_source_resolution.") logger.warn(u"Unable to retrieve data for get_plays_by_source_resolution.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plays_by_stream_resolution(self, time_range='30', y_axis='plays', user_id=None, **kwargs): def get_plays_by_stream_resolution(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
@ -1001,6 +1054,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_plays_by_stream_resolution.") logger.warn(u"Unable to retrieve data for get_plays_by_stream_resolution.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_stream_type_by_top_10_users(self, time_range='30', y_axis='plays', user_id=None, **kwargs): def get_stream_type_by_top_10_users(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
@ -1014,6 +1068,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_stream_type_by_top_10_users.") logger.warn(u"Unable to retrieve data for get_stream_type_by_top_10_users.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_stream_type_by_top_10_platforms(self, time_range='30', y_axis='plays', user_id=None, **kwargs): def get_stream_type_by_top_10_platforms(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
@ -1027,6 +1082,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_stream_type_by_top_10_platforms.") logger.warn(u"Unable to retrieve data for get_stream_type_by_top_10_platforms.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def history_table_modal(self, **kwargs): def history_table_modal(self, **kwargs):
return serve_template(templatename="history_table_modal.html", title="History Data", data=kwargs) return serve_template(templatename="history_table_modal.html", title="History Data", data=kwargs)
@ -1035,11 +1091,12 @@ class WebInterface(object):
##### Sync ##### ##### Sync #####
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def sync(self): def sync(self):
return serve_template(templatename="sync.html", title="Synced Items") return serve_template(templatename="sync.html", title="Synced Items")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_sync(self, machine_id=None, user_id=None, **kwargs): def get_sync(self, machine_id=None, user_id=None, **kwargs):
if not machine_id: if not machine_id:
@ -1061,7 +1118,7 @@ class WebInterface(object):
##### Logs ##### ##### Logs #####
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def logs(self): def logs(self):
return serve_template(templatename="logs.html", title="Log", lineList=plexpy.LOG_LIST) return serve_template(templatename="logs.html", title="Log", lineList=plexpy.LOG_LIST)
@ -1109,6 +1166,7 @@ class WebInterface(object):
}) })
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plex_log(self, window=1000, **kwargs): def get_plex_log(self, window=1000, **kwargs):
log_lines = [] log_lines = []
@ -1123,6 +1181,7 @@ class WebInterface(object):
return json.dumps(log_lines) return json.dumps(log_lines)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_notification_log(self, **kwargs): def get_notification_log(self, **kwargs):
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
@ -1132,6 +1191,7 @@ class WebInterface(object):
return json.dumps(notifications) return json.dumps(notifications)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def clearNotifyLogs(self, **kwargs): def clearNotifyLogs(self, **kwargs):
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
@ -1145,12 +1205,14 @@ class WebInterface(object):
return json.dumps({'message': 'no data received'}) return json.dumps({'message': 'no data received'})
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def clearLogs(self): def clearLogs(self):
plexpy.LOG_LIST = [] plexpy.LOG_LIST = []
logger.info(u"Web logs cleared") logger.info(u"Web logs cleared")
raise cherrypy.HTTPRedirect("logs") raise cherrypy.HTTPRedirect("logs")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def toggleVerbose(self): def toggleVerbose(self):
plexpy.VERBOSE = not plexpy.VERBOSE plexpy.VERBOSE = not plexpy.VERBOSE
logger.initLogger(console=not plexpy.QUIET, logger.initLogger(console=not plexpy.QUIET,
@ -1160,6 +1222,7 @@ class WebInterface(object):
raise cherrypy.HTTPRedirect("logs") raise cherrypy.HTTPRedirect("logs")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def log_js_errors(self, page, message, file, line): def log_js_errors(self, page, message, file, line):
""" Logs javascript errors from the web interface. """ """ Logs javascript errors from the web interface. """
logger.error(u"WebUI :: /%s : %s. (%s:%s)" % (page.rpartition('/')[-1], logger.error(u"WebUI :: /%s : %s. (%s:%s)" % (page.rpartition('/')[-1],
@ -1169,6 +1232,7 @@ class WebInterface(object):
return True return True
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def logFile(self): def logFile(self):
try: try:
with open(os.path.join(plexpy.CONFIG.LOG_DIR, 'plexpy.log'), 'r') as f: with open(os.path.join(plexpy.CONFIG.LOG_DIR, 'plexpy.log'), 'r') as f:
@ -1180,7 +1244,7 @@ class WebInterface(object):
##### Settings ##### ##### Settings #####
@cherrypy.expose @cherrypy.expose
@require() @requireAuth(member_of("admin"))
def settings(self): def settings(self):
interface_dir = os.path.join(plexpy.PROG_DIR, 'data/interfaces/') interface_dir = os.path.join(plexpy.PROG_DIR, 'data/interfaces/')
interface_list = [name for name in os.listdir(interface_dir) if interface_list = [name for name in os.listdir(interface_dir) if
@ -1306,6 +1370,7 @@ class WebInterface(object):
return serve_template(templatename="settings.html", title="Settings", config=config) return serve_template(templatename="settings.html", title="Settings", config=config)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def configUpdate(self, **kwargs): def configUpdate(self, **kwargs):
# Handle the variable config options. Note - keys with False values aren't getting passed # Handle the variable config options. Note - keys with False values aren't getting passed
@ -1446,10 +1511,12 @@ class WebInterface(object):
raise cherrypy.HTTPRedirect("settings") raise cherrypy.HTTPRedirect("settings")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_scheduler_table(self, **kwargs): def get_scheduler_table(self, **kwargs):
return serve_template(templatename="scheduler_table.html") return serve_template(templatename="scheduler_table.html")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def backup_db(self): def backup_db(self):
""" Creates a manual backup of the plexpy.db file """ """ Creates a manual backup of the plexpy.db file """
@ -1464,6 +1531,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_notification_agent_config(self, agent_id, **kwargs): def get_notification_agent_config(self, agent_id, **kwargs):
if agent_id.isdigit(): if agent_id.isdigit():
config = notifiers.get_notification_agent_config(agent_id=agent_id) config = notifiers.get_notification_agent_config(agent_id=agent_id)
@ -1483,6 +1551,7 @@ class WebInterface(object):
agent=this_agent, data=config, checkboxes=checkboxes) agent=this_agent, data=config, checkboxes=checkboxes)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_notification_agent_triggers(self, agent_id, **kwargs): def get_notification_agent_triggers(self, agent_id, **kwargs):
if agent_id.isdigit(): if agent_id.isdigit():
agents = notifiers.available_notification_agents() agents = notifiers.available_notification_agents()
@ -1500,6 +1569,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@addtoapi('notify') @addtoapi('notify')
@requireAuth(member_of("admin"))
def test_notifier(self, agent_id=None, subject='PlexPy', body='Test notification', **kwargs): def test_notifier(self, agent_id=None, subject='PlexPy', body='Test notification', **kwargs):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
@ -1525,12 +1595,14 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def twitterStep1(self): def twitterStep1(self):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
tweet = notifiers.TwitterNotifier() tweet = notifiers.TwitterNotifier()
return tweet._get_authorization() return tweet._get_authorization()
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def twitterStep2(self, key): def twitterStep2(self, key):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
tweet = notifiers.TwitterNotifier() tweet = notifiers.TwitterNotifier()
@ -1542,12 +1614,14 @@ class WebInterface(object):
return "Unable to verify key" return "Unable to verify key"
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def facebookStep1(self): def facebookStep1(self):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
facebook = notifiers.FacebookNotifier() facebook = notifiers.FacebookNotifier()
return facebook._get_authorization() return facebook._get_authorization()
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def facebookStep2(self, code): def facebookStep2(self, code):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
facebook = notifiers.FacebookNotifier() facebook = notifiers.FacebookNotifier()
@ -1559,6 +1633,7 @@ class WebInterface(object):
return "Unable to verify key" return "Unable to verify key"
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def osxnotifyregister(self, app): def osxnotifyregister(self, app):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
from osxnotify import registerapp as osxnotify from osxnotify import registerapp as osxnotify
@ -1573,6 +1648,7 @@ class WebInterface(object):
return msg return msg
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def set_notification_config(self, **kwargs): def set_notification_config(self, **kwargs):
for plain_config, use_config in [(x[4:], x) for x in kwargs if x.startswith('use_')]: for plain_config, use_config in [(x[4:], x) for x in kwargs if x.startswith('use_')]:
@ -1588,6 +1664,7 @@ class WebInterface(object):
cherrypy.response.status = 200 cherrypy.response.status = 200
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_plexwatch_export_data(self, database_path=None, table_name=None, import_ignore_interval=0, **kwargs): def get_plexwatch_export_data(self, database_path=None, table_name=None, import_ignore_interval=0, **kwargs):
from plexpy import plexwatch_import from plexpy import plexwatch_import
@ -1604,10 +1681,12 @@ class WebInterface(object):
return db_check_msg return db_check_msg
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def plexwatch_import(self, **kwargs): def plexwatch_import(self, **kwargs):
return serve_template(templatename="plexwatch_import.html", title="Import PlexWatch Database") return serve_template(templatename="plexwatch_import.html", title="Import PlexWatch Database")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_pms_token(self): def get_pms_token(self):
token = plextv.PlexTV() token = plextv.PlexTV()
@ -1620,6 +1699,7 @@ class WebInterface(object):
return False return False
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_server_id(self, hostname=None, port=None, identifier=None, ssl=0, remote=0, **kwargs): def get_server_id(self, hostname=None, port=None, identifier=None, ssl=0, remote=0, **kwargs):
from plexpy import http_handler from plexpy import http_handler
@ -1661,6 +1741,7 @@ class WebInterface(object):
return None return None
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_server_pref(self, pref=None, **kwargs): def get_server_pref(self, pref=None, **kwargs):
""" Return a specified server preference. """ Return a specified server preference.
@ -1682,12 +1763,14 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_server_pref.") logger.warn(u"Unable to retrieve data for get_server_pref.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def generateAPI(self): def generateAPI(self):
apikey = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[0:32] apikey = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[0:32]
logger.info(u"New API key generated.") logger.info(u"New API key generated.")
return apikey return apikey
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def checkGithub(self): def checkGithub(self):
from plexpy import versioncheck from plexpy import versioncheck
@ -1695,6 +1778,7 @@ class WebInterface(object):
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def do_state_change(self, signal, title, timer): def do_state_change(self, signal, title, timer):
message = title message = title
quote = self.random_arnold_quotes() quote = self.random_arnold_quotes()
@ -1704,14 +1788,17 @@ class WebInterface(object):
message=message, timer=timer, quote=quote) message=message, timer=timer, quote=quote)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def shutdown(self): def shutdown(self):
return self.do_state_change('shutdown', 'Shutting Down', 15) return self.do_state_change('shutdown', 'Shutting Down', 15)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def restart(self): def restart(self):
return self.do_state_change('restart', 'Restarting', 30) return self.do_state_change('restart', 'Restarting', 30)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def update(self): def update(self):
return self.do_state_change('update', 'Updating', 120) return self.do_state_change('update', 'Updating', 120)
@ -1719,6 +1806,7 @@ class WebInterface(object):
##### Info ##### ##### Info #####
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def info(self, rating_key=None, source=None, query=None, **kwargs): def info(self, rating_key=None, source=None, query=None, **kwargs):
metadata = None metadata = None
@ -1746,6 +1834,7 @@ class WebInterface(object):
return self.update_metadata(rating_key, query) return self.update_metadata(rating_key, query)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_item_children(self, rating_key='', **kwargs): def get_item_children(self, rating_key='', **kwargs):
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
@ -1758,6 +1847,7 @@ class WebInterface(object):
return serve_template(templatename="info_children_list.html", data=None, title="Children List") return serve_template(templatename="info_children_list.html", data=None, title="Children List")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def pms_image_proxy(self, img='', width='0', height='0', fallback=None, **kwargs): def pms_image_proxy(self, img='', width='0', height='0', fallback=None, **kwargs):
try: try:
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
@ -1786,6 +1876,7 @@ class WebInterface(object):
return None return None
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def delete_poster_url(self, poster_url=''): def delete_poster_url(self, poster_url=''):
if poster_url: if poster_url:
@ -1805,10 +1896,12 @@ class WebInterface(object):
##### Search ##### ##### Search #####
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def search(self, query=''): def search(self, query=''):
return serve_template(templatename="search.html", title="Search", query=query) return serve_template(templatename="search.html", title="Search", query=query)
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi('search') @addtoapi('search')
def search_results(self, query, **kwargs): def search_results(self, query, **kwargs):
@ -1822,6 +1915,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for search_results.") logger.warn(u"Unable to retrieve data for search_results.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_search_results_children(self, query, media_type=None, season_index=None, **kwargs): def get_search_results_children(self, query, media_type=None, season_index=None, **kwargs):
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
@ -1843,6 +1937,7 @@ class WebInterface(object):
##### Update Metadata ##### ##### Update Metadata #####
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def update_metadata(self, rating_key=None, query=None, update=False, **kwargs): def update_metadata(self, rating_key=None, query=None, update=False, **kwargs):
query_string = query query_string = query
update = True if update == 'True' else False update = True if update == 'True' else False
@ -1859,6 +1954,7 @@ class WebInterface(object):
return serve_template(templatename="update_metadata.html", query=query, update=update, title="Info") return serve_template(templatename="update_metadata.html", query=query, update=update, title="Info")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def update_metadata_details(self, old_rating_key, new_rating_key, media_type, **kwargs): def update_metadata_details(self, old_rating_key, new_rating_key, media_type, **kwargs):
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
@ -1881,6 +1977,7 @@ class WebInterface(object):
# test code # test code
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_new_rating_keys(self, rating_key='', media_type='', **kwargs): def get_new_rating_keys(self, rating_key='', media_type='', **kwargs):
""" """
@ -1905,6 +2002,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_new_rating_keys.") logger.warn(u"Unable to retrieve data for get_new_rating_keys.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_old_rating_keys(self, rating_key='', media_type='', **kwargs): def get_old_rating_keys(self, rating_key='', media_type='', **kwargs):
""" """
@ -1928,6 +2026,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi('get_sessions') @addtoapi('get_sessions')
def get_pms_sessions_json(self, **kwargs): def get_pms_sessions_json(self, **kwargs):
@ -1942,6 +2041,7 @@ class WebInterface(object):
return False return False
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi('get_metadata') @addtoapi('get_metadata')
def get_metadata_json(self, rating_key='', **kwargs): def get_metadata_json(self, rating_key='', **kwargs):
@ -1955,6 +2055,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_metadata_json.") logger.warn(u"Unable to retrieve data for get_metadata_json.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def get_metadata_xml(self, rating_key='', **kwargs): def get_metadata_xml(self, rating_key='', **kwargs):
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
@ -1967,6 +2068,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_metadata_xml.") logger.warn(u"Unable to retrieve data for get_metadata_xml.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi('get_recently_added') @addtoapi('get_recently_added')
def get_recently_added_json(self, count='0', **kwargs): def get_recently_added_json(self, count='0', **kwargs):
""" Get all items that where recelty added to plex """ Get all items that where recelty added to plex
@ -1989,6 +2091,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_recently_added_json.") logger.warn(u"Unable to retrieve data for get_recently_added_json.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_friends_list(self, **kwargs): def get_friends_list(self, **kwargs):
""" Gets the friends list of the server owner for plex.tv """ """ Gets the friends list of the server owner for plex.tv """
@ -2003,6 +2106,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_friends_list.") logger.warn(u"Unable to retrieve data for get_friends_list.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_user_details(self, **kwargs): def get_user_details(self, **kwargs):
""" Get all details about a user from plextv """ """ Get all details about a user from plextv """
@ -2017,6 +2121,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_user_details.") logger.warn(u"Unable to retrieve data for get_user_details.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_server_list(self, **kwargs): def get_server_list(self, **kwargs):
""" Find all servers published on plextv""" """ Find all servers published on plextv"""
@ -2031,6 +2136,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_server_list.") logger.warn(u"Unable to retrieve data for get_server_list.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_sync_lists(self, machine_id='', **kwargs): def get_sync_lists(self, machine_id='', **kwargs):
@ -2044,6 +2150,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_sync_lists.") logger.warn(u"Unable to retrieve data for get_sync_lists.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_servers(self, **kwargs): def get_servers(self, **kwargs):
""" All servers """ All servers
@ -2071,6 +2178,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_servers.") logger.warn(u"Unable to retrieve data for get_servers.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_servers_info(self, **kwargs): def get_servers_info(self, **kwargs):
""" Grabs list of info about the servers """ Grabs list of info about the servers
@ -2098,6 +2206,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_servers_info.") logger.warn(u"Unable to retrieve data for get_servers_info.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_server_identity(self, **kwargs): def get_server_identity(self, **kwargs):
""" Grabs info about the local server """ Grabs info about the local server
@ -2122,6 +2231,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_server_identity.") logger.warn(u"Unable to retrieve data for get_server_identity.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_server_friendly_name(self, **kwargs): def get_server_friendly_name(self, **kwargs):
@ -2134,6 +2244,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_server_friendly_name.") logger.warn(u"Unable to retrieve data for get_server_friendly_name.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_server_prefs(self, pref=None, **kwargs): def get_server_prefs(self, pref=None, **kwargs):
@ -2150,6 +2261,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_server_prefs.") logger.warn(u"Unable to retrieve data for get_server_prefs.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_activity(self, **kwargs): def get_activity(self, **kwargs):
""" Return processed and validated session list. """ Return processed and validated session list.
@ -2173,6 +2285,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_activity.") logger.warn(u"Unable to retrieve data for get_activity.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_full_users_list(self, **kwargs): def get_full_users_list(self, **kwargs):
""" Get a list all users that has access to your server """ Get a list all users that has access to your server
@ -2200,6 +2313,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_full_users_list.") logger.warn(u"Unable to retrieve data for get_full_users_list.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_sync_item(self, sync_id, **kwargs): def get_sync_item(self, sync_id, **kwargs):
""" Return sync item details. """ Return sync item details.
@ -2248,6 +2362,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_sync_item.") logger.warn(u"Unable to retrieve data for get_sync_item.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_sync_transcode_queue(self, **kwargs): def get_sync_transcode_queue(self, **kwargs):
@ -2261,6 +2376,7 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_sync_transcode_queue.") logger.warn(u"Unable to retrieve data for get_sync_transcode_queue.")
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def random_arnold_quotes(self, **kwargs): def random_arnold_quotes(self, **kwargs):
from random import randint from random import randint
@ -2312,6 +2428,7 @@ class WebInterface(object):
return a.fetchData() return a.fetchData()
@cherrypy.expose @cherrypy.expose
@requireAuth(member_of("admin"))
def check_pms_updater(self): def check_pms_updater(self):
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_update_staus() result = pms_connect.get_update_staus()

View file

@ -124,9 +124,6 @@ def initialize(options):
}, },
} }
if options['http_password']:
conf['/api'] = {'tools.auth.on': False}
# Prevent time-outs # Prevent time-outs
cherrypy.engine.timeout_monitor.unsubscribe() cherrypy.engine.timeout_monitor.unsubscribe()
cherrypy.tree.mount(WebInterface(), options['http_root'], config=conf) cherrypy.tree.mount(WebInterface(), options['http_root'], config=conf)