Beispiel #1
0
    def test_chmod(self):
        self.fs.touch("test.txt")
        remote_path = fs.path.join(self.test_folder, "test.txt")

        # Initial permissions
        info = self.fs.getinfo("test.txt", ["access"])
        self.assertEqual(info.permissions.mode, 0o644)
        st = self.fs.delegate_fs()._sftp.stat(remote_path)
        self.assertEqual(stat.S_IMODE(st.st_mode), 0o644)

        # Change permissions with SSHFS._chown
        self.fs.delegate_fs()._chmod(remote_path, 0o744)
        info = self.fs.getinfo("test.txt", ["access"])
        self.assertEqual(info.permissions.mode, 0o744)
        st = self.fs.delegate_fs()._sftp.stat(remote_path)
        self.assertEqual(stat.S_IMODE(st.st_mode), 0o744)

        # Change permissions with SSHFS.setinfo
        self.fs.setinfo("test.txt",
                        {"access": {
                            "permissions": Permissions(mode=0o600)
                        }})
        info = self.fs.getinfo("test.txt", ["access"])
        self.assertEqual(info.permissions.mode, 0o600)
        st = self.fs.delegate_fs()._sftp.stat(remote_path)
        self.assertEqual(stat.S_IMODE(st.st_mode), 0o600)

        with self.assertRaises(fs.errors.PermissionDenied):
            self.fs.delegate_fs().setinfo(
                "/", {"access": {
                    "permissions": Permissions(mode=0o777)
                }})
    def test_constructor(self):
        p = Permissions(names=["foo", "bar"])
        self.assertIn("foo", p)
        self.assertIn("bar", p)
        self.assertNotIn("baz", p)

        p = Permissions(user="******", group="w", other="x")
        self.assertIn("u_r", p)
        self.assertIn("g_w", p)
        self.assertIn("o_x", p)
        self.assertNotIn("sticky", p)
        self.assertNotIn("setuid", p)
        self.assertNotIn("setguid", p)

        p = Permissions(user="******",
                        group="rwx",
                        other="rwx",
                        sticky=True,
                        setuid=True,
                        setguid=True)
        self.assertIn("sticky", p)
        self.assertIn("setuid", p)
        self.assertIn("setguid", p)

        p = Permissions(mode=0o421)
        self.assertIn("u_r", p)
        self.assertIn("g_w", p)
        self.assertIn("o_x", p)
        self.assertNotIn("u_w", p)
        self.assertNotIn("g_x", p)
        self.assertNotIn("o_r", p)
        self.assertNotIn("sticky", p)
        self.assertNotIn("setuid", p)
        self.assertNotIn("setguid", p)
Beispiel #3
0
    def test_constructor(self):
        p = Permissions(names=['foo', 'bar'])
        self.assertIn('foo', p)
        self.assertIn('bar', p)
        self.assertNotIn('baz', p)

        p = Permissions(user='******', group='w', other='x')
        self.assertIn('u_r', p)
        self.assertIn('g_w', p)
        self.assertIn('o_x', p)
        self.assertNotIn('sticky', p)
        self.assertNotIn('setuid', p)
        self.assertNotIn('setguid', p)

        p = Permissions(user='******',
                        group='rwx',
                        other='rwx',
                        sticky=True,
                        setuid=True,
                        setguid=True)
        self.assertIn('sticky', p)
        self.assertIn('setuid', p)
        self.assertIn('setguid', p)

        p = Permissions(mode=0o421)
        self.assertIn('u_r', p)
        self.assertIn('g_w', p)
        self.assertIn('o_x', p)
        self.assertNotIn('u_w', p)
        self.assertNotIn('g_x', p)
        self.assertNotIn('o_r', p)
        self.assertNotIn('sticky', p)
        self.assertNotIn('setuid', p)
        self.assertNotIn('setguid', p)
