yf_manage_security admin module

Fileplugins/sys/admin_modules/yf_manage_security.class.php
Useadmin URL ?object=manage_security

Public properties

A site sets them in its config with $PROJECT_CONF['manage_security']['NAME'] = ...;

PropertyDefaultDescription
$_country_names null
$_ip_to_country null

Public methods 5

show

public function show()
    public function show()
    {
        if ( ! main()->ADMIN_ID) {
            return _403();
        }
        $body = ''
            . '<div class="col-md-4">'
                . '<h3>' . t('Security settings') . '</h3>'
                . $this->_security_settings()
            . '</div>';
        return '<div class="container-block row" style="margin-top:20px;">' . $body . '</div>';
    }

Methods starting with _ hooks and helpers; not routable as page actions

public function _get_country_name($code)
    public function _get_country_name($code)
    {
        if ( ! isset($this->_country_names)) {
            $this->_country_names = db()->select('code', 'name')->from('geo_countries')->get_2d();
        }
        return $this->_country_names[$code];
    }
public function _get_ip_country($ip)
    public function _get_ip_country($ip)
    {
        if ( ! isset($this->_ip_to_country[$ip])) {
            $func = 'geoip_country_code_by_name';
            $this->_ip_to_country[$ip] = is_callable($func) ? $func($ip) : '';
        }
        return $this->_ip_to_country[$ip];
    }
public function _get_latest_auths()
    public function _get_latest_auths()
    {
        asset('bfh-select');
        $user_id = main()->USER_ID;
        return table(db()->from('log_auth')->whereid($user_id, 'user_id')->order_by('date DESC'), [
                'condensed' => true,
                'no_header' => true,
                'pager_records_on_page' => 50,
                'pager_num_records' => 50,
                'no_pages' => 1,
            ])
            ->func('date', function ($date) {
                return '<small>' . _format_date($date, 'long') . '</small>';
            }, ['nowrap' => true])
            ->func('ip', function ($ip) {
                return html()->ip($ip);
            })
            ->func('user_agent', function ($ua) {
                return '<small>' . $ua . '</small>';
            });
    }
public function _security_settings()
    public function _security_settings()
    {
        asset('bfh-select');

        $user_id = main()->USER_ID;

        $country_names = db()->select('code', 'name')->from('geo_countries')->order_by('name ASC')->get_2d();
        $countries = [];
        foreach ((array) $country_names as $code => $name) {
            $countries[$code] = [
                'code' => $code,
                'name' => $name,
            ];
        }
        $cur_ip = common()->get_ip();
        $cur_country = html()->_get_ip_country($cur_ip);

        $fields_ip = ['ip_whitelist', 'ip_blacklist'];
        $fields_country = ['country_whitelist', 'country_blacklist'];

        $a = db()->from('settings')->get_2d('item, value');
        if (is_post()) {
            foreach ($fields_ip as $k) {
                $tmp = [];
                foreach (explode(PHP_EOL, str_replace([' ', ',', ';'], PHP_EOL, trim(($_POST[$k] ?? '')))) as $v) {
                    $v = trim($v);
                    if (preg_match('~^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$~', $v)) {
                        $tmp[$v] = $v;
                    }
                }
                $_POST[$k] = implode(';', $tmp);
                if (($_POST[$k] ?? null) && $a[$k] != ($_POST[$k] ?? null)) {
                    $to_update[$k] = ($_POST[$k] ?? null);
                }
            }
            foreach ($fields_country as $k) {
                $tmp = [];
                foreach ((array) ($_POST[$k] ?? null) as $v) {
                    $v = strtoupper(trim($v));
                    if (isset($country_names[$v])) {
                        $tmp[$v] = $v;
                    }
                }
                $_POST[$k] = implode(';', $tmp);
            }
            $sql = [];
            $date = date('Y-m-d H:i:s');
            foreach (array_merge($fields_ip, $fields_country) as $k) {
                $v = ($_POST[$k] ?? null);
                if ( ! $v || $v === $a[$k]) {
                    continue;
                }
                $sql[$k] = [
                    'user_id' => $user_id,
                    'key' => $k,
                    'value' => $v,
                    'date' => $date,
                ];
                db()->insert_safe('user_settings_changelog', [
                    'date' => $date,
                    'user_id' => $user_id,
                    'key' => $k,
                    'val_old' => $a[$k],
                    'val_new' => $v,
                    'ip' => $cur_ip,
                    'ua' => ($_SERVER['HTTP_USER_AGENT'] ?? null),
                ]);
            }
            if ($sql) {
                db()->replace_safe('user_settings', $sql);
            }
            $a = (array) $_POST + (array) $a;
        }
        foreach ($fields_ip as $k) {
            $a[$k] = implode(PHP_EOL, explode(';', $a[$k]));
        }
        foreach ($fields_country as $k) {
            $tmp = [];
            foreach (explode(';', $a[$k]) as $v) {
                $tmp[$v] = $v;
            }
            $a[$k] = $tmp;
        }
        return form($a, ['autocomplete' => 'off', 'class' => 'form-vertical'])
            ->container('Current IP address: <b>' . $cur_ip . '</b>')
            ->container('Current country: <b>' . ($cur_country ? html()->icon('bfh-flag-' . $cur_country) . $country_names[$cur_country] : 'Not detected') . '</b>')
            ->container('<br />')
            ->textarea('ip_whitelist', 'IP address whitelist', ['label_tip' => 'security.ip_whitelist'])
            ->textarea('ip_blacklist', 'IP address blacklist', ['label_tip' => 'security.ip_blacklist'])
            ->chosen_box('country_whitelist', $country_names, ['multiple' => true, 'desc' => 'Country whitelist', 'label_tip' => 'security.country_whitelist'])
            ->chosen_box('country_blacklist', $country_names, ['multiple' => true, 'desc' => 'Country blacklist', 'label_tip' => 'security.country_blacklist'])
            ->container('<br />')
            ->save();
    }