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\storage\storage; |
20 | use Symfony\Component\HttpFoundation\Request as symfony_request; |
21 | use Symfony\Component\HttpFoundation\Response; |
22 | use Symfony\Component\HttpFoundation\ResponseHeaderBag; |
23 | use Symfony\Component\HttpFoundation\StreamedResponse; |
24 | |
25 | /** |
26 | * Controller for /download/avatar/{file} routes |
27 | */ |
28 | class avatar extends controller |
29 | { |
30 | /** @var config */ |
31 | protected $config; |
32 | |
33 | /** @var array */ |
34 | protected $allowed_extensions = ['png', 'gif', 'jpg', 'jpeg']; |
35 | |
36 | /** |
37 | * Constructor |
38 | * |
39 | * @param service $cache |
40 | * @param config $config |
41 | * @param driver_interface $db |
42 | * @param storage $storage |
43 | * @param symfony_request $symfony_request |
44 | */ |
45 | public function __construct(service $cache, config $config, driver_interface $db, storage $storage, symfony_request $symfony_request) |
46 | { |
47 | parent::__construct($cache, $db, $storage, $symfony_request); |
48 | |
49 | $this->config = $config; |
50 | } |
51 | |
52 | /** |
53 | * {@inheritdoc} |
54 | */ |
55 | public function handle(string $file): Response |
56 | { |
57 | $file = $this->decode_filename($file); |
58 | |
59 | return parent::handle($file); |
60 | } |
61 | |
62 | /** |
63 | * {@inheritdoc} |
64 | */ |
65 | protected function is_allowed(string $file): bool |
66 | { |
67 | $ext = substr(strrchr($file, '.'), 1); |
68 | |
69 | // If filename have point and have an allowed extension |
70 | return strpos($file, '.') && in_array($ext, $this->allowed_extensions, true); |
71 | } |
72 | |
73 | /** |
74 | * Decode avatar filename |
75 | * |
76 | * @param string $file Filename |
77 | * |
78 | * @return string Filename in filesystem |
79 | */ |
80 | protected function decode_filename(string $file): string |
81 | { |
82 | $avatar_group = false; |
83 | |
84 | if (isset($file[0]) && $file[0] === 'g') |
85 | { |
86 | $avatar_group = true; |
87 | $file = substr($file, 1); |
88 | } |
89 | |
90 | $ext = substr(strrchr($file, '.'), 1); |
91 | $file = (int) $file; |
92 | |
93 | return $this->config['avatar_salt'] . '_' . ($avatar_group ? 'g' : '') . $file . '.' . $ext; |
94 | } |
95 | |
96 | /** |
97 | * {@inheritdoc} |
98 | */ |
99 | protected function prepare(StreamedResponse $response, string $file): void |
100 | { |
101 | $response->setPublic(); |
102 | |
103 | $disposition = $response->headers->makeDisposition( |
104 | ResponseHeaderBag::DISPOSITION_INLINE, |
105 | rawurlencode($file) |
106 | ); |
107 | |
108 | $response->headers->set('Content-Disposition', $disposition); |
109 | |
110 | $time = new \DateTime(); |
111 | $response->setExpires($time->modify('+1 year')); |
112 | |
113 | parent::prepare($response, $file); |
114 | } |
115 | } |