Beispiel #4
0
    def getinfo(self, path, namespaces=None):
        self.check()
        namespaces = namespaces or ()
        _path = self.validatepath(path)
        _stat = self._fs.getinfo(_path)

        info = {
            "basic": {"name": basename(_path), "is_dir": stat.S_ISDIR(_stat["st_mode"])}
        }

        if "details" in namespaces:
            info["details"] = {
                "_write": ["accessed", "modified"],
                "accessed": _stat["st_atime"],
                "modified": _stat["st_mtime"],
                "size": _stat["st_size"],
                "type": int(
                    self.STAT_TO_RESOURCE_TYPE.get(
                        stat.S_IFMT(_stat["st_mode"]), ResourceType.unknown
                    )
                ),
            }
        if "stat" in namespaces:
            info["stat"] = _stat

        if "access" in namespaces:
            info["access"] = {
                "permissions": Permissions(mode=_stat["st_mode"]).dump(),
                "uid": 1000,  # TODO: fix
                "gid": 100,  # TODO: fix
            }

        return Info(info)
Beispiel #5
0
 def chmod(self, path: str, mode: oct, recursive: bool = False) -> None:
     """Change file/directory mode.
     :param path: Path to be modified.
     :param mode: Operating-system mode bitfield. Must be in octal's form.
     Eg: chmod with (mode=0o755) = Permissions(user='******', group='rx', other='rx')
     :param recursive: If the path is directory, setting recursive to true would change permissions to sub folders
     and contained files.
     :type recursive: bool
     """
     assert isinstance(mode, str) or isinstance(mode, int)
     if isinstance(mode, str):
         # convert mode to octal
         mode = int(mode, 8)
     chmod_cache_info = {
         "access": {
             "permissions": Permissions.create(mode)
         }
     }
     if self.isdir(path) and recursive:
         if path is not "/":
             self.setinfo(path, chmod_cache_info)
         # create a walker
         sub_dir = self.opendir(path)
         for _path, _ in sub_dir.walk.info():
             self.setinfo(path + _path, chmod_cache_info)
         sub_dir.close()
     else:
         self.setinfo(path, chmod_cache_info)
Beispiel #6
0
 def makedir(self,
             path,               # type: Text
             permissions=None,   # type: Optional[int]
             recreate=True       # type: bool
             ):
     # make a directory in the file system. Also, update the cache about the directory.
     _path = self.norm_path(path)
     # we always want to overwrite a directory if it already exists.
     recreate = True if recreate is False else recreate
     perms = permissions
     fs_err = None
     try:
         super(AbstractFS, self).makedir(_path, permissions=None, recreate=recreate)
     except fs.errors.FSError as err:
         fs_err = err
     finally:
         if not fs_err:
             dir_perms = perms if perms else self.default_perms
             dir_cache = {
                 'access': {
                     'permissions': Permissions.create(dir_perms),
                     'uid': self.default_uid,
                     'gid': self.default_gid
                 }
             }
             logger.debug('Created directory {}'.format(_path))
             self.setinfo(_path, info=dir_cache)
         else:
             raise fs_err
Beispiel #7
0
 def chmod(self, path: str, mode: oct, recursive: bool = False) -> None:
     """Change file/directory mode.
     :param path: Path to be modified.
     :param mode: Operating-system mode bitfield. Must be in octal's form.
     Eg: chmod with (mode=0o755) = Permissions(user='******', group='rx', other='rx')
     :param recursive: If the path is directory, setting recursive to true would change permissions to sub folders
     and contained files.
     :type recursive: bool
     """
     assert (isinstance(mode, str) or isinstance(mode, int))
     if isinstance(mode, str):
         # convert mode to octal
         mode = int(mode, 8)
     chmod_cache_info = {
                 'access': {
                     'permissions': Permissions.create(mode)
                 }
             }
     if self.isdir(path) and recursive:
         if path is not '/':
             self.setinfo(path, chmod_cache_info)
         # create a walker
         sub_dir = self.opendir(path)
         for _path, _ in sub_dir.walk.info():
             self.setinfo(path + _path, chmod_cache_info)
         sub_dir.close()
     else:
         self.setinfo(path, chmod_cache_info)
