forked from openlp/openlp
More updates to authentication
This commit is contained in:
parent
c62dab074e
commit
5c79832bcc
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 <username> is in <groupname>
|
||||
# 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 """<html><body>
|
||||
<form method="post" action="/auth/login">
|
||||
<input type="hidden" name="from_page" value="%(from_page)s" />
|
||||
%(msg)s<br />
|
||||
Username: <input type="text" name="username" value="%(username)s" /><br />
|
||||
Password: <input type="password" name="password" /><br />
|
||||
<input type="submit" value="Log in" />
|
||||
</body></html>""" % locals()
|
||||
return """<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1" />
|
||||
<title>User Login</title>
|
||||
<link rel="stylesheet" href="/files/jquery.mobile.css" />
|
||||
<link rel="stylesheet" href="/files/openlp.css" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico">
|
||||
<script type="text/javascript" src="/files/jquery.js"></script>
|
||||
<script type="text/javascript" src="/files/openlp.js"></script>
|
||||
<script type="text/javascript" src="/files/jquery.mobile.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<form method="post" action="/auth/login">
|
||||
<input type="hidden" name="from_page" value="%(from_page)s" />
|
||||
%(msg)s<br/>
|
||||
Username: <input type="text" name="username" value="%(username)s" /><br />
|
||||
Password: <input type="password" name="password" /><br />
|
||||
<input type="submit" value="Log in" />
|
||||
</body></html>""" % locals()
|
||||
|
||||
@cherrypy.expose
|
||||
def login(self, username=None, password=None, from_page="/"):
|
||||
|
@ -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 = ["<html><body>Sorry, an error occured</body></html>"]
|
||||
cherrypy.response.body = ["<html><body>Sorry, an error occurred </body></html>"]
|
||||
|
||||
def _get_service_manager(self):
|
||||
"""
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user