Ejemplo n.º 1
0
 def __getattribute__(self, attr):
     # Restrict access to methods that are implemented in AbstractFS class - Calling methods from base class may
     # not be safe to use.
     # FIXME: Need to fix these for only allow methods that are defined here.
     if not WrapFS:
         return
     method_list = [
         x for x, y in WrapFS.__dict__.items() if type(y) == FunctionType
     ]
     if attr in method_list:
         if attr in super(AbstractFS, self).__getattribute__(
                 "__dict__").keys() or attr not in ["match", "settext"]:
             # These methods have been overwritten and are safe to use.
             try:
                 return super(AbstractFS, self).__getattribute__(attr)
             except KeyError as ke:
                 raise FilesystemError("Invalid Path : {}".format(ke))
         else:
             raise NotImplementedError(
                 "The method requested is not supported by Conpot's VFS")
     else:
         try:
             return super(AbstractFS, self).__getattribute__(attr)
         except KeyError as ke:
             raise FilesystemError("Invalid Path : {}".format(ke))
Ejemplo n.º 2
0
 def getfile(self, path, file, chunk_size=None, **options):
     # check where there exists a copy in the cache
     if (self.exists(self.norm_path(path))
             and self.norm_path(path) in self._cache.keys()):
         self.setinfo(self.norm_path(path), {})
         return self._wrap_fs.getfile(self.norm_path(path), file,
                                      chunk_size, **options)
     else:
         raise FilesystemError("Can't get. File does not exist!")
Ejemplo n.º 3
0
 def norm_path(self, path):
     path = "/" if path == "." else path
     try:
         _path = (self.validatepath(self._cwd + path)
                  if self._cwd not in path else self.validatepath(path))
         return _path
     except fs.errors.FSError:
         logger.debug("Could not validate path: {}".format(path))
         raise FilesystemError("Could not validate path: {}".format(path))
Ejemplo n.º 4
0
 def register_user(self, name: str, uid: int) -> None:
     """Store all user related data for the file system."""
     assert name and isinstance(name, str)
     self._users[uid] = {"user": name}
     # let us check for duplicate usernames/group names
     if len(set([v["user"] for k, v in self._users.items()])) != len(
             self._users.keys()):
         _uname = self._users.pop(uid)["user"]
         raise FilesystemError(
             "Can't add users with duplicate uname: {}.".format(_uname))
Ejemplo n.º 5
0
 def norm_path(self, path):
     path = '/' if path == '.' else path
     try:
         _path = self.validatepath(
             self._cwd +
             path) if self._cwd not in path else self.validatepath(path)
         return _path
     except fs.errors.FSError:
         logger.debug('Could not validate path: {}'.format(path))
         raise FilesystemError('Could not validate path: {}'.format(path))
Ejemplo n.º 6
0
 def create_group(self, name: str, gid: int) -> None:
     """
     Store all group related data for the file system.
     :param name: Name of the group
     :param gid: gid of the group
     """
     assert name and isinstance(name, str)
     self._grps[gid] = {"group": name}
     if len(set([v["group"] for k, v in self._grps.items()])) != len(
             self._grps.keys()):
         _gname = self._grps.pop(gid)
         raise FilesystemError(
             "Can't create groups with duplicate names: {}.".format(_gname))
Ejemplo n.º 7
0
    def chown(self,
              fs_path: str,
              uid: int,
              gid: int,
              recursive: Optional[bool] = False) -> None:
        """Change the owner of a specified file. Wrapper for os.chown
        :param fs_path: path or directory in the VFS where chown would be executed.
        :param uid: The `uid` of the user. **User must be a registered user on the filesystem or an exception would be
        thrown.
        :param gid: The `gid` of the group **Group must be a registered group on the filesystem or an exception would be
        thrown.
        :param recursive: If the given path is directory, then setting the recursive option to true would walk down the
        tree and recursive change permissions in the cache.

        ** `fs_path` needs to be the absolute path w.r.t to the vfs. If you are in a sub file system, please use
        `subvfs.getcwd()` to get the current directory. **
        """
        path = self.norm_path(fs_path)
        try:
            assert isinstance(uid, int) and isinstance(gid, int)
        except AssertionError:
            logger.exception("Integers expected got {} - {}".format(uid, gid))
        if self.isdir(path) or self.isfile(path):
            assert self._grps[gid] and self._users[uid]
            chown_cache = {
                "access": {
                    "user": self._users[uid]["user"],
                    "uid": self._users[uid],
                    "group": self._grps[gid]["group"],
                    "gid": self._grps[gid],
                }
            }
            if self.isdir(path) and recursive:
                if self.norm_path(path) is not "/":
                    self.setinfo(path, chown_cache)
                sub_dir = self.opendir(path)
                for _path, _ in sub_dir.walk.info():
                    assert self._cache[self.norm_path(path + _path)]
                    self.setinfo(path + _path, chown_cache)
                sub_dir.close()
            else:
                self.setinfo(path, chown_cache)

        else:
            # TODO: map this to the actual output of os.chown
            raise FilesystemError("File not found for chown")