Beispiel #8
0
 def makedir(
         self,
         path,  # type: Text
         permissions=None,  # type: Optional[int]
         recreate=True,  # type: bool
 ):
     # make a directory in the file system. Also, update the cache about the directory.
     _path = self.norm_path(path)
     # we always want to overwrite a directory if it already exists.
     recreate = True if recreate is False else recreate
     perms = permissions
     fs_err = None
     try:
         super(AbstractFS, self).makedir(_path,
                                         permissions=None,
                                         recreate=recreate)
     except fs.errors.FSError as err:
         fs_err = err
     finally:
         if not fs_err:
             dir_perms = perms if perms else self.default_perms
             dir_cache = {
                 "access": {
                     "permissions": Permissions.create(dir_perms),
                     "uid": self.default_uid,
                     "gid": self.default_gid,
                 }
             }
             logger.debug("Created directory {}".format(_path))
             self.setinfo(_path, info=dir_cache)
         else:
             raise fs_err
Beispiel #9
0
    def makedir(self, path, permissions=None, recreate=False):
        """
        Create a directory under `path`.

        :param str path: Path pointing to a file.
        :param Permissions permissions: PyFilesystem permission instance
        :param bool recreate: Not supported
        """
        # type: (Text, Permissions, bool) -> SubFS

        path = ensureUnicode(path)
        self.check()
        _path = toAscii(self.validatepath(path))

        if not self.isdir(dirname(_path)):
            raise errors.ResourceNotFound(path)

        if permissions is None:
            permissions = Permissions(user='******', group='r-x', other='r-x')

        try:
            self.getinfo(path)
        except errors.ResourceNotFound:
            self._odfs.mkdir(_path, permissions.mode)

        return SubFS(self, path)
 def test_create(self):
     self.assertEqual(Permissions.create(None).mode, 0o777)
     self.assertEqual(Permissions.create(0o755).mode, 0o755)
     self.assertEqual(Permissions.create(["u_r", "u_w", "u_x"]).mode, 0o700)
     self.assertEqual(Permissions.create(Permissions(user="******")).mode, 0o700)
     with self.assertRaises(ValueError):
         Permissions.create("foo")
Beispiel #11
0
 def test_check(self):
     p = Permissions(user='******')
     self.assertTrue(p.check('u_r'))
     self.assertTrue(p.check('u_r', 'u_w'))
     self.assertTrue(p.check('u_r', 'u_w', 'u_x'))
     self.assertFalse(p.check('u_r', 'g_w'))
     self.assertFalse(p.check('g_r', 'g_w'))
     self.assertFalse(p.check('foo'))
