Config.php 10.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 3/6/17
 * Time: 8:47 PM
 */

namespace qfq;

use qfq;

13
14
require_once(__DIR__ . '/../Constants.php');
require_once(__DIR__ . '/../helper/Support.php');
15
16
17
18
19
20

class Config {

    /**
     * Read config.qfq.ini.
     *
21
     * @param string $fileConfigIni
Carsten  Rose's avatar
Carsten Rose committed
22
     *
23
24
     * @return array
     * @throws UserFormException
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
     */
    public function readConfig($fileConfigIni = '') {

        if ($fileConfigIni == '') {
            // Production Path to CONFIG_INI
            $fileConfigIni = __DIR__ . '/../../../../../' . CONFIG_INI;
            if (!file_exists($fileConfigIni)) {
                // PHPUnit Path to CONFIG_INI
                $fileConfigIni = __DIR__ . '/../../../' . CONFIG_INI;
            }
        }

        try {
            $config = parse_ini_file($fileConfigIni, false);

        } catch (\Exception $e) {
            throw new qfq\UserFormException ("Error read file " . $fileConfigIni . ": " . $e->getMessage(), ERROR_IO_READ_FILE);
        }

        $config = self::renameConfigElements($config);
45
46
47
48
49
50
51
52
53
54
55
        $config = self::setDefaults($config);

        self::checkForAttack($config);

        return $config;
    }

    /**
     * @param array $config
     */
    private static function checkForAttack(array $config) {
56
        $attack = false;
57
        $key = '';
58
59
60
61

        // Iterate over all fake vars
        $arr = explode(',', $config[SYSTEM_SECURITY_VARS_HONEYPOT]);
        foreach ($arr as $key) {
62
63
64
65
            $key = trim($key);
            if ($key === '') {
                continue;
            }
66
            if (!empty($_POST[$key]) || !empty($_GET[$key])) {
67
68
69
70
71
72
73
                $attack = true;
            }
        }

        // Limit length of all get vars: protect against SQL injection based on long ...%34%34%24%34...
        $maxLength = $config[SYSTEM_SECURITY_GET_MAX_LENGTH];
        if ($maxLength > 0) {
74
75
76
            foreach ($_GET as $key => $value) {
                // Check if the variable is something like 'my_name_100' - if the part after the last '_' is numerical, this means a valid, non standard length.
                $arr = explode(GET_EXTRA_LENGTH_TOKEN, $key);
77

78
79
                $cnt = count($arr);
                if ($cnt > 1 && is_numeric($arr[$cnt - 1])) {
80
81
82
83
84
85
                    $maxLength = $arr[$cnt - 1];
                } else {
                    $maxLength = $config[SYSTEM_SECURITY_GET_MAX_LENGTH]; // might change again.
                }

                if (strlen($value) > $maxLength) {
86
                    $attack = true;
87
                    break;
88
                }
89
90
91
92
            }
        }

        // Nothing found?
93
        if ($attack === false) {
94
95
96
            return;
        }

97
        self::attackDetectedExitNow($config, $key);
98
99
100
101
102
    }

    /**
     * @throws UserFormException
     */
103
    public static function attackDetectedExitNow(array $config = array(), $getParamName = '') {
104
105
106

        if (count($config) == 0) {
            $config = self::readConfig();
107
108
        }

109
110
111
        // In case of an attack: log out the current user.
        Session::destroy();

112
113
114
115
116
117
        // Sleep
        $penalty = (empty($config[SYSTEM_SECURITY_ATTACK_DELAY]) || !is_numeric($config[SYSTEM_SECURITY_ATTACK_DELAY])) ?
            SYSTEM_SECURITY_ATTACK_DELAY_DEFAULT : $config[SYSTEM_SECURITY_ATTACK_DELAY];

        sleep($penalty);

118
        if ($config[SYSTEM_SECURITY_SHOW_MESSAGE] == 'true' || $config[SYSTEM_SECURITY_SHOW_MESSAGE] == 1) {
119

120
            echo "Attack detected - stop process";
121
122
123
124
125
126
127
//            $answer[API_STATUS] = API_ANSWER_STATUS_ERROR;
//            $answer[API_MESSAGE] = 'Attack detected - stop process.';
//            if($getParamName!='') {
//                $answer[API_MESSAGE] .= " Attack parameter: $getParamName";
//            }
//            header("Content-Type: application/json");
//            echo json_encode($answer);
128
129
130
131
132
133
134
        }

        exit;
    }

