Config.php 10.8 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
        $config = self::setDefaults($config);
46
        self::checkDeprecated($config);
47
48
49
50
51
52

        self::checkForAttack($config);

        return $config;
    }

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
    /**
     * Checks for deprecated options.
     */
    private static function checkDeprecated(array $config) {

        foreach ([SYSTEM_VAR_ADD_BY_SQL] as $key) {

            if (isset($config[$key])) {
                $msg = '';
                switch ($key) {
                    case SYSTEM_VAR_ADD_BY_SQL:
                        $msg = 'Replaced by: ' . SYSTEM_FILL_STORE_SYSTEM_BY_SQL . '_1|2|3';
                }
                throw new qfq\UserFormException ("Deprecated option in " . CONFIG_INI . ": " . SYSTEM_VAR_ADD_BY_SQL . " - " . $msg);
            }
        }
    }


72
73
74
75
    /**
     * @param array $config
     */
    private static function checkForAttack(array $config) {
76
        $attack = false;
77
        $key = '';
78
79
80
81

        // Iterate over all fake vars
        $arr = explode(',', $config[SYSTEM_SECURITY_VARS_HONEYPOT]);
        foreach ($arr as $key) {
82
83
84
85
            $key = trim($key);
            if ($key === '') {
                continue;
            }
86
            if (!empty($_POST[$key]) || !empty($_GET[$key])) {
87
88
89
90
91
92
93
                $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) {
94
95
96
            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);
97

98
99
                $cnt = count($arr);
                if ($cnt > 1 && is_numeric($arr[$cnt - 1])) {
100
101
102
103
104
105
                    $maxLength = $arr[$cnt - 1];
                } else {
                    $maxLength = $config[SYSTEM_SECURITY_GET_MAX_LENGTH]; // might change again.
                }

                if (strlen($value) > $maxLength) {
106
                    $attack = true;
107
                    break;
108
                }
109
110
111
112
            }
        }

        // Nothing found?
113
        if ($attack === false) {
114
115
116
            return;
        }

117
        self::attackDetectedExitNow($config, $key);
118
119
120
121
122
    }

    /**
     * @throws UserFormException
     */
123
    public static function attackDetectedExitNow(array $config = array(), $getParamName = '') {
124
125
126

        if (count($config) == 0) {
            $config = self::readConfig();
127
128
        }

129
130
131
        // In case of an attack: log out the current user.
        Session::destroy();

132
133
134
135
136
137
        // 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);

138
        if ($config[SYSTEM_SECURITY_SHOW_MESSAGE] == 'true' || $config[SYSTEM_SECURITY_SHOW_MESSAGE] == 1) {
139

140
            echo "Attack detected - stop process";
141
142
143
144
145
146
147
//            $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);
148
149
150
151
152
153
154
        }

        exit;
    }

    /**
     * @param array $config
Carsten  Rose's avatar
Carsten Rose committed
155
     *
156
157
158
159
     * @return array
     */
    private static function setDefaults(array $config) {
        // Defaults
160
161
        Support::setIfNotSet($config, SYSTEM_DB_INDEX_DATA, DB_INDEX_DATA_DEFAULT);
        Support::setIfNotSet($config, SYSTEM_DB_INDEX_QFQ, DB_INDEX_DATA_DEFAULT);
162

163
        Support::setIfNotSet($config, SYSTEM_DATE_FORMAT, 'yyyy-mm-dd');
164
        Support::setIfNotSet($config, SYSTEM_SHOW_DEBUG_INFO, SYSTEM_SHOW_DEBUG_INFO_AUTO);
165
166
        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.
167
168
169
170
171
172
        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');
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

        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);

194
195
196
        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');
197
        Support::setIfNotSet($config, SYSTEM_SECURITY_ATTACK_DELAY, SYSTEM_SECURITY_ATTACK_DELAY_DEFAULT);
198
        Support::setIfNotSet($config, SYSTEM_SECURITY_SHOW_MESSAGE, '0');
199
        Support::setIfNotSet($config, SYSTEM_SECURITY_GET_MAX_LENGTH, SYSTEM_SECURITY_GET_MAX_LENGTH_DEFAULT);
200
        Support::setIfNotSet($config, SYSTEM_ESCAPE_TYPE_DEFAULT, TOKEN_ESCAPE_MYSQL);
201
202
        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>');
203
204
        Support::setIfNotSet($config, SYSTEM_EXTRA_BUTTON_INFO_CLASS, '');

205
        Support::setIfNotSet($config, SYSTEM_DB_UPDATE, SYSTEM_DB_UPDATE_AUTO);
Carsten  Rose's avatar
Carsten Rose committed
206
        Support::setIfNotSet($config, SYSTEM_RECORD_LOCK_TIMEOUT_SECONDS, SYSTEM_RECORD_LOCK_TIMEOUT_SECONDS_DEFAULT);
207

208
209
        Support::setIfNotSet($config, DOCUMENTATION_QFQ, DOCUMENTATION_QFQ_URL);

210
        Support::setIfNotSet($config, SYSTEM_FILL_STORE_SYSTEM_BY_SQL, SYSTEM_VAR_ADD_BY_SQL_DEFAULT);
211

212
213
214
215
216
        return $config;
    }

    /**
     * Rename Elements defined in config.qfq.ini to more appropriate in user interaction.
Carsten  Rose's avatar
Carsten Rose committed
217
218
     * E.g.: in config.qfq.ini everything is in upper case and word space is '_'. In Form.parameter it's lowercase and
     * camel hook.
219
220
     *
     * @param array $config
Carsten  Rose's avatar
Carsten Rose committed
221
     *
222
223
224
225
226
227
     * @return array
     */
    private static function renameConfigElements(array $config) {

        // oldname > newname
        $setting = [
228
            [SYSTEM_FORM_BS_COLUMNS, F_BS_COLUMNS],
229
230
231
232
233
234
235
236
237
238
239
            [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],
240
            [SYSTEM_ESCAPE_TYPE_DEFAULT, F_ESCAPE_TYPE_DEFAULT],
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

            [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],

262
263
            [SYSTEM_EXTRA_BUTTON_INFO_CLASS, FE_INPUT_EXTRA_BUTTON_INFO_CLASS],

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
        ];

        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;
    }
}