Beispiel #12
0
 def test_create(self):
     self.assertEqual(Permissions.create(None).mode, 0o777)
     self.assertEqual(Permissions.create(0o755).mode, 0o755)
     self.assertEqual(Permissions.create(['u_r', 'u_w', 'u_x']).mode, 0o700)
     self.assertEqual(
         Permissions.create(Permissions(user='******')).mode, 0o700)
     with self.assertRaises(ValueError):
         Permissions.create('foo')
 def test_check(self):
     p = Permissions(user="******")
     self.assertTrue(p.check("u_r"))
     self.assertTrue(p.check("u_r", "u_w"))
     self.assertTrue(p.check("u_r", "u_w", "u_x"))
     self.assertFalse(p.check("u_r", "g_w"))
     self.assertFalse(p.check("g_r", "g_w"))
     self.assertFalse(p.check("foo"))
    def format_list(self, basedir, listing):
        """
        Return an iterator object that yields the entries of given directory emulating the "/bin/ls -lA" UNIX command
        output.
        This is how output should appear:
        -rw-rw-rw-   1 owner   group    7045120 Sep 02  3:47 music.mp3
        drwxrwxrwx   1 owner   group          0 Aug 31 18:50 e-books
        -rw-rw-rw-   1 owner   group        380 Sep 02  3:40 module.py

        :param basedir: (str) must be protocol relative path
        :param listing: (list) list of files to needed for output.
        """
        assert isinstance(basedir, str), basedir
        basedir += '/' if basedir[-1:] != '/' else basedir
        now = time.time()
        for basename in listing:
            file = self.norm_path(
                basedir +
                basename)  # for e.g. basedir = '/' and basename = test.png.
            # So file is '/test.png'
            try:
                st = self.stat(file)
            except (fs.errors.FSError, FilesystemError):
                raise
            permission = filemode(Permissions.create(st['st_mode']).mode)
            if self.isdir(file):
                permission = permission.replace('?', 'd')
            elif self.isfile(file):
                permission = permission.replace('?', '-')
            elif self.islink(file):
                permission = permission.replace('?', 'l')
            nlinks = st['st_nlink']
            size = st['st_size']  # file-size
            uname = self.getinfo(path=file, namespaces=['access']).user
            # |-> pwd.getpwuid(st['st_uid']).pw_name would fetch the user_name of the actual owner of these files.
            gname = self.getinfo(path=file, namespaces=['access']).group
            # |-> grp.getgrgid(st['st_gid']).gr_name would fetch the user_name of the actual of these files.
            mtime = time.gmtime(
                fs.time.datetime_to_epoch(
                    self.getinfo(file, namespaces=['details']).modified))
            if (now - st['st_mtime']) > (180 * 24 * 60 * 60):
                fmtstr = "%d  %Y"
            else:
                fmtstr = "%d %H:%M"
            mtimestr = "%s %s" % (months_map[mtime.tm_mon],
                                  time.strftime(fmtstr, mtime))
            if (st['st_mode'] & 61440) == stat.S_IFLNK:
                # if the file is a symlink, resolve it, e.g.  "symlink -> realfile"
                basename = basename + " -> " + self.readlink(file)
                # formatting is matched with proftpd ls output
            line = "%s %3s %-8s %-8s %8s %s %s\r\n" % (
                permission, nlinks, uname, gname, size, mtimestr, basename)
            yield line
