xref: /unit/test/test_static_chroot.py (revision 2330:4b1f175f9c88)
1import os
2from pathlib import Path
3
4import pytest
5from unit.applications.proto import TestApplicationProto
6from unit.option import option
7
8
9class TestStaticChroot(TestApplicationProto):
10    prerequisites = {'features': ['chroot']}
11
12    @pytest.fixture(autouse=True)
13    def setup_method_fixture(self, temp_dir):
14        os.makedirs(f'{temp_dir}/assets/dir')
15        Path(f'{temp_dir}/assets/index.html').write_text('0123456789')
16        Path(f'{temp_dir}/assets/dir/file').write_text('blah')
17
18        self.test_path = f'/{os.path.relpath(Path(__file__))}'
19
20        self._load_conf(
21            {
22                "listeners": {"*:7080": {"pass": "routes"}},
23                "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}],
24            }
25        )
26
27    def update_action(self, chroot, share=f'{option.temp_dir}/assets$uri'):
28        return self.conf(
29            {'chroot': chroot, 'share': share},
30            'routes/0/action',
31        )
32
33    def get_custom(self, uri, host):
34        return self.get(url=uri, headers={'Host': host, 'Connection': 'close'})[
35            'status'
36        ]
37
38    def test_static_chroot(self, temp_dir):
39        assert self.get(url='/dir/file')['status'] == 200, 'default chroot'
40        assert self.get(url='/index.html')['status'] == 200, 'default chroot 2'
41
42        assert 'success' in self.update_action(f'{temp_dir}/assets/dir')
43
44        assert self.get(url='/dir/file')['status'] == 200, 'chroot'
45        assert self.get(url='/index.html')['status'] == 403, 'chroot 403 2'
46        assert self.get(url='/file')['status'] == 403, 'chroot 403'
47
48    def test_share_chroot_array(self, temp_dir):
49        assert 'success' in self.update_action(
50            f'{temp_dir}/assets/dir', ["/blah", f'{temp_dir}/assets$uri']
51        )
52        assert self.get(url='/dir/file')['status'] == 200, 'share array'
53
54        assert 'success' in self.update_action(
55            f'{temp_dir}/assets/$host',
56            ['/blah', f'{temp_dir}/assets$uri'],
57        )
58        assert self.get_custom('/dir/file', 'dir') == 200, 'array variable'
59
60        assert 'success' in self.update_action(
61            f'{temp_dir}/assets/dir', ['/blah', '/blah2']
62        )
63        assert self.get()['status'] != 200, 'share array bad'
64
65    def test_static_chroot_permission(self, is_su, temp_dir):
66        if is_su:
67            pytest.skip("does't work under root")
68
69        os.chmod(f'{temp_dir}/assets/dir', 0o100)
70
71        assert 'success' in self.update_action(
72            f'{temp_dir}/assets/dir'
73        ), 'configure chroot'
74
75        assert self.get(url='/dir/file')['status'] == 200, 'chroot'
76
77    def test_static_chroot_empty(self, temp_dir):
78        assert 'success' in self.update_action('')
79        assert self.get(url='/dir/file')['status'] == 200, 'empty absolute'
80
81        assert 'success' in self.update_action("", ".$uri")
82        assert self.get(url=self.test_path)['status'] == 200, 'empty relative'
83
84    def test_static_chroot_relative(self, is_su, temp_dir):
85        if is_su:
86            pytest.skip("Does't work under root.")
87
88        assert 'success' in self.update_action('.')
89        assert self.get(url='/dir/file')['status'] == 403, 'relative chroot'
90
91        assert 'success' in self.conf({"share": ".$uri"}, 'routes/0/action')
92        assert self.get(url=self.test_path)['status'] == 200, 'relative share'
93
94        assert 'success' in self.update_action(".", ".$uri")
95        assert self.get(url=self.test_path)['status'] == 200, 'relative'
96
97    def test_static_chroot_variables(self, temp_dir):
98        assert 'success' in self.update_action(f'{temp_dir}/assets/$host')
99        assert self.get_custom('/dir/file', 'dir') == 200
100
101        assert 'success' in self.update_action(f'{temp_dir}/assets/${{host}}')
102        assert self.get_custom('/dir/file', 'dir') == 200
103
104    def test_static_chroot_variables_buildin_start(self, temp_dir):
105        assert 'success' in self.update_action(
106            '$uri/assets/dir',
107            f'{temp_dir}/assets/dir/$host',
108        )
109        assert self.get_custom(temp_dir, 'file') == 200
110
111    def test_static_chroot_variables_buildin_mid(self, temp_dir):
112        assert 'success' in self.update_action(f'{temp_dir}/$host/dir')
113        assert self.get_custom('/dir/file', 'assets') == 200
114
115    def test_static_chroot_variables_buildin_end(self, temp_dir):
116        assert 'success' in self.update_action(f'{temp_dir}/assets/$host')
117        assert self.get_custom('/dir/file', 'dir') == 200
118
119    def test_static_chroot_slash(self, temp_dir):
120        assert 'success' in self.update_action(f'{temp_dir}/assets/dir/')
121        assert self.get(url='/dir/file')['status'] == 200, 'slash end'
122        assert self.get(url='/dirxfile')['status'] == 403, 'slash end bad'
123
124        assert 'success' in self.update_action(f'{temp_dir}/assets/dir')
125        assert self.get(url='/dir/file')['status'] == 200, 'no slash end'
126
127        assert 'success' in self.update_action(f'{temp_dir}/assets/dir/')
128        assert self.get(url='/dir/file')['status'] == 200, 'slash end 2'
129        assert self.get(url='/dirxfile')['status'] == 403, 'slash end 2 bad'
130
131        assert 'success' in self.update_action(
132            f'{temp_dir}//assets////dir///', f'{temp_dir}///assets/////$uri'
133        )
134        assert self.get(url='/dir/file')['status'] == 200, 'multiple slashes'
135
136    def test_static_chroot_invalid(self, temp_dir):
137        assert 'error' in self.conf(
138            {"share": temp_dir, "chroot": True},
139            'routes/0/action',
140        ), 'configure chroot error'
141        assert 'error' in self.conf(
142            {"share": temp_dir, "symlinks": "True"},
143            'routes/0/action',
144        ), 'configure symlink error'
145        assert 'error' in self.conf(
146            {"share": temp_dir, "mount": "True"},
147            'routes/0/action',
148        ), 'configure mount error'
149
150        assert 'error' in self.update_action(f'{temp_dir}/assets/d$r$uri')
151        assert 'error' in self.update_action(f'{temp_dir}/assets/$$uri')
152