Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
form_helper
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
3 / 3
16
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 get_form_tokens
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 check_form_tokens
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
12
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
14namespace phpbb\form;
15
16use phpbb\config\config;
17use phpbb\request\request_interface;
18use phpbb\user;
19
20class form_helper
21{
22    /** @var config */
23    protected $config;
24
25    /** @var request_interface  */
26    protected $request;
27
28    /** @var user */
29    protected $user;
30
31    /**
32     * Constructor for form_helper
33     *
34     * @param config $config
35     * @param request_interface $request
36     * @param user $user
37     */
38    public function __construct(config $config, request_interface $request, user $user)
39    {
40        $this->config = $config;
41        $this->request = $request;
42        $this->user = $user;
43    }
44
45    /**
46     * Get form tokens for form
47     *
48     * @param string $form_name Name of form
49     * @param int|null $now Token generation time
50     * @param string|null $token_sid SID used for form token
51     * @param string|null $token Generated token
52     *
53     * @return array Array containing form_token and creation_time of form token
54     */
55    public function get_form_tokens(string $form_name, ?int &$now = 0, ?string &$token_sid = '', ?string &$token = ''): array
56    {
57        $now = time();
58        $token_sid = ($this->user->data['user_id'] == ANONYMOUS && !empty($this->config['form_token_sid_guests'])) ? $this->user->session_id : '';
59        $token = sha1($now . $this->user->data['user_form_salt'] . $form_name . $token_sid);
60
61        return [
62            'creation_time' => $now,
63            'form_token'    => $token,
64        ];
65    }
66
67    /**
68     * Check form token for form
69     *
70     * @param string $form_name Name of form
71     * @param int|null $timespan Lifetime of token or null if default value should be used
72     * @return bool True if form token is valid, false if not
73     */
74    public function check_form_tokens(string $form_name, ?int $timespan = null): bool
75    {
76        if ($timespan === null)
77        {
78            // we enforce a minimum value of half a minute here.
79            $timespan = ($this->config['form_token_lifetime'] == -1) ? -1 : max(30, $this->config['form_token_lifetime']);
80        }
81
82        if ($this->request->is_set_post('creation_time') && $this->request->is_set_post('form_token'))
83        {
84            $creation_time    = abs($this->request->variable('creation_time', 0));
85            $token = $this->request->variable('form_token', '');
86
87            $diff = time() - $creation_time;
88
89            // If creation_time and the time() now is zero we can assume it was not a human doing this (the check for if ($diff)...
90            if (defined('DEBUG_TEST') || $diff && ($diff <= $timespan || $timespan === -1))
91            {
92                $token_sid = ($this->user->data['user_id'] == ANONYMOUS && !empty($this->config['form_token_sid_guests'])) ? $this->user->session_id : '';
93                $key = sha1($creation_time . $this->user->data['user_form_salt'] . $form_name . $token_sid);
94
95                if (hash_equals($key, $token))
96                {
97                    return true;
98                }
99            }
100        }
101
102        return false;
103    }
104}