Пример #1
0
class UserDB(object):
    def __init__(self, storage, key, namespace):
        self.storage = SecureStorage(storage)
        self.key = key
        self.logger = Logger()
        self.namespace = namespace_prefix + namespace
        self.dbnamespace = namespace_prefix + "apps"
        self.lognamespace = namespace_prefix + "logs"
        self.logger.info("UserDB has been initialized. Use namespace %s" %
                         self.namespace)

    @asynchronous
    def exists(self, name):
        try:
            yield self.storage.read(self.namespace, name)
        except Exception as err:
            self.logger.error(str(err))
            yield False
        else:
            yield True

    @asynchronous
    def get(self, name):
        yield self.storage.read(self.namespace, name)

    @asynchronous
    def create(self, info):
        user_info = dict()
        uid = uuid.uuid4().hex
        name = info['name']
        password = info['password']

        exists = yield self.exists(name)
        if exists:
            raise Exception("Already exists")
        # Store user uid
        user_info['uid'] = uid
        # Store username
        user_info['name'] = name
        # Crypt user passwd
        h = HMAC.new(uid)
        h.update(password)
        user_info['hash'] = h.hexdigest()
        try:
            yield self.storage.write(self.namespace, name, user_info, USER_TAG)
        except Exception as err:
            self.logger.error(str(err))
            yield False
        else:
            yield True

    @asynchronous
    def remove(self, name):
        try:
            self.logger.info("Remove user %s" % name)
            yield self.storage.remove(self.namespace, name)
        except Exception as err:
            self.logger.error(repr(err))

        try:
            self.logger.info("Remove user %s application info" % name)
            yield self.storage.remove(self.dbnamespace, name)
        except Exception as err:
            self.logger.error(repr(err))

        try:
            self.logger.info("Remove user %s upload logs" % name)
            tags = LOG_TAG + [name]
            logkeys = yield self.storage.find(self.lognamespace, tags)
            self.logger.debug("Uploadlogs keys %s" % logkeys)
            for key in logkeys:
                yield self.storage.remove(self.lognamespace, key)
        except Exception as err:
            self.logger.error(repr(err))

    @asynchronous
    def login(self, name, password):
        user_info = yield self.get(name)
        self.logger.info(str(user_info))
        h = HMAC.new(user_info['uid'])
        h.update(password)
        self.logger.error("%s %s" % (h.hexdigest(), user_info['hash']))
        if (h.hexdigest() == user_info['hash']):
            user_info.pop('uid')
            yield user_info
        else:
            raise Exception("Invalid pair of login/password")

    @asynchronous
    def users(self):
        yield self.storage.find(self.namespace, USER_TAG)

    @asynchronous
    def user_apps(self, user):
        apps = list()
        try:
            raw_apps = yield self.storage.read(self.dbnamespace, user)
            apps = msgpack.unpackb(raw_apps)
        except Exception as err:
            self.logger.error(repr(err))
        finally:
            yield apps

    @asynchronous
    def write_app_info(self, user, name):
        def handler(data):
            apps = list()
            if data is None:
                apps = list()
            else:
                apps = msgpack.unpackb(data)

            if name in apps:
                self.logger.error("App %s already exists" % name)
                return None

            apps.append(name)
            return msgpack.packb(apps)

        reader = partial(self.storage.read, self.dbnamespace, user)
        writer = lambda result: self.storage.write(self.dbnamespace, user,
                                                   result, USER_TAG)
        yield self.quasi_atomic_write(reader, writer, handler)

    @asynchronous
    def write_buildlog(self, user, key, logdata):
        tags = LOG_TAG + [user]
        yield self.storage.write(self.lognamespace, key, logdata, tags)

    @asynchronous
    def read_buildlog(self, key):
        yield self.storage.read(self.lognamespace, key)

    @asynchronous
    def list_buildlog(self, user):
        tags = [user] if user else LOG_TAG
        yield self.storage.find(self.lognamespace, tags)

    @asynchronous
    def quasi_atomic_write(self, reader, writer, handler):
        while True:
            data = None
            summ = ""
            try:
                data = yield reader()
                summ = hashlib.md5(data).hexdigest()
            except Exception as err:
                self.logger.error(repr(err))

            result = handler(data)
            if result is None:
                break

            try:
                data = yield reader()
            except Exception as err:
                self.logger.error(repr(err))

            if data is None or summ == hashlib.md5(data).hexdigest():
                self.logger.info("MD5 is still valid. Do write")
                yield writer(result)
                break

            self.logger.info("MD5 mismatchs. Continue")
