import tornado.auth import tornado.httpserver import tornado.ioloop from tornado.options import define, options import tornado.web import pymongo import bson import hashlib import base64 import uuid import os import logging logging.getLogger('qbt').setLevel(logging.DEBUG) logger = logging.getLogger('qbt') define("port", default=8888, help="run the qbt on the given port", type=int) define("mongodb_host", default="127.0.0.1", help="mongodb host address") define("mongodb_port", default=27017, help="connect to the mongodb on the given port", type=int) define("mongodb_dbname", default="blog", help="database name") define("mongodb_user", default="blog", help="database user") define("mongodb_password", default="blog", help="database password") HASH_ALGO = 'sha256' class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", MainHandler), (r"/login", LoginHandler), ] settings = dict( template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=os.path.join(os.path.dirname(__file__), "static"), xsrf_cookies=False, cookie_secret=base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes), login_url="/login", #autoescape=None, debug=True, ) tornado.web.Application.__init__(self, handlers, **settings) # Have one global connection to the blog DB across all handlers self.connection = pymongo.Connection(options.mongodb_host, options.mongodb_port) self.db = self.connection[options.mongodb_dbname] self.db.authenticate(options.mongodb_user, options.mongodb_password) class BaseHandler(tornado.web.RequestHandler): @property def db(self): return self.application.db def get_current_user(self): user_id = self.get_secure_cookie(u"user_id") logger.info("looking up user with id: {id}".format(id=user_id)) if not user_id: return None #get user record by id users = self.db.users.find(spec={"_id":bson.ObjectId(user_id)}, limit=1) if(users.count > 0): return users[0] return None class MainHandler(BaseHandler): @tornado.web.authenticated def get(self): self.write("Hello, world") class LoginHandler(BaseHandler): def get(self): self.write('
') def post(self): self.authenticate(self.get_argument("user_name"),self.get_argument("password")) self.redirect("/") def authenticate(self, username, password): h = hashlib.new(HASH_ALGO) #find user record by username. users = self.db.users.find(spec={"email":username}, limit=1) if(users.count > 0): user_record = users[0] else: logger.debug("no user with name: {username}", username=username) return #calculate password hash h.update(user_record['salt']+"--"+password) encrypted_password = h.hexdigest() logger.debug("checking {password} as {encrypted_password} against {record}".format(password=password, encrypted_password=encrypted_password, record=user_record['encrypted_password'])) if (user_record['encrypted_password'] == encrypted_password): #we have a match, so set the secure cookie to the salt logger.debug("setting user_id cookie to {id}".format(id=user_record['_id'])) self.set_secure_cookie(u"user_id", unicode(user_record['_id'])) def main(): tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(Application()) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start() if __name__ == "__main__": main()