    /**
     * @param array $config
Carsten  Rose's avatar
Carsten Rose committed
135
     *
136
137
138
139
     * @return array
     */
    private static function setDefaults(array $config) {
        // Defaults
140
141
        Support::setIfNotSet($config, SYSTEM_DB_INDEX_DATA, DB_INDEX_DATA_DEFAULT);
        Support::setIfNotSet($config, SYSTEM_DB_INDEX_QFQ, DB_INDEX_DATA_DEFAULT);
142

143
        Support::setIfNotSet($config, SYSTEM_DATE_FORMAT, 'yyyy-mm-dd');
144
        Support::setIfNotSet($config, SYSTEM_SHOW_DEBUG_INFO, SYSTEM_SHOW_DEBUG_INFO_AUTO);
145
146
        Support::setIfNotSet($config, SYSTEM_SQL_LOG, SYSTEM_SQL_LOG_FILE);
        Support::setIfNotSet($config, SYSTEM_SQL_LOG_MODE, SQL_LOG_MODE_NONE, ''); // do not worry: parse_ini_file() will replace 'none' and 'off' by ''. Set it here again.
147
148
149
150
151
152
        Support::setIfNotSet($config, F_BS_COLUMNS, '12');
        Support::setIfNotSet($config, F_BS_LABEL_COLUMNS, '3');
        Support::setIfNotSet($config, F_BS_INPUT_COLUMNS, '6');
        Support::setIfNotSet($config, F_BS_NOTE_COLUMNS, '3');
        Support::setIfNotSet($config, F_CLASS_PILL, 'qfq-color-grey-1');
        Support::setIfNotSet($config, F_CLASS_BODY, 'qfq-color-grey-2');
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

        Support::setIfNotSet($config, F_SAVE_BUTTON_TEXT, '');
        Support::setIfNotSet($config, F_SAVE_BUTTON_TOOLTIP, 'Save');
        Support::setIfNotSet($config, F_SAVE_BUTTON_CLASS, 'btn btn-default navbar-btn');
        Support::setIfNotSet($config, F_SAVE_BUTTON_GLYPH_ICON, GLYPH_ICON_CHECK);

        Support::setIfNotSet($config, F_CLOSE_BUTTON_TEXT, '');
        Support::setIfNotSet($config, F_CLOSE_BUTTON_TOOLTIP, 'Close');
        Support::setIfNotSet($config, F_CLOSE_BUTTON_CLASS, 'btn btn-default navbar-btn');
        Support::setIfNotSet($config, F_CLOSE_BUTTON_GLYPH_ICON, GLYPH_ICON_CLOSE);

        Support::setIfNotSet($config, F_DELETE_BUTTON_TEXT, '');
        Support::setIfNotSet($config, F_DELETE_BUTTON_TOOLTIP, 'Delete');
        Support::setIfNotSet($config, F_DELETE_BUTTON_CLASS, 'btn btn-default navbar-btn');
        Support::setIfNotSet($config, F_DELETE_BUTTON_GLYPH_ICON, GLYPH_ICON_DELETE);

        Support::setIfNotSet($config, F_NEW_BUTTON_TEXT, '');
        Support::setIfNotSet($config, F_NEW_BUTTON_TOOLTIP, 'New');
        Support::setIfNotSet($config, F_NEW_BUTTON_CLASS, 'btn btn-default navbar-btn');
        Support::setIfNotSet($config, F_NEW_BUTTON_GLYPH_ICON, GLYPH_ICON_NEW);

174
175
176
        Support::setIfNotSet($config, F_BUTTON_ON_CHANGE_CLASS, 'btn-info alert-info');
        Support::setIfNotSet($config, SYSTEM_EDIT_FORM_PAGE, 'form');
        Support::setIfNotSet($config, SYSTEM_SECURITY_VARS_HONEYPOT, 'email,username,password');
177
        Support::setIfNotSet($config, SYSTEM_SECURITY_ATTACK_DELAY, SYSTEM_SECURITY_ATTACK_DELAY_DEFAULT);
178
        Support::setIfNotSet($config, SYSTEM_SECURITY_SHOW_MESSAGE, '0');
179
        Support::setIfNotSet($config, SYSTEM_SECURITY_GET_MAX_LENGTH, SYSTEM_SECURITY_GET_MAX_LENGTH_DEFAULT);
180
        Support::setIfNotSet($config, SYSTEM_ESCAPE_TYPE_DEFAULT, TOKEN_ESCAPE_MYSQL);
181
182
        Support::setIfNotSet($config, SYSTEM_GFX_EXTRA_BUTTON_INFO_INLINE, '<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>');
        Support::setIfNotSet($config, SYSTEM_GFX_EXTRA_BUTTON_INFO_BELOW, '<span class="glyphicon glyphicon-info-sign text-info" aria-hidden="true"></span>');
183
184
        Support::setIfNotSet($config, SYSTEM_EXTRA_BUTTON_INFO_CLASS, '');

185
        Support::setIfNotSet($config, SYSTEM_DB_UPDATE, SYSTEM_DB_UPDATE_AUTO);
Carsten  Rose's avatar
Carsten Rose committed
186
        Support::setIfNotSet($config, SYSTEM_RECORD_LOCK_TIMEOUT_SECONDS, SYSTEM_RECORD_LOCK_TIMEOUT_SECONDS_DEFAULT);
187

188
189
        Support::setIfNotSet($config, DOCUMENTATION_QFQ, DOCUMENTATION_QFQ_URL);

190
191
        Support::setIfNotSet($config, SYSTEM_VAR_ADD_BY_SQL, SYSTEM_VAR_ADD_BY_SQL_DEFAULT);

192
193
194
195
196
        return $config;
    }