Пример #2
0
class MySqlDG(object):
    def __init__(self, **config):
        self.logger = Logger()
        self.place = None
        self.tablename = ''
        try:
            unix_socket = config.get('MysqlSocket',
                                     "/var/run/mysqld/mysqld.sock")
            self.dbname = config.get('local_db_name', 'COMBAINE')
            self.user = config.get('user', 'root')
            self.password = config.get('password', "")
            self.db = MySQLdb.connect(unix_socket=unix_socket,
                                      user=self.user,
                                      passwd=self.password)
            self.cursor = self.db.cursor()
            self.cursor.execute('CREATE DATABASE IF NOT EXISTS %s' %
                                self.dbname)
            self.db.commit()
            self.db.select_db(self.dbname)
        except Exception as err:
            self.logger.error('Error in init MySQLdb %s' % err)
            raise Exception

    def putData(self, data, tablename):
        try:
            tablename = tablename.replace('.',
                                          '_').replace('-',
                                                       '_').replace('+', '_')
            line = None
            fname = '/dev/shm/%s-%i' % ('COMBAINE', random.randint(0, 65535))
            with open(fname, 'w') as table_file:
                for line in data:
                    table_file.write('GOPA'.join([str(x)
                                                  for _, x in line]) + '\n')
                table_file.close()

                if not line:
                    self.logger.info("Data for mysql is missed")
                    os.remove(table_file.name)
                    return False

                self.logger.debug(
                    'Data has been written to a temporary file %s, size: %d bytes'
                    % (table_file.name, os.lstat(table_file.name).st_size))

            if not self._preparePlace(line):
                self.logger.error(
                    'Unsupported field types. Look at preparePlace()')
                return False

            self.cursor.execute('DROP TABLE IF EXISTS %s' % tablename)
            query = "CREATE TABLE IF NOT EXISTS `%(tablename)s` %(struct)s ENGINE = MEMORY DATA DIRECTORY='/dev/shm/'" % {
                'tablename': tablename,
                'struct': self.place
            }
            self.cursor.execute(query)
            self.db.commit()

            query = "LOAD DATA INFILE '%(filename)s' INTO TABLE `%(tablename)s` FIELDS TERMINATED BY 'GOPA'" % {
                'filename': table_file.name,
                'tablename': tablename
            }
            self.cursor.execute(query)
            self.db.commit()
            if os.path.isfile(table_file.name):
                os.remove(table_file.name)
        except Exception as err:
            self.logger.error('Error in putData %s' % err)
            if os.path.isfile(table_file.name):
                os.remove(table_file.name)
            return False
        else:
            self.tablename = tablename
            return True

    def _preparePlace(self, example):
        ftypes = {
            types.IntType: "BIGINT",
            types.UnicodeType: "VARCHAR(200)",
            types.StringType: "VARCHAR(200)",
            types.FloatType: "DOUBLE"
        }
        try:
            self.place = '( %s )' % ','.join([
                " `%s` %s" % (field_name, ftypes[type(field_type)])
                for field_name, field_type in example
            ])
        except Exception as err:
            self.logger.error('Error in preparePlace() %s' % err)
            self.place = None
            return False
        else:
            return True

    def perfomCustomQuery(self, query_string):
        self.logger.debug("Execute query: %s" % query_string)
        self.cursor.execute(query_string)
        _ret = self.cursor.fetchall()
        self.db.commit()
        return _ret
