Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # Native Python imports
- import cgi
- import logging
- import logging.handlers
- import sys
- import simplejson
- import signal
- import ConfigParser
- #import MySQLdb as mdb
- from zope.interface import implements
- from datetime import datetime
- # Twisted imports
- from twisted.cred import error as credError
- from twisted.cred.credentials import IUsernameHashedPassword, IUsernamePassword
- from twisted.cred.checkers import ICredentialsChecker
- from twisted.cred.portal import Portal, IRealm
- from twisted.enterprise import adbapi
- from twisted.internet import ssl, reactor
- from twisted.internet.defer import Deferred
- from twisted.web.http import HTTPChannel
- from twisted.web.guard import HTTPAuthSessionWrapper
- from twisted.web.guard import DigestCredentialFactory
- from twisted.web.guard import BasicCredentialFactory
- from twisted.web.server import Site
- from twisted.web.resource import Resource, IResource
- # Our imports
- import gameplayLogic
- import utils
- import accountLogic
- from utils import MBLogAdapter
- class Registration(Resource):
- def render_POST(self, request):
- logger = logging.getLogger('MB-Server.RegistrationResource')
- #formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(thread)d - Registration - render_POST - %(message)s')
- #for hand in logger.handlers:
- # hand.setFormatter(formatter)
- logger = MBLogAdapter(logger, {'file': 'main.py', 'object': 'Registration', 'method': 'render_POST'})
- logger.debug('request="%s"', str(request))
- username = cgi.escape(request.args['username'][0])
- password = cgi.escape(request.args['password'][0])
- email = cgi.escape(request.args['email'][0])
- logger.debug('username="%s" password="%s" email="%s"', username, password, email)
- output = accountLogic.registerUser(username, password, email)
- response_text = str({ 'status': output })
- request.setHeader("content-type", "application/json")
- request.setResponseCode(200)
- logger.debug('returning response="%s"', response_text)
- return response_text
- # http://twistedmatrix.com/documents/current/core/examples/dbcred.py
- class DBCredentialsChecker(object):
- implements(ICredentialsChecker)
- baseLogger = None
- def __init__(self, runQuery,
- query="""
- CALL checkLogin(%s);
- """, customCheckFunc=None, caseSensitivePasswords=True):
- """@param runQuery: This will be called to get the info from the db.
- Generally, you'd want to create a L{twisted.enterprise.abdapi.ConnectionPool}
- and pass its runQuery method here. Otherwise pass a function with the same prototype.
- @type runQuery: C{callable}
- @param query: query used to authenticate user.
- @type query: C{str}
- @param customCheckFunc: Use this if the passwords in the db are stored as hashed. We'll just call this, so you can do the checking yourself. It takes the following params: (username, suppliedPass, dbPass) and must return a boolean.
- @type customCheckFunc: C{callable}
- @param caseSensitivePasswords: If true requires that every letter in C{credentials.password} is exactly the same case as its counterpart character in the database. This is only relevant if C{customCheckFunc} is not used.
- @type caseSensitivePasswords: C{bool}
- """
- self.baseLogger = logging.getLogger('MB-Server.DBCredentialsChecker')
- logger = MBLogAdapter(self.baseLogger, {'file': 'main.py', 'object': 'DBCredentialsChecker', 'method': '__init__'})
- logger.debug('Starting method...')
- logger.debug('runQuery="%s" caseSensitivePasswords="%s" customCheckFunc="%s" query="%s"', str(runQuery), str(caseSensitivePasswords), str(customCheckFunc), str(query))
- self.runQuery = runQuery
- self.caseSensitivePasswords = caseSensitivePasswords
- self.customCheckFunc = customCheckFunc
- # We can't support hashed password credentials if we only have a hash in the DB
- if customCheckFunc:
- self.credentialsInterfaces = (IUsernamePassword,)
- else:
- self.credentialInterfaces = (IUsernamePassword, IUsernameHashedPassword,)
- self.sql = query
- def requestAvatarId(self, credentials):
- """
- Authenticates the kiosk against the database.
- """
- logger = MBLogAdapter(self.baseLogger, {'file': 'main.py', 'object': 'DBCredentialsChecker', 'method': 'requestAvatarId'})
- logger.debug('Starting method...')
- logger.debug('credentials="%s"', str(credentials))
- # Check that the credentials instance implements at least one of our interfaces
- for interface in self.credentialInterfaces:
- if interface.providedBy(credentials):
- break
- else:
- raise credError.UnhandledCredentials()
- # Ask the database for the username and password
- dbDeferred = self.runQuery(self.sql, (credentials.username,))
- # Setup our deferred result
- deferred = Deferred()
- dbDeferred.addCallbacks(self._cbAuthenticate, self._ebAuthenticate,
- callbackArgs=(credentials, deferred),
- errbackArgs=(credentials, deferred))
- return deferred
- def _cbAuthenticate(self, result, credentials, deferred):
- """
- Checks to see if the authentication was good. Called once the info has been retrieved from the DB.
- """
- logger = MBLogAdapter(self.baseLogger, {'file': 'main.py', 'object': 'DBCredentialsChecker', 'method': '_cbAuthenticate'})
- logger.debug('Starting method...')
- logger.debug('result="%s" credentials="%s" deferred="%s"', str(result), str(credentials), str(deferred))
- if len(result) == 0:
- # Username not found in db
- deferred.errback(credError.UnauthorizedLogin('Username unknown'))
- else:
- username, password = result[0]
- if self.customCheckFunc:
- # Let the owner do the checking
- if self.customCheckFunc(
- username, credentials.password, password):
- deferred.callback(credentials.username)
- else:
- deferred.errback(credError.UnauthorizedLogin('Password mismatch'))
- else:
- # It's up to us or the credentials object to do the checking now
- if IUsernameHashedPassword.providedBy(credentials):
- # Let the hashed password checker do the checking
- if credentials.checkPassword(password):
- deferred.callback(credentials.username)
- else:
- deferred.errback(credError.UnauthorizedLogin('Password mismatch'))
- elif IUsernamePassword.providedBy(credentials):
- # Compare the passwords, deciding whether or not to use case sensitivity
- if self.caseSensiivePasswords:
- passOk = (password.lower() == credentials.password.lower())
- else:
- passOk = password == credentials.password
- # See if they match
- if passOk:
- deferred.callback(credentials.username)
- else:
- deferred.errback(credError.UnauthorizedLogin('Password mismatch'))
- else:
- # OK, we don't know how to check this
- deferred.errback(credError.UnhandledCredentials())
- def _ebAuthenticate(self, message, credentials, deferred):
- """
- The database lookup failed for some reason.
- """
- logger = MBLogAdapter(self.baseLogger, {'file': 'main.py', 'object': 'DBCredentialsChecker', 'method': '_ebAuthenticate'})
- logger.debug('Starting method...')
- logger.debug('message="%s" credentials="%s" deferred="%s"', str(message), str(credentials), str(deferred))
- deferred.errback(credError.LoginFailed(message))
- #class PasswordChecker:
- # implements(checkers.ICredentialsChecker)
- # credentialInterfaces = (credentials.IUsernamePassword,)
- #
- # def requestAvatarId(self, credentials):
- # logger = logging.getLogger('MB-Server.PasswordChecker')
- # logger = MBLogAdapter(logger, {'file': 'main.py', 'object': 'PasswordChecker', 'method': 'requestAvatarId'})
- # username = credentials.username
- # # check DB here
- #
- # if True:
- # return defer.succeed(username)
- # else:
- # return defer.fail(credError.UnauthorizedLogin("bad creds"))
- class HttpPasswordRealm(object):
- implements(IRealm)
- logger = None
- def __init__(self, myresource):
- self.logger = logging.getLogger('MB-Server.HttpPasswordRealm')
- self.logger = MBLogAdapter(self.logger, {'file': 'main.py', 'object': 'HttpPasswordRealm', 'method': '__init__'})
- self.logger.info('Creating new HttpPasswordRealm')
- self.myresource = myresource
- def requestAvatar(self, user, mind, *interfaces):
- self.logger = MBLogAdapter(self.logger, {'file': 'main.py', 'object': 'HttpPasswordRealm', 'method': 'requestAvatar'})
- self.logger.debug('requestAvatar(%s, %s, %s) called', str(user), str(mind), str(interface))
- if IResource in interfaces:
- self.logger.debug('IResource="%s"', str(IResource))
- # myresource is passed regardless of user
- return (IResource, self.myresource, lambda: None)
- raise NotImplementedError()
- class MyResource(Resource):
- def __init__(self):
- self.logger = logging.getLogger('MB-Server.MyResource')
- self.logger = MBLogAdapter(self.logger, {'file': 'main.py', 'object': 'MyResource', 'method': '__init__'})
- self.logger.info('Creating new HttpPasswordRealm')
- Resource.__init__(self)
- def getChild(self, path, request):
- self.logger = MBLogAdapter(self.logger, {'file': 'main.py', 'object': 'MyResource', 'method': 'getChild'})
- self.logger.debug('getChild(%s, %s) called', str(path), str(request))
- text = "You're in. The path is /%s." % path
- return static.Data(text, "text/plain")
- #class Login(Resource):
- # def render_POST(self, request):
- # logger = logging.getLogger('MB-Server.LoginResource')
- # formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(thread)d - Login - render_POST - %(message)s')
- # for hand in logger.handlers:
- # hand.setFormatter(formatter)
- #
- # logger.debug('request="%s"', str(request))
- # username = cgi.escape(request.args['username'][0])
- # password = cgi.escape(request.args['password'][0])
- # email = cgi.escape(request.args['email'][0])
- #
- # logger.debug('username="%s" password="%s" email="%s"', username, password, email)
- #
- # output = accountLogic.registerUser(username, password, email)
- # response_text = str({ 'status': output })
- #
- # request.setHeader("content-type", "application/json")
- # request.setResponseCode(200)
- # logger.debug('returning response="%s"', response_text)
- # return response_text
- if __name__ == "__main__":
- # Run Dat server
- # CONFIGS
- config = ConfigParser.RawConfigParser()
- config.read('server.conf')
- PORT = int(config.get('server','port'))
- # LOGGING
- log = logging.getLogger('MB-Server')
- formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(thread)d - %(message)s')
- consoleHandler = logging.StreamHandler()
- consoleHandler.setFormatter(formatter)
- consoleHandler.setLevel(logging.DEBUG)
- log.addHandler(consoleHandler)
- fileHandler = logging.handlers.RotatingFileHandler('log/server.log', maxBytes=52428800) # 50 MB files
- fileHandler.setFormatter(formatter)
- fileHandler.setLevel(logging.DEBUG)
- log.addHandler(fileHandler)
- log.setLevel(logging.DEBUG)
- log = MBLogAdapter(log, {'file': 'main.py', 'object': 'raw', 'method': 'init'})
- log.info('Server starting on port="%s"...', PORT)
- # SERVER SETUP
- root = Resource()
- myresource = MyResource()
- pool = adbapi.ConnectionPool('MySQLdb',(config.get('database','host'),config.get('database','user'),config.get('database','password'),config.get('database','database')))
- #checker = PasswordChecker()
- checker = DBCredentialsChecker(pool.runQuery, query="SELECT username, password FROM user WHERE username = ?")
- #checker.requestAvatarId('my bogus data')
- realm = HttpPasswordRealm(myresource)
- p = Portal(realm)
- p.registerChecker(checker)
- log.debug('p="%s"', str(p))
- credentialFactory = BasicCredentialFactory("Chainsaw Rabbit Games")
- log.debug('credentialFactory="%s"', str(credentialFactory))
- protected_resource = HTTPAuthSessionWrapper(p, [credentialFactory])
- log.debug('protected_resource="%s"', str(protected_resource))
- root.putChild('register', Registration())
- root.putChild('example', protected_resource)
- #root.putChild('login', Login())
- factory = Site(root)
- factory.protocol = HTTPChannel
- #reactor.listenTCP(PORT, factory)
- log.debug('listCredentialsInterfaces="%s"', str(p.listCredentialsInterfaces()))
- reactor.listenSSL(PORT, factory,
- ssl.DefaultOpenSSLContextFactory(
- 'ssl/server.key', 'ssl/server.crt'))
- reactor.run()
Advertisement
Add Comment
Please, Sign In to add comment