Example #1
0
 def test_localRealPath(self):
     # localRealPath takes a URL-encoded relpath and returns a URL-encoded
     # absolute path.
     filename = 'foo bar'
     escaped_filename = urlutils.escape(filename)
     self.assertNotEqual(filename, escaped_filename)
     realpath = self.transport.local_realPath(escaped_filename)
     self.assertEqual(urlutils.escape(os.path.abspath(filename)), realpath)
Example #2
0
 def test_localRealPath(self):
     # localRealPath takes a URL-encoded relpath and returns a URL-encoded
     # absolute path.
     filename = 'foo bar'
     escaped_filename = urlutils.escape(filename)
     self.assertNotEqual(filename, escaped_filename)
     realpath = self.transport.local_realPath(escaped_filename)
     self.assertEqual(
         urlutils.escape(os.path.abspath(filename)), realpath)
Example #3
0
    def translate_client_path(self, client_path):
        """Translate a path received from a network client into a local
        relpath.

        All paths received from the client *must* be translated.

        :param client_path: the path from the client.
        :returns: a relpath that may be used with self._backing_transport
            (unlike the untranslated client_path, which must not be used with
            the backing transport).
        """
        if self._root_client_path is None:
            # no translation necessary!
            return client_path
        if not client_path.startswith('/'):
            client_path = '/' + client_path
        if client_path + '/' == self._root_client_path:
            return '.'
        if client_path.startswith(self._root_client_path):
            path = client_path[len(self._root_client_path):]
            relpath = urlutils.joinpath('/', path)
            if not relpath.startswith('/'):
                raise ValueError(relpath)
            return urlutils.escape('.' + relpath)
        else:
            raise errors.PathNotChild(client_path, self._root_client_path)
Example #4
0
 def __init__(self, transport, name, flags, server):
     self._unescaped_relpath = name
     self._escaped_path = urlutils.escape(self._unescaped_relpath)
     self._flags = flags
     self.transport = transport
     self._written = False
     self._server = server
Example #5
0
    def getAttrs(self, path, followLinks):
        """See `ISFTPServer`.

        This just delegates to TransportSFTPFile's implementation.
        """
        deferred = self.transport.stat(urlutils.escape(path))
        return deferred.addCallback(self._translate_stat)
Example #6
0
    def translate_client_path(self, client_path):
        """Translate a path received from a network client into a local
        relpath.

        All paths received from the client *must* be translated.

        :param client_path: the path from the client.
        :returns: a relpath that may be used with self._backing_transport
            (unlike the untranslated client_path, which must not be used with
            the backing transport).
        """
        if self._root_client_path is None:
            # no translation necessary!
            return client_path
        if not client_path.startswith('/'):
            client_path = '/' + client_path
        if client_path + '/' == self._root_client_path:
            return '.'
        if client_path.startswith(self._root_client_path):
            path = client_path[len(self._root_client_path):]
            relpath = urlutils.joinpath('/', path)
            if not relpath.startswith('/'):
                raise ValueError(relpath)
            return urlutils.escape('.' + relpath)
        else:
            raise errors.PathNotChild(client_path, self._root_client_path)
Example #7
0
 def test_no_such_product_series_non_ascii(self):
     # lp:product/<non-ascii-string> resolves to the branch alias with the
     # name escaped.
     product = self.factory.makeProduct()
     lp_path = '%s/%s' % (product.name, NON_ASCII_NAME)
     escaped_name = urlutils.escape(lp_path)
     self.assertResolves(lp_path, None, escaped_name)
 def test_no_such_product_series_non_ascii(self):
     # lp:product/<non-ascii-string> resolves to the branch alias with the
     # name escaped.
     product = self.factory.makeProduct()
     lp_path = '%s/%s' % (product.name, NON_ASCII_NAME)
     escaped_name = urlutils.escape(lp_path)
     self.assertResolves(lp_path, None, escaped_name)
Example #9
0
 def get_url(self):
     """See bzrlib.transport.Server.get_url."""
     homedir = self._homedir
     if sys.platform != 'win32':
         # Remove the initial '/' on all platforms but win32
         homedir = homedir[1:]
     return self._get_sftp_url(urlutils.escape(homedir))
Example #10
0
 def performLookup(self, requester_id, lookup, branch_name_only=False):
     branch = None
     if branch_name_only and lookup['type'] != 'branch_name':
         return
     if lookup['type'] == 'control_name':
         return self._serializeControlDirectory(requester_id,
                                                lookup)
     elif lookup['type'] == 'id':
         branch = self._branch_set.get(lookup['branch_id'])
         if branch is None:
             return None
         trailing = lookup['trailing']
     elif lookup['type'] == 'alias':
         result = get_first_path_result(lookup['lp_path'],
             lambda l: self.performLookup(requester_id, l,
                 branch_name_only=True), None)
         if result is not None:
             return result
         product_name = lookup['lp_path'].split('/', 2)[0]
         product = self._product_set.getByName(product_name)
         if product is None:
             return None
         branch = product.development_focus.branch
         trailing = lookup['lp_path'][len(product_name):]
     elif lookup['type'] == 'branch_name':
         branch = self._branch_set._find(
             unique_name=lookup['unique_name'])
         trailing = escape(lookup['trailing'])
     else:
         return None
     if branch is not None:
         serialized = self._serializeBranch(requester_id, branch,
             trailing.lstrip('/'), lookup['type'] == 'id')
         if serialized is not None:
             return serialized
