summaryrefslogtreecommitdiff
path: root/modules/installed/lib/auth.py
diff options
context:
space:
mode:
authorJames Vasile <james@hackervisions.org>2011-02-22 13:32:45 -0500
committerJames Vasile <james@hackervisions.org>2011-02-22 13:32:45 -0500
commit35071d7212cec1fc23e8204bfd392a116a5313ed (patch)
tree1c75a525227769fc94f303b5c0233882d90ef2a8 /modules/installed/lib/auth.py
...
Diffstat (limited to 'modules/installed/lib/auth.py')
-rw-r--r--modules/installed/lib/auth.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/modules/installed/lib/auth.py b/modules/installed/lib/auth.py
new file mode 100644
index 0000000..4b0f229
--- /dev/null
+++ b/modules/installed/lib/auth.py
@@ -0,0 +1,118 @@
+# Form based authentication for CherryPy. Requires the
+# Session tool to be loaded.
+#
+# Thanks for this code is owed to Arnar Birgisson -at - gmail.com. It
+# is based on code he wrote that was retrieved from
+# http://tools.cherrypy.org/wiki/AuthenticationAndAccessRestrictions
+# on 1 February 2011.
+
+# TODO: DeprecationWarning: the md5 module is deprecated; use hashlib instead import md5
+
+import cherrypy
+import urllib, hashlib
+import cfg
+
+cfg.session_key = '_cp_username'
+
+def check_credentials(username, passphrase):
+ """Verifies credentials for username and passphrase.
+ Returns None on success or a string describing the error on failure"""
+
+ u = cfg.users.get(username)
+ if u is None:
+ cfg.log("Unknown user: %s" % username)
+ return u"Username %s is unknown to me." % username
+ if u['passphrase'] != hashlib.md5(passphrase).hexdigest():
+ return u"Incorrect passphrase."
+
+
+def check_auth(*args, **kwargs):
+ """A tool that looks in config for 'auth.require'. If found and it
+ is not None, a login is required and the entry is evaluated as a
+ list of conditions that the user must fulfill"""
+ conditions = cherrypy.request.config.get('auth.require', None)
+ if conditions is not None:
+ username = cherrypy.session.get(cfg.session_key)
+ if username:
+ cherrypy.request.login = username
+ for condition in conditions:
+ # A condition is just a callable that returns true or false
+ if not condition():
+ raise cherrypy.HTTPRedirect("/auth/login")
+ else:
+ raise cherrypy.HTTPRedirect("/auth/login")
+
+def check_auth(*args, **kwargs):
+ """A tool that looks in config for 'auth.require'. If found and it
+ is not None, a login is required and the entry is evaluated as a
+ list of conditions that the user must fulfill"""
+ conditions = cherrypy.request.config.get('auth.require', None)
+ # format GET params
+ get_params = urllib.quote(cherrypy.request.request_line.split()[1])
+ if conditions is not None:
+ username = cherrypy.session.get(cfg.session_key)
+ if username:
+ cherrypy.request.login = username
+ for condition in conditions:
+ # A condition is just a callable that returns true or false
+ if not condition():
+ # Send old page as from_page parameter
+ raise cherrypy.HTTPRedirect("/auth/login?from_page=%s" % get_params)
+ else:
+ # Send old page as from_page parameter
+ raise cherrypy.HTTPRedirect("/auth/login?from_page=%s" % get_params)
+
+cherrypy.tools.auth = cherrypy.Tool('before_handler', check_auth)
+
+def require(*conditions):
+ """A decorator that appends conditions to the auth.require config
+ variable."""
+ def decorate(f):
+ if not hasattr(f, '_cp_config'):
+ f._cp_config = dict()
+ if 'auth.require' not in f._cp_config:
+ f._cp_config['auth.require'] = []
+ f._cp_config['auth.require'].extend(conditions)
+ return f
+ 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
+
+# These might be handy
+
+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
+
+