From 5c79832bcc8f1448292c7ec5c1bfe5775ea75fd9 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 11 Mar 2013 21:00:00 +0000 Subject: [PATCH] More updates to authentication --- openlp/core/lib/settingstab.py | 1 + openlp/core/ui/slidecontroller.py | 2 - openlp/plugins/remotes/lib/httpauth.py | 90 ++++++++---------------- openlp/plugins/remotes/lib/httpserver.py | 32 ++++----- openlp/plugins/remotes/lib/remotetab.py | 7 +- 5 files changed, 46 insertions(+), 86 deletions(-) diff --git a/openlp/core/lib/settingstab.py b/openlp/core/lib/settingstab.py index 5b8a01fc6..51abfbe03 100644 --- a/openlp/core/lib/settingstab.py +++ b/openlp/core/lib/settingstab.py @@ -36,6 +36,7 @@ from PyQt4 import QtGui from openlp.core.lib import Registry + class SettingsTab(QtGui.QWidget): """ SettingsTab is a helper widget for plugins to define Tabs for the settings diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 5fdd58aae..44ae023b6 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -860,8 +860,6 @@ class SlideController(DisplayController): """ Go to the requested slide """ - if not self.service_item or not message[0]: - return index = int(message[0]) if not self.service_item: return diff --git a/openlp/plugins/remotes/lib/httpauth.py b/openlp/plugins/remotes/lib/httpauth.py index 6ed42cebd..7e0e2ebe5 100644 --- a/openlp/plugins/remotes/lib/httpauth.py +++ b/openlp/plugins/remotes/lib/httpauth.py @@ -34,24 +34,24 @@ http://tools.cherrypy.org/wiki/AuthenticationAndAccessRestrictions """ import cherrypy -import urlparse +import logging + +from openlp.core.lib import Settings SESSION_KEY = '_cp_openlp' +log = logging.getLogger(__name__) + def check_credentials(user_name, password): """ Verifies credentials for username and password. Returns None on success or a string describing the error on failure """ - # @todo make from config - print "check_credentials" - if user_name == 'openlp' and password == 'openlp': + if user_name == Settings().value(u'remotes/user id') and password == Settings().value(u'remotes/password'): return None else: return u"Incorrect username or password." - # if u.password != md5.new(password).hexdigest(): - # return u"Incorrect password" def check_auth(*args, **kwargs): @@ -60,17 +60,14 @@ def check_auth(*args, **kwargs): is not None, a login is required and the entry is evaluated as a list of conditions that the user must fulfill """ - print "check_auth" conditions = cherrypy.request.config.get('auth.require', None) - print urlparse.urlparse(cherrypy.url()), conditions - print conditions + if not Settings().value(u'remotes/authentication enabled'): + return None if conditions is not None: username = cherrypy.session.get(SESSION_KEY) - print username if username: cherrypy.request.login = username for condition in conditions: - print "c ", condition # A condition is just a callable that returns true or false if not condition(): raise cherrypy.HTTPRedirect("/auth/login") @@ -97,49 +94,6 @@ def require_auth(*conditions): return decorate -# Conditions are callables that return True -# if the user fulfills the conditions they define, False otherwise -# -# They can access the current username as cherrypy.request.login -# -# Define those at will however suits the application. - -#def member_of(groupname): -# def check(): -# # replace with actual check if is in -# return cherrypy.request.login == 'joe' and groupname == 'admin' -# return check - - -#def name_is(reqd_username): -# return lambda: reqd_username == cherrypy.request.login - -#def any_of(*conditions): -# """ -# Returns True if any of the conditions match -# """ -# def check(): -# for c in conditions: -# if c(): -# return True -# return False -# return check - -# By default all conditions are required, but this might still be -# needed if you want to use it inside of an any_of(...) condition -#def all_of(*conditions): -# """ -# Returns True if all of the conditions match -# """ -# def check(): -# for c in conditions: -# if not c(): -# return False -# return True -# return check -# Controller to provide login and logout actions - - class AuthController(object): def on_login(self, username): @@ -156,14 +110,26 @@ class AuthController(object): """ Provides a login form """ - return """ -
- - %(msg)s
- Username:
- Password:
- - """ % locals() + return """ + + + + User Login + + + + + + + + + + + %(msg)s
+ Username:
+ Password:
+ + """ % locals() @cherrypy.expose def login(self, username=None, password=None, from_page="/"): diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index 345c0b1b7..211608858 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -130,6 +130,7 @@ from openlp.plugins.remotes.lib.httpauth import AuthController, require_auth log = logging.getLogger(__name__) + class HttpServer(object): """ Ability to control OpenLP via a web browser. @@ -156,10 +157,19 @@ class HttpServer(object): clients. Listen out for socket connections. """ log.debug(u'Start CherryPy server') - port = Settings().value(self.plugin.settingsSection + u'/port') - address = Settings().value(self.plugin.settingsSection + u'/ip address') - server_config = {u'server.socket_host': str(address), - u'server.socket_port': port} + if Settings().value(self.plugin.settingsSection + u'/https enabled'): + port = Settings().value(self.plugin.settingsSection + u'/https port') + address = Settings().value(self.plugin.settingsSection + u'/ip address') + shared_data = AppLocation.get_directory(AppLocation.SharedData) + server_config = {u'server.socket_host': str(address), + u'server.socket_port': port, + u'server.ssl_certificate': os.path.join(shared_data, u'openlp.crt'), + u'server.ssl_private_key': os.path.join(shared_data, u'openlp.key')} + else: + port = Settings().value(self.plugin.settingsSection + u'/port') + address = Settings().value(self.plugin.settingsSection + u'/ip address') + server_config = {u'server.socket_host': str(address), + u'server.socket_port': port} cherrypy.config.update(server_config) cherrypy.config.update({'environment': 'embedded'}) cherrypy.config.update({'engine.autoreload_on': False}) @@ -231,10 +241,8 @@ class HttpConnection(object): """ Handles the requests for the main url. This is secure depending on settings in config. """ - print "default" url = urlparse.urlparse(cherrypy.url()) self.url_params = urlparse.parse_qs(url.query) - print url # Loop through the routes we set up earlier and execute them return self._process_http_request(args, kwargs) @@ -243,10 +251,8 @@ class HttpConnection(object): """ Handles the requests for the stage url. This is not secure. """ - print "Stage" url = urlparse.urlparse(cherrypy.url()) self.url_params = urlparse.parse_qs(url.query) - print url return self._process_http_request(args, kwargs) @cherrypy.expose @@ -254,24 +260,20 @@ class HttpConnection(object): """ Handles the requests for the files url. This is not secure. """ - print "files" url = urlparse.urlparse(cherrypy.url()) self.url_params = urlparse.parse_qs(url.query) - print url return self._process_http_request(args, kwargs) def _process_http_request(self, args, kwargs): """ Common function to process HTTP requests where secure or insecure """ - print "common handler" url = urlparse.urlparse(cherrypy.url()) self.url_params = urlparse.parse_qs(url.query) response = None for route, func in self.routes: match = re.match(route, url.path) if match: - print 'Route "%s" matched "%s"', route, url.path, func log.debug('Route "%s" matched "%s"', route, url.path) args = [] for param in match.groups(): @@ -474,11 +476,8 @@ class HttpConnection(object): # This slot expects an int within a list. id = data[u'request'][u'id'] Registry().execute(event, [id]) - else: - Registry().execute(event, [0]) json_data = {u'results': {u'success': True}} cherrypy.response.headers['Content-Type'] = u'application/json' - print json.dumps(json_data) return json.dumps(json_data) def service(self, action): @@ -545,7 +544,6 @@ class HttpConnection(object): """ Go live on an item of type ``plugin``. """ - print "go_live" try: id = json.loads(self.url_params[u'data'][0])[u'request'][u'id'] except KeyError, ValueError: @@ -577,7 +575,7 @@ class HttpConnection(object): def _http_not_found(self): cherrypy.response.status = 404 - cherrypy.response.body = ["Sorry, an error occured"] + cherrypy.response.body = ["Sorry, an error occurred "] def _get_service_manager(self): """ diff --git a/openlp/plugins/remotes/lib/remotetab.py b/openlp/plugins/remotes/lib/remotetab.py index b5c911257..7d47988fc 100644 --- a/openlp/plugins/remotes/lib/remotetab.py +++ b/openlp/plugins/remotes/lib/remotetab.py @@ -56,15 +56,13 @@ class RemoteTab(SettingsTab): self.address_label.setObjectName(u'address_label') self.address_edit = QtGui.QLineEdit(self.server_settings_group_box) self.address_edit.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) - - self.address_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), + self.address_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self)) self.address_edit.setObjectName(u'address_edit') self.server_settings_layout.addRow(self.address_label, self.address_edit) self.twelve_hour_check_box = QtGui.QCheckBox(self.server_settings_group_box) self.twelve_hour_check_box.setObjectName(u'twelve_hour_check_box') self.server_settings_layout.addRow(self.twelve_hour_check_box) - self.leftLayout.addWidget(self.server_settings_group_box) self.http_settings_group_box = QtGui.QGroupBox(self.leftColumn) self.http_settings_group_box.setObjectName(u'http_settings_group_box') @@ -75,7 +73,6 @@ class RemoteTab(SettingsTab): self.port_spin_box = QtGui.QSpinBox(self.http_settings_group_box) self.port_spin_box.setMaximum(32767) self.port_spin_box.setObjectName(u'port_spin_box') - self.http_setting_layout.addRow(self.port_label, self.port_spin_box) self.remote_url_label = QtGui.QLabel(self.http_settings_group_box) self.remote_url_label.setObjectName(u'remote_url_label') @@ -244,7 +241,7 @@ class RemoteTab(SettingsTab): Settings().setValue(self.settingsSection + u'/user id', self.user_id.text()) Settings().setValue(self.settingsSection + u'/password', self.password.text()) if changed: - Registry().register_function(u'remotes_config_updated') + Registry().execute(u'remotes_config_updated') def on_twelve_hour_check_box_changed(self, check_state):