Example #11
0
 def performLookup(self, lookup):
     if lookup['type'] == 'id':
         return (self.get(lookup['branch_id']), lookup['trailing'])
     elif lookup['type'] == 'alias':
         try:
             branch, trail = self.getByLPPath(lookup['lp_path'])
             return branch, escape(trail)
         except (InvalidProductName, NoLinkedBranch, CannotHaveLinkedBranch,
                 NameLookupFailed, InvalidNamespace):
             pass
     elif lookup['type'] == 'branch_name':
         result = IStore(Branch).find(
             Branch, Branch.unique_name == lookup['unique_name'])
         for branch in result:
             return (branch, escape(lookup['trailing']))
     return None, ''
Example #12
0
 def get_url(self):
     """See bzrlib.transport.Server.get_url."""
     homedir = self._homedir
     if sys.platform != 'win32':
         # Remove the initial '/' on all platforms but win32
         homedir = homedir[1:]
     return self._get_sftp_url(urlutils.escape(homedir))
Example #13
0
def local_path_to_url(local_path):
    """Return a file:// URL to `local_path`.

    This implementation is unusual in that it returns a file://localhost/ URL.
    This is to work around the valid_vcs_details constraint on CodeImport.
    """
    return 'file://localhost' + escape(
        os.path.normpath(os.path.abspath(local_path)))
 def performLookup(self, lookup):
     if lookup['type'] == 'id':
         return (self.get(lookup['branch_id']), lookup['trailing'])
     elif lookup['type'] == 'alias':
         try:
             branch, trail = self.getByLPPath(lookup['lp_path'])
             return branch, escape(trail)
         except (InvalidProductName, NoLinkedBranch,
                 CannotHaveLinkedBranch, NameLookupFailed,
                 InvalidNamespace):
             pass
     elif lookup['type'] == 'branch_name':
         result = IStore(Branch).find(Branch,
                             Branch.unique_name == lookup['unique_name'])
         for branch in result:
             return (branch, escape(lookup['trailing']))
     return None, ''
Example #15
0
def local_path_to_url(local_path):
    """Return a file:// URL to `local_path`.

    This implementation is unusual in that it returns a file://localhost/ URL.
    This is to work around the valid_vcs_details constraint on CodeImport.
    """
    return 'file://localhost' + escape(
        os.path.normpath(os.path.abspath(local_path)))
Example #16
0
 def test_resolve_branch_with_no_such_owner_non_ascii(self):
     # lp:~<non-ascii-string>/product/name returns NoSuchPersonWithName
     # with the name escaped.
     nonexistent_owner_branch = u"~%s/%s/%s" % (
         NON_ASCII_NAME, self.factory.getUniqueString(),
         self.factory.getUniqueString())
     self.assertFault(
         nonexistent_owner_branch,
         faults.NoSuchPersonWithName(urlutils.escape(NON_ASCII_NAME)))
Example #17
0
 def check_entry(entries, filename):
     t = get_transport('.')
     stat = t.stat(urlutils.escape('%s/%s' % (parent_dir, filename)))
     named_entries = [
         entry for entry in entries if entry[0] == filename]
     self.assertEqual(1, len(named_entries))
     name, longname, attrs = named_entries[0]
     self.assertEqual(lsLine(name, stat), longname)
     self.assertEqual(self.sftp_server._translate_stat(stat), attrs)
Example #18
0
 def test_no_such_branch_product_non_ascii(self):
     # A path to a branch that contains non ascii characters will never
     # find a branch, but it still resolves rather than erroring.
     owner = self.factory.makePerson()
     product = self.factory.makeProduct()
     nonexistent_branch = u'~%s/%s/%s' % (
         owner.name, product.name, NON_ASCII_NAME)
     self.assertResolves(
         nonexistent_branch, urlutils.escape(nonexistent_branch))
Example #19
0
 def test_no_such_branch_product_non_ascii(self):
     # A path to a branch that contains non ascii characters will never
     # find a branch, but it still resolves rather than erroring.
     owner = self.factory.makePerson()
     product = self.factory.makeProduct()
     nonexistent_branch = u'~%s/%s/%s' % (owner.name, product.name,
                                          NON_ASCII_NAME)
     self.assertResolves(nonexistent_branch,
                         urlutils.escape(nonexistent_branch))
