Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 22 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
avatar | |
0.00% |
0 / 22 |
|
0.00% |
0 / 5 |
90 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
handle | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
is_allowed | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
decode_filename | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
prepare | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\storage\controller; |
15 | |
16 | use phpbb\cache\service; |
17 | use phpbb\config\config; |
18 | use phpbb\db\driver\driver_interface; |
19 | use phpbb\mimetype\extension_guesser; |
20 | use phpbb\storage\storage; |
21 | use Symfony\Component\HttpFoundation\Request as symfony_request; |
22 | use Symfony\Component\HttpFoundation\Response; |
23 | use Symfony\Component\HttpFoundation\ResponseHeaderBag; |
24 | use Symfony\Component\HttpFoundation\StreamedResponse; |
25 | |
26 | /** |
27 | * Controller for /download/avatar/{file} routes |
28 | */ |
29 | class avatar extends controller |
30 | { |
31 | /** @var config */ |
32 | protected $config; |
33 | |
34 | /** @var array */ |
35 | protected $allowed_extensions = ['png', 'gif', 'jpg', 'jpeg']; |
36 | |
37 | /** |
38 | * Constructor |
39 | * |
40 | * @param service $cache |
41 | * @param config $config |
42 | * @param driver_interface $db |
43 | * @param extension_guesser $extension_guesser |
44 | * @param storage $storage |
45 | * @param symfony_request $symfony_request |
46 | */ |
47 | public function __construct(service $cache, config $config, driver_interface $db, extension_guesser $extension_guesser, storage $storage, symfony_request $symfony_request) |
48 | { |
49 | parent::__construct($cache, $db , $extension_guesser, $storage, $symfony_request); |
50 | |
51 | $this->config = $config; |
52 | } |
53 | |
54 | /** |
55 | * {@inheritdoc} |
56 | */ |
57 | public function handle(string $file): Response |
58 | { |
59 | $file = $this->decode_filename($file); |
60 | |
61 | return parent::handle($file); |
62 | } |
63 | |
64 | /** |
65 | * {@inheritdoc} |
66 | */ |
67 | protected function is_allowed(string $file): bool |
68 | { |
69 | $ext = substr(strrchr($file, '.'), 1); |
70 | |
71 | // If filename have point and have an allowed extension |
72 | return strpos($file, '.') && in_array($ext, $this->allowed_extensions, true); |
73 | } |
74 | |
75 | /** |
76 | * Decode avatar filename |
77 | * |
78 | * @param string $file Filename |
79 | * |
80 | * @return string Filename in filesystem |
81 | */ |
82 | protected function decode_filename(string $file): string |
83 | { |
84 | $avatar_group = false; |
85 | |
86 | if (isset($file[0]) && $file[0] === 'g') |
87 | { |
88 | $avatar_group = true; |
89 | $file = substr($file, 1); |
90 | } |
91 | |
92 | $ext = substr(strrchr($file, '.'), 1); |
93 | $file = (int) $file; |
94 | |
95 | return $this->config['avatar_salt'] . '_' . ($avatar_group ? 'g' : '') . $file . '.' . $ext; |
96 | } |
97 | |
98 | /** |
99 | * {@inheritdoc} |
100 | */ |
101 | protected function prepare(StreamedResponse $response, string $file): void |
102 | { |
103 | $response->setPublic(); |
104 | |
105 | $disposition = $response->headers->makeDisposition( |
106 | ResponseHeaderBag::DISPOSITION_INLINE, |
107 | rawurlencode($file) |
108 | ); |
109 | |
110 | $response->headers->set('Content-Disposition', $disposition); |
111 | |
112 | $time = new \DateTime(); |
113 | $response->setExpires($time->modify('+1 year')); |
114 | |
115 | parent::prepare($response, $file); |
116 | } |
117 | } |