Beispiel #15
0
 def getinfo(self, path: str, get_actual: bool = False, namespaces=None):
     if get_actual or (not self.built_cache):
         return self._wrap_fs.getinfo(path, namespaces)
     else:
         try:
             # ensure that the path starts with '/'
             if path[0] != "/":
                 path = "/" + path
             info = {"basic": self._cache[path].raw["basic"]}
             if namespaces is not None:
                 if "details" in namespaces:
                     info["details"] = self._cache[path].raw["details"]
                 if "stat" in namespaces:
                     stat_cache = {
                         "st_uid":
                         self._cache[path].raw["access"]["uid"],
                         "st_gid":
                         self._cache[path].raw["access"]["gid"],
                         "st_atime":
                         self._cache[path].raw["details"]["accessed"],
                         "st_mtime":
                         self._cache[path].raw["details"]["modified"],
                         # TODO: Fix these to appropriate values
                         "st_mtime_ns":
                         None,
                         "st_ctime_ns":
                         None,
                         "st_ctime":
                         None,
                     }
                     if isinstance(
                             self._cache[path].raw["access"]["permissions"],
                             list):
                         stat_cache["st_mode"] = Permissions(
                             self._cache[path].raw["access"]
                             ["permissions"]).mode
                     else:
                         stat_cache["st_mode"] = (
                             self._cache[path].raw["access"]
                             ["permissions"].mode)
                     self._cache[path].raw["stat"].update(stat_cache)
                     info["stat"] = self._cache[path].raw["stat"]
                     # Note that we won't be keeping tabs on 'lstat'
                 if "lstat" in namespaces:
                     info["lstat"] = self._cache[path].raw["lstat"]
                     info["lstat"] = self._cache[path].raw["lstat"]
                 if "link" in namespaces:
                     info["link"] = self._cache[path].raw["link"]
                 if "access" in namespaces:
                     info["access"] = self._cache[path].raw["access"]
             return Info(info)
         except KeyError:
             raise FilesystemError
 def getinfo(self, path: str, get_actual: bool = False, namespaces=None):
     if get_actual or (not self.built_cache):
         return self._wrap_fs.getinfo(path, namespaces)
     else:
         try:
             # ensure that the path starts with '/'
             if path[0] != '/':
                 path = '/' + path
             info = {'basic': self._cache[path].raw['basic']}
             if namespaces is not None:
                 if 'details' in namespaces:
                     info['details'] = self._cache[path].raw['details']
                 if 'stat' in namespaces:
                     stat_cache = {
                         'st_uid':
                         self._cache[path].raw['access']['uid'],
                         'st_gid':
                         self._cache[path].raw['access']['gid'],
                         'st_atime':
                         self._cache[path].raw['details']['accessed'],
                         'st_mtime':
                         self._cache[path].raw['details']['modified'],
                         # TODO: Fix these to appropriate values
                         'st_mtime_ns':
                         None,
                         'st_ctime_ns':
                         None,
                         'st_ctime':
                         None,
                     }
                     if isinstance(
                             self._cache[path].raw['access']['permissions'],
                             list):
                         stat_cache['st_mode'] = Permissions(
                             self._cache[path].raw['access']
                             ['permissions']).mode
                     else:
                         stat_cache['st_mode'] = self._cache[path].raw[
                             'access']['permissions'].mode
                     self._cache[path].raw['stat'].update(stat_cache)
                     info['stat'] = self._cache[path].raw['stat']
                     # Note that we won't be keeping tabs on 'lstat'
                 if 'lstat' in namespaces:
                     info['lstat'] = self._cache[path].raw['lstat']
                     info['lstat'] = self._cache[path].raw['lstat']
                 if 'link' in namespaces:
                     info['link'] = self._cache[path].raw['link']
                 if 'access' in namespaces:
                     info['access'] = self._cache[path].raw['access']
             return Info(info)
         except KeyError:
             raise FilesystemError
    def test_properties(self):
        p = Permissions()
        self.assertFalse(p.u_r)
        self.assertNotIn("u_r", p)
        p.u_r = True
        self.assertIn("u_r", p)
        self.assertTrue(p.u_r)
        p.u_r = False
        self.assertNotIn("u_r", p)
        self.assertFalse(p.u_r)

        self.assertFalse(p.u_w)
        p.add("u_w")
        self.assertTrue(p.u_w)
        p.remove("u_w")
        self.assertFalse(p.u_w)
 def test_repr(self):
     self.assertEqual(repr(Permissions()),
                      "Permissions(user='', group='', other='')")
     self.assertEqual(repr(Permissions(names=["foo"])),
                      "Permissions(names=['foo'])")
     repr(Permissions(user="******", group="rw", other="r"))
     repr(Permissions(user="******", group="rw", other="r", sticky=True))
     repr(Permissions(user="******", group="rw", other="r", setuid=True))
     repr(Permissions(user="******", group="rw", other="r", setguid=True))
Beispiel #19
0
    def makedir(self, path, permissions=None, recreate=False):  # noqa: D102
        self.check()
        _permissions = permissions or Permissions(mode=0o755)
        _path = self.validatepath(path)

        try:
            info = self.getinfo(_path)
        except errors.ResourceNotFound:
            with self._lock:
                with convert_sshfs_errors('makedir', path):
                    self._sftp.mkdir(_path, _permissions.mode)
        else:
            if (info.is_dir and not recreate) or info.is_file:
                six.raise_from(errors.DirectoryExists(path), None)

        return self.opendir(path)