Example #20
0
    def realPath(self, relpath):
        """See `ISFTPServer`."""
        deferred = self.transport.local_realPath(urlutils.escape(relpath))

        def unescape_path(path):
            unescaped_path = urlutils.unescape(path)
            return unescaped_path.encode('utf-8')

        return deferred.addCallback(unescape_path)
Example #21
0
 def test_resolve_branch_with_no_such_owner_non_ascii(self):
     # lp:~<non-ascii-string>/product/name returns NoSuchPersonWithName
     # with the name escaped.
     nonexistent_owner_branch = u"~%s/%s/%s" % (
         NON_ASCII_NAME, self.factory.getUniqueString(),
         self.factory.getUniqueString())
     self.assertFault(
         nonexistent_owner_branch,
         faults.NoSuchPersonWithName(urlutils.escape(NON_ASCII_NAME)))
Example #22
0
 def check_entry(entries, filename):
     t = get_transport('.')
     stat = t.stat(urlutils.escape('%s/%s' % (parent_dir, filename)))
     named_entries = [
         entry for entry in entries if entry[0] == filename]
     self.assertEqual(1, len(named_entries))
     name, longname, attrs = named_entries[0]
     self.assertEqual(lsLine(name, stat), longname)
     self.assertEqual(self.sftp_server._translate_stat(stat), attrs)
Example #23
0
 def _serializeControlDirectory(self, requester, lookup):
     try:
         namespace = lookup_branch_namespace(lookup['control_name'])
     except (InvalidNamespace, NotFoundError):
         return
     trailing_path = lookup['trailing'].lstrip('/')
     if not ('.bzr' == trailing_path or trailing_path.startswith('.bzr/')):
         # '.bzr' is OK, '.bzr/foo' is OK, '.bzrfoo' is not.
         return
     default_branch = namespace.target.default_stacked_on_branch
     if default_branch is None:
         return
     try:
         path = branch_id_alias(default_branch)
     except Unauthorized:
         return
     return (CONTROL_TRANSPORT, {
         'default_stack_on': escape(path)
     }, escape(trailing_path))
    def test_realPathEscaping(self):
        # local_realPath returns an escaped path to the file.
        escaped_path = escape('~baz')
        deferred = self.transport.mkdir(escaped_path)

        def get_real_path(ignored):
            return self.transport.local_realPath(escaped_path)

        deferred.addCallback(get_real_path)
        return deferred.addCallback(self.assertEqual, '/' + escaped_path)
    def test_realPathEscaping(self):
        # local_realPath returns an escaped path to the file.
        escaped_path = escape('~baz')
        deferred = self.transport.mkdir(escaped_path)

        def get_real_path(ignored):
            return self.transport.local_realPath(escaped_path)

        deferred.addCallback(get_real_path)
        return deferred.addCallback(self.assertEqual, '/' + escaped_path)
Example #26
0
 def _serializeControlDirectory(self, requester, lookup):
     try:
         namespace = lookup_branch_namespace(lookup['control_name'])
     except (InvalidNamespace, NotFoundError):
         return
     trailing_path = lookup['trailing'].lstrip('/')
     if not ('.bzr' == trailing_path or trailing_path.startswith('.bzr/')):
         # '.bzr' is OK, '.bzr/foo' is OK, '.bzrfoo' is not.
         return
     default_branch = namespace.target.default_stacked_on_branch
     if default_branch is None:
         return
     try:
         path = branch_id_alias(default_branch)
     except Unauthorized:
         return
     return (
         CONTROL_TRANSPORT,
         {'default_stack_on': escape(path)},
         escape(trailing_path))
Example #27
0
 def _get_compose_commandline(self, to, subject, attach_path):
     """See ExternalMailClient._get_compose_commandline"""
     message_options = {}
     if subject is not None:
         message_options['subject'] = subject
     if attach_path is not None:
         message_options['attach'] = attach_path
     options_list = ['%s=%s' % (k, urlutils.escape(v)) for (k, v) in
                     sorted(message_options.iteritems())]
     return ['mailto:%s?%s' % (self._encode_safe(to or ''),
         '&'.join(options_list))]
 def test_get_mapped_file_escaped_url(self):
     # Getting a file from a public branch URL gets the file as stored on
     # the base transport, even when the URL is escaped.
     branch = self.factory.makeAnyBranch(
         branch_type=BranchType.HOSTED, owner=self.requester)
     backing_transport = self._makeOnBackingTransport(branch)
     backing_transport.put_bytes('hello.txt', 'Hello World!')
     url = escape('%s/.bzr/hello.txt' % branch.unique_name)
     transport = self.getTransport()
     deferred = self._ensureDeferred(transport.get_bytes, url)
     return deferred.addCallback(self.assertEqual, 'Hello World!')
 def test_get_mapped_file_escaped_url(self):
     # Getting a file from a public branch URL gets the file as stored on
     # the base transport, even when the URL is escaped.
     branch = self.factory.makeAnyBranch(branch_type=BranchType.HOSTED,
                                         owner=self.requester)
     backing_transport = self._makeOnBackingTransport(branch)
     backing_transport.put_bytes('hello.txt', 'Hello World!')
     url = escape('%s/.bzr/hello.txt' % branch.unique_name)
     transport = self.getTransport()
     deferred = self._ensureDeferred(transport.get_bytes, url)
     return deferred.addCallback(self.assertEqual, 'Hello World!')
