Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • DM/dm-docs
  • hammonds/dm-docs
  • hparraga/dm-docs
3 results
Show changes
Showing
with 2576 additions and 0 deletions
#!/usr/bin/env python
from dm.common.constants import dmRole
from dm.common.objects.authorizationPrincipal import AuthorizationPrincipal
from dm.common.db.api.userDbApi import UserDbApi
from authorizationPrincipalRetriever import AuthorizationPrincipalRetriever
class DbPrincipalRetriever(AuthorizationPrincipalRetriever):
def __init__(self):
AuthorizationPrincipalRetriever.__init__(self, self.__class__.__name__)
self.dbApi = UserDbApi()
def getAuthorizationPrincipal(self, username):
principal = None
try:
user = self.dbApi.getUserWithPasswordByUsername(username)
principal = AuthorizationPrincipal(name=username, token=user.get('password'))
principal.setUserSystemRoleDict(user.get('userSystemRoleDict', {}))
principal.setUserExperimentRoleDict(user.get('userExperimentRoleDict', {}))
self.setAuthorizationPrincipalSessionRole(principal)
except Exception, ex:
self.logger.debug(ex)
return principal
#######################################################################
# Testing.
if __name__ == '__main__':
pass
#!/usr/bin/env python
from dm.common.utility.ldapUtility import LdapUtility
from authorizationPrincipalAuthenticator import AuthorizationPrincipalAuthenticator
class LdapPasswordPrincipalAuthenticator(AuthorizationPrincipalAuthenticator):
def __init__(self, serverUrl, dnFormat):
AuthorizationPrincipalAuthenticator.__init__(self, self.__class__.__name__)
self.ldapUtility = LdapUtility(serverUrl, dnFormat)
def authenticatePrincipal(self, principal, password):
if principal is not None:
try:
self.logger.debug('Checking credentials for %s' % principal.getName())
self.ldapUtility.checkCredentials(principal.getName(), password)
return principal
except Exception, ex:
self.logger.debug(ex)
return None
#######################################################################
# Testing.
if __name__ == '__main__':
pass
#!/usr/bin/env python
from dm.common.constants import dmRole
from dm.common.objects.authorizationPrincipal import AuthorizationPrincipal
from dm.common.utility.cryptUtility import CryptUtility
from authorizationPrincipalRetriever import AuthorizationPrincipalRetriever
class NoOpPrincipalRetriever(AuthorizationPrincipalRetriever):
def __init__(self):
AuthorizationPrincipalRetriever.__init__(self, self.__class__.__name__)
def getAuthorizationPrincipal(self, username):
# Set password to be the same as username
noOpPassword = CryptUtility.cryptPasswordWithPbkdf2(username)
principal = AuthorizationPrincipal(name=username, token=noOpPassword)
principal.setUserSystemRoleDict({dmRole.DM_ADMIN_SYSTEM_ROLE_ID:[]})
principal.setUserExperimentRoleDict({})
self.setAuthorizationPrincipalSessionRole(principal)
return principal
#######################################################################
# Testing.
if __name__ == '__main__':
pass
#!/usr/bin/env python
from dm.common.utility.loggingManager import LoggingManager
class SessionManager:
def __init__(self, name=None):
self.name = name
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
def getName(self):
return self.name
def addSession(self, sessionId, sessionInfo):
return None
def checkSession(self, sessionId):
return None
#######################################################################
# Testing.
if __name__ == '__main__':
pass
#!/usr/bin/env python
import os
from dm.common.utility.configurationManager import ConfigurationManager
from dm.common.objects.dmObjectManager import DmObjectManager
from dm.common.utility.objectUtility import ObjectUtility
from dm.common.utility.singleton import Singleton
from dm.common.exceptions.objectNotFound import ObjectNotFound
class SingleSignOnManager(DmObjectManager, Singleton):
DEFAULT_SESSION_TIMEOUT_IN_SECONDS = 3600 # seconds
CONFIG_SECTION_NAME = 'SingleSignOnManager'
SESSION_MANAGER_KEY = 'sessionManager'
SESSION_TIMEOUT_IN_SECONDS_KEY = 'sessionTimeoutInSeconds'
# Singleton instance.
__instance = None
def __init__(self):
if SingleSignOnManager.__instance:
return
SingleSignOnManager.__instance = self
DmObjectManager.__init__(self)
self.configurationManager = ConfigurationManager.getInstance()
self.sessionManager = None
self.configure()
def configure(self):
configItems = self.configurationManager.getConfigItems(SingleSignOnManager.CONFIG_SECTION_NAME)
self.logger.debug('Got config items: %s' % configItems)
if not configItems:
return
sessionTimeout = self.configurationManager.getConfigOption(SingleSignOnManager.CONFIG_SECTION_NAME, SingleSignOnManager.SESSION_TIMEOUT_IN_SECONDS_KEY, SingleSignOnManager.DEFAULT_SESSION_TIMEOUT_IN_SECONDS)
self.logger.debug('Session timeout: %s' % sessionTimeout)
# Create session manager
sessionManager = self.configurationManager.getConfigOption(SingleSignOnManager.CONFIG_SECTION_NAME, SingleSignOnManager.SESSION_MANAGER_KEY)
(moduleName,className,constructor) = self.configurationManager.getModuleClassConstructorTuple(sessionManager, SingleSignOnManager)
self.logger.debug('Creating session manager class: %s' % className)
self.sessionManager = ObjectUtility.createObjectInstance(moduleName, className, constructor)
def addSession(self, sessionId, sessionInfo):
if self.sessionManager:
self.logger.debug('Adding session id %s: %s' % (sessionId,sessionInfo))
try:
return self.sessionManager.addSession(sessionId, sessionInfo)
except Exception, ex:
self.logger.error(ex)
return None
def checkSession(self, sessionId):
if self.sessionManager:
self.logger.debug('Checking session id: %s' % sessionId)
try:
return self.sessionManager.checkSession(sessionId)
except ObjectNotFound, ex:
self.logger.debug(ex)
except Exception, ex:
self.logger.error(ex)
return None
#######################################################################
# Testing.
if __name__ == '__main__':
am = AuthorizationPrincipalManager.getInstance()
authPrincipal = am.getAuthorizationPrincipal('sveseli', 'sv')
print 'Auth principal: ', authPrincipal
#!/usr/bin/env python
#
# Base DM controller class.
#
#######################################################################
import cherrypy
import httplib
import json
from sys import exc_info
from dm.common.utility.loggingManager import LoggingManager
from dm.common.constants import dmStatus
from dm.common.constants import dmHttpHeaders
from dm.common.exceptions.dmException import DmException
from dm.common.exceptions import dmExceptionMap
from dm.common.exceptions.internalError import InternalError
#######################################################################
class DmController(object):
""" Base controller class. """
def __init__(self):
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
@classmethod
def getLogger(cls):
logger = LoggingManager.getInstance().getLogger(cls.__name__)
return logger
@classmethod
def addDmResponseHeaders(cls, status=dmStatus.DM_OK, msg='Success', exceptionType=None):
cherrypy.response.headers[dmHttpHeaders.DM_STATUS_CODE_HTTP_HEADER] = status
cherrypy.response.headers[dmHttpHeaders.DM_STATUS_MESSAGE_HTTP_HEADER] = msg
if exceptionType is not None:
cherrypy.response.headers[dmHttpHeaders.DM_EXCEPTION_TYPE_HTTP_HEADER] = exceptionType
@classmethod
def addDmSessionRoleHeaders(cls, role):
cherrypy.response.headers[dmHttpHeaders.DM_SESSION_ROLE_HTTP_HEADER] = role
@classmethod
def addDmExceptionHeaders(cls, ex):
cls.handleException(ex)
@classmethod
def handleCpException(cls):
cherrypy.response.status = httplib.OK
ex = exc_info()[1]
if ex == None:
ex = InternalError('Internal Webservice Error')
cls.handleException(ex)
@classmethod
def handleException(cls, ex):
exClass = ex.__class__.__name__.split('.')[-1]
status = None
msg = '%s' % ex
msg = msg.split('\n')[0]
for code in dmExceptionMap.DM_EXCEPTION_MAP.keys():
exStr = dmExceptionMap.DM_EXCEPTION_MAP.get(code).split('.')[-1]
if exStr == exClass:
status = code
if not status:
status = dmStatus.DM_ERROR
cls.addDmResponseHeaders(status, msg, exClass)
@classmethod
def formatJsonResponse(cls, response):
cherrypy.response.headers['Content-Type'] = 'application/json'
return '%s' % (response)
@classmethod
def toJson(cls, o):
return json.dumps(o)
@classmethod
def fromJson(cls, s):
return json.loads(s)
@classmethod
def listToJson(cls, dmObjectList):
jsonList = []
for dmObject in dmObjectList:
jsonList.append(dmObject.getDictRep(keyList='ALL'))
return json.dumps(jsonList)
@classmethod
def getSessionUser(cls):
return cherrypy.serving.session.get('user')
@classmethod
def getSessionUsername(cls):
return cherrypy.serving.session.get('_cp_username')
# Exception decorator for all exposed method calls
@classmethod
def execute(cls, func):
def decorate(*args, **kwargs):
try:
response = func(*args, **kwargs)
except DmException, ex:
cls.getLogger().error('%s' % ex)
cls.handleException(ex)
response = ex.getFullJsonRep()
except Exception, ex:
cls.getLogger().error('%s' % ex)
cls.handleException(ex)
response = InternalError(ex).getFullJsonRep()
return cls.formatJsonResponse(response)
return decorate
#!/usr/bin/env python
#
# Base web service class.
#
####################################################################
import sys
import os
import cherrypy
from cherrypy.process import plugins
from cherrypy import server
from dm.common.constants import dmStatus
from dm.common.utility.configurationManager import ConfigurationManager
from dm.common.utility.loggingManager import LoggingManager
from dm.common.utility.dmModuleManager import DmModuleManager
from dm.common.exceptions.configurationError import ConfigurationError
####################################################################
class DmRestWebServiceBase:
DEFAULT_N_SERVER_REQUEST_THREADS = 50
DEFAULT_SERVER_SOCKET_TIMEOUT = 30
CONFIG_SECTION_NAME = 'WebService'
CONFIG_OPTION_NAME_LIST = [ 'serviceHost', 'servicePort',
'sslCertFile', 'sslKeyFile', 'sslCaCertFile', 'stationName' ]
class SignalHandler:
def __init__(self, signal, oldSignalHandler):
self.signal = signal
self.oldSignalHandler = oldSignalHandler
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
def signalHandler(self):
self.logger.debug('%s signal handler called' % self.signal)
DmModuleManager.getInstance().stopModules()
self.oldSignalHandler()
def __init__(self, routeMapper):
self.configurationManager = ConfigurationManager.getInstance()
self.routeMapper = routeMapper
self.options = None
self.args = None
self.logger = None
def prepareOptions(self):
from optparse import OptionParser
p = OptionParser()
p.add_option('-d', '--daemon', action="store_true",
dest='daemonFlag', default=False,
help="Run as a daemon.")
p.add_option('-p', '--pid-file',
dest='pidFile', default=None,
help="Store process id in the given file.")
p.add_option('', '--config-file',
dest='configFile', default=None,
help="Service configuration file.")
p.add_option('-P', '--port',
dest='servicePort', default=None,
help="Service port.")
p.add_option('-H', '--host',
dest='serviceHost', default=None,
help="Service host.")
p.add_option('-C', '--ssl-ca-cert',
dest='sslCaCertFile', default=None,
help='SSL CA certificate path (used for client SSL certificate verification). Requires --ssl-key and --ssl-cert.')
p.add_option('-c', '--ssl-cert',
dest='sslCertFile', default=None,
help='SSL certificate path. SSL operation requires both --ssl-key and --ssl-cert. Client SSL certificate verification also requires --ssl-ca-cert.')
p.add_option('-k', '--ssl-key',
dest='sslKeyFile', default=None,
help='SSL key path. SSL operation requires both --ssl-key and --ssl-cert. Client SSL certificate verification also requires --ssl-ca-cert.')
p.add_option('', '--n-server-threads',
dest='nServerThreads', default=DmRestWebServiceBase.DEFAULT_N_SERVER_REQUEST_THREADS,
help='Number of service request handler threads (defaut: %s).' % DmRestWebServiceBase.DEFAULT_N_SERVER_REQUEST_THREADS)
return p
def initDmModules(self):
return None
def getDefaultServerHost(self):
return None
def getDefaultServerPort(self):
return None
# Instantiate modified signal handler that stops dm modules first,
# and then does the default action.
def modifySignalHandlers(self, engine):
pluginsSignalHandler = plugins.SignalHandler(engine)
handlers = pluginsSignalHandler.handlers
# Add handler for interrupt
handlers['SIGINT'] = engine.exit
# Modify all signal handlers
for signal in handlers.keys():
self.logger.debug('Modifying signal: %s' % signal)
oldSignalHandler = handlers[signal]
self.logger.debug('Old signal handler: %s' % oldSignalHandler)
signalHandler = DmRestWebServiceBase.SignalHandler(signal, oldSignalHandler)
self.logger.debug('Setting signal handler to: %s' % signalHandler.signalHandler)
handlers[signal] = signalHandler.signalHandler
pluginsSignalHandler.subscribe()
def initServerLog(self):
cherrypyLogLevel = self.configurationManager.getCherrypyLogLevel()
cherrypy.log.error_log.setLevel(cherrypyLogLevel)
cherrypy.log.error_file = self.configurationManager.getCherrypyLogFile()
cherrypy.log.error_log.propagate = False
cherrypy.log.access_log.setLevel(cherrypyLogLevel)
cherrypy.log.access_file = self.configurationManager.getCherrypyAccessFile()
cherrypy.log.access_log.propagate = False
def updateServerConfig(self):
serviceHost = self.configurationManager.getServiceHost()
servicePort = int(self.configurationManager.getServicePort())
nServerThreads = int(self.options.nServerThreads)
configDict = {
'server.socket_host' : serviceHost,
'server.socket_port' : servicePort,
'server.thread_pool' : nServerThreads,
'log.screen' : (self.options.daemonFlag != True),
}
cherrypy.config.update(configDict)
def readConfigFile(self, configFile):
configFile = self.options.configFile
if not configFile:
configFile = self.configurationManager.getConfigFile()
else:
self.configurationManager.setConfigFile(configFile)
if not os.path.exists(configFile):
raise ConfigurationError('Configuration file %s does not exist.' % configFile)
# Read file and set config options
self.configurationManager.setOptionsFromConfigFile(DmRestWebServiceBase.CONFIG_SECTION_NAME, DmRestWebServiceBase.CONFIG_OPTION_NAME_LIST, configFile)
def readCommandLineOptions(self):
# This method should be called after reading config file
# in case some options are overridden
if self.options.sslCaCertFile != None:
self.configurationManager.setSslCaCertFile(self.options.sslCaCertFile)
if self.options.sslCertFile != None:
self.configurationManager.setSslCertFile(self.options.sslCertFile)
if self.options.sslKeyFile != None:
self.configurationManager.setSslKeyFile(self.options.sslKeyFile)
if self.options.serviceHost != None:
self.configurationManager.setServiceHost(self.options.serviceHost)
if self.options.servicePort != None:
self.configurationManager.setServicePort(self.options.servicePort)
def prepareServer(self):
try:
optionParser = self.prepareOptions()
(self.options, self.args) = optionParser.parse_args()
# Read config file and override with command line options
self.readConfigFile(self.options.configFile)
self.readCommandLineOptions()
# Turn off console log for daemon mode.
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
if self.options.daemonFlag:
LoggingManager.getInstance().setConsoleLogLevel('CRITICAL')
dispatch = self.routeMapper.setupRoutes()
self.logger.debug('Using route dispatch: %s' % dispatch)
config = {
'/' : {
'request.dispatch' : dispatch,
},
}
# No root controller as we provided our own.
cherrypy.tree.mount(root=None, config=config)
self.initServerLog()
self.updateServerConfig()
self.logger.info('Using host %s' % self.configurationManager.getServiceHost())
self.logger.info('Using port %s' % self.configurationManager.getServicePort())
self.logger.debug('Using %s request handler threads' % self.options.nServerThreads)
except Exception, ex:
if self.logger is not None:
self.logger.exception(ex)
else:
import traceback
print '\n%s' % sys.exc_info()[1]
traceback.print_exc(file=sys.stderr)
sys.exit(dmStatus.DM_ERROR)
# Run server.
def __runServer(self):
self.logger.info('Starting service')
engine = cherrypy.engine
# Set up Deamonization
if self.options.daemonFlag:
plugins.Daemonizer(engine).subscribe()
self.logger.debug('Daemon mode: %s' % self.options.daemonFlag)
if self.options.pidFile != None:
plugins.PIDFile(engine, self.options.pidFile).subscribe()
self.logger.debug('Using PID file: %s' % self.options.pidFile)
sslCertFile = self.configurationManager.getSslCertFile()
sslKeyFile = self.configurationManager.getSslKeyFile()
sslCaCertFile = self.configurationManager.getSslCaCertFile()
if sslCertFile != None and sslKeyFile != None:
server.ssl_ca_certificate = None
if sslCaCertFile != None:
server.ssl_ca_certificate = self.options.sslCaCertFile
self.logger.info('Using SSL CA cert file: %s' % sslCaCertFile)
server.ssl_certificate = sslCertFile
self.logger.info('Using SSL cert file: %s' % sslCertFile)
server.ssl_private_key = sslKeyFile
self.logger.info('Using SSL key file: %s' % sslKeyFile)
server.ssl_module = 'builtin'
#server.ssl_module = 'pyopenssl'
# Increase timeout to prevent early SSL connection terminations
server.socket_timeout = DmRestWebServiceBase.DEFAULT_SERVER_SOCKET_TIMEOUT
# Setup the signal handler to stop the application while running.
if hasattr(engine, 'signal_handler'):
self.logger.debug('Subscribing signal handler')
engine.signal_handler.subscribe()
self.modifySignalHandlers(engine)
# Turn off autoreloader.
self.logger.debug('Turning off autoreloader')
engine.autoreload.unsubscribe()
# Start the engine.
try:
self.logger.debug('Starting engine')
engine.start()
# Prepare dm services.
self.logger.debug('Starting modules')
self.initDmModules()
DmModuleManager.getInstance().startModules()
except Exception, ex:
self.logger.exception('Service exiting: %s' % ex)
DmModuleManager.getInstance().stopModules()
return dmStatus.DM_ERROR
self.logger.info('Service ready')
engine.block()
DmModuleManager.getInstance().stopModules()
self.logger.info('Service done')
return dmStatus.DM_OK
# Run server instance.
def run(self):
self.prepareServer()
sys.exit(self.__runServer())
####################################################################
# Testing
if __name__ == '__main__':
pass
#!/usr/bin/env python
#
# Base DM session controller class.
#
import cherrypy
from dm.common.constants import dmRole
from dm.common.utility.configurationManager import ConfigurationManager
from dm.common.service.dmController import DmController
from dm.common.service.loginController import LoginController
class DmSessionController(DmController):
""" Base session controller class. """
_cp_config = {
'tools.sessions.on': True,
'tools.auth.on': True
}
#auth = LoginController()
# Add before_handler for authorization
cherrypy.tools.auth = cherrypy.Tool('before_handler', LoginController.authCheck)
def __init__(self):
DmController.__init__(self)
@classmethod
def require(cls, *conditions):
"""
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
@classmethod
def anyOf(cls, *conditions):
""" Returns True if any of the conditions match. """
def check():
for c in conditions:
if c():
return True
return False
return check
@classmethod
def allOf(cls, *conditions):
""" Returns True if all of the conditions match. """
def check():
for c in conditions:
if not c():
return False
return True
return check
@classmethod
def isLoggedIn(cls):
""" Returns True if session has been established. """
def userIsLoggedIn():
role = cherrypy.session.get(LoginController.SESSION_ROLE_KEY, None)
if role is not None:
return True
return False
return userIsLoggedIn
@classmethod
def isAdministrator(cls):
def userIsAdministrator():
result = (cherrypy.session.get(LoginController.SESSION_ROLE_KEY, None) == dmRole.DM_ADMIN_SESSION_ROLE)
return result
return userIsAdministrator
@classmethod
def hasAdministratorRole(cls):
sessionRole = cherrypy.session.get(LoginController.SESSION_ROLE_KEY, None)
return (sessionRole == dmRole.DM_ADMIN_SESSION_ROLE)
@classmethod
def hasManagerRole(cls, experimentStationIdOrName):
systemRoleDict = cherrypy.session.get(LoginController.SESSION_SYSTEM_ROLE_DICT_KEY, None)
experimentStationIdOrNameList = systemRoleDict.get(dmRole.DM_MANAGER_SYSTEM_ROLE_ID, [])
if not experimentStationIdOrNameList:
# Remote sessions may come with string key
experimentStationIdOrNameList = systemRoleDict.get(str(dmRole.DM_MANAGER_SYSTEM_ROLE_ID), [])
return (experimentStationIdOrNameList.count(experimentStationIdOrName) > 0)
@classmethod
def hasPiRole(cls, experimentIdOrName):
experimentRoleDict = cherrypy.session.get(LoginController.SESSION_EXPERIMENT_ROLE_DICT_KEY, None)
experimentIdOrNameList = experimentRoleDict.get(dmRole.DM_PI_EXPERIMENT_ROLE_ID, [])
return (experimentIdOrNameList.count(experimentIdOrName) > 0)
@classmethod
def hasUserRole(cls, experimentIdOrName):
experimentRoleDict = cherrypy.session.get(LoginController.SESSION_EXPERIMENT_ROLE_DICT_KEY, None)
experimentIdOrNameList = experimentRoleDict.get(dmRole.DM_USER_EXPERIMENT_ROLE_ID, [])
return (experimentIdOrNameList.count(experimentIdOrName) > 0)
@classmethod
def canManageStation(cls):
def userCanManageStation():
if cls.hasAdministratorRole():
return True
stationName = ConfigurationManager.getInstance().getStationName()
return cls.hasManagerRole(stationName)
return userCanManageStation
#!/usr/bin/env python
import cherrypy
import datetime
import urllib
from cherrypy.lib import httpauth
from dm.common.constants import dmStatus
from dm.common.constants import dmRole
from dm.common.constants import dmHttpStatus
from dm.common.exceptions.dmException import DmException
from dm.common.exceptions.dmHttpError import DmHttpError
from dm.common.exceptions.authorizationError import AuthorizationError
from dm.common.exceptions.invalidSession import InvalidSession
from dm.common.utility.loggingManager import LoggingManager
from dm.common.service.dmController import DmController
from dm.common.service.auth.authorizationPrincipalManager import AuthorizationPrincipalManager
from dm.common.service.auth.singleSignOnManager import SingleSignOnManager
class LoginController(DmController):
""" Controller to provide login and logout actions. """
SESSION_USERNAME_KEY = '_cp_username'
SESSION_ROLE_KEY = 'sessionRole'
SESSION_SYSTEM_ROLE_DICT_KEY = 'systemRoleDict'
SESSION_EXPERIMENT_ROLE_DICT_KEY = 'experimentRoleDict'
ORIGINAL_SESSION_ID_KEY = 'originalid'
INVALID_SESSION_KEY = 'invalidSession'
_cp_config = {
'tools.sessions.on' : True,
'tools.auth.on' : True
}
def __init__(self):
DmController.__init__(self)
def onLogin(self, username):
""" Called on successful login. """
return
def onLogout(self, username):
""" Called on logout. """
return
@classmethod
def getLoginForm(cls, msg='Enter username and password:', username='', fromPage='/'):
return """
<html>
<body>
<form method='post' action='/auth/login'>
<input type='hidden' name='fromPage' value='%(fromPage)s' />
<h2>DM Service</h2>
<p/>
%(msg)s
<p/>
<table border='0'>
<tr>
<td>Username:</td><td><input type='text' name="username" value='%(username)s'/></td>
</tr>
<tr>
<td>Password:</td><td><input type='password' name='password' /></td>
</tr>
<p/>
<tr>
<td></td>
<td><input type='submit' value='Log In' /></td>
</tr>
</table>
</form>
</body>
</html>""" % locals()
@classmethod
def parseBasicAuthorizationHeaders(cls):
try:
username = None
password = None
authorization = cherrypy.request.headers['authorization']
authorizationHeader = httpauth.parseAuthorization(authorization)
if authorizationHeader['auth_scheme'] == 'basic':
username = authorizationHeader['username']
password = authorizationHeader['password']
if username and password:
return (username, password)
else:
raise AuthorizationError('Username and/or password not supplied.')
except Exception, ex:
errorMsg = 'Could not extract username/password from authorization header: %s' % ex
raise AuthorizationError(errorMsg)
@classmethod
def checkCredentials(cls, username, password):
""" Verifies credentials for username and password."""
logger = LoggingManager.getInstance().getLogger('LoginController:checkCredentials')
logger.debug('Checking credential for User: %s' % (username))
#logger.debug('Checking credential for User: %s, Password: %s' % (username, password))
logger.debug('Session id: %s' % cherrypy.serving.session.id)
principal = AuthorizationPrincipalManager.getInstance().getAuthenticatedAuthorizationPrincipal(username, password)
logger.debug('Principal: %s' % (principal))
if principal:
cherrypy.session[LoginController.SESSION_ROLE_KEY] = principal.getSessionRole()
cherrypy.session[LoginController.SESSION_SYSTEM_ROLE_DICT_KEY] = principal['userSystemRoleDict']
cherrypy.session[LoginController.SESSION_EXPERIMENT_ROLE_DICT_KEY] = principal['userExperimentRoleDict']
logger.debug('Successful login from user: %s (role: %s)' % (username, principal.getSessionRole()))
# Try adding to SingleSignOnManager
sessionId = cherrypy.serving.session.id
sessionCache = cherrypy.session.cache
sessionInfo = {LoginController.SESSION_ROLE_KEY : principal.getSessionRole()}
sessionInfo[LoginController.SESSION_USERNAME_KEY] = username
sessionInfo[LoginController.SESSION_SYSTEM_ROLE_DICT_KEY] = principal.get('userSystemRoleDict', {})
sessionInfo[LoginController.SESSION_EXPERIMENT_ROLE_DICT_KEY] = principal.get('userExperimentRoleDict', {})
ssoManager = SingleSignOnManager.getInstance()
ssoManager.addSession(sessionId, sessionInfo)
else:
logger.debug('Login denied for user: %s' % username)
username = cherrypy.session.get(LoginController.SESSION_USERNAME_KEY, None)
if username is not None:
cherrypy.request.login = None
cherrypy.session[LoginController.INVALID_DM_SESSION_KEY] = True
raise AuthorizationError('Incorrect username or password.')
return principal
@classmethod
def authCheck(cls, *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.
"""
logger = LoggingManager.getInstance().getLogger('LoginController:authCheck')
conditions = cherrypy.request.config.get('auth.require', None)
#logger.debug('Headers: %s' % (cherrypy.request.headers))
#logger.debug('Request params: %s' % (cherrypy.request.params))
#logger.debug('Request query string: %s' % (cherrypy.request.query_string))
method = urllib.quote(cherrypy.request.request_line.split()[0])
params = urllib.quote(cherrypy.request.request_line.split()[1])
if conditions is None:
logger.debug('No conditions imposed')
return
sessionId = cherrypy.serving.session.id
sessionCache = cherrypy.session.cache
# If session cache does not have current session id, reuse original
# session id
if not sessionCache.has_key(sessionId) and cherrypy.serving.session.__dict__.has_key(LoginController.ORIGINAL_SESSION_ID_KEY):
logger.debug('Reusing original session id: %s' % sessionId)
sessionId = cherrypy.serving.session.__dict__.get(LoginController.ORIGINAL_SESSION_ID_KEY)
#logger.debug('Session: %s' % ((cherrypy.session.__dict__)))
logger.debug('Session cache length: %s' % (len(sessionCache)))
#logger.debug('Session cache: %s' % (sessionCache))
# Check session.
# Try SingleSignOnManager first
ssoManager = SingleSignOnManager.getInstance()
# SSO Manager returns session info
sessionInfo = ssoManager.checkSession(sessionId)
if not sessionInfo:
# Cache has tuple (sessionInfo, updateTime)
sessionTuple = sessionCache.get(sessionId)
if sessionTuple:
sessionInfo = sessionTuple[0]
logger.debug('Retrieved session info from cache: %s' % sessionInfo)
else:
logger.debug('Retrieved session %s from SSO Manager' % sessionId)
sessionCache[sessionId] = (sessionInfo, datetime.datetime.now())
if not sessionInfo:
errorMsg = 'Invalid or expired session id: %s.' % sessionId
logger.debug(errorMsg)
raise DmHttpError(dmHttpStatus.DM_HTTP_UNAUTHORIZED, 'User Not Authorized', InvalidSession(errorMsg))
username = sessionInfo.get(LoginController.SESSION_USERNAME_KEY)
if not username:
errorMsg = 'Invalid session id: %s (no username supplied).' % sessionId
logger.debug(errorMsg)
raise DmHttpError(dmHttpStatus.DM_HTTP_UNAUTHORIZED, 'User Not Authorized', InvalidSession(errorMsg))
cherrypy.session[LoginController.SESSION_ROLE_KEY] = sessionInfo[LoginController.SESSION_ROLE_KEY]
cherrypy.session[LoginController.SESSION_SYSTEM_ROLE_DICT_KEY] = sessionInfo[LoginController.SESSION_SYSTEM_ROLE_DICT_KEY]
cherrypy.session[LoginController.SESSION_EXPERIMENT_ROLE_DICT_KEY] = sessionInfo[LoginController.SESSION_EXPERIMENT_ROLE_DICT_KEY]
logger.debug('Session id %s is valid (username: %s)' % (sessionId, username))
cherrypy.request.login = username
for condition in conditions:
# A condition is just a callable that returns true or false
if not condition():
logger.debug('Authorization check %s() failed for username %s' % (condition.func_name, username))
errorMsg = 'Authorization check %s() failed for user %s.' % (condition.func_name, username)
raise DmHttpError(dmHttpStatus.DM_HTTP_UNAUTHORIZED, 'User Not Authorized', AuthorizationError(errorMsg))
@cherrypy.expose
def login(self, username=None, password=None, fromPage='/'):
self.logger.debug('Attempting login from username %s' % (username))
try:
if username is None or password is None:
self.logger.debug('Parsing auth headers for username %s' % (username))
(username, password) = LoginController.parseBasicAuthorizationHeaders()
self.logger.debug('Retrieving principal for username %s' % (username))
principal = LoginController.checkCredentials(username, password)
except DmHttpError, ex:
raise
except DmException, ex:
self.logger.debug('Authorization failed (username %s): %s' % (username, ex))
self.addDmExceptionHeaders(ex)
raise DmHttpError(dmHttpStatus.DM_HTTP_UNAUTHORIZED, 'User Not Authorized', ex)
# Authorization worked.
cherrypy.session[LoginController.SESSION_USERNAME_KEY] = cherrypy.request.login = username
self.onLogin(username)
self.addDmSessionRoleHeaders(principal.getSessionRole())
self.addDmResponseHeaders()
@cherrypy.expose
def logout(self, fromPage='/'):
sess = cherrypy.session
username = sess.get(LoginController.SESSION_USERNAME_KEY, None)
if username:
del sess[LoginController.SESSION_USERNAME_KEY]
cherrypy.request.login = None
self.onLogout(username)
#!/usr/bin/env python
#
# Login route descriptor.
#
from dm.common.utility.configurationManager import ConfigurationManager
from dm.common.service.loginController import LoginController
class LoginRouteDescriptor:
@classmethod
def getRoutes(cls):
contextRoot = ConfigurationManager.getInstance().getContextRoot()
loginController = LoginController()
routes = [
# Login
{
'name' : 'login',
'path' : '%s/login' % contextRoot,
'controller' : loginController,
'action' : 'login',
'method' : [ 'PUT', 'POST' ]
},
]
return routes
#!/usr/bin/env python
#
# Configuration manager singleton.
#
#######################################################################
import os
import socket
import pwd
import UserDict
import ConfigParser
from dm.common.constants import dmServiceConstants
from dm.common.exceptions.configurationError import ConfigurationError
#######################################################################
# Defaults.
DEFAULT_DM_ROOT_DIR = '/opt/dm'
DEFAULT_DM_INSTALL_DIR = '%s' # requires install dir
DEFAULT_DM_CONFIG_FILE = '%s/etc/%s.%s.conf' # requires install dir/db name/service name
DEFAULT_DM_SERVICE_NAME= 'web-service'
DEFAULT_DM_LOG_FILE = '%s/var/log/%s.%s.log' # requires install dir/db name/service name
DEFAULT_DM_CONSOLE_LOG_LEVEL = 'CRITICAL'
DEFAULT_DM_FILE_LOG_LEVEL = 'INFO'
#DEFAULT_DM_LOG_RECORD_FORMAT = '%(asctime)s,%(msecs)03d [%(levelname)s] %(module)s:%(lineno)d %(user)s@%(host)s %(name)s (%(process)d): %(message)s'
#DEFAULT_DM_LOG_RECORD_FORMAT = '%(asctime)s,%(msecs)03d %(levelname)s %(module)s:%(lineno)d %(process)d: %(message)s'
DEFAULT_DM_LOG_RECORD_FORMAT = '%(asctime)s,%(msecs)03d %(levelname)s %(process)d: %(message)s'
DEFAULT_DM_LOG_DATE_FORMAT = '%Y/%m/%d %H:%M:%S'
DEFAULT_DM_CHERRYPY_LOG_LEVEL = 'ERROR'
DEFAULT_DM_CHERRYPY_LOG_FILE = '%s/var/log/%s.%s.cherrypy.error' # requires install dir/db name/service name
DEFAULT_DM_CHERRYPY_ACCESS_FILE = '%s/var/log/%s.%s.cherrypy.access' # requires install dir/db name/service name
DEFAULT_DM_SERVICE_PORT = 22236 # 222DM
DEFAULT_DM_SERVICE_HOST = '0.0.0.0'
DEFAULT_DM_SERVICE_PROTOCOL = dmServiceConstants.DM_SERVICE_PROTOCOL_HTTP
DEFAULT_DM_WEB_SERVICE_PROTOCOL = DEFAULT_DM_SERVICE_PROTOCOL
DEFAULT_DM_DS_WEB_SERVICE_PORT = 22236 # 222DM
DEFAULT_DM_DS_WEB_SERVICE_HOST = '127.0.0.1'
DEFAULT_DM_DAQ_WEB_SERVICE_PORT = 33336 # 333DM
DEFAULT_DM_DAQ_WEB_SERVICE_HOST = '127.0.0.1'
DEFAULT_DM_CAT_WEB_SERVICE_PORT = 44436 # 444DM
DEFAULT_DM_CAT_WEB_SERVICE_HOST = '127.0.0.1'
DEFAULT_DM_PROC_WEB_SERVICE_PORT = 55536 # 555DM
DEFAULT_DM_PROC_WEB_SERVICE_HOST = '127.0.0.1'
DEFAULT_DM_DB = 'postgresql'
DEFAULT_DM_DB_HOST = '127.0.0.1'
DEFAULT_DM_DB_PORT = 11136
DEFAULT_DM_DB_PASSWORD = ''
DEFAULT_DM_DB_NAME = 'dm'
DEFAULT_DM_DB_SCHEMA = DEFAULT_DM_DB_NAME
DEFAULT_DM_DB_USER = DEFAULT_DM_DB_NAME
DEFAULT_DM_DB_PASSWORD_FILE = '%s/etc/%s.db.passwd' # requires install dir/db name
DEFAULT_DM_CONTEXT_ROOT = '/dm'
# Session cache file
DEFAULT_DM_SESSION_CACHE_FILE = None
# Enforce session credentials.
DEFAULT_DM_REQUIRE_SESSION_CREDENTIALS = False
# SSL variables
DEFAULT_DM_SSL_CA_CERT_FILE = None
DEFAULT_DM_SSL_CERT_FILE = None
DEFAULT_DM_SSL_KEY_FILE = None
# Login (user|password) files
DEFAULT_DM_LOGIN_FILE = None
DEFAULT_DM_BSS_LOGIN_FILE = None
# Station name
DEFAULT_DM_STATION_NAME = None
# Allowed experiment types
DEFAULT_DM_ALLOWED_EXPERIMENT_TYPES = None
# Beamline stuff
DEFAULT_DM_BEAMLINE_NAME = None
DEFAULT_DM_BEAMLINE_MANAGERS = None
class ConfigurationManager(UserDict.UserDict):
"""
Singleton class used for keeping system configuration data. The class
initializes its data using predefined defaults, or from certain
environment variables.
Usage:
from dm.common.utility import configurationManager
cm = configurationManager.getInstance()
cm.setConsoleLogLevel('info')
level = cm.getConsoleLogLevel()
cm['myKey'] = 'myValue'
value = cm.get('myKey')
"""
# Get singleton instance.
@classmethod
def getInstance(cls):
""" Get configuration manager singleton instance. """
from dm.common.utility.configurationManager import ConfigurationManager
try:
cm = ConfigurationManager()
except ConfigurationManager, ex:
cm = ex
return cm
# Singleton.
__instance = None
def __init__(self):
if ConfigurationManager.__instance:
raise ConfigurationManager.__instance
ConfigurationManager.__instance = self
UserDict.UserDict.__init__(self)
self['user'] = pwd.getpwuid(os.getuid())[0]
self['host'] = socket.gethostname()
self['defaultRootDir'] = DEFAULT_DM_ROOT_DIR
self.__setFromEnvVar('rootDir', 'DM_ROOT_DIR')
self['defaultInstallDir'] = DEFAULT_DM_INSTALL_DIR % self.getRootDir()
self.__setFromEnvVar('installDir', 'DM_INSTALL_DIR')
self['defaultServiceName'] = DEFAULT_DM_SERVICE_NAME
self.__setFromEnvVar('serviceName', 'DM_SERVICE_NAME')
self['defaultDbName'] = DEFAULT_DM_DB_NAME
self.__setFromEnvVar('dbName', 'DM_DB_NAME')
self.__resetDynamicDefaults()
self['defaultConsoleLogLevel'] = DEFAULT_DM_CONSOLE_LOG_LEVEL
self['defaultFileLogLevel'] = DEFAULT_DM_FILE_LOG_LEVEL
self['defaultLogRecordFormat'] = DEFAULT_DM_LOG_RECORD_FORMAT
self['defaultLogDateFormat'] = DEFAULT_DM_LOG_DATE_FORMAT
self['defaultCherrypyLogLevel'] = DEFAULT_DM_CHERRYPY_LOG_LEVEL
self['defaultServicePort'] = DEFAULT_DM_SERVICE_PORT
self['defaultServiceHost'] = DEFAULT_DM_SERVICE_HOST
self['defaultServiceProtocol'] = DEFAULT_DM_SERVICE_PROTOCOL
self['defaultWebServiceProtocol'] = DEFAULT_DM_WEB_SERVICE_PROTOCOL
self['defaultDaqWebServicePort'] = DEFAULT_DM_DAQ_WEB_SERVICE_PORT
self['defaultDaqWebServiceHost'] = DEFAULT_DM_DAQ_WEB_SERVICE_HOST
self['defaultDsWebServicePort'] = DEFAULT_DM_DS_WEB_SERVICE_PORT
self['defaultDsWebServiceHost'] = DEFAULT_DM_DS_WEB_SERVICE_HOST
self['defaultCatWebServicePort'] = DEFAULT_DM_CAT_WEB_SERVICE_PORT
self['defaultCatWebServiceHost'] = DEFAULT_DM_CAT_WEB_SERVICE_HOST
self['defaultProcWebServicePort'] = DEFAULT_DM_PROC_WEB_SERVICE_PORT
self['defaultProcWebServiceHost'] = DEFAULT_DM_PROC_WEB_SERVICE_HOST
self['defaultDb'] = DEFAULT_DM_DB
self['defaultDbHost'] = DEFAULT_DM_DB_HOST
self['defaultDbPort'] = DEFAULT_DM_DB_PORT
self['defaultDbPassword'] = DEFAULT_DM_DB_PASSWORD
self['defaultContextRoot'] = DEFAULT_DM_CONTEXT_ROOT
self['defaultSessionCacheFile'] = DEFAULT_DM_SESSION_CACHE_FILE
self['defaultRequireSessionCredentials'] = DEFAULT_DM_REQUIRE_SESSION_CREDENTIALS
self['defaultSslCaCertFile'] = DEFAULT_DM_SSL_CA_CERT_FILE
self['defaultSslCertFile'] = DEFAULT_DM_SSL_CERT_FILE
self['defaultSslKeyFile'] = DEFAULT_DM_SSL_KEY_FILE
self['defaultLoginFile'] = DEFAULT_DM_LOGIN_FILE
self['defaultBssLoginFile'] = DEFAULT_DM_BSS_LOGIN_FILE
self['defaultStationName'] = DEFAULT_DM_STATION_NAME
self['defaultAllowedExperimentTypes'] = DEFAULT_DM_ALLOWED_EXPERIMENT_TYPES
self['defaultBeamlineName'] = DEFAULT_DM_BEAMLINE_NAME
self['defaultBeamlineManagers'] = DEFAULT_DM_BEAMLINE_MANAGERS
# Settings that might come from environment variables.
self.__setFromEnvVar('logFile', 'DM_LOG_FILE')
self.__setFromEnvVar('consoleLogLevel', 'DM_CONSOLE_LOG_LEVEL')
self.__setFromEnvVar('fileLogLevel', 'DM_FILE_LOG_LEVEL')
self.__setFromEnvVar('logRecordFormat', 'DM_LOG_RECORD_FORMAT')
self.__setFromEnvVar('logDateFormat', 'DM_LOG_DATE_FORMAT')
self.__setFromEnvVar('cherrypyLogLevel', 'DM_CHERRYPY_LOG_LEVEL')
self.__setFromEnvVar('cherrypyLogFile', 'DM_CHERRYPY_LOG_FILE')
self.__setFromEnvVar('cherrypyAccessFile', 'DM_CHERRYPY_ACCESS_FILE')
self.__setFromEnvVar('serviceHost', 'DM_SERVICE_HOST')
self.__setFromEnvVar('servicePort', 'DM_SERVICE_PORT')
self.__setFromEnvVar('serviceProtocol', 'DM_SERVICE_PROTOCOL')
self.__setFromEnvVar('webServiceProtocol', 'DM_WEB_SERVICE_PROTOCOL')
self.__setFromEnvVar('daqWebServiceHost', 'DM_DAQ_WEB_SERVICE_HOST')
self.__setFromEnvVar('daqWebServicePort', 'DM_DAQ_WEB_SERVICE_PORT')
self.__setFromEnvVar('dsWebServiceHost', 'DM_DS_WEB_SERVICE_HOST')
self.__setFromEnvVar('dsWebServicePort', 'DM_DS_WEB_SERVICE_PORT')
self.__setFromEnvVar('catWebServiceHost', 'DM_CAT_WEB_SERVICE_HOST')
self.__setFromEnvVar('catWebServicePort', 'DM_CAT_WEB_SERVICE_PORT')
self.__setFromEnvVar('procWebServiceHost', 'DM_PROC_WEB_SERVICE_HOST')
self.__setFromEnvVar('procWebServicePort', 'DM_PROC_WEB_SERVICE_PORT')
self.__setFromEnvVar('contextRoot', 'DM_CONTEXT_ROOT')
self.__setFromEnvVar('sessionCacheFile', 'DM_SESSION_CACHE_FILE')
self.__setFromEnvVar('sslCaCertFile', 'DM_SSL_CA_CERT_FILE')
self.__setFromEnvVar('sslCertFile', 'DM_SSL_CERT_FILE')
self.__setFromEnvVar('sslKeyFile', 'DM_SSL_KEY_FILE')
self.__setFromEnvVar('configFile', 'DM_CONFIG_FILE')
self.__setFromEnvVar('dbPasswordFile', 'DM_DB_PASSWORD_FILE')
self.__setFromEnvVar('loginFile', 'DM_LOGIN_FILE')
self.__setFromEnvVar('bssLoginFile', 'DM_BSS_LOGIN_FILE')
self.__setFromEnvVar('stationName', 'DM_STATION_NAME')
self.__setFromEnvVar('allowedExperimentTypes', 'DM_ALLOWED_EXPERIMENT_TYPES')
self.__setFromEnvVar('beamlineName', 'DM_BEAMLINE_NAME')
self.__setFromEnvVar('beamlineManagers', 'DM_BEAMLINE_MANAGERS')
# Settings that might come from file.
self.__setFromVarFile('dbPassword', self.getDbPasswordFile())
# Variables we do not keep in a dictionary
self.configParser = None
# Reset defaults that depend on install dir and service name
def __resetDynamicDefaults(self):
self['defaultConfigFile'] = DEFAULT_DM_CONFIG_FILE % (self.getInstallDir(), self.getDbName(), self.getServiceName())
self['defaultLogFile'] = DEFAULT_DM_LOG_FILE % (self.getInstallDir(), self.getDbName(), self.getServiceName())
self['defaultCherrypyAccessFile'] = DEFAULT_DM_CHERRYPY_ACCESS_FILE % (self.getInstallDir(), self.getDbName(), self.getServiceName())
self['defaultCherrypyLogFile'] = DEFAULT_DM_CHERRYPY_LOG_FILE % (self.getInstallDir(), self.getDbName(), self.getServiceName())
self['defaultDbUser'] = self.getDbName()
self['defaultDbSchema'] = self.getDbName()
self['defaultDbPasswordFile'] = DEFAULT_DM_DB_PASSWORD_FILE % (self.getInstallDir(), self.getDbName())
# This function will ignore errors if environment variable is not set.
def __setFromEnvVar(self, key, envVar):
"""
Set value for the specified key from a given environment variable.
This function ignores errors for env. variables that are not set.
"""
try:
self[key] = os.environ[envVar]
except:
pass
# This function will ignore errors if variable file is not present.
def __setFromVarFile(self, key, varFile):
"""
Set value for the specified key from a given file. The first line
in the file is variable value.
This function ignores errors.
"""
try:
v = open(varFile, 'r').readline()
self[key] = v.lstrip().rstrip()
except Exception, ex:
pass
def __getKeyValue(self, key, default='__dm_default__'):
"""
Get value for a given key.
Keys will be of the form 'logFile', and the default keys have
the form 'defaultLogFile'.
"""
defaultKey = "default" + key[0].upper() + key[1:]
defaultValue = self.get(defaultKey, None)
if default != '__dm_default__':
defaultValue = default
return self.get(key, defaultValue)
def setOptionsFromConfigFile(self, configSection, keyList, configFile=None):
_configFile = configFile
if _configFile is None:
_configFile = self.getConfigFile()
if _configFile is not None and os.path.exists(_configFile):
configParser = ConfigParser.RawConfigParser()
configParser.read(_configFile)
if not configParser.has_section(configSection):
return
for key in keyList:
if configParser.has_option(configSection, key):
self[key] = configParser.get(configSection, key)
def clearConfigParser(self):
self.configParser = None
def getConfigParser(self, defaults={}):
if self.configParser is None:
configFile = self.getConfigFile()
if os.path.exists(configFile):
self.configParser = ConfigParser.ConfigParser(defaults)
self.configParser.read(configFile)
self.configParser.defaults = defaults
return self.configParser
def setConfigDefaults(self, defaults={}):
configParser = self.getConfigParser()
if configParser is not None:
configParser.defaults = defaults
def getConfigOption(self, configSection, key, defaultValue=None):
configParser = self.getConfigParser()
if self.hasConfigSection(configSection):
try:
return configParser.get(configSection, key)
except ConfigParser.NoOptionError, ex:
# ok, return default value
pass
return defaultValue
def getConfigSections(self):
configParser = self.getConfigParser()
if configParser is not None:
return configParser.sections()
return []
def hasConfigSection(self, name):
configSections = self.getConfigSections()
if name in configSections:
return True
return False
def getConfigItems(self, configSection):
configParser = self.getConfigParser()
if configParser is not None and configParser.has_section(configSection):
return configParser.items(configSection)
return []
@classmethod
def getConfigParserFromConfigFile(cls, configFile):
if not os.path.exists(configFile):
return None
configParser = ConfigParser.RawConfigParser()
configParser.read(configFile)
return configParser
@classmethod
def getOptionFromConfigParser(cls, configParser, configSection, key, defaultValue=None):
if configParser is not None and configParser.has_section(configSection):
return configParser.get(configSection, key)
else:
return defaultValue
@classmethod
def getConfigSectionsFromConfigParser(cls, configParser):
if configParser is not None:
return configParser.sections()
return []
@classmethod
def getModuleClassConstructorTuple(cls, value, creatorClass=None):
""" Extract (module,class,constructor) tuple from the given value. """
itemList = value.split('(')
if not itemList:
return ()
itemList2 = itemList[0].split('.')
moduleNameList = itemList2[0:-1]
className = itemList2[-1]
moduleName = className[0].lower() + className[1:]
# If module name list is empty, use convention
# for determining import module name (use creator class module)
if not len(moduleNameList) and creatorClass is not None:
moduleNameList = creatorClass.__module__.split('.')
moduleNameList[-1] = moduleName
if len(moduleNameList):
moduleName = '.'.join(moduleNameList)
constructor = '%s(%s' % (className, ''.join(itemList[1:]))
return (moduleName,className,constructor)
def getHost(self):
return self['host']
def getUser(self):
return self['user']
def getDefaultRootDir(self):
return self['defaultRootDir']
def setRootDir(self, rootDir):
self['rootDir'] = rootDir
def getRootDir(self, default='__dm_default__'):
return self.__getKeyValue('rootDir', default)
def getDefaultInstallDir(self):
return self['defaultInstallDir']
def setInstallDir(self, installDir):
self['installDir'] = installDir
self.__resetDynamicDefaults()
def getInstallDir(self, default='__dm_default__'):
return self.__getKeyValue('installDir', default)
def getDefaultServiceName(self):
return self['defaultServiceName']
def setServiceName(self, serviceName):
self['serviceName'] = serviceName
self.__resetDynamicDefaults()
def getServiceName(self, default='__dm_default__'):
return self.__getKeyValue('serviceName', default)
def getDefaultDbName(self):
return self['defaultDbName']
def setDbName(self, dbName):
self['dbName'] = dbName
self.__resetDynamicDefaults()
def getDbName(self, default='__dm_default__'):
return self.__getKeyValue('dbName', default)
def getDefaultLogFile(self):
return self['defaultLogFile']
def setLogFile(self, logFile):
self['logFile'] = logFile
def getLogFile(self, default='__dm_default__'):
return self.__getKeyValue('logFile', default)
def hasLogFile(self):
return self.has_key('logFile')
def getDefaultConsoleLogLevel(self):
return self['defaultConsoleLogLevel']
def setConsoleLogLevel(self, level):
self['consoleLogLevel'] = level
def getConsoleLogLevel(self, default='__dm_default__'):
return self.__getKeyValue('consoleLogLevel', default)
def getConsoleLogLevelFromEnvVar(self):
return os.environ.get('DM_CONSOLE_LOG_LEVEL')
def hasConsoleLogLevel(self):
return self.has_key('consoleLogLevel')
def getDefaultFileLogLevel(self):
return self['defaultFileLogLevel']
def setFileLogLevel(self, level):
self['fileLogLevel'] = level
def getFileLogLevel(self, default='__dm_default__'):
return self.__getKeyValue('fileLogLevel', default)
def hasFileLogLevel(self):
return self.has_key('fileLogLevel')
def getDefaultLogRecordFormat(self):
return self['defaultLogRecordFormat']
def setLogRecordFormat(self, format):
self['logRecordFormat'] = format
def getLogRecordFormat(self, default='__dm_default__'):
return self.__getKeyValue('logRecordFormat', default)
def hasLogRecordFormat(self):
return self.has_key('logRecordFormat')
def getDefaultLogDateFormat(self):
return self['defaultLogDateFormat']
def setLogDateFormat(self, format):
self['logDateFormat'] = format
def getLogDateFormat(self, default='__dm_default__'):
return self.__getKeyValue('logDateFormat', default)
def hasLogDateFormat(self):
return self.has_key('logDateFormat')
def getDefaultCherrypyLogLevel(self):
return self['defaultCherrypyLogLevel']
def setCherrypyLogLevel(self, level):
self['cherrypyLogLevel'] = level
def getCherrypyLogLevel(self, default='__dm_default__'):
return self.__getKeyValue('cherrypyLogLevel', default)
def hasCherrypyLogLevel(self):
return self.has_key('cherrypyLogLevel')
def getDefaultCherrypyLogCherrypy(self):
return self['defaultCherrypyLogFile']
def setCherrypyLogFile(self, cherrypyLogFile):
self['cherrypyLogFile'] = cherrypyLogFile
def getCherrypyLogFile(self, default='__dm_default__'):
return self.__getKeyValue('cherrypyLogFile', default)
def hasCherrypyLogFile(self):
return self.has_key('cherrypyLogFile')
def getDefaultCherrypyAccessFile(self):
return self['defaultCherrypyAccessFile']
def setCherrypyAccessFile(self, cherrypyAccessFile):
self['cherrypyAccessFile'] = cherrypyAccessFile
def getCherrypyAccessFile(self, default='__dm_default__'):
return self.__getKeyValue('cherrypyAccessFile', default)
def hasCherrypyAccessFile(self):
return self.has_key('cherrypyAccessFile')
def isDbAvailable(self):
if os.access(self.getDbPasswordFile(), os.R_OK):
return True
return False
def getDefaultServiceProtocol(self):
return self['defaultServiceProtocol']
def setServiceProtocol(self, serviceProtocol):
self['serviceProtocol'] = serviceProtocol
def getServiceProtocol(self, default='__dm_default__'):
return self.__getKeyValue('serviceProtocol', default)
def hasServiceProtocol(self):
return self.has_key('serviceProtocol')
def getDefaultServicePort(self):
return self['defaultServicePort']
def setServicePort(self, servicePort):
self['servicePort'] = servicePort
def getServicePort(self, default='__dm_default__'):
return int(self.__getKeyValue('servicePort', default))
def hasServicePort(self):
return self.has_key('servicePort')
def getDefaultServiceHost(self):
return self['defaultServiceHost']
def setServiceHost(self, serviceHost):
self['serviceHost'] = serviceHost
def getServiceHost(self, default='__dm_default__'):
return self.__getKeyValue('serviceHost', default)
def hasServiceHost(self):
return self.has_key('serviceHost')
def getDefaultWebServiceProtocol(self):
return self['defaultWebServiceProtocol']
def setWebServiceProtocol(self, webServiceProtocol):
self['webServiceProtocol'] = webServiceProtocol
def getWebServiceProtocol(self, default='__dm_default__'):
return self.__getKeyValue('webServiceProtocol', default)
def hasWebServiceProtocol(self):
return self.has_key('webServiceProtocol')
def getDefaultDaqWebServicePort(self):
return self['defaultDaqWebServicePort']
def setDaqWebServicePort(self, daqWebServicePort):
self['daqWebServicePort'] = daqWebServicePort
def getDaqWebServicePort(self, default='__dm_default__'):
return int(self.__getKeyValue('daqWebServicePort', default))
def hasDaqWebServicePort(self):
return self.has_key('daqWebServicePort')
def getDefaultDaqWebServiceHost(self):
return self['defaultDaqWebServiceHost']
def setDaqWebServiceHost(self, daqWebServiceHost):
self['daqWebServiceHost'] = daqWebServiceHost
def getDaqWebServiceHost(self, default='__dm_default__'):
return self.__getKeyValue('daqWebServiceHost', default)
def hasDaqWebServiceHost(self):
return self.has_key('daqWebServiceHost')
def getDefaultDsWebServicePort(self):
return self['defaultDsWebServicePort']
def setDsWebServicePort(self, dsWebServicePort):
self['dsWebServicePort'] = dsWebServicePort
def getDsWebServicePort(self, default='__dm_default__'):
return int(self.__getKeyValue('dsWebServicePort', default))
def hasDsWebServicePort(self):
return self.has_key('dsWebServicePort')
def getDefaultDsWebServiceHost(self):
return self['defaultDsWebServiceHost']
def setDsWebServiceHost(self, dsWebServiceHost):
self['dsWebServiceHost'] = dsWebServiceHost
def getDsWebServiceHost(self, default='__dm_default__'):
return self.__getKeyValue('dsWebServiceHost', default)
def hasDsWebServiceHost(self):
return self.has_key('dsWebServiceHost')
def getDefaultCatWebServicePort(self):
return self['defaultCatWebServicePort']
def setCatWebServicePort(self, catWebServicePort):
self['catWebServicePort'] = catWebServicePort
def getCatWebServicePort(self, default='__dm_default__'):
return int(self.__getKeyValue('catWebServicePort', default))
def hasCatWebServicePort(self):
return self.has_key('catWebServicePort')
def getDefaultCatWebServiceHost(self):
return self['defaultCatWebServiceHost']
def setCatWebServiceHost(self, catWebServiceHost):
self['catWebServiceHost'] = catWebServiceHost
def getCatWebServiceHost(self, default='__dm_default__'):
return self.__getKeyValue('catWebServiceHost', default)
def hasCatWebServiceHost(self):
return self.has_key('catWebServiceHost')
def getDefaultProcWebServicePort(self):
return self['defaultProcWebServicePort']
def setProcWebServicePort(self, procWebServicePort):
self['procWebServicePort'] = procWebServicePort
def getProcWebServicePort(self, default='__dm_default__'):
return int(self.__getKeyValue('procWebServicePort', default))
def hasProcWebServicePort(self):
return self.has_key('procWebServicePort')
def getDefaultProcWebServiceHost(self):
return self['defaultProcWebServiceHost']
def setProcWebServiceHost(self, procWebServiceHost):
self['procWebServiceHost'] = procWebServiceHost
def getProcWebServiceHost(self, default='__dm_default__'):
return self.__getKeyValue('procWebServiceHost', default)
def hasProcWebServiceHost(self):
return self.has_key('procWebServiceHost')
def getDefaultDb(self):
return self['defaultDb']
def setDb(self, db):
self['db'] = db
def getDb(self, default='__dm_default__'):
return self.__getKeyValue('db', default)
def hasDb(self):
return self.has_key('db')
def getDefaultDbHost(self):
return self['defaultDbHost']
def setDbHost(self, dbHost):
self['dbHost'] = dbHost
def getDbHost(self, default='__dm_default__'):
return self.__getKeyValue('dbHost', default)
def hasDbHost(self):
return self.has_key('dbHost')
def getDefaultDbPort(self):
return self['defaultDbPort']
def setDbPort(self, dbPort):
self['dbPort'] = dbPort
def getDbPort(self, default='__dm_default__'):
return self.__getKeyValue('dbPort', default)
def hasDbPort(self):
return self.has_key('dbPort')
def getDefaultDbPassword(self):
return self['defaultDbPassword']
def setDbPassword(self, dbPassword):
self['dbPassword'] = dbPassword
def getDbPassword(self, default='__dm_default__'):
return self.__getKeyValue('dbPassword', default)
def hasDbPassword(self):
return self.has_key('dbPassword')
def getDefaultDbPasswordFile(self):
return self['defaultDbPasswordFile']
def getDbPasswordFile(self, default='__dm_default__'):
return self.__getKeyValue('dbPasswordFile', default)
def setDbPasswordFile(self, f):
self['dbPasswordFile'] = f
def hasDbPasswordFile(self):
return self.has_key('dbPasswordFile')
def getDefaultDbUser(self):
return self['defaultDbUser']
def getDbUser(self, default='__dm_default__'):
return self.__getKeyValue('dbUser', default)
def setDbUser(self, dbUser):
self['dbUser'] = dbUser
def hasDbUser(self):
return self.has_key('dbUser')
def getDbSchema(self, default='__dm_default__'):
return self.__getKeyValue('dbSchema', default)
def getDefaultConfigFile(self):
return self['defaultConfigFile']
def setConfigFile(self, configFile):
self['configFile'] = configFile
# Must reinitialize config parser at this point
self.configParser = None
def getConfigFile(self, default='__dm_default__'):
return self.__getKeyValue('configFile', default)
def hasConfigFile(self):
return self.has_key('configFile')
def getDefaultContextRoot(self):
return self['defaultContextRoot']
def setContextRoot(self, contextRoot):
self['contextRoot'] = contextRoot
def getContextRoot(self, default='__dm_default__'):
return self.__getKeyValue('contextRoot', default)
def hasContextRoot(self):
return self.has_key('contextRoot')
def getDefaultSessionCacheFile(self):
return self['defaultSessionCacheFile']
def setSessionCacheFile(self, sessionCacheFile):
self['sessionCacheFile'] = sessionCacheFile
def getSessionCacheFile(self, default='__dm_default__'):
return self.__getKeyValue('sessionCacheFile', default)
def hasSessionCacheFile(self):
return self.has_key('sessionCacheFile')
def getDefaultRequireSessionCredentials(self):
return self['defaultRequireSessionCredentials']
def setRequireSessionCredentials(self, requireSessionCredentials):
self['requireSessionCredentials'] = requireSessionCredentials
def getRequireSessionCredentials(self, default='__dm_default__'):
return self.__getKeyValue('requireSessionCredentials', default)
def hasRequireSessionCredentials(self):
return self.has_key('requireSessionCredentials')
def getDefaultSslCaCertFile(self):
return self['defaultSslCaCertFile']
def setSslCaCertFile(self, sslCaCertFile):
self['sslCaCertFile'] = sslCaCertFile
def getSslCaCertFile(self, default='__dm_default__'):
return self.__getKeyValue('sslCaCertFile', default)
def hasSslCaCertFile(self):
return self.has_key('sslCaCertFile')
def getDefaultSslCertFile(self):
return self['defaultSslCertFile']
def setSslCertFile(self, sslCertFile):
self['sslCertFile'] = sslCertFile
def getSslCertFile(self, default='__dm_default__'):
return self.__getKeyValue('sslCertFile', default)
def hasSslCertFile(self):
return self.has_key('sslCertFile')
def getDefaultSslKeyFile(self):
return self['defaultSslKeyFile']
def setSslKeyFile(self, sslKeyFile):
self['sslKeyFile'] = sslKeyFile
def getSslKeyFile(self, default='__dm_default__'):
return self.__getKeyValue('sslKeyFile', default)
def hasSslKeyFile(self):
return self.has_key('sslKeyFile')
def getDefaultUsername(self):
return self['defaultUsername']
def setUsername(self, username):
self['username'] = username
def getUsername(self, default='__dm_default__'):
return self.__getKeyValue('username', default)
def hasUsername(self):
return self.has_key('username')
def getDefaultPassword(self):
return self['defaultPassword']
def setPassword(self, password):
self['password'] = password
def getPassword(self, default='__dm_default__'):
return self.__getKeyValue('password', default)
def hasPassword(self):
return self.has_key('password')
def getDefaultLoginFile(self):
return self['defaultLoginFile']
def getLoginFile(self, default='__dm_default__'):
return self.__getKeyValue('loginFile', default)
def setLoginFile(self, f):
self['loginFile'] = f
def hasLoginFile(self):
return self.has_key('loginFile')
def getDefaultBssLoginFile(self):
return self['defaultBssLoginFile']
def getBssLoginFile(self, default='__dm_default__'):
return self.__getKeyValue('bssLoginFile', default)
def setBssLoginFile(self, f):
self['bssLoginFile'] = f
def hasBssLoginFile(self):
return self.has_key('bssLoginFile')
def getDefaultStationName(self):
return self['defaultStationName']
def getStationName(self, default='__dm_default__'):
return self.__getKeyValue('stationName', default)
def setStationName(self, f):
self['stationName'] = f
def hasStationName(self):
return self.has_key('stationName')
def getDefaultAllowedExperimentTypes(self):
return self['defaultAllowedExperimentTypes']
def getAllowedExperimentTypes(self, default='__dm_default__'):
return self.__getKeyValue('allowedExperimentTypes', default)
def setAllowedExperimentTypes(self, f):
self['allowedExperimentTypes'] = f
def hasAllowedExperimentTypes(self):
return self.has_key('allowedExperimentTypes')
def getDefaultBeamlineName(self):
return self['defaultBeamlineName']
def getBeamlineName(self, default='__dm_default__'):
return self.__getKeyValue('beamlineName', default)
def setBeamlineName(self, f):
self['beamlineName'] = f
def hasBeamlineName(self):
return self.has_key('beamlineName')
def getDefaultBeamlineManagers(self):
return self['defaultBeamlineManagers']
def getBeamlineManagers(self, default='__dm_default__'):
return self.__getKeyValue('beamlineManagers', default)
def setBeamlineManagers(self, f):
self['beamlineManagers'] = f
def hasBeamlineManagers(self):
return self.has_key('beamlineManagers')
#######################################################################
# Testing.
if __name__ == '__main__':
cm = ConfigurationManager.getInstance()
print cm
print cm.getUsername()
#!/usr/bin/env python
#
# Console logging handler class
#
#######################################################################
import socket
import pwd
import os
from logging import StreamHandler
#######################################################################
class ConsoleLoggingHandler(StreamHandler):
""" Class that enables console logging. """
def __init__(self, *args):
StreamHandler.__init__(self, *args)
self.user = pwd.getpwuid(os.getuid())[0]
self.host = socket.gethostname()
def emit(self, record):
record.__dict__['user'] = self.user
record.__dict__['host'] = self.host
return StreamHandler.emit(self, record)
#######################################################################
# Testing.
if __name__ == '__main__':
import sys
import logging
exec 'sh = ConsoleLoggingHandler(sys.stdout,)'
sh.setLevel(logging.INFO)
rootLogger = logging.getLogger('')
logging.basicConfig(level=logging.DEBUG)
mainLogger = logging.getLogger('main')
mainLogger.debug("main debug")
mainLogger.info("main info")
#!/usr/bin/env python
import random
import string
import crypt
#import md5
import hashlib
import base64
class CryptUtility:
CRYPT_TYPE = 6 # SHA-512 (man crypt)
SALT_CHARACTERS = string.lowercase + string.uppercase + string.digits
SALT_DELIMITER = '$'
SALT_LENGTH_IN_BYTES = 4
PBKDF2_ENCRYPTION = 'sha1' # use SHA-1 for compatibility with java
PBKDF2_KEY_LENGTH_IN_BYTES = 24
PBKDF2_ITERATIONS = 1003
@classmethod
def getRandomWord(cls, length):
return ''.join(random.choice(CryptUtility.SALT_CHARACTERS) for i in range(length))
@classmethod
def cryptPassword(cls, password):
""" Return crypted password. """
#calculator = md5.md5()
#calculator.update(salt)
#md5Salt = calculator.hexdigest()
#return crypt.crypt(cleartext, md5Salt)
salt = CryptUtility.getRandomWord(CryptUtility.SALT_LENGTH_IN_BYTES)
salt = '%s%s%s%s%s'.format(CryptUtility.SALT_DELIMITER, CryptUtility.CRYPT_TYPE, CryptUtility.SALT_DELIMITER, salt, CryptUtility.SALT_DELIMITER)
return crypt.crypt(password, salt)
@classmethod
def verifyPassword(cls, password, cryptedPassword):
""" Verify crypted password. """
return cryptedPassword == crypt.crypt(password, cryptedPassword)
@classmethod
def cryptPasswordWithPbkdf2(cls, password):
""" Crypt password with pbkdf2 package and encode with b64. """
salt = CryptUtility.getRandomWord(CryptUtility.SALT_LENGTH_IN_BYTES)
return cls.saltAndCryptPasswordWithPbkdf2(password, salt)
@classmethod
def saltAndCryptPasswordWithPbkdf2(cls, password, salt):
""" Crypt salted password with pbkdf2 package and encode with b64. """
cryptedPassword = hashlib.pbkdf2_hmac(
CryptUtility.PBKDF2_ENCRYPTION,
password, salt,
CryptUtility.PBKDF2_ITERATIONS,
CryptUtility.PBKDF2_KEY_LENGTH_IN_BYTES)
encodedPassword = base64.b64encode(cryptedPassword)
return '%s%s%s' % (salt, CryptUtility.SALT_DELIMITER, encodedPassword)
@classmethod
def verifyPasswordWithPbkdf2(cls, password, cryptedPassword):
""" Verify crypted password. """
# Get salt
salt = '%s' % cryptedPassword.split(CryptUtility.SALT_DELIMITER)[0]
# Verify crypted password
return cryptedPassword == cls.saltAndCryptPasswordWithPbkdf2(password, salt)
#######################################################################
# Testing.
if __name__ == '__main__':
import sys
#password = "dm"
password = sys.argv[1]
print 'Clear text: ', password
#cryptedPassword = CryptUtility.cryptPassword(password)
#print 'Crypted: ', cryptedPassword
#isVerified = CryptUtility.verifyPassword(password, cryptedPassword)
#print 'Verify: ', isVerified
cryptedPassword = CryptUtility.cryptPasswordWithPbkdf2(password)
print 'Crypted: ', cryptedPassword
isVerified = CryptUtility.verifyPasswordWithPbkdf2(password, cryptedPassword)
print 'Verify: ', isVerified
#!/usr/bin/env python
import copy
class DictUtility:
@classmethod
def getAndRemoveKey(cls, dict, key, default=None):
value = dict.get(key, default)
if dict.has_key(key):
del dict[key]
return value
@classmethod
def deepCopy(cls, dict, includeKeys=[], excludeKeys=[]):
dict2 = {}
if len(includeKeys):
for key in includeKeys:
value = dict.get(key)
if value is not None:
dict2[key] = copy.deepcopy(value)
elif len(excludeKeys):
for key in dict.keys():
if key not in excludeKeys:
dict2[key] = copy.deepcopy(dict[key])
else:
dict2 = copy.deepcopy(dict)
return dict2
@classmethod
def deepCopy2(cls, dict, includeKeys=[], excludeKeys=[]):
dict2 = copy.deepcopy(dict)
if len(includeKeys):
for key in dict2.keys():
if not key in includeKeys:
del dict2[key]
elif len(excludeKeys):
for key in excludeKeys:
if dict2.has_key(key):
del dict2[key]
return dict2
#######################################################################
# Testing.
if __name__ == '__main__':
print DictUtility.deepCopy({'k1': '1', 'k2' : '2'}, excludeKeys=['k1'])
print DictUtility.deepCopy({'k1': '1', 'k2' : '2'}, includeKeys=['k1'])
print DictUtility.deepCopy({'k1': '1', 'k2' : '2'})
#!/usr/bin/env python
#
# Module manager class.
#
#######################################################################
import threading
#######################################################################
class DmModuleManager:
""" Singleton class used for managing dm modules. """
# Get singleton instance.
@classmethod
def getInstance(cls):
from dm.common.utility.dmModuleManager import DmModuleManager
try:
mgr = DmModuleManager()
except DmModuleManager, ex:
mgr = ex
return mgr
# Singleton.
__instanceLock = threading.RLock()
__instance = None
def __init__(self):
DmModuleManager.__instanceLock.acquire()
try:
if DmModuleManager.__instance:
raise DmModuleManager.__instance
DmModuleManager.__instance = self
from dm.common.utility.loggingManager import LoggingManager
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
self.lock = threading.RLock()
self.moduleList = []
self.modulesRunning = False
finally:
DmModuleManager.__instanceLock.release()
def addModule(self, m):
self.lock.acquire()
try:
self.logger.debug('Adding dm module: %s' % m.__class__.__name__)
self.moduleList.append(m)
finally:
self.lock.release()
def startModules(self):
self.lock.acquire()
try:
if self.modulesRunning:
return
for m in self.moduleList:
self.logger.debug('Starting dm module: %s' % m.__class__.__name__)
m.start()
self.modulesRunning = True
finally:
self.lock.release()
def stopModules(self):
self.lock.acquire()
try:
if not self.modulesRunning:
return
n = len(self.moduleList)
for i in range(0, n):
m = self.moduleList[n-1-i]
self.logger.debug('Stopping dm module: %s' % m.__class__.__name__)
m.stop()
self.modulesRunning = False
finally:
self.lock.release()
#######################################################################
# Testing.
if __name__ == '__main__':
pass
#!/usr/bin/env python
#
# Subprocess class
#
import os
import subprocess
import platform
from dm.common.utility.loggingManager import LoggingManager
from dm.common.exceptions.commandFailed import CommandFailed
#######################################################################
class DmSubprocess(subprocess.Popen):
# Get subprocess instance.
@classmethod
def getSubprocess(cls, command, cwd=None):
close_fds = True
if platform.system() != 'Windows':
close_fds = False
p = DmSubprocess(command, close_fds=close_fds, cwd=cwd)
return p
# Execute command
@classmethod
def executeCommand(cls, command, cwd=None):
""" Create subprocess and run it, return subprocess object. """
p = cls.getSubprocess(command, cwd)
p.run()
return p
# Execute command, ignore errors.
@classmethod
def executeCommandAndIgnoreFailure(cls, command, cwd=None):
""" Create subprocess, run it, igore any failures, and return subprocess object. """
p = cls.getSubprocess(command, cwd)
try:
p.run()
except CommandFailed, ex:
p.getLogger().debug('Command failed, stdout: %s, stderr: %s' % (p.getStdOut(), p.getStdErr()))
return p
@classmethod
def executeCommandAndLogToStdOut(cls, command, cwd=None):
""" Execute command, display output to stdout, maintain log file and return subprocess object. """
p = cls.getSubprocess(command, cwd)
p.__commandLog()
while True:
outp = p.stdout.readline()
if not outp:
break
print outp,
retval = p.wait()
p.logger.debug('Exit status: %s' % retval)
if retval != 0:
error = ''
while True:
err = p.stderr.readline()
if not err:
break
error += err
raise CommandFailed(error)
return p
def __init__(self, args, bufsize=0, executable=None, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=None, close_fds=False, shell=True, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, useExceptions=True, quietMode=False):
""" Overrides Popen constructor with more appropriate defaults. """
subprocess.Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags)
self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
self._stdout = None
self._stderr = None
self._args = args
self._cwd = cwd
self.useExceptions = useExceptions
self.quietMode = quietMode
def __commandLog(self):
# Not very useful to show the name of this file.
# Walk up the stack to find the caller.
import traceback
stack = traceback.extract_stack()
for i in range(2, len(stack)):
if stack[-i][0] != stack[-1][0]:
fileName, lineNumber, functionName, text = stack[-i]
break
else:
fileName = lineNumber = functionName = text = '?'
self.logger.debug('From [%s:%s] Invoking: [%s]' % (os.path.basename(fileName), lineNumber, self._args))
def run(self, input=None):
""" Run subprocess. """
if not self.quietMode:
self.__commandLog()
(self._stdout, self._stderr) = subprocess.Popen.communicate(self, input)
if not self.quietMode:
self.logger.debug('Exit status: %s' % self.returncode)
if self.returncode != 0 and self.useExceptions:
if not self.quietMode:
self.logger.debug('StdOut: %s' % self._stdout)
self.logger.debug('StdErr: %s' % self._stderr)
error = self._stderr.strip()
if error == '':
error = self._stdout.strip()
raise CommandFailed('%s' % (error))
return (self._stdout, self._stderr)
def getLogger(self):
return self.logger
def getArgs(self):
return self._args
def getStdOut(self):
return self._stdout
def getStdErr(self):
return self._stderr
def getExitStatus(self):
return self.returncode
def toDict(self):
result = {
'command' : self._args,
'exitStatus' : self.returncode,
'stdErr' : self._stderr,
'stdOut' : self._stdout,
'workingDir' : self._cwd
}
return result
#######################################################################
# Testing.
if __name__ == '__main__':
p = DmSubprocess('ls -l', useExceptions=False)
print p.toDict()
p.run()
#print p.getStdOut()
#print p.getStdErr()
#print p.getExitStatus()
print p.toDict()
#!/usr/bin/env python
import base64
class Encoder:
@classmethod
def encode(cls, data):
# Encode twice, in order to avoid issues like '+' being
# interpreted as space after decoding
if not data:
return data
encodedData = base64.b64encode(base64.encodestring('%s' % data))
return encodedData
@classmethod
def decode(cls, encodedData):
if not encodedData:
return encodedData
data = base64.decodestring(base64.b64decode('%s' % encodedData))
return data
@classmethod
def encodeDict(cls, dict, excludedKeyList=[]):
encodedDict = {}
for (key,value) in dict.items():
if key not in excludedKeyList:
encodedDict[key] = cls.encode(value)
else:
encodedDict[key] = value
return encodedDict
@classmethod
def decodeDict(cls, encodedDict, excludedKeyList=[]):
dict = {}
for (key,value) in encodedDict.items():
if key not in excludedKeyList:
dict[key] = cls.decode(value)
else:
dict[key] = value
return dict
#!/usr/bin/env python
import os
import stat
from dm.common.utility.dmSubprocess import DmSubprocess
from dm.common.utility.timeUtility import TimeUtility
class FileUtility:
@classmethod
def getMd5Sum(cls, filePath, fileInfo={}):
p = DmSubprocess.getSubprocess('md5sum "%s"' % filePath)
p.run()
md5Sum = p.getStdOut().split()[0]
fileInfo['md5Sum'] = md5Sum
fileInfo['filePath'] = filePath
return fileInfo
@classmethod
def statFile(cls, filePath, fileInfo={}):
statResult = os.stat(filePath)
fileInfo['filePath'] = filePath
fileInfo['fileSize'] = statResult[stat.ST_SIZE]
fileInfo['fileCreationTime'] = statResult[stat.ST_CTIME]
fileInfo['fileAccessTime'] = statResult[stat.ST_ATIME]
fileInfo['fileModificationTime'] = statResult[stat.ST_MTIME]
return fileInfo
#######################################################################
# Testing.
if __name__ == '__main__':
print FileUtility.getMd5Sum('/tmp/file')
print FileUtility.statFile('/tmp/file')
#!/usr/bin/env python
import copy
import os
import time
from ftplib import FTP
from dm.common.utility.timeUtility import TimeUtility
from dm.common.utility.loggingManager import LoggingManager
import urlparse
class FtpUtility:
def __init__(self, host, port, username=None, password=None, serverUsesUtcTime=True):
self.host = host
self.port = port
self.username = username
self.password = password
self.ftpClient = None
self.serverUsesUtcTime = serverUsesUtcTime
self.mlsdFileStatDict = {}
@classmethod
def parseFtpUrl(cls, url, defaultHost=None, defaultPort=None):
host = defaultHost
port = defaultPort
scheme = None
dirPath = url
if url.startswith('ftp://'):
parseResult = urlparse.urlparse(url)
scheme = parseResult.scheme
netlocTokens = parseResult.netloc.split(':')
host = netlocTokens[0]
if len(netlocTokens) > 1:
port = int(netlocTokens[1])
dirPath = parseResult.path
return (scheme, host, port, dirPath)
@classmethod
def parseUrl(cls, url, defaultHost=None, defaultPort=None):
host = defaultHost
port = defaultPort
parseResult = urlparse.urlparse(url)
scheme = parseResult.scheme
netlocTokens = parseResult.netloc
if netlocTokens:
netlocTokens = netlocTokens.split(':')
host = netlocTokens[0]
if len(netlocTokens) > 1:
port = int(netlocTokens[1])
dirPath = parseResult.path
dirPath = os.path.normpath(dirPath)
return (scheme, host, port, dirPath)
@classmethod
def assembleUrl(cls, scheme, host, port, dirPath):
url = ''
if scheme:
url += '%s://' % scheme
if host:
url += '%s' % (host)
if port:
url += ':%s' % (port)
if dirPath:
if len(url) and not dirPath.startswith('/'):
url += '/%s' % (os.path.normpath(dirPath))
else:
url += '%s' % (os.path.normpath(dirPath))
return url
@classmethod
def getFtpClient(cls, host, port, username=None, password=None):
ftp = FTP()
ftp.connect(host, port)
ftp.login(username, password)
return ftp
@classmethod
def getLogger(cls):
logger = LoggingManager.getInstance().getLogger(cls.__name__)
return logger
def __parseKeyValue(cls, origKeyValue, outputDict={}, newKey=None):
key,value = origKeyValue.split('=')
value = value.strip()
if newKey is not None:
key = newKey
outputDict[key] = value
return outputDict
def __parseMlsdOutput(self, line):
# ['Type=dir', 'Modify=20151018024430', 'Size=4096', 'Perm=el', 'UNIX.mode=0775', 'UNIX.owner=sveseli', 'UNIX.uid=500', 'UNIX.group=sveseli', 'UNIX.gid=500', 'Unique=fd00-c2e3e', ' dir2\r']
parts = line.split(';')
parseDict = {}
self.__parseKeyValue(parts[0], parseDict)
self.__parseKeyValue(parts[1], parseDict)
self.__parseKeyValue(parts[2], parseDict, 'fileSize')
name = parts[-1].strip()
parseDict['Name'] = name
type = parseDict.get('Type', '')
if type == 'dir' :
self.mlsdDirList.append(name)
elif type == 'file':
self.mlsdFileDict[name] = parseDict
def __parseMlsdFileStat(self, line):
# ['Type=dir', 'Modify=20151018024430', 'Size=4096', 'Perm=el', 'UNIX.mode=0775', 'UNIX.owner=sveseli', 'UNIX.uid=500', 'UNIX.group=sveseli', 'UNIX.gid=500', 'Unique=fd00-c2e3e', ' dir2\r']
parts = line.split(';')
parseDict = {}
self.__parseKeyValue(parts[0], parseDict)
self.__parseKeyValue(parts[1], parseDict)
self.__parseKeyValue(parts[2], parseDict, 'fileSize')
name = parts[-1].strip()
self.mlsdFileStatDict[name] = parseDict
def __processFileStatDict(self, fileStatDict):
modifyTime = fileStatDict.get('Modify')
modifyTime = time.mktime(time.strptime(modifyTime, '%Y%m%d%H%M%S'))
if self.serverUsesUtcTime:
modifyTime = TimeUtility.utcToLocalTime(modifyTime)
fileStatDict['fileModificationTime'] = modifyTime
fileStatDict['fileSize'] = int(fileStatDict.get('fileSize'))
del fileStatDict['Modify']
del fileStatDict['Type']
def getFiles2(self, dirPath, fileDict={}, replacementDirPath=None, initialCall=True):
if not self.ftpClient:
self.ftpClient = self.getFtpClient(self.host, self.port, self.username, self.password)
# Need these to be class members for the callback function
self.mlsdFileDict = {}
self.mlsdDirList = []
self.ftpClient.retrlines('MLSD %s' % dirPath, self.__parseMlsdOutput)
if not replacementDirPath:
replacementDirPath = dirPath
for (fileName,fileInfo) in self.mlsdFileDict.items():
self.__processFileStatDict(fileInfo)
del fileInfo['Name']
filePath = '%s/%s' % (replacementDirPath, fileName)
fileDict[filePath] = fileInfo
mlsdDirList = copy.copy(self.mlsdDirList)
for d in mlsdDirList:
dirPath2 = '%s/%s' % (dirPath,d)
replacementDirPath2 = '%s/%s' % (replacementDirPath,d)
self.getFiles2(dirPath2,fileDict, replacementDirPath2, initialCall=False)
if initialCall:
del self.mlsdFileDict
del self.mlsdDirList
return fileDict
def getFiles(self, dirPath, fileDict={}, replacementDirPath=None):
if not self.ftpClient:
self.ftpClient = self.getFtpClient(self.host, self.port, self.username, self.password)
# Need these to be class members for the callback function
self.mlsdFileDict = {}
self.mlsdDirList = []
self.ftpClient.retrlines('MLSD %s' % dirPath, self.__parseMlsdOutput)
if not replacementDirPath:
replacementDirPath = dirPath
for (fileName,fileInfo) in self.mlsdFileDict.items():
filePath = '%s/%s' % (replacementDirPath, fileName)
modifyTime = fileInfo.get('Modify')
modifyTime = time.mktime(time.strptime(modifyTime, '%Y%m%d%H%M%S'))
if self.serverUsesUtcTime:
modifyTime = TimeUtility.utcToLocalTime(modifyTime)
fileSize = int(fileInfo.get('fileSize'))
#print '%s %s %s' % (filePath, fileSize, modifyTime)
fileDict[filePath] = {'fileSize' : fileSize, 'fileModificationTime' : modifyTime}
self.mlsdFileDict.clear()
mlsdDirList = copy.copy(self.mlsdDirList)
for d in mlsdDirList:
dirPath2 = '%s/%s' % (dirPath,d)
replacementDirPath2 = '%s/%s' % (replacementDirPath,d)
self.getFiles(dirPath2, fileDict, replacementDirPath2)
self.mlsdDirList = []
return fileDict
def getMd5Sum(self, filePath, fileInfo={}):
if not self.ftpClient:
self.ftpClient = self.getFtpClient(self.host, self.port, self.username, self.password)
md5Sum = self.ftpClient.sendcmd('CKSM MD5 0 -1 %s' % filePath).split()[-1]
fileInfo['md5Sum'] = md5Sum
return md5Sum
def statFile(self, filePath, fileInfo={}):
fileName = os.path.basename(filePath)
if not self.ftpClient:
self.ftpClient = self.getFtpClient(self.host, self.port, self.username, self.password)
# Need this to be class members for the callback function
self.ftpClient.retrlines('MLSD %s' % filePath, self.__parseMlsdFileStat)
fileStatDict = self.mlsdFileStatDict.get(fileName)
if fileStatDict:
self.__processFileStatDict(fileStatDict)
fileInfo.update(fileStatDict)
del self.mlsdFileStatDict[fileName]
return fileInfo
#######################################################################
# Testing.
if __name__ == '__main__':
print "Round 1: "
ftpUtility = FtpUtility('s33dserv', 2811)
#files = ftpUtility.getFiles2('/export/7IDSprayimage/Cummins/Data')
files = ftpUtility.getFiles2('/export/dm/test')
print files
files = ftpUtility.getFiles('/export/dm/test')
print ftpUtility.parseFtpUrl('/export/dm/test')
print files
#files = ftpUtility.getFiles('/export/7IDSprayimage/Cummins/Data')
#files = ftpUtility.getFiles2('/export/8-id-i/test', replacementDirPath='/data/testing/8-id-i')
#print "Number of files: ", len(files)
#time.sleep(60)
#print "Removing files"
#del files
#print "Files removed"
#time.sleep(60)
#del ftpUtility
#print "Utility removed"
#time.sleep(60)
#print "Round 2: "
#ftpUtility = FtpUtility('s7dserv', 2811)
#files = ftpUtility.getFiles2('/export/7IDSprayimage/Cummins/Data')
print ftpUtility.getMd5Sum('/export/dm/test/testfile01')
#print ftpUtility.statFile('/export/8-id-i/test/testfile01')
#ftpUtility = FtpUtility('xstor-devel', 22)
#files = ftpUtility.getFiles2('/data/testing')
#print files