Пример #1
0
class VaultFileKey(os.PathLike):
    """ HGI vault file key properties """
    # NOTE This is implemented in a separate class to keep that part of
    # the logic outside VaultFile and to decouple it from the filesystem
    _delimiter: T.ClassVar[str] = "-"

    _prefix: T.Optional[T.Path]  # inode prefix path, without the LSB
    _suffix: str  # LSB and encoded basename suffix name

    def __init__(self,
                 path: T.Path,
                 inode: T.Optional[int] = None,
                 max_file_name_length: int = _default_max_name_length) -> None:
        """
        Construct the key from a path and (optional) inode

        @param   path           Path to construct from
        @param   inode          inode ID to construct from (defaults to inode
                                    of path)
        @param   max_file_name  The maximum length of a filename. Defaults to
                                    current directory, however can be passed
                                    in for each path being added to the Vault
        """
        # Use the path's inode, if one is not explicitly provided
        if inode is None:
            inode = file.inode_id(path)

        # The byte-padded hexadecimal representation of the inode ID
        if len(inode_hex := f"{inode:x}") % 2:
            inode_hex = f"0{inode_hex}"

        # Chunk the inode ID into 8-bit segments
        chunks = [inode_hex[i:i + 2] for i in range(0, len(inode_hex), 2)]

        # inode ID, without the least significant byte, if it exists
        self._prefix = None
        if len(chunks) > 1:
            self._prefix = T.Path(*chunks[:-1])

        # inode ID LSB, delimiter, and the base64 encoding of the path.
        # If the relative file path is too long, we split it by max file name length
        # and save each part as a directory until we get to a final file
        encoded_path = base64.encode(path)
        max_file_name_length -= 3
        self._suffix = chunks[-1] + self._delimiter + str(
            T.Path(*[
                encoded_path[i:i + max_file_name_length]
                for i in range(0, len(encoded_path), max_file_name_length)
            ]))
Пример #2
0
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along
with this program. If not, see https://www.gnu.org/licenses/
"""

import unittest

from core import typing as T
from core.utils import base64
from .utils import VFK, VFK_k


_DUMMY = T.Path("foo/bar/quux")
_B64_DUMMY = base64.encode(_DUMMY)

_DUMMY_LONG = T.Path('this/path/is/going/to/be/much/much/much/much/much/much/'
                     'much/much/much/much/much/much/much/much/much/much/much/much/much/much/much'
                     '/much/much/much/much/much/much/much/much/much/much/much/much/much/much/'
                     'much/much/much/much/much/much/much/much/much/longer/than/two/hundred/and/'
                     'fifty/five/characters')
_B64_DUMMY_LONG = base64.encode(_DUMMY_LONG)
# Assuming test is run on a filesystem (such as Linux) where NAME_MAX = 255.
# If NAME_MAX != 255, these tests for long and really long relative paths
# would fail.
_B64_DUMMY_LONG_FIRST_PART = _B64_DUMMY_LONG[0:252]
_B64_DUMMY_LONG_SECOND_PART = _B64_DUMMY_LONG[252:]

_DUMMY_LONGEST = T.Path('this/path/is/going/to/be/much/much/much/much/much/much'
                        '/much/much/much/much/much/much/much/much/much/much/much/much/much/much/'
Пример #3
0
    def test_altchars(self):
        self.assertEqual(base64.encode(b"\xfa"), "+g==")
        self.assertEqual(base64.encode(b"\xff"), "_w==")

        self.assertEqual(base64.decode("+g=="), b"\xfa")
        self.assertEqual(base64.decode("_w=="), b"\xff")
Пример #4
0
 def test_encode(self):
     self.assertEqual(base64.encode("foo"), "Zm9v")
     self.assertEqual(base64.encode(b"foo"), "Zm9v")
     self.assertEqual(base64.encode(_DUMMY("foo")), "Zm9v")
Пример #5
0
    def _base64_prefix(path: T.Path) -> str:
        # Find the common base64 prefix of a path to optimise searching
        bare = base64.encode(path)
        slashed = base64.encode(f"{path}/")

        return commonprefix([bare, slashed])