Example #30
0
 def list_dir(self, relpath):
     """See Transport.list_dir."""
     if 'gio' in debug.debug_flags:
         mutter("GIO list_dir")
     try:
         entries = []
         f = self._get_GIO(relpath)
         children = f.enumerate_children(gio.FILE_ATTRIBUTE_STANDARD_NAME)
         for child in children:
             entries.append(urlutils.escape(child.get_name()))
         return entries
     except gio.Error, e:
         self._translate_gio_error(e, relpath)
    def test_canAccessEscapedPathsOnDisk(self):
        # Sometimes, the paths to files on disk are themselves URL-escaped.
        # The AsyncVirtualTransport can access these files.
        #
        # This test added in response to https://launchpad.net/bugs/236380.
        escaped_disk_path = 'prefix_%43razy'
        content = 'content\n'
        escaped_file = open(escaped_disk_path, 'w')
        escaped_file.write(content)
        escaped_file.close()

        deferred = self.transport.get_bytes(escape('%43razy'))
        return deferred.addCallback(self.assertEqual, content)
 def list_dir(self, relpath):
     """See Transport.list_dir."""
     if 'gio' in debug.debug_flags:
         mutter("GIO list_dir")
     try:
         entries = []
         f = self._get_GIO(relpath)
         children = f.enumerate_children(gio.FILE_ATTRIBUTE_STANDARD_NAME)
         for child in children:
             entries.append(urlutils.escape(child.get_name()))
         return entries
     except gio.Error, e:
         self._translate_gio_error(e, relpath)
Example #33
0
    def openDirectory(self, path):
        """See `ISFTPServer`."""
        escaped_path = urlutils.escape(path)
        deferred = self.transport.list_dir(escaped_path)

        def produce_entries_from_file_list(file_list):
            stats_deferred = self._stat_files_in_list(file_list, escaped_path)
            stats_deferred.addCallback(self._format_directory_entries,
                                       file_list)
            return stats_deferred

        return deferred.addCallback(
            produce_entries_from_file_list).addCallback(DirectoryListing)
    def test_canAccessEscapedPathsOnDisk(self):
        # Sometimes, the paths to files on disk are themselves URL-escaped.
        # The AsyncVirtualTransport can access these files.
        #
        # This test added in response to https://launchpad.net/bugs/236380.
        escaped_disk_path = 'prefix_%43razy'
        content = 'content\n'
        escaped_file = open(escaped_disk_path, 'w')
        escaped_file.write(content)
        escaped_file.close()

        deferred = self.transport.get_bytes(escape('%43razy'))
        return deferred.addCallback(self.assertEqual, content)
Example #35
0
        def create_branch(requester):
            if not branch_path.startswith('/'):
                return faults.InvalidPath(branch_path)
            escaped_path = unescape(branch_path.strip('/'))
            try:
                namespace, branch_name, link_func, path = (
                    self._getBranchNamespaceExtras(escaped_path, requester))
            except ValueError:
                return faults.PermissionDenied(
                    "Cannot create branch at '%s'" % branch_path)
            except InvalidNamespace:
                return faults.PermissionDenied(
                    "Cannot create branch at '%s'" % branch_path)
            except NoSuchPerson as e:
                return faults.NotFound(
                    "User/team '%s' does not exist." % e.name)
            except NoSuchProduct as e:
                return faults.NotFound(
                    "Project '%s' does not exist." % e.name)
            except InvalidProductName as e:
                return faults.InvalidProductName(escape(e.name))
            except NoSuchSourcePackageName as e:
                try:
                    getUtility(ISourcePackageNameSet).new(e.name)
                except InvalidName:
                    return faults.InvalidSourcePackageName(e.name)
                return self.createBranch(login_id, branch_path)
            except NameLookupFailed as e:
                return faults.NotFound(str(e))
            try:
                branch = namespace.createBranch(
                    BranchType.HOSTED, branch_name, requester)
            except LaunchpadValidationError as e:
                msg = e.args[0]
                if isinstance(msg, unicode):
                    msg = msg.encode('utf-8')
                return faults.PermissionDenied(msg)
            except BranchCreationException as e:
                return faults.PermissionDenied(str(e))

            if link_func:
                try:
                    link_func(branch)
                except Unauthorized:
                    # We don't want to keep the branch we created.
                    transaction.abort()
                    return faults.PermissionDenied(
                        "Cannot create linked branch at '%s'." % path)

            return branch.id