Пример #3
0
class MySqlDG(object):

    def __init__(self, **config):
        self.logger = Logger()
        self.place = None
        self.tablename = ''
        try:
            # port = config.get('local_db_port', 3306)
            unix_socket = config.get('MysqlSocket',
                                     "/var/run/mysqld/mysqld.sock")
            self.dbname = config.get('local_db_name', 'COMBAINE')
            self.db = MySQLdb.connect(unix_socket=unix_socket, user='******', )
            self.cursor = self.db.cursor()
            self.cursor.execute('CREATE DATABASE IF NOT EXISTS %s' % self.dbname)
            self.db.commit()
            self.db.select_db(self.dbname)
        except Exception as err:
            self.logger.error('Error in init MySQLdb %s' % err)
            raise Exception

    def putData(self, data, tablename):
        try:
            tablename = tablename.replace('.', '_').replace('-', '_').replace('+', '_')
            line = None
            fname = '/dev/shm/%s-%i' % ('COMBAINE', random.randint(0, 65535))
            with open(fname, 'w') as table_file:
                for line in data:
                    table_file.write('GOPA'.join([str(x) for x in line.values()]) + '\n')
                table_file.close()

                if not line:
                    self.logger.info("Data for mysql is missed")
                    os.remove(table_file.name)
                    return False

                self.logger.debug('Data written to a temporary file %s, size: %d bytes'
                                  % (table_file.name, os.lstat(table_file.name).st_size))

            if not self._preparePlace(line):
                self.logger.error('Unsupported field types. Look at preparePlace()')
                return False

            self.cursor.execute('DROP TABLE IF EXISTS %s' % tablename)
            query = "CREATE TABLE IF NOT EXISTS %(tablename)s %(struct)s ENGINE = MEMORY DATA DIRECTORY='/dev/shm/'" % {'tablename': tablename,
                                                                                                                                  'struct': self.place}
            self.cursor.execute(query)
            self.db.commit()

            query = "LOAD DATA INFILE '%(filename)s' INTO TABLE %(tablename)s FIELDS TERMINATED BY 'GOPA'" % {'filename': table_file.name,
                                                                                                              'tablename': tablename}
            self.cursor.execute(query)
            self.db.commit()
            if os.path.isfile(table_file.name):
                os.remove(table_file.name)
        except Exception as err:
            self.logger.error('Error in putData %s' % err)
            if os.path.isfile(table_file.name):
                os.remove(table_file.name)
            return False
        else:
            self.tablename = tablename
            return True

    def _preparePlace(self, example):
        ftypes = {types.IntType: "INT",
                  types.UnicodeType: "VARCHAR(200)",
                  types.StringType: "VARCHAR(200)",
                  types.FloatType: "FLOAT"}
        try:
            self.place = '( %s )' % ','.join([" %s %s" % (field_name,
                                                          ftypes[type(field_type)])
                                             for field_name, field_type in example.items()])
        except Exception as err:
            self.logger.error('Error in preparePlace() %s' % err)
            self.place = None
            return False
        else:
            return True

    def perfomCustomQuery(self, query_string):
        self.logger.debug("Execute query: %s" % query_string)
        self.cursor.execute(query_string)
        _ret = self.cursor.fetchall()
        self.db.commit()
        return _ret

    def __del__(self):
        if self.db:
            self.cursor.close()
            self.db.commit()
            self.db.close()