Beispiel #20
0
 def test_access(self):
     info = Info({
         "access": {
             "uid": 10,
             "gid": 12,
             "user": "******",
             "group": "devs",
             "permissions": ["u_r"],
         }
     })
     self.assertIsInstance(info.permissions, Permissions)
     self.assertEqual(info.permissions, Permissions(user="******"))
     self.assertEqual(info.user, "will")
     self.assertEqual(info.group, "devs")
     self.assertEqual(info.uid, 10)
     self.assertEqual(info.gid, 12)
Beispiel #21
0
 def test_access(self):
     info = Info({
         "access": {
             "uid": 10,
             "gid": 12,
             "user": '******',
             "group": 'devs',
             "permissions": ['u_r']
         }
     })
     self.assertIsInstance(info.permissions, Permissions)
     self.assertEqual(info.permissions, Permissions(user='******'))
     self.assertEqual(info.user, 'will')
     self.assertEqual(info.group, 'devs')
     self.assertEqual(info.uid, 10)
     self.assertEqual(info.gid, 12)
Beispiel #22
0
    def format_list(self, basedir, listing):
        """
        Return an iterator object that yields the entries of given directory emulating the "/bin/ls -lA" UNIX command
        output.
        This is how output should appear:
        -rw-rw-rw-   1 owner   group    7045120 Sep 02  3:47 music.mp3
        drwxrwxrwx   1 owner   group          0 Aug 31 18:50 e-books
        -rw-rw-rw-   1 owner   group        380 Sep 02  3:40 module.py

        :param basedir: (str) must be protocol relative path
        :param listing: (list) list of files to needed for output.
        """
        assert isinstance(basedir, str), basedir
        basedir += '/' if basedir[-1:] != '/' else basedir
        now = time.time()
        for basename in listing:
            file = self.norm_path(basedir + basename)  # for e.g. basedir = '/' and basename = test.png.
            # So file is '/test.png'
            try:
                st = self.stat(file)
            except (fs.errors.FSError, FilesystemError):
                raise
            permission = filemode(Permissions.create(st['st_mode']).mode)
            if self.isdir(file):
                permission = permission.replace('?', 'd')
            elif self.isfile(file):
                permission = permission.replace('?', '-')
            elif self.islink(file):
                permission = permission.replace('?', 'l')
            nlinks = st['st_nlink']
            size = st['st_size']  # file-size
            uname = self.getinfo(path=file, namespaces=['access']).user
            # |-> pwd.getpwuid(st['st_uid']).pw_name would fetch the user_name of the actual owner of these files.
            gname = self.getinfo(path=file, namespaces=['access']).group
            # |-> grp.getgrgid(st['st_gid']).gr_name would fetch the user_name of the actual of these files.
            mtime = time.gmtime(fs.time.datetime_to_epoch(self.getinfo(file, namespaces=['details']).modified))
            if (now - st['st_mtime']) > (180 * 24 * 60 * 60):
                fmtstr = "%d  %Y"
            else:
                fmtstr = "%d %H:%M"
            mtimestr = "%s %s" % (months_map[mtime.tm_mon], time.strftime(fmtstr, mtime))
            if (st['st_mode'] & 61440) == stat.S_IFLNK:
                # if the file is a symlink, resolve it, e.g.  "symlink -> realfile"
                basename = basename + " -> " + self.readlink(file)
                # formatting is matched with proftpd ls output
            line = "%s %3s %-8s %-8s %8s %s %s\r\n" % (permission, nlinks, uname, gname, size, mtimestr, basename)
            yield line
Beispiel #23
0
 def test_repr(self):
     self.assertEqual(
         repr(Permissions()),
         "Permissions(user='', group='', other='')",
     )
     self.assertEqual(repr(Permissions(names=['foo'])),
                      "Permissions(names=['foo'])")
     repr(Permissions(user='******', group='rw', other='r'))
     repr(Permissions(user='******', group='rw', other='r', sticky=True))
     repr(Permissions(user='******', group='rw', other='r', setuid=True))
     repr(Permissions(user='******', group='rw', other='r', setguid=True))