Example #36
0
        def create_branch(requester):
            if not branch_path.startswith('/'):
                return faults.InvalidPath(branch_path)
            escaped_path = unescape(branch_path.strip('/'))
            try:
                namespace, branch_name, link_func, path = (
                    self._getBranchNamespaceExtras(escaped_path, requester))
            except ValueError:
                return faults.PermissionDenied("Cannot create branch at '%s'" %
                                               branch_path)
            except InvalidNamespace:
                return faults.PermissionDenied("Cannot create branch at '%s'" %
                                               branch_path)
            except NoSuchPerson as e:
                return faults.NotFound("User/team '%s' does not exist." %
                                       e.name)
            except NoSuchProduct as e:
                return faults.NotFound("Project '%s' does not exist." % e.name)
            except InvalidProductName as e:
                return faults.InvalidProductName(escape(e.name))
            except NoSuchSourcePackageName as e:
                try:
                    getUtility(ISourcePackageNameSet).new(e.name)
                except InvalidName:
                    return faults.InvalidSourcePackageName(e.name)
                return self.createBranch(login_id, branch_path)
            except NameLookupFailed as e:
                return faults.NotFound(str(e))
            try:
                branch = namespace.createBranch(BranchType.HOSTED, branch_name,
                                                requester)
            except LaunchpadValidationError as e:
                msg = e.args[0]
                if isinstance(msg, unicode):
                    msg = msg.encode('utf-8')
                return faults.PermissionDenied(msg)
            except BranchCreationException as e:
                return faults.PermissionDenied(str(e))

            if link_func:
                try:
                    link_func(branch)
                except Unauthorized:
                    # We don't want to keep the branch we created.
                    transaction.abort()
                    return faults.PermissionDenied(
                        "Cannot create linked branch at '%s'." % path)

            return branch.id
Example #37
0
 def _get_compose_commandline(self, to, subject, attach_path):
     """See ExternalMailClient._get_compose_commandline"""
     message_options = {}
     if subject is not None:
         message_options['subject'] = subject
     if attach_path is not None:
         message_options['attach'] = attach_path
     options_list = [
         '%s=%s' % (k, urlutils.escape(v))
         for (k, v) in sorted(message_options.iteritems())
     ]
     return [
         'mailto:%s?%s' %
         (self._encode_safe(to or ''), '&'.join(options_list))
     ]
Example #38
0
    def _getBranchPaths(self, strip_path, supported_schemes):
        """Get the specific paths for a branch.

        If the branch is not found, but it looks like a branch name, then we
        return a writable URL for it.  If it doesn't look like a branch name a
        fault is raised.
        """
        branch_set = getUtility(IBranchLookup)
        try:
            branch, suffix = branch_set.getByLPPath(strip_path)
        except NoSuchBranch:
            # If the branch isn't found, but it looks like a valid name, then
            # resolve it anyway, treating the path like a branch's unique
            # name. This lets people push new branches up to Launchpad using
            # lp: URL syntax.
            supported_schemes = ['bzr+ssh']
            return self._getUniqueNameResultDict(
                strip_path, supported_schemes=supported_schemes)
        # XXX: JonathanLange 2009-03-21 bug=347728: All of this is repetitive
        # and thus error prone. Alternatives are directly raising faults from
        # the model code(blech) or some automated way of reraising as faults
        # or using a narrower range of faults (e.g. only one "NoSuch" fault).
        except InvalidProductName as e:
            raise faults.InvalidProductName(urlutils.escape(e.name))
        except NoSuchProductSeries as e:
            raise faults.NoSuchProductSeries(urlutils.escape(e.name),
                                             e.product)
        except NoSuchPerson as e:
            raise faults.NoSuchPersonWithName(urlutils.escape(e.name))
        except NoSuchProduct as e:
            raise faults.NoSuchProduct(urlutils.escape(e.name))
        except NoSuchDistroSeries as e:
            raise faults.NoSuchDistroSeries(urlutils.escape(e.name))
        except NoSuchSourcePackageName as e:
            raise faults.NoSuchSourcePackageName(urlutils.escape(e.name))
        except NoLinkedBranch as e:
            raise faults.NoLinkedBranch(e.component)
        except CannotHaveLinkedBranch as e:
            raise faults.CannotHaveLinkedBranch(e.component)
        except InvalidNamespace as e:
            raise faults.InvalidBranchUniqueName(urlutils.escape(e.name))
        # Reverse engineer the actual lp_path that is used, so we need to
        # remove any suffix that may be there from the strip_path.
        lp_path = strip_path
        if suffix != '':
            # E.g. 'project/trunk/filename.txt' the suffix is 'filename.txt'
            # we want lp_path to be 'project/trunk'.
            lp_path = lp_path[:-(len(suffix) + 1)]
        return self._getUrlsForBranch(branch, lp_path, suffix,
                                      supported_schemes)