Пример #4
0
class UrlFetcher():
    def __init__(self, io_loop):
        self.io_loop = io_loop
        self.http_client = AsyncHTTPClient()
        self.logger = Logger()

    @chain.source
    def perform_request(self, request, response, method):
        try:
            constants = request_consts[method]

            url = request[constants.URL]
            timeout = request[constants.TIMEOUT]

            http_request = HTTPRequest(url=url, method=method)
            http_request.request_timeout = float(timeout)/1000

            if method == 'POST':
                http_request.body = request[constants.BODY]

            #adds cookies to request
            params_num = len(request)
            if constants.COOKIES <= params_num - 1:
                cookies = request[constants.COOKIES]
                if len(cookies) > 0:
                    list_of_cookies = list('{0}={1}'.format(cookie, value) for cookie, value in cookies.iteritems())
                    cookies_str = '; '.join(list_of_cookies)

                    http_request.headers.add('Cookie', cookies_str)

            #adds headers to request
            if constants.HEADERS <= params_num - 1:
                for name, values_list in request[constants.HEADERS].iteritems():
                    for value in values_list:
                        http_request.headers.add(name, value)

            self.logger.info("Downloading {0}, headers {1}, method {2}".format(url, http_request.headers, method))
            http_response = yield self.http_client.fetch(http_request)

            response_headers = self._get_headers_from_response(http_response)
            response.write((True, http_response.body, http_response.code, response_headers,))

            response.close()
            self.logger.info("{0} has been successfuly downloaded".format(url))
        except HTTPError as e:
            self.logger.info("Error ({0}) occured while downloading {1}".format(e.message, url))

            if e.response is not None:
                http_response = e.response
                response_headers = self._get_headers_from_response(http_response)
                response.write((False, http_response.body, http_response.code, response_headers,))
            else:
                response.write((False, '', e.code, {},))

            response.close()
        except socket.gaierror as e:
            self.logger.info("Error ({0}) occured while downloading {1}".format(e.message, url))
            response.write((False, '', e.errno, {},))
            response.close()
        except Exception as e:
            self.logger.error("Unhandled error ({0}) occured in perform_request, report about this problem "
                          "to httpclient service developers. Method is {1}, stacktrace is: {2}".format(
                                e.message, method, traceback.format_exc()))

            response.write((False, '', 0, {},))
            response.close()

    @chain.source
    def on_get_request(self, request, response):
        try:
            request_data_packed = yield request.read()
            request_data = msgpack.unpackb(request_data_packed)

            yield self.perform_request(request_data, response, 'GET')
        except StopIteration:
            pass
        except Exception as e:
            self.logger.error("Unhandled error ({0}) occured in on_get_request, report about this problem "
                              "to httpclient service developers. Stacktrace is: {1}".format(e.message, traceback.format_exc()))
            response.write((False, '', 0, {},))
            response.close()

    @chain.source
    def on_post_request(self, request, response):
        try:
            request_data_packed = yield request.read()
            request_data = msgpack.unpackb(request_data_packed)

            yield self.perform_request(request_data, response, 'POST')
        except StopIteration:
            pass
        except Exception as e:
            self.logger.error("Unhandled error ({0}) occured in on_post_request, report about this problem "
                              "to httpclient service developers. Stacktrace is: {1}".format(e.message, traceback.format_exc()))
            response.write((False, '', 0, {},))
            response.close()

    def _get_headers_from_response(self, http_response):
        response_headers = {}
        for header_tuple in http_response.headers.items():
            name = header_tuple[0]
            value = header_tuple[1]
            if not name in response_headers:
                response_headers[name] = []

            response_headers[name].append(value)

        return response_headers
