File: test_base.py

package info (click to toggle)
python-django 3%3A3.2.19-1%2Bdeb12u2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 56,696 kB
  • sloc: python: 264,418; javascript: 18,362; xml: 193; makefile: 178; sh: 43
file content (72 lines) | stat: -rw-r--r-- 2,799 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import os
from unittest import mock

from django.core.exceptions import SuspiciousFileOperation
from django.core.files.storage import Storage
from django.test import SimpleTestCase


class CustomStorage(Storage):
    """Simple Storage subclass implementing the bare minimum for testing."""

    def exists(self, name):
        return False

    def _save(self, name):
        return name


class StorageValidateFileNameTests(SimpleTestCase):

    invalid_file_names = [
        os.path.join("path", "to", os.pardir, "test.file"),
        os.path.join(os.path.sep, "path", "to", "test.file"),
    ]
    error_msg = "Detected path traversal attempt in '%s'"

    def test_validate_before_get_available_name(self):
        s = CustomStorage()
        # The initial name passed to `save` is not valid nor safe, fail early.
        for name in self.invalid_file_names:
            with (
                self.subTest(name=name),
                mock.patch.object(s, "get_available_name") as mock_get_available_name,
                mock.patch.object(s, "_save") as mock_internal_save,
            ):
                with self.assertRaisesMessage(
                    SuspiciousFileOperation, self.error_msg % name
                ):
                    s.save(name, content="irrelevant")
                self.assertEqual(mock_get_available_name.mock_calls, [])
                self.assertEqual(mock_internal_save.mock_calls, [])

    def test_validate_after_get_available_name(self):
        s = CustomStorage()
        # The initial name passed to `save` is valid and safe, but the returned
        # name from `get_available_name` is not.
        for name in self.invalid_file_names:
            with (
                self.subTest(name=name),
                mock.patch.object(s, "get_available_name", return_value=name),
                mock.patch.object(s, "_save") as mock_internal_save,
            ):
                with self.assertRaisesMessage(
                    SuspiciousFileOperation, self.error_msg % name
                ):
                    s.save("valid-file-name.txt", content="irrelevant")
                self.assertEqual(mock_internal_save.mock_calls, [])

    def test_validate_after_internal_save(self):
        s = CustomStorage()
        # The initial name passed to `save` is valid and safe, but the result
        # from `_save` is not (this is achieved by monkeypatching _save).
        for name in self.invalid_file_names:
            with (
                self.subTest(name=name),
                mock.patch.object(s, "_save", return_value=name),
            ):

                with self.assertRaisesMessage(
                    SuspiciousFileOperation, self.error_msg % name
                ):
                    s.save("valid-file-name.txt", content="irrelevant")