xref: /unit/test/test_static_chroot.py (revision 2073:bc6ad31ce286)
1import os
2from pathlib import Path
3
4import pytest
5from unit.applications.proto import TestApplicationProto
6
7
8class TestStaticChroot(TestApplicationProto):
9    prerequisites = {'features': ['chroot']}
10
11    @pytest.fixture(autouse=True)
12    def setup_method_fixture(self, temp_dir):
13        os.makedirs(temp_dir + '/assets/dir')
14        Path(temp_dir + '/assets/index.html').write_text('0123456789')
15        Path(temp_dir + '/assets/dir/file').write_text('blah')
16
17        test = Path(__file__)
18        self.test_path = '/' + test.parent.name + '/' + test.name
19
20        self._load_conf(
21            {
22                "listeners": {"*:7080": {"pass": "routes"}},
23                "routes": [{"action": {"share": temp_dir + "/assets$uri"}}],
24            }
25        )
26
27    def update_action(self, share, chroot):
28        return self.conf(
29            {"share": share, "chroot": chroot},
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.conf(
43            {
44                "share": temp_dir + "/assets$uri",
45                "chroot": temp_dir + "/assets/dir",
46            },
47            'routes/0/action',
48        ), 'configure chroot'
49
50        assert self.get(url='/dir/file')['status'] == 200, 'chroot'
51        assert self.get(url='/index.html')['status'] == 403, 'chroot 403 2'
52        assert self.get(url='/file')['status'] == 403, 'chroot 403'
53
54    def test_share_chroot_array(self, temp_dir):
55        assert 'success' in self.conf(
56            {
57                "share": ["/blah", temp_dir + "/assets$uri"],
58                "chroot": temp_dir + "/assets/dir",
59            },
60            'routes/0/action',
61        ), 'configure share array'
62        assert self.get(url='/dir/file')['status'] == 200, 'share array'
63
64        assert 'success' in self.update_action(
65            ["/blah", temp_dir + '/assets$uri'], temp_dir + '/assets/$host'
66        )
67        assert self.get_custom('/dir/file', 'dir') == 200, 'array variable'
68
69        assert 'success' in self.conf(
70            {
71                "share": ["/blah", "/blah2"],
72                "chroot": temp_dir + "/assets/dir",
73            },
74            'routes/0/action',
75        ), 'configure share array bad'
76        assert self.get()['status'] != 200, 'share array bad'
77
78    def test_static_chroot_permission(self, is_su, temp_dir):
79        if is_su:
80            pytest.skip('does\'t work under root')
81
82        os.chmod(temp_dir + '/assets/dir', 0o100)
83
84        assert 'success' in self.conf(
85            {
86                "share": temp_dir + "/assets$uri",
87                "chroot": temp_dir + "/assets/dir",
88            },
89            'routes/0/action',
90        ), 'configure chroot'
91
92        assert self.get(url='/dir/file')['status'] == 200, 'chroot'
93
94    def test_static_chroot_empty(self, temp_dir):
95        assert 'success' in self.conf(
96            {"share": temp_dir + "/assets$uri", "chroot": ""},
97            'routes/0/action',
98        ), 'configure chroot empty absolute'
99
100        assert (
101            self.get(url='/dir/file')['status'] == 200
102        ), 'chroot empty absolute'
103
104        assert 'success' in self.conf(
105            {"share": ".$uri", "chroot": ""},
106            'routes/0/action',
107        ), 'configure chroot empty relative'
108
109        assert (
110            self.get(url=self.test_path)['status'] == 200
111        ), 'chroot empty relative'
112
113    def test_static_chroot_relative(self, is_su, temp_dir):
114        if is_su:
115            pytest.skip('does\'t work under root')
116
117        assert 'success' in self.conf(
118            {"share": temp_dir + "/assets$uri", "chroot": "."},
119            'routes/0/action',
120        ), 'configure relative chroot'
121
122        assert self.get(url='/dir/file')['status'] == 403, 'relative chroot'
123
124        assert 'success' in self.conf(
125            {"share": ".$uri"},
126            'routes/0/action',
127        ), 'configure relative share'
128
129        assert self.get(url=self.test_path)['status'] == 200, 'relative share'
130
131        assert 'success' in self.conf(
132            {"share": ".$uri", "chroot": "."},
133            'routes/0/action',
134        ), 'configure relative'
135
136        assert self.get(url=self.test_path)['status'] == 200, 'relative'
137
138    def test_static_chroot_variables(self, temp_dir):
139        assert 'success' in self.update_action(
140            temp_dir + '/assets$uri', temp_dir + '/assets/$host'
141        )
142        assert self.get_custom('/dir/file', 'dir') == 200
143
144        assert 'success' in self.update_action(
145            temp_dir + '/assets$uri', temp_dir + '/assets/${host}'
146        )
147        assert self.get_custom('/dir/file', 'dir') == 200
148
149    def test_static_chroot_variables_buildin_start(self, temp_dir):
150        assert 'success' in self.update_action(
151            temp_dir + '/assets/dir/$host', '$uri/assets/dir'
152        )
153
154        assert self.get_custom(temp_dir, 'file') == 200
155
156    def test_static_chroot_variables_buildin_mid(self, temp_dir):
157        assert 'success' in self.update_action(
158            temp_dir + '/assets$uri', temp_dir + '/$host/dir'
159        )
160
161        assert self.get_custom('/dir/file', 'assets') == 200
162
163    def test_static_chroot_variables_buildin_end(self, temp_dir):
164        assert 'success' in self.update_action(
165            temp_dir + '/assets$uri', temp_dir + '/assets/$host'
166        )
167
168        assert self.get_custom('/dir/file', 'dir') == 200
169
170    def test_static_chroot_slash(self, temp_dir):
171        assert 'success' in self.conf(
172            {
173                "share": temp_dir + "/assets$uri",
174                "chroot": temp_dir + "/assets/dir/",
175            },
176            'routes/0/action',
177        ), 'configure chroot slash end'
178
179        assert self.get(url='/dir/file')['status'] == 200, 'slash end'
180        assert self.get(url='/dirxfile')['status'] == 403, 'slash end bad'
181
182        assert 'success' in self.conf(
183            {
184                "share": temp_dir + "/assets$uri",
185                "chroot": temp_dir + "/assets/dir",
186            },
187            'routes/0/action',
188        ), 'configure chroot no slash end'
189
190        assert self.get(url='/dir/file')['status'] == 200, 'no slash end'
191
192        assert 'success' in self.conf(
193            {
194                "share": temp_dir + "/assets$uri",
195                "chroot": temp_dir + "/assets/dir/",
196            },
197            'routes/0/action',
198        ), 'configure chroot slash end 2'
199
200        assert self.get(url='/dir/file')['status'] == 200, 'slash end 2'
201        assert self.get(url='/dirxfile')['status'] == 403, 'slash end 2 bad'
202
203        assert 'success' in self.conf(
204            {
205                "share": temp_dir + "///assets/////$uri",
206                "chroot": temp_dir + "//assets////dir///",
207            },
208            'routes/0/action',
209        ), 'configure chroot multiple slashes'
210
211        assert self.get(url='/dir/file')['status'] == 200, 'multiple slashes'
212
213    def test_static_chroot_invalid(self, temp_dir):
214        assert 'error' in self.conf(
215            {"share": temp_dir, "chroot": True},
216            'routes/0/action',
217        ), 'configure chroot error'
218        assert 'error' in self.conf(
219            {"share": temp_dir, "symlinks": "True"},
220            'routes/0/action',
221        ), 'configure symlink error'
222        assert 'error' in self.conf(
223            {"share": temp_dir, "mount": "True"},
224            'routes/0/action',
225        ), 'configure mount error'
226
227        assert 'error' in self.update_action(
228            temp_dir + '/assets$uri', temp_dir + '/assets/d$r$uri'
229        )
230        assert 'error' in self.update_action(
231            temp_dir + '/assets$uri', temp_dir + '/assets/$$uri'
232        )
233