Пример #5
0
class UserDB(object):
    def __init__(self, storage, key, namespace):
        self.storage = SecureStorage(storage)
        self.key = key
        self.logger = Logger()
        self.namespace = namespace_prefix + namespace
        self.dbnamespace = namespace_prefix + "apps"
        self.lognamespace = namespace_prefix + "logs"
        self.logger.info("UserDB has been initialized. Use namespace %s"
                         % self.namespace)

    @asynchronous
    def exists(self, name):
        try:
            yield self.storage.read(self.namespace, name)
        except Exception as err:
            self.logger.error(str(err))
            yield False
        else:
            yield True

    @asynchronous
    def get(self, name):
        yield self.storage.read(self.namespace, name)

    @asynchronous
    def create(self, info):
        user_info = dict()
        uid = uuid.uuid4().hex
        name = info['name']
        password = info['password']

        exists = yield self.exists(name)
        if exists:
            raise Exception("Already exists")
        # Store user uid
        user_info['uid'] = uid
        # Store username
        user_info['name'] = name
        # Crypt user passwd
        h = HMAC.new(uid)
        h.update(password)
        user_info['hash'] = h.hexdigest()
        try:
            yield self.storage.write(self.namespace, name, user_info, USER_TAG)
        except Exception as err:
            self.logger.error(str(err))
            yield False
        else:
            yield True

    @asynchronous
    def remove(self, name):
        try:
            self.logger.info("Remove user %s" % name)
            yield self.storage.remove(self.namespace, name)
        except Exception as err:
            self.logger.error(repr(err))

        try:
            self.logger.info("Remove user %s application info" % name)
            yield self.storage.remove(self.dbnamespace, name)
        except Exception as err:
            self.logger.error(repr(err))

        try:
            self.logger.info("Remove user %s upload logs" % name)
            tags = LOG_TAG + [name]
            logkeys = yield self.storage.find(self.lognamespace, tags)
            self.logger.debug("Uploadlogs keys %s" % logkeys)
            for key in logkeys:
                yield self.storage.remove(self.lognamespace, key)
        except Exception as err:
            self.logger.error(repr(err))

    @asynchronous
    def login(self, name, password):
        user_info = yield self.get(name)
        self.logger.info(str(user_info))
        h = HMAC.new(user_info['uid'])
        h.update(password)
        self.logger.error("%s %s" % (h.hexdigest(), user_info['hash']))
        if (h.hexdigest() == user_info['hash']):
            user_info.pop('uid')
            yield user_info
        else:
            raise Exception("Invalid pair of login/password")

    @asynchronous
    def users(self):
        yield self.storage.find(self.namespace, USER_TAG)

    @asynchronous
    def user_apps(self, user):
        apps = list()
        try:
            raw_apps = yield self.storage.read(self.dbnamespace, user)
            apps = msgpack.unpackb(raw_apps)
        except Exception as err:
            self.logger.error(repr(err))
        finally:
            yield apps

    @asynchronous
    def write_app_info(self, user, name):
        def handler(data):
            apps = list()
            if data is None:
                apps = list()
            else:
                apps = msgpack.unpackb(data)

            if name in apps:
                self.logger.error("App %s already exists" % name)
                return None

            apps.append(name)
            return msgpack.packb(apps)

        reader = partial(self.storage.read, self.dbnamespace, user)
        writer = lambda result: self.storage.write(self.dbnamespace,
                                                   user,
                                                   result,
                                                   USER_TAG)
        yield self.quasi_atomic_write(reader, writer, handler)

    @asynchronous
    def write_buildlog(self, user, key, logdata):
        tags = LOG_TAG + [user]
        yield self.storage.write(self.lognamespace, key, logdata, tags)

    @asynchronous
    def read_buildlog(self, key):
        yield self.storage.read(self.lognamespace, key)

    @asynchronous
    def list_buildlog(self, user):
        tags = [user] if user else LOG_TAG
        yield self.storage.find(self.lognamespace, tags)

    @asynchronous
    def quasi_atomic_write(self, reader, writer, handler):
        while True:
            data = None
            summ = ""
            try:
                data = yield reader()
                summ = hashlib.md5(data).hexdigest()
            except Exception as err:
                self.logger.error(repr(err))

            result = handler(data)
            if result is None:
                break

            try:
                data = yield reader()
            except Exception as err:
                self.logger.error(repr(err))

            if data is None or summ == hashlib.md5(data).hexdigest():
                self.logger.info("MD5 is still valid. Do write")
                yield writer(result)
                break

            self.logger.info("MD5 mismatchs. Continue")