def get_auth(path=None): user = bottle.request.get_header('x-auth-user', None) key = bottle.request.get_header('x-auth-key', None) if user is None or key is None: raise bottle.HTTPError(400) users = get_users() if user not in users: logger.debug("Unknown user '%s'" % user) raise bottle.HTTPError(401) user = users[user] if user['pwd'] != key: logger.debug("Wrong key for user '%s'" % user['name']) raise bottle.HTTPError(401) settings = get_settings() name = user['name'] sxsid = hashlib.sha1(SECRET + name).hexdigest() sxsid += ':' + os.urandom(128).encode('hex') cache = get_cache() cache.set(AUTH_CACHE_TEMPLATE % sxsid, json.dumps(user)) url = settings['this.storage_url'] + 'SXSID_' + sxsid ttl = settings['cache.expiration_time'] exp = int(time.time()) + ttl bottle.response.set_cookie('sxsid', sxsid, max_age=ttl, expires=exp) bottle.response.set_header('x-storage-url', url) bottle.response.status = 200
def configure_sx(application): reload(sys) sys.setdefaultencoding('utf8') settings = config.get_settings() logger.debug('Configure called with settings: %s.' % settings) # SX initialization global _sxcontroller if os.path.isfile(settings['sx.admin_key']): user_data = sxclient.UserData.from_key_path(settings['sx.admin_key']) else: user_data = sxclient.UserData.from_key(settings['sx.admin_key']) cluster = sxclient.Cluster( settings['sx.cluster_name'], ip_addresses=settings.get('sx.host_list'), is_secure=settings.get('sx.ssl', True), port=settings.get('sx.port'), verify_ssl_cert=settings.get('sx.verify_cert', True) ) _sxcontroller = sxclient.SXController(cluster, user_data=user_data) logger.debug('SXController initialized.') # # SX cleanup initialization config.register_signal(signal.SIGINT, close_sxcontroller) config.register_signal(signal.SIGTERM, close_sxcontroller) config.register_signal(signal.SIGQUIT, close_sxcontroller) logger.debug('Cleanup actions initialized.') # Other stuff requests.packages.urllib3.disable_warnings() # unnecessary noise logger.info('Fully configured SX.')
def get_downloader(): global _sxdownloader if _sxdownloader is None: sxcontroller = get_sxcontroller() settings = get_settings() kwargs = {} threads_no = settings.get("default.downloader.threads") if threads_no is not None: kwargs["threads_no"] = threads_no kwargs["number_of_connections"] = threads_no tmp_dir = settings.get("default.downloader.tmp_dir") if tmp_dir is not None: kwargs["tmp_dir"] = tmp_dir cache_files = settings.get("default.downloader.cache_files") if cache_files is not None: kwargs["cache_files"] = cache_files _sxdownloader = SXFileDownloader(sxcontroller, **kwargs) _sxdownloader.initialize() return _sxdownloader
def configure_sx(application): reload(sys) sys.setdefaultencoding('utf8') settings = config.get_settings() logger.debug('Configure called with settings: %s.' % settings) # SX initialization global _sxcontroller if os.path.isfile(settings['sx.admin_key']): user_data = sxclient.UserData.from_key_path(settings['sx.admin_key']) else: user_data = sxclient.UserData.from_key(settings['sx.admin_key']) cluster = sxclient.Cluster(settings['sx.cluster_name'], ip_addresses=settings.get('sx.host_list'), is_secure=settings.get('sx.ssl', True), port=settings.get('sx.port'), verify_ssl_cert=settings.get( 'sx.verify_cert', True)) _sxcontroller = sxclient.SXController(cluster, user_data=user_data) logger.debug('SXController initialized.') # # SX cleanup initialization config.register_signal(signal.SIGINT, close_sxcontroller) config.register_signal(signal.SIGTERM, close_sxcontroller) config.register_signal(signal.SIGQUIT, close_sxcontroller) logger.debug('Cleanup actions initialized.') # Other stuff requests.packages.urllib3.disable_warnings() # unnecessary noise logger.info('Fully configured SX.')
def get_downloader(): global _sxdownloader if _sxdownloader is None: sxcontroller = get_sxcontroller() settings = get_settings() kwargs = {} threads_no = settings.get('default.downloader.threads') if threads_no is not None: kwargs['threads_no'] = threads_no kwargs['number_of_connections'] = threads_no tmp_dir = settings.get('default.downloader.tmp_dir') if tmp_dir is not None: kwargs['tmp_dir'] = tmp_dir cache_files = settings.get('default.downloader.cache_files') if cache_files is not None: kwargs['cache_files'] = cache_files _sxdownloader = SXFileDownloader(sxcontroller, **kwargs) _sxdownloader.initialize() return _sxdownloader
def get_cache(): global region if region is None: settings = get_settings() region = make_region().configure_from_config(settings, 'cache.') if settings['cache.backend'] == 'dogpile.cache.dbm': os.chmod(settings['cache.arguments.filename'], 0700) return region
def _validate_signature(path, methods, sig, expires): try: expires = int(expires) except (ValueError, TypeError): raise bottle.HTTPError(400, 'expires not an integer') if expires < time.time(): raise bottle.HTTPError(400, 'expires points at the time in past') has_valid_signature = False admin_key = get_settings().get('this.admin_key') for method in methods: digested_msg = _get_hmac(method, path, expires, admin_key) sigs_are_equal = const_time_is_equal(digested_msg, sig) has_valid_signature = has_valid_signature or sigs_are_equal # Even though we could break here we leave it as it is to # prevent timing attack even further. if not has_valid_signature: raise bottle.HTTPError(401, 'Incorrect sig for given expires')
def put_container(api_ver, account, container): _validate_container(api_ver, account, container) settings = get_settings() size = bottle.request.get_header('x-container-meta-quota-bytes', '') try: size = int(size) except ValueError: size = settings['default.volume.size'] info = {'created_by': 'sxswift', 'created_at': time.time()} info = json.dumps(info).encode('hex') create_user_if_not_exists(account) created = create_volume_if_not_exists( vol_name=container, user_name=account, size=size, replica_count=settings['default.volume.replica_count'], max_revisions=settings['default.volume.max_revisions'], meta={'creation_info': info} ) bottle.response.status = 201 if created else 202 post_container(api_ver, account, container)
def put_container(api_ver, account, container): _validate_container(api_ver, account, container) settings = get_settings() size = bottle.request.get_header('x-container-meta-quota-bytes', '') try: size = int(size) except ValueError: size = settings['default.volume.size'] info = {'created_by': 'sxswift', 'created_at': time.time()} info = json.dumps(info).encode('hex') create_user_if_not_exists(account) created = create_volume_if_not_exists( vol_name=container, user_name=account, size=size, replica_count=settings['default.volume.replica_count'], max_revisions=settings['default.volume.max_revisions'], meta={'creation_info': info}) bottle.response.status = 201 if created else 202 post_container(api_ver, account, container)
def requires_priv(priv_name): settings = get_settings() disable = settings.get('this.disable_access_restrictions') disable = is_truthy(disable) if disable: return no_restrictions if priv_name not in PRIVS_BY_NAME: raise Exception('Wrong access!') priv = PRIVS_BY_NAME[priv_name] @decorator def wrapper(func, *args, **kwargs): user = bottle.request.environ.get('sxswift.user') if not user: raise bottle.HTTPError(401) access = user.get('access', NO_PRIVS) if not access.extends(priv): raise bottle.HTTPError(403) return func(*args, **kwargs) return wrapper
def configure_urls(application): settings = get_settings() from sxswift.controllers.error import default_error_handler application.default_error_handler = default_error_handler from sxswift.controllers.auth import get_auth application.route(settings['auth.prefix'], 'GET', get_auth) from sxswift.controllers.home import get_home application.route('/', 'GET', get_home) from sxswift.controllers.healthcheck import get_healthcheck application.route('/healthcheck', 'GET', get_healthcheck) application.route('/healthcheck/', 'GET', get_healthcheck) from sxswift.controllers.info import get_info application.route('/info', 'GET', get_info) application.route('/info/', 'GET', get_info) from sxswift.controllers.endpoints import get_endpoints application.route('/<api_ver>/endpoints', 'GET', get_endpoints) application.route('/<api_ver>/endpoints/', 'GET', get_endpoints) from sxswift.controllers.accounts import ( get_account, post_account, ) application.route('/<api_ver>/<account>', 'GET', get_account) application.route('/<api_ver>/<account>', 'POST', post_account) from sxswift.controllers.containers import ( get_container, put_container, post_container, delete_container, ) application.route( '/<api_ver>/<account>/<container>', 'GET', get_container ) application.route( '/<api_ver>/<account>/<container>', 'POST', post_container ) application.route( '/<api_ver>/<account>/<container>', 'PUT', put_container ) application.route( '/<api_ver>/<account>/<container>', 'DELETE', delete_container ) from sxswift.controllers.objects import ( get_object, put_object, post_object, copy_object, delete_object, ) application.route( '/<api_ver>/<account>/<container>/<object:re:.+>', 'GET', get_object ) application.route( '/<api_ver>/<account>/<container>/<object:re:.+>', 'PUT', put_object ) application.route( '/<api_ver>/<account>/<container>/<object:re:.+>', 'POST', post_object ) application.route( '/<api_ver>/<account>/<container>/<object:re:.+>', 'COPY', copy_object ) application.route( '/<api_ver>/<account>/<container>/<object:re:.+>', 'DELETE', delete_object ) logger.info('Configured routing.')