Ejemplo n.º 8
0
 def add_users_to_group(self, gid: int, uids: List) -> None:
     """Add list of users to an existing group
     :param gid: Group id of the group.
     :param uids: List of registers users that belong to this group
     """
     try:
         assert gid in self._grps.keys()
         for i in uids:
             if i not in self._users.keys():
                 raise AssertionError
         _uids = set(uids)
         if gid in self._user_grps.keys():
             self._user_grps[gid] += _uids
         else:
             self._user_grps[gid] = _uids
     except AssertionError:
         raise FilesystemError(
             "uid/gid does not exist in the file system. Please register it via create_group/"
             "register_user method.")
Ejemplo n.º 9
0
 def setinfo(self, path, info):
     """
     Higher level function to directly change values in the file system. Dictionary specified here changes cache
     values.
     :param path: path of the file that is to be changed
     :param info: Raw Info object. Please check pyfilesystem2's docs for more info.
     """
     assert path and isinstance(path, str)
     path = self.norm_path(path)
     if "lstat" not in info:
         try:
             if "details" in info:
                 details = info["details"]
                 if "accessed" in details or "modified" in details:
                     return self._wrap_fs.setinfo(path, info)
         finally:
             try:
                 assert self._cache[path]
             except (AssertionError, KeyError):
                 # This is the first time we have seen this file. Let us create this entry.
                 logger.debug(
                     "Creating cache for file/directory : {}".format(path))
                 self._cache[path] = self._wrap_fs.getinfo(path,
                                                           namespaces=[
                                                               "basic",
                                                               "access",
                                                               "details",
                                                               "stat",
                                                               "link"
                                                           ])
             # update the 'accessed' and 'modified' time.
             self.settimes(path)
             if "access" in info:
                 access = info["access"]
                 if "permissions" in access:
                     self._cache[path].raw["access"][
                         "permissions"] = access["permissions"]
                     self._cache[path].raw["details"][
                         "metadata_changed"] = fs.time.datetime_to_epoch(
                             datetime.now())
                 if "user" in access or "uid" in access:
                     try:
                         if "user" in access or ("user" in access
                                                 and "uid" in access):
                             self._cache[path].raw["access"][
                                 "user"] = access["user"]
                             [_uid] = [
                                 key for key, value in self._users.items()
                                 if value == {
                                     "user": access["user"]
                                 }
                             ]
                             self._cache[path].raw["access"]["uid"] = _uid
                             self._cache[path].raw["details"][
                                 "metadata_changed"] = fs.time.datetime_to_epoch(
                                     datetime.now())
                         else:
                             # Must be 'uid' that is available.
                             _uid = int(access["uid"])  # type: ignore
                             self._cache[path].raw["access"]["uid"] = _uid
                             self._cache[path].raw["access"][
                                 "user"] = self._users[_uid]["user"]
                             self._cache[path].raw["details"][
                                 "metadata_changed"] = fs.time.datetime_to_epoch(
                                     datetime.now())
                     except (TypeError, AssertionError, KeyError):
                         raise
                 if "group" in access or "gid" in access:
                     try:
                         if "group" in access or ("group" in access
                                                  and "gid" in access):
                             self._cache[path].raw["access"][
                                 "group"] = access["group"]
                             [_gid] = [
                                 key for key, value in self._grps.items()
                                 if value == {
                                     "group": access["group"]
                                 }
                             ]
                             self._cache[path].raw["access"]["gid"] = _gid
                             self._cache[path].raw["details"][
                                 "metadata_changed"] = fs.time.datetime_to_epoch(
                                     datetime.now())
                         else:
                             # Must be 'gid' that is available.
                             _gid = int(access["gid"])  # type: ignore
                             self._cache[path].raw["access"]["gid"] = _gid
                             self._cache[path].raw["access"][
                                 "group"] = self._grps[_gid]["group"]
                             self._cache[path].raw["details"][
                                 "metadata_changed"] = fs.time.datetime_to_epoch(
                                     datetime.now())
                     except (TypeError, AssertionError, KeyError):
                         raise
     else:
         raise FilesystemError("lstat is not currently supported!")