Example #39
0
 def _serializeControlDirectory(self, requester, lookup):
     trailing_path = lookup['trailing'].lstrip('/')
     if not ('.bzr' == trailing_path or trailing_path.startswith('.bzr/')):
         return
     target = self._get_product_target(lookup['control_name'])
     if target is None:
         target = self._get_package_target(lookup['control_name'])
     if target is None:
         return
     default_branch = IBranchTarget(target).default_stacked_on_branch
     if default_branch is None:
         return
     if not self._canRead(requester, default_branch):
         return
     path = branch_id_alias(default_branch)
     return (CONTROL_TRANSPORT, {
         'default_stack_on': escape(path)
     }, trailing_path)
Example #40
0
    def _getBranchPaths(self, strip_path, supported_schemes):
        """Get the specific paths for a branch.

        If the branch is not found, but it looks like a branch name, then we
        return a writable URL for it.  If it doesn't look like a branch name a
        fault is raised.
        """
        branch_set = getUtility(IBranchLookup)
        try:
            branch, suffix = branch_set.getByLPPath(strip_path)
        except NoSuchBranch:
            # If the branch isn't found, but it looks like a valid name, then
            # resolve it anyway, treating the path like a branch's unique
            # name. This lets people push new branches up to Launchpad using
            # lp: URL syntax.
            supported_schemes = ["bzr+ssh"]
            return self._getUniqueNameResultDict(strip_path, supported_schemes=supported_schemes)
        # XXX: JonathanLange 2009-03-21 bug=347728: All of this is repetitive
        # and thus error prone. Alternatives are directly raising faults from
        # the model code(blech) or some automated way of reraising as faults
        # or using a narrower range of faults (e.g. only one "NoSuch" fault).
        except InvalidProductName as e:
            raise faults.InvalidProductName(urlutils.escape(e.name))
        except NoSuchProductSeries as e:
            raise faults.NoSuchProductSeries(urlutils.escape(e.name), e.product)
        except NoSuchPerson as e:
            raise faults.NoSuchPersonWithName(urlutils.escape(e.name))
        except NoSuchProduct as e:
            raise faults.NoSuchProduct(urlutils.escape(e.name))
        except NoSuchDistroSeries as e:
            raise faults.NoSuchDistroSeries(urlutils.escape(e.name))
        except NoSuchSourcePackageName as e:
            raise faults.NoSuchSourcePackageName(urlutils.escape(e.name))
        except NoLinkedBranch as e:
            raise faults.NoLinkedBranch(e.component)
        except CannotHaveLinkedBranch as e:
            raise faults.CannotHaveLinkedBranch(e.component)
        except InvalidNamespace as e:
            raise faults.InvalidBranchUniqueName(urlutils.escape(e.name))
        # Reverse engineer the actual lp_path that is used, so we need to
        # remove any suffix that may be there from the strip_path.
        lp_path = strip_path
        if suffix != "":
            # E.g. 'project/trunk/filename.txt' the suffix is 'filename.txt'
            # we want lp_path to be 'project/trunk'.
            lp_path = lp_path[: -(len(suffix) + 1)]
        return self._getUrlsForBranch(branch, lp_path, suffix, supported_schemes)
Example #41
0
 def _serializeControlDirectory(self, requester, lookup):
     trailing_path = lookup['trailing'].lstrip('/')
     if not ('.bzr' == trailing_path or trailing_path.startswith('.bzr/')):
         return
     target = self._get_product_target(lookup['control_name'])
     if target is None:
         target = self._get_package_target(lookup['control_name'])
     if target is None:
         return
     default_branch = IBranchTarget(target).default_stacked_on_branch
     if default_branch is None:
         return
     if not self._canRead(requester, default_branch):
         return
     path = branch_id_alias(default_branch)
     return (
         CONTROL_TRANSPORT,
         {'default_stack_on': escape(path)},
         trailing_path)
    def test_url_escaping(self):
        # Transports accept and return escaped URL segments. The literal path
        # we use should be preserved, even if it can be unescaped itself.
        transport = self._getBzrDirTransport()

        # The bug we are checking only occurs if
        # unescape(path).encode('utf-8') != path.
        path = '%41%42%43'
        escaped_path = escape(path)
        content = 'content'
        transport.put_bytes(escaped_path, content)

        # We can use the escaped path to reach the file.
        self.assertEqual(content, transport.get_bytes(escaped_path))

        # We can also use the value that list_dir returns, which may be
        # different from our original escaped path. Note that in this case,
        # returned_path is equivalent but not equal to escaped_path.
        [returned_path] = list(transport.list_dir('.'))
        self.assertEqual(content, transport.get_bytes(returned_path))
    def test_url_escaping(self):
        # Transports accept and return escaped URL segments. The literal path
        # we use should be preserved, even if it can be unescaped itself.
        transport = self._getBzrDirTransport()

        # The bug we are checking only occurs if
        # unescape(path).encode('utf-8') != path.
        path = '%41%42%43'
        escaped_path = escape(path)
        content = 'content'
        transport.put_bytes(escaped_path, content)

        # We can use the escaped path to reach the file.
        self.assertEqual(content, transport.get_bytes(escaped_path))

        # We can also use the value that list_dir returns, which may be
        # different from our original escaped path. Note that in this case,
        # returned_path is equivalent but not equal to escaped_path.
        [returned_path] = list(transport.list_dir('.'))
        self.assertEqual(content, transport.get_bytes(returned_path))