    /**
     * Rename Elements defined in config.qfq.ini to more appropriate in user interaction.
Carsten  Rose's avatar
Carsten Rose committed
197
198
     * E.g.: in config.qfq.ini everything is in upper case and word space is '_'. In Form.parameter it's lowercase and
     * camel hook.
199
200
     *
     * @param array $config
Carsten  Rose's avatar
Carsten Rose committed
201
     *
202
203
204
205
206
207
     * @return array
     */
    private static function renameConfigElements(array $config) {

        // oldname > newname
        $setting = [
208
            [SYSTEM_FORM_BS_COLUMNS, F_BS_COLUMNS],
209
210
211
212
213
214
215
216
217
218
219
            [SYSTEM_FORM_BS_LABEL_COLUMNS, F_BS_LABEL_COLUMNS],
            [SYSTEM_FORM_BS_INPUT_COLUMNS, F_BS_INPUT_COLUMNS],
            [SYSTEM_FORM_BS_NOTE_COLUMNS, F_BS_NOTE_COLUMNS],
            [SYSTEM_FORM_DATA_PATTERN_ERROR, F_FE_DATA_PATTERN_ERROR],
            [SYSTEM_FORM_DATA_REQUIRED_ERROR, F_FE_DATA_REQUIRED_ERROR],
            [SYSTEM_FORM_DATA_MATCH_ERROR, F_FE_DATA_MATCH_ERROR],
            [SYSTEM_FORM_DATA_ERROR, F_FE_DATA_ERROR],
            [SYSTEM_CSS_CLASS_QFQ_FORM, F_CLASS],
            [SYSTEM_CSS_CLASS_QFQ_FORM_PILL, F_CLASS_PILL],
            [SYSTEM_CSS_CLASS_QFQ_FORM_BODY, F_CLASS_BODY],
            [SYSTEM_FORM_BUTTON_ON_CHANGE_CLASS, F_BUTTON_ON_CHANGE_CLASS],
220
            [SYSTEM_ESCAPE_TYPE_DEFAULT, F_ESCAPE_TYPE_DEFAULT],
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

            [SYSTEM_SAVE_BUTTON_TEXT, F_SAVE_BUTTON_TEXT],
            [SYSTEM_SAVE_BUTTON_TOOLTIP, F_SAVE_BUTTON_TOOLTIP],
            [SYSTEM_SAVE_BUTTON_CLASS, F_SAVE_BUTTON_CLASS],
            [SYSTEM_SAVE_BUTTON_GLYPH_ICON, F_SAVE_BUTTON_GLYPH_ICON],

            [SYSTEM_CLOSE_BUTTON_TEXT, F_CLOSE_BUTTON_TEXT],
            [SYSTEM_CLOSE_BUTTON_TOOLTIP, F_CLOSE_BUTTON_TOOLTIP],
            [SYSTEM_CLOSE_BUTTON_CLASS, F_CLOSE_BUTTON_CLASS],
            [SYSTEM_CLOSE_BUTTON_GLYPH_ICON, F_CLOSE_BUTTON_GLYPH_ICON],

            [SYSTEM_DELETE_BUTTON_TEXT, F_DELETE_BUTTON_TEXT],
            [SYSTEM_DELETE_BUTTON_TOOLTIP, F_DELETE_BUTTON_TOOLTIP],
            [SYSTEM_DELETE_BUTTON_CLASS, F_DELETE_BUTTON_CLASS],
            [SYSTEM_DELETE_BUTTON_GLYPH_ICON, F_DELETE_BUTTON_GLYPH_ICON],

            [SYSTEM_NEW_BUTTON_TEXT, F_NEW_BUTTON_TEXT],
            [SYSTEM_NEW_BUTTON_TOOLTIP, F_NEW_BUTTON_TOOLTIP],
            [SYSTEM_NEW_BUTTON_CLASS, F_NEW_BUTTON_CLASS],
            [SYSTEM_NEW_BUTTON_GLYPH_ICON, F_NEW_BUTTON_GLYPH_ICON],

242
243
            [SYSTEM_EXTRA_BUTTON_INFO_CLASS, FE_INPUT_EXTRA_BUTTON_INFO_CLASS],

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
        ];

        foreach ($setting as $row) {
            $oldName = $row[0];
            $newName = $row[1];

            if (isset($config[$oldName])) {
                $config[$newName] = $config[$oldName];
                if ($oldName != $newName) {
                    unset($config[$oldName]);
                }
            }
        }

        return $config;
    }
}