Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Simple authn and authz

  • Loading branch information...
commit 4bcab21a6b714321cfb3d98994eca494f29f1fb3 1 parent a2c32bd
Peter Parente authored
6 README.rst
View
@@ -1,6 +1,6 @@
-===========
-Handler Bag
-===========
+==========
+handlerbag
+==========
:Author: Peter Parente
:Description: A little layer on top of the Tornado web server to manage a bag of dynamic handlers.
18 handlerbag.py
View
@@ -17,10 +17,12 @@
import re
# handlerbag
import hbag
+import login
+import uuid
class HandlerBag(tornado.web.Application):
- def __init__(self, **kwargs):
- super(HandlerBag, self).__init__([], **kwargs)
+ def __init__(self, handlers=[], **kwargs):
+ super(HandlerBag, self).__init__(handlers, **kwargs)
# load the bag db
self.db = shelve.open('hbdata')
# import dynamic module
@@ -164,9 +166,19 @@ def set_handler_status(self, name, enable):
if __name__ == '__main__':
define('webroot', default='/', help='absolute root url of all handlers (default: /)')
define('port', default=5000, type=int, help='drop server port (default: 5000)')
+ define('debug', default=False, type=bool, help='enable debug autoreload (default: false)')
tornado.options.parse_command_line()
- application = HandlerBag()
+ settings = {
+ 'login_url' : '/login',
+ 'auth_cookie' : 'handlerbag.user',
+ 'cookie_secret' : uuid.uuid4().hex,
+ 'debug' : options.debug
+ }
+ handlers = [
+ ('/login/?', login.GoogleHandler)
+ ]
+ application = HandlerBag(handlers, **settings)
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
ioloop = tornado.ioloop.IOLoop.instance()
11 hbag/admin/admin.py
View
@@ -3,15 +3,24 @@
import tornado.web
# std lib
import json
+# handlerbag
+import users
class AdminHandler(tornado.web.RequestHandler):
+ def get_current_user(self):
+ return self.get_secure_cookie(self.settings['auth_cookie'])
+
+ @tornado.web.authenticated
+ @users.requireRole('admin')
def get(self, *args, **kwargs):
# force update of handler list
db = self.application.refresh_handlers_in_db()
# show all handlers but ourselves
items = (item for item in db.iteritems() if item[0] != 'admin')
self.render('admin.html', items=items)
-
+
+ @tornado.web.authenticated
+ @users.requireRole('admin')
def post(self, *args, **kwargs):
obj = json.loads(self.request.body)
for name, enabled in obj.iteritems():
28 login.py
View
@@ -0,0 +1,28 @@
+# tornado
+import tornado.web
+import tornado.auth
+# handlerbag
+import users
+
+class GoogleHandler(tornado.web.RequestHandler, tornado.auth.GoogleMixin):
+ NEXT_COOKIE='handlerbag.next'
+ def get_current_user(self):
+ return self.get_secure_cookie(self.settings['auth_cookie'])
+
+ @tornado.web.asynchronous
+ def get(self):
+ if self.get_argument('openid.mode', None):
+ self.get_authenticated_user(self.async_callback(self._on_auth))
+ else:
+ # save next into a temp cookie
+ next = self.request.arguments.get('next', ['/'])[0]
+ self.set_secure_cookie(self.NEXT_COOKIE, next)
+ self.authenticate_redirect(ax_attrs=['email'])
+
+ def _on_auth(self, user):
+ if not user:
+ raise tornado.web.HTTPError(500, 'Google auth failed')
+ self.set_secure_cookie(self.settings['auth_cookie'], user['email'])
+ next = self.get_secure_cookie(self.NEXT_COOKIE)
+ self.clear_cookie(self.NEXT_COOKIE)
+ self.redirect(next)
15 users.py
View
@@ -0,0 +1,15 @@
+# tornado
+import tornado.web
+
+allowed = {
+ 'parente@gmail.com' : 'admin'
+}
+
+def requireRole(role='admin'):
+ def wrap(method):
+ def wrapped_m(self, *args, **kwargs):
+ if allowed.get(self.current_user, '') != role:
+ raise tornado.web.HTTPError(403)
+ return method(self, *args, **kwargs)
+ return wrapped_m
+ return wrap
Please sign in to comment.
Something went wrong with that request. Please try again.