Example #44
0
    def test_set_get_parent(self):
        """Set, re-get and reset the parent"""
        b = self.make_branch('subdir')
        url = 'http://example.com/bzr/bzr.dev'
        b.set_parent(url)
        self.assertEqual(url, b.get_parent())
        self.assertEqual(url, b._get_parent_location())

        b.set_parent(None)
        self.assertEqual(None, b.get_parent())

        b.set_parent('../other_branch')

        expected_parent = urlutils.join(self.get_url('subdir'),
                                        '../other_branch')
        self.assertEqual(expected_parent, b.get_parent())
        path = urlutils.join(self.get_url('subdir'), '../yanb')
        b.set_parent(path)
        self.assertEqual('../yanb', b._get_parent_location())
        self.assertEqual(path, b.get_parent())


        self.assertRaises(bzrlib.errors.InvalidURL, b.set_parent, u'\xb5')
        b.set_parent(urlutils.escape(u'\xb5'))
        self.assertEqual('%C2%B5', b._get_parent_location())

        self.assertEqual(b.base + '%C2%B5', b.get_parent())

        # Handle the case for older style absolute local paths
        if sys.platform == 'win32':
            # TODO: jam 20060515 Do we want to special case Windows local
            #       paths as well? Nobody has complained about it.
            pass
        else:
            b.lock_write()
            b._set_parent_location('/local/abs/path')
            b.unlock()
            self.assertEqual('file:///local/abs/path', b.get_parent())
Example #45
0
    def test_set_get_parent(self):
        """Set, re-get and reset the parent"""
        b = self.make_branch('subdir')
        url = 'http://example.com/bzr/bzr.dev'
        b.set_parent(url)
        self.assertEqual(url, b.get_parent())
        self.assertEqual(url, b._get_parent_location())

        b.set_parent(None)
        self.assertEqual(None, b.get_parent())

        b.set_parent('../other_branch')

        expected_parent = urlutils.join(self.get_url('subdir'),
                                        '../other_branch')
        self.assertEqual(expected_parent, b.get_parent())
        path = urlutils.join(self.get_url('subdir'), '../yanb')
        b.set_parent(path)
        self.assertEqual('../yanb', b._get_parent_location())
        self.assertEqual(path, b.get_parent())

        self.assertRaises(bzrlib.errors.InvalidURL, b.set_parent, u'\xb5')
        b.set_parent(urlutils.escape(u'\xb5'))
        self.assertEqual('%C2%B5', b._get_parent_location())

        self.assertEqual(b.base + '%C2%B5', b.get_parent())

        # Handle the case for older style absolute local paths
        if sys.platform == 'win32':
            # TODO: jam 20060515 Do we want to special case Windows local
            #       paths as well? Nobody has complained about it.
            pass
        else:
            b.lock_write()
            b._set_parent_location('/local/abs/path')
            b.unlock()
            self.assertEqual('file:///local/abs/path', b.get_parent())
Example #46
0
 def test_escape_unescape(self):
     self.assertEqual(u'\xe5', urlutils.unescape(urlutils.escape(u'\xe5')))
     self.assertEqual('%', urlutils.unescape(urlutils.escape('%')))
Example #47
0
 def test_escape_tildes(self):
     self.assertEqual('~foo', urlutils.escape('~foo'))
Example #48
0
 def test_escape(self):
     self.assertEqual('%25', urlutils.escape('%'))
     self.assertEqual('%C3%A5', urlutils.escape(u'\xe5'))
     self.assertFalse(isinstance(urlutils.escape(u'\xe5'), unicode))
Example #49
0
 def _escape(self, file_or_path):
     if not isinstance(file_or_path, basestring):
         file_or_path = '/'.join(file_or_path)
     if file_or_path == '':
         return u''
     return urlutils.escape(osutils.safe_unicode(file_or_path))
