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