def __call__(self, env, start_response): req = swob.Request(env) is_search = False if req.headers.get('X-Context', None) == 'search': is_search = True else: try: version, account, path = swift_utils.split_path( req.path, 2, 3, True) if version.lower() == self.path: is_search = True except ValueError: return self.app(env, start_response) if is_search: try: if 'swift.authorize' in req.environ: auth_response = req.environ['swift.authorize'](req) if auth_response: return auth_response else: # This is bad, very bad. return swob.HTTPForbidden(request=req) return self.GET(req)(env, start_response) except Exception: traceback.print_exc(file=sys.stdout) return swob.HTTPInternalServerError(request=req) return self.app(env, start_response)
def authorize_cb(req): # Assume swift owner, if not yet set req.environ.setdefault('REMOTE_USER', 'authorized') req.environ.setdefault('swift_owner', True) # But then default to blocking authz, to ensure we've replaced # the default auth system return swob.HTTPForbidden(request=req)
def __call__(self, req): try: vrs, acc, con, obj = req.split_path(2, 4, rest_with_last=True) except ValueError: # /info or similar... return self.app # Check if it's an account request... if con is None: return self.translate_sysmeta_and_complete( req, {'x-' + SYSMETA_UNDELETE_ENABLED: SYSMETA_ACCOUNT}) # ...or a container request... if obj is None: return self.translate_sysmeta_and_complete( req, {'x-' + SYSMETA_UNDELETE_ENABLED: SYSMETA_CONTAINER}) # ...must be object. # We only want to step in on object DELETE requests if req.method != 'DELETE': return self.app # Okay, this is definitely an object DELETE request; let's see if it's # one we want to step in for. if self.is_trash(con) and self.block_trash_deletes: return swob.HTTPMethodNotAllowed( content_type="text/plain", body=("Attempted to delete from a trash container, but " "block_trash_deletes is enabled\n")) elif self.is_trash(con) and not self.is_superuser(req.environ): return swob.HTTPForbidden( content_type="text/plain", body=("Attempted to delete from a trash container, but " "user is not a superuser\n")) elif not self.should_save_copy(req.environ, con, obj): return self.app trash_container = self.trash_prefix + con copy_status, copy_headers, copy_body = self.copy_object( req, trash_container, obj) if copy_status == 404: self.create_trash_container(req, vrs, acc, trash_container) copy_status, copy_headers, copy_body = self.copy_object( req, trash_container, obj) elif not http.is_success(copy_status): # other error; propagate this to the client return swob.Response(body=friendly_error(copy_body), status=copy_status, headers=copy_headers) return self.app
def __call__(self, req): # Get will never be locked if req.method.lower() in READ_METHODS or\ self._is_obj_req(req) is False: return self.app locked_methods = self._get_req_lockers(req) if req.method.lower() in locked_methods: self.logger.info('{} {} blocked'.format(req.method, req.path_info)) return swob.HTTPForbidden() return self.app
def _fake_auth_middleware(self, env): if 'swift.authorize_override' in env: return if 'HTTP_AUTHORIZATION' not in env: return _, authorization = env['HTTP_AUTHORIZATION'].split(' ') tenant_user, sign = authorization.rsplit(':', 1) tenant, user = tenant_user.rsplit(':', 1) path = env['PATH_INFO'] env['PATH_INFO'] = path.replace(tenant_user, 'AUTH_' + tenant) env['REMOTE_USER'] = '******' # AccessDenied by default env['swift.authorize'] = lambda req: swob.HTTPForbidden(request=req)
def fake_authorize(req): authorize_call.append(req) return swob.HTTPForbidden()
def fake_authorize(req): # the container GET is pre-auth'd so here we deny the object DELETE authorize_call.append(req) return swob.HTTPForbidden()
def get_controller(self, req): # Maybe handle /info specially here, like our superclass' # get_controller() does? # Note: the only difference I can see between doing # "split_path(req.path, ...)" vs. req.split_path() is that req.path # will quote the path string with urllib.quote() prior to # splititng it. Unlike our superclass' similarly-named method, we're # going to leave the acct/cont/obj values UTF8-encoded and unquoted. ver, acct, cont, obj = req.split_path(1, 4, True) if not obj and not cont: # We've decided to not support any actions on accounts... raise swob.HTTPForbidden(body="Account operations are not " "supported.") if not obj and req.method not in ('GET', 'HEAD'): # We've decided to only support container listings (GET) raise swob.HTTPForbidden(body="The only supported container " "operations are GET and HEAD.") profile_key1, profile_key2 = (acct, cont), (acct, '/*') profile = self.sync_profiles.get( profile_key1, self.sync_profiles.get(profile_key2, None)) if not profile: self.logger.debug('No matching sync profile for %r or %r', profile_key1, profile_key2) raise swob.HTTPForbidden(body="No matching sync profile.") # Cook up a Provider "profile" here that can talk to the onprem Swift # cluster (the "profile" details will depend on whether or not this # request came into cloud-connector via S3 API or Swift API because of # the differences in authentication between the two APIs. # For now, only S3 API access is supported. if S3_IDENTITY_ENV_KEY in req.environ: # We got a S3 API request s3_identity = req.environ[S3_IDENTITY_ENV_KEY] onprem_swift_profile = { # Other code will expect Unicode strings in here "account": acct.decode('utf8'), "container": profile['container'], # All the "aws_*" stuff will be pointing to the onprem Swift # cluster "aws_bucket": profile['container'], "aws_endpoint": self.swift_baseurl, "aws_identity": s3_identity['access_key'], # already Unicode "aws_secret": s3_identity['secret_key'], # already Unicode "protocol": "s3", "custom_prefix": "", # "native" access } else: raise swob.HTTPNotImplemented( 'UNEXPECTED: only S3 access supported, but ' 'S3_IDENTITY_ENV_KEY missing??') d = dict(local_to_me_profile=profile, remote_to_me_profile=onprem_swift_profile, version=ver, account_name=acct, container_name=cont, object_name=obj) return CloudConnectorController, d