Example #50
0
                           ' Assuming it means empty directory',
                           str(e))
                    return []
                raise
        finally:
            # Restore binary mode as nlst switch to ascii mode to retrieve file
            # list
            f.voidcmd('TYPE I')

        # If FTP.nlst returns paths prefixed by relpath, strip 'em
        if paths and paths[0].startswith(basepath):
            entries = [path[len(basepath)+1:] for path in paths]
        else:
            entries = paths
        # Remove . and .. if present
        return [urlutils.escape(entry) for entry in entries
                if entry not in ('.', '..')]

    def iter_files_recursive(self):
        """See Transport.iter_files_recursive.

        This is cargo-culted from the SFTP transport"""
        mutter("FTP iter_files_recursive")
        queue = list(self.list_dir("."))
        while queue:
            relpath = queue.pop(0)
            st = self.stat(relpath)
            if stat.S_ISDIR(st.st_mode):
                for i, basename in enumerate(self.list_dir(relpath)):
                    queue.insert(i, relpath+"/"+basename)
            else:
Example #51
0
    def _createBranch(self, registrant, branch_path):
        """The guts of the create branch method.

        Raises exceptions on error conditions.
        """
        to_link = None
        if branch_path.startswith(BRANCH_ALIAS_PREFIX + '/'):
            branch_path = branch_path[len(BRANCH_ALIAS_PREFIX) + 1:]
            if branch_path.startswith('~'):
                data, branch_name = self._parseUniqueName(branch_path)
            else:
                tokens = branch_path.split('/')
                data = {
                    'person': registrant.name,
                    'product': tokens[0],
                    }
                branch_name = 'trunk'
                # check the series
                product = self._product_set.getByName(data['product'])
                if product is not None:
                    if len(tokens) > 1:
                        series = product.getSeries(tokens[1])
                        if series is None:
                            raise faults.NotFound(
                                "No such product series: '%s'." % tokens[1])
                        else:
                            to_link = ICanHasLinkedBranch(series)
                    else:
                        to_link = ICanHasLinkedBranch(product)
                # don't forget the link.
        else:
            data, branch_name = self._parseUniqueName(branch_path)

        owner = self._person_set.getByName(data['person'])
        if owner is None:
            raise faults.NotFound(
                "User/team '%s' does not exist." % (data['person'],))
        # The real code consults the branch creation policy of the product. We
        # don't need to do so here, since the tests above this layer never
        # encounter that behaviour. If they *do* change to rely on the branch
        # creation policy, the observed behaviour will be failure to raise
        # exceptions.
        if not registrant.inTeam(owner):
            raise faults.PermissionDenied(
                ('%s cannot create branches owned by %s'
                 % (registrant.displayname, owner.displayname)))
        product = sourcepackage = None
        if data['product'] == '+junk':
            product = None
        elif data['product'] is not None:
            if not valid_name(data['product']):
                raise faults.InvalidProductName(escape(data['product']))
            product = self._product_set.getByName(data['product'])
            if product is None:
                raise faults.NotFound(
                    "Project '%s' does not exist." % (data['product'],))
        elif data['distribution'] is not None:
            distro = self._distribution_set.getByName(data['distribution'])
            if distro is None:
                raise faults.NotFound(
                    "No such distribution: '%s'." % (data['distribution'],))
            distroseries = self._distroseries_set.getByName(
                data['distroseries'])
            if distroseries is None:
                raise faults.NotFound(
                    "No such distribution series: '%s'."
                    % (data['distroseries'],))
            sourcepackagename = self._sourcepackagename_set.getByName(
                data['sourcepackagename'])
            if sourcepackagename is None:
                try:
                    sourcepackagename = self._sourcepackagename_set.new(
                        data['sourcepackagename'])
                except InvalidName:
                    raise faults.InvalidSourcePackageName(
                        data['sourcepackagename'])
            sourcepackage = self._factory.makeSourcePackage(
                distroseries, sourcepackagename)
        else:
            raise faults.PermissionDenied(
                "Cannot create branch at '%s'" % branch_path)
        branch = self._factory.makeBranch(
            owner=owner, name=branch_name, product=product,
            sourcepackage=sourcepackage, registrant=registrant,
            branch_type=BranchType.HOSTED)
        if to_link is not None:
            if registrant.inTeam(to_link.product.owner):
                to_link.branch = branch
            else:
                self._branch_set._delete(branch)
                raise faults.PermissionDenied(
                    "Cannot create linked branch at '%s'." % branch_path)
        return branch.id
Example #52
0
 def iter_files_recursive(self):
     for file in self._files:
         if file.startswith(self._cwd):
             yield urlutils.escape(file[len(self._cwd):])
Example #53
0
 def removeDirectory(self, path):
     """See `ISFTPServer`."""
     return self.transport.rmdir(urlutils.escape(path))
Example #54
0
    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()
Example #55
0
 def removeFile(self, path):
     """See `ISFTPServer`."""
     return self.transport.delete(urlutils.escape(path))
Example #56
0
 def local_realPath(self, path):
     """Return the absolute path to `path`."""
     abspath = self._abspath(path)
     return urlutils.escape(os.path.realpath(abspath))
Example #57
0
 def renameFile(self, oldpath, newpath):
     """See `ISFTPServer`."""
     return self.transport.rename(urlutils.escape(oldpath),
                                  urlutils.escape(newpath))