def test_stacked_within_scheme(self): # A branch that is stacked on a URL of the same scheme is safe to # open. self.get_transport().mkdir('inside') self.make_branch('inside/stacked') self.make_branch('inside/stacked-on') scheme, get_chrooted_url = self.get_chrooted_scheme('inside') Branch.open(get_chrooted_url('stacked')).set_stacked_on_url( get_chrooted_url('stacked-on')) safe_open(scheme, get_chrooted_url('stacked'))
def __init__(self, branch, target_dir, logger, bzr_branch=None): self.branch = branch self.bzr_branch = bzr_branch if self.bzr_branch is None: self.bzr_branch = safe_open('lp-internal', self.branch.getInternalBzrUrl(), ignore_fallbacks=True) self.target_dir = target_dir self.target_subdir = os.path.join( self.target_dir, str(self.branch.id)) self.logger = logger
def test_ignore_fallbacks(self): """"Cross-format stacking doesn't error with ignore_fallbacks.""" scheme, get_chrooted_url = self.get_chrooted_scheme('inside') stacked, stacked_on = make_cross_format_stacked(self) force_stacked_on_url(stacked, get_chrooted_url('stacked-on')) safe_open(scheme, get_chrooted_url('stacked'), ignore_fallbacks=True)
def __call__(self, environ, start_response): environ['loggerhead.static.url'] = environ['SCRIPT_NAME'] if environ['PATH_INFO'].startswith('/static/'): path_info_pop(environ) return static_app(environ, start_response) elif environ['PATH_INFO'] == '/favicon.ico': return favicon_app(environ, start_response) elif environ['PATH_INFO'] == '/robots.txt': return robots_app(environ, start_response) elif environ['PATH_INFO'].startswith('/+login'): return self._complete_login(environ, start_response) elif environ['PATH_INFO'].startswith('/+logout'): return self._logout(environ, start_response) path = environ['PATH_INFO'] trailingSlashCount = len(path) - len(path.rstrip('/')) user = environ[self.session_var].get('user', LAUNCHPAD_ANONYMOUS) lp_server = get_lp_server(user, branch_transport=self.get_transport()) lp_server.start_server() try: try: transport_type, info, trail = self.branchfs.translatePath( user, urlutils.escape(path)) except xmlrpclib.Fault as f: if check_fault(f, faults.PathTranslationError): raise HTTPNotFound() elif check_fault(f, faults.PermissionDenied): # If we're not allowed to see the branch... if environ['wsgi.url_scheme'] != 'https': # ... the request shouldn't have come in over http, as # requests for private branches over http should be # redirected to https by the dynamic rewrite script we # use (which runs before this code is reached), but # just in case... env_copy = environ.copy() env_copy['wsgi.url_scheme'] = 'https' raise HTTPMovedPermanently(construct_url(env_copy)) elif user != LAUNCHPAD_ANONYMOUS: # ... if the user is already logged in and still can't # see the branch, they lose. exc = HTTPUnauthorized() exc.explanation = "You are logged in as %s." % user raise exc else: # ... otherwise, lets give them a chance to log in # with OpenID. return self._begin_login(environ, start_response) else: raise if transport_type != BRANCH_TRANSPORT: raise HTTPNotFound() trail = urlutils.unescape(trail).encode('utf-8') trail += trailingSlashCount * '/' amount_consumed = len(path) - len(trail) consumed = path[:amount_consumed] branch_name = consumed.strip('/') self.log.info('Using branch: %s', branch_name) if trail and not trail.startswith('/'): trail = '/' + trail environ['PATH_INFO'] = trail environ['SCRIPT_NAME'] += consumed.rstrip('/') branch_url = lp_server.get_url() + branch_name branch_link = urlparse.urljoin( config.codebrowse.launchpad_root, branch_name) cachepath = os.path.join( config.codebrowse.cachepath, branch_name[1:]) if not os.path.isdir(cachepath): os.makedirs(cachepath) self.log.info('branch_url: %s', branch_url) base_api_url = allvhosts.configs['api'].rooturl branch_api_url = '%s/%s/%s' % ( base_api_url, 'devel', branch_name, ) self.log.info('branch_api_url: %s', branch_api_url) req = urllib2.Request(branch_api_url) private = False try: # We need to determine if the branch is private response = urllib2.urlopen(req) except urllib2.HTTPError as response: code = response.getcode() if code in (400, 401, 403, 404): # There are several error codes that imply private data. # 400 (bad request) is a default error code from the API # 401 (unauthorized) should never be returned as the # requests are always from anon. If it is returned # however, the data is certainly private. # 403 (forbidden) is obviously private. # 404 (not found) implies privacy from a private team or # similar situation, which we hide as not existing rather # than mark as forbidden. self.log.info("Branch is private") private = True self.log.info( "Branch state not determined; api error, return code: %s", code) response.close() else: self.log.info("Branch is public") response.close() try: bzr_branch = safe_open( lp_server.get_url().strip(':/'), branch_url) except errors.NotBranchError as err: self.log.warning('Not a branch: %s', err) raise HTTPNotFound() bzr_branch.lock_read() try: view = BranchWSGIApp( bzr_branch, branch_name, {'cachepath': cachepath}, self.graph_cache, branch_link=branch_link, served_url=None, private=private) return view.app(environ, start_response) finally: bzr_branch.repository.revisions.clear_cache() bzr_branch.repository.signatures.clear_cache() bzr_branch.repository.inventories.clear_cache() if bzr_branch.repository.chk_bytes is not None: bzr_branch.repository.chk_bytes.clear_cache() bzr_branch.repository.texts.clear_cache() bzr_branch.unlock() finally: lp_server.stop_server()
def __call__(self, environ, start_response): request_is_private = (environ['SERVER_PORT'] == str( config.codebrowse.private_port)) environ['loggerhead.static.url'] = environ['SCRIPT_NAME'] if environ['PATH_INFO'].startswith('/static/'): path_info_pop(environ) return static_app(environ, start_response) elif environ['PATH_INFO'] == '/favicon.ico': return favicon_app(environ, start_response) elif environ['PATH_INFO'] == '/robots.txt': return robots_app(environ, start_response) elif not request_is_private: if environ['PATH_INFO'].startswith('/+login'): return self._complete_login(environ, start_response) elif environ['PATH_INFO'].startswith('/+logout'): return self._logout(environ, start_response) path = environ['PATH_INFO'] trailingSlashCount = len(path) - len(path.rstrip('/')) if request_is_private: # Requests on the private port are internal API requests from # something that has already performed security checks. As # such, they get read-only access to everything. identity_url = LAUNCHPAD_SERVICES user = LAUNCHPAD_SERVICES else: identity_url = environ[self.session_var].get( 'identity_url', LAUNCHPAD_ANONYMOUS) user = environ[self.session_var].get('user', LAUNCHPAD_ANONYMOUS) lp_server = get_lp_server(identity_url, branch_transport=self.get_transport()) lp_server.start_server() try: try: branchfs = self.get_branchfs() transport_type, info, trail = branchfs.translatePath( identity_url, urlutils.escape(path)) except xmlrpclib.Fault as f: if check_fault(f, faults.PathTranslationError): raise HTTPNotFound() elif check_fault(f, faults.PermissionDenied): # If we're not allowed to see the branch... if environ['wsgi.url_scheme'] != 'https': # ... the request shouldn't have come in over http, as # requests for private branches over http should be # redirected to https by the dynamic rewrite script we # use (which runs before this code is reached), but # just in case... env_copy = environ.copy() env_copy['wsgi.url_scheme'] = 'https' raise HTTPMovedPermanently(construct_url(env_copy)) elif user != LAUNCHPAD_ANONYMOUS: # ... if the user is already logged in and still can't # see the branch, they lose. exc = HTTPUnauthorized() exc.explanation = "You are logged in as %s." % user raise exc else: # ... otherwise, lets give them a chance to log in # with OpenID. return self._begin_login(environ, start_response) else: raise if transport_type != BRANCH_TRANSPORT: raise HTTPNotFound() trail = urlutils.unescape(trail).encode('utf-8') trail += trailingSlashCount * '/' amount_consumed = len(path) - len(trail) consumed = path[:amount_consumed] branch_name = consumed.strip('/') self.log.info('Using branch: %s', branch_name) if trail and not trail.startswith('/'): trail = '/' + trail environ['PATH_INFO'] = trail environ['SCRIPT_NAME'] += consumed.rstrip('/') branch_url = lp_server.get_url() + branch_name branch_link = urlparse.urljoin(config.codebrowse.launchpad_root, branch_name) cachepath = os.path.join(config.codebrowse.cachepath, branch_name[1:]) if not os.path.isdir(cachepath): os.makedirs(cachepath) self.log.info('branch_url: %s', branch_url) private = info['private'] if private: self.log.info("Branch is private") else: self.log.info("Branch is public") try: bzr_branch = safe_open(lp_server.get_url().strip(':/'), branch_url) except errors.NotBranchError as err: self.log.warning('Not a branch: %s', err) raise HTTPNotFound() bzr_branch.lock_read() try: view = BranchWSGIApp(bzr_branch, branch_name, {'cachepath': cachepath}, self.graph_cache, branch_link=branch_link, served_url=None, private=private) return view.app(environ, start_response) finally: bzr_branch.repository.revisions.clear_cache() bzr_branch.repository.signatures.clear_cache() bzr_branch.repository.inventories.clear_cache() if bzr_branch.repository.chk_bytes is not None: bzr_branch.repository.chk_bytes.clear_cache() bzr_branch.repository.texts.clear_cache() bzr_branch.unlock() finally: lp_server.stop_server()