Beispiel #24
0
    def _make_access_from_stat(self, stat_result):
        """Make an *access* dictionnary from a stat result.
        """
        access = {}
        access['permissions'] = Permissions(mode=stat_result.st_mode).dump()
        access['gid'] = stat_result.st_gid
        access['uid'] = stat_result.st_uid

        if self.platform in ("linux", "darwin", "freebsd"):

            def entry_name(db, _id):
                entry = self._exec_command('getent {} {}'.format(db, _id))
                name = next(iter(entry.split(b':')))
                return name.decode(self.locale or 'utf-8')

            access['group'] = entry_name('group', access['gid'])
            access['user'] = entry_name('passwd', access['uid'])

        return access
Beispiel #25
0
def statToPermissions(attr):
    """
    Convert PyFilesystem Info instance `attr` to permissions
    string.

    :param Info attr: The PyFilesystem Info instance.
    """

    # 'other' permissions
    other = ''
    other += 'r' if stat.S_IROTH & attr.mode else '-'
    other += 'w' if stat.S_IWOTH & attr.mode else '-'
    other += 'x' if stat.S_IXOTH & attr.mode else '-'

    # 'group' permission
    group = ''
    group += 'r' if stat.S_IRGRP & attr.mode else '-'
    group += 'w' if stat.S_IWGRP & attr.mode else '-'
    group += 'x' if stat.S_IXGRP & attr.mode else '-'

    # 'user' permission
    user = ''
    user += 'r' if stat.S_IRUSR & attr.mode else '-'
    user += 'w' if stat.S_IWUSR & attr.mode else '-'
    user += 'x' if stat.S_IXUSR & attr.mode else '-'

    sticky = stat.S_ISVTX & attr.mode
    setuid = stat.S_ISUID & attr.mode
    setguid = stat.S_ISGID & attr.mode

    return Permissions(user=user,
                       group=group,
                       other=other,
                       sticky=sticky,
                       setuid=setuid,
                       setguid=setguid)
 def test_copy(self):
     p = Permissions(mode=0o700)
     p_copy = p.copy()
     self.assertIsNot(p, p_copy)
     self.assertEqual(p, p_copy)
 def test_mode(self):
     p = Permissions(user="******", group="rw", other="")
     self.assertEqual(p.mode, 0o760)
 def test_as_str(self):
     p = Permissions(user="******", group="rwx", other="rwx")
     self.assertEqual(p.as_str(), "rwxrwxrwx")
     self.assertEqual(str(p), "rwxrwxrwx")
     p = Permissions(mode=0o777, setuid=True, setguid=True, sticky=True)
     self.assertEqual(p.as_str(), "rwsrwsrwt")
 def test_make_mode(self):
     self.assertEqual(make_mode(None), 0o777)
     self.assertEqual(make_mode(0o755), 0o755)
     self.assertEqual(make_mode(["u_r", "u_w", "u_x"]), 0o700)
     self.assertEqual(make_mode(Permissions(user="******")), 0o700)
 def test_iter(self):
     iter_p = iter(Permissions(names=["foo"]))
     self.assertEqual(list(iter_p), ["foo"])
    def test_equality(self):
        self.assertEqual(Permissions(mode=0o700), Permissions(user="******"))
        self.assertNotEqual(Permissions(mode=0o500), Permissions(user="******"))

        self.assertEqual(Permissions(mode=0o700), ["u_r", "u_w", "u_x"])
 def test_parse(self):
     self.assertEqual(Permissions.parse("---------").mode, 0)
     self.assertEqual(Permissions.parse("rwxrw-r--").mode, 0o764)
 def test_mode_set(self):
     p = Permissions(user="******")
     self.assertEqual(text_type(p), "r--------")
     p.mode = 0o700
     self.assertEqual(text_type(p), "rwx------")