Ejemplo n.º 10
0
 def setinfo(self, path, info):
     """
     Higher level function to directly change values in the file system. Dictionary specified here changes cache
     values.
     :param path: path of the file that is to be changed
     :param info: Raw Info object. Please check pyfilesystem2's docs for more info.
     """
     assert path and isinstance(path, str)
     path = self.norm_path(path)
     if 'lstat' not in info:
         try:
             if 'details' in info:
                 details = info['details']
                 if 'accessed' in details or 'modified' in details:
                     return self._wrap_fs.setinfo(path, info)
         finally:
             try:
                 assert self._cache[path]
             except (AssertionError, KeyError):
                 # This is the first time we have seen this file. Let us create this entry.
                 logger.debug(
                     'Creating cache for file/directory : {}'.format(path))
                 self._cache[path] = self._wrap_fs.getinfo(path,
                                                           namespaces=[
                                                               'basic',
                                                               'access',
                                                               'details',
                                                               'stat',
                                                               'link'
                                                           ])
             # update the 'accessed' and 'modified' time.
             self.settimes(path)
             if 'access' in info:
                 access = info['access']
                 if 'permissions' in access:
                     self._cache[path].raw['access'][
                         'permissions'] = access['permissions']
                     self._cache[path].raw['details'][
                         'metadata_changed'] = fs.time.datetime_to_epoch(
                             datetime.now())
                 if 'user' in access or 'uid' in access:
                     try:
                         if 'user' in access or ('user' in access
                                                 and 'uid' in access):
                             self._cache[path].raw['access'][
                                 'user'] = access['user']
                             [_uid] = [
                                 key for key, value in self._users.items()
                                 if value == {
                                     'user': access['user']
                                 }
                             ]
                             self._cache[path].raw['access']['uid'] = _uid
                             self._cache[path].raw['details'][
                                 'metadata_changed'] = fs.time.datetime_to_epoch(
                                     datetime.now())
                         else:
                             # Must be 'uid' that is available.
                             _uid = int(access['uid'])  # type: ignore
                             self._cache[path].raw['access']['uid'] = _uid
                             self._cache[path].raw['access'][
                                 'user'] = self._users[_uid]['user']
                             self._cache[path].raw['details'][
                                 'metadata_changed'] = fs.time.datetime_to_epoch(
                                     datetime.now())
                     except (TypeError, AssertionError, KeyError):
                         raise
                 if 'group' in access or 'gid' in access:
                     try:
                         if 'group' in access or ('group' in access
                                                  and 'gid' in access):
                             self._cache[path].raw['access'][
                                 'group'] = access['group']
                             [_gid] = [
                                 key for key, value in self._grps.items()
                                 if value == {
                                     'group': access['group']
                                 }
                             ]
                             self._cache[path].raw['access']['gid'] = _gid
                             self._cache[path].raw['details'][
                                 'metadata_changed'] = fs.time.datetime_to_epoch(
                                     datetime.now())
                         else:
                             # Must be 'gid' that is available.
                             _gid = int(access['gid'])  # type: ignore
                             self._cache[path].raw['access']['gid'] = _gid
                             self._cache[path].raw['access'][
                                 'group'] = self._grps[_gid]['group']
                             self._cache[path].raw['details'][
                                 'metadata_changed'] = fs.time.datetime_to_epoch(
                                     datetime.now())
                     except (TypeError, AssertionError, KeyError):
                         raise
     else:
         raise FilesystemError('lstat is not currently supported!')