%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/intranet.vacivitta.com.br/protected/modules/twofa/helpers/
Upload File :
Create Path :
Current File : /home/vacivi36/intranet.vacivitta.com.br/protected/modules/twofa/helpers/TwofaHelper.php

<?php

/**
 * @link https://www.humhub.org/
 * @copyright Copyright (c) 2020 HumHub GmbH & Co. KG
 * @license https://www.humhub.com/licences
 */

namespace humhub\modules\twofa\helpers;

use DateTime;
use humhub\modules\admin\Module as AdminModule;
use humhub\modules\content\components\ContentContainerSettingsManager;
use humhub\modules\twofa\drivers\BaseDriver;
use humhub\modules\twofa\Module as TwofaModule;
use humhub\modules\user\models\User;
use humhub\modules\user\Module as UserModule;
use Yii;
use yii\helpers\BaseIpHelper;
use yii\web\Cookie;

class TwofaHelper
{
    const USER_SETTING = 'twofaDriver';
    const CODE_SETTING = 'twofaCode';
    const CODE_CHARS = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';

    /**
     * Get settings manager of current User
     *
     * @return ContentContainerSettingsManager|false
     */
    public static function getSettings()
    {
        /** @var User $user */
        $user = Yii::$app->user->getIdentity();
        /** @var UserModule $module */
        $module = Yii::$app->getModule('user');

        return $user ? $module->settings->contentContainer($user) : false;
    }

    /**
     * Get setting value of current User
     *
     * @param string $name Setting name
     * @return string|null
     */
    public static function getSetting($name)
    {
        return ($settings = self::getSettings()) ? $settings->get($name) : null;
    }

    /**
     * Get setting value of current User
     *
     * @param string $name Setting name
     * @param string|null $value Setting value, null - to delete the setting
     * @return string|null
     */
    public static function setSetting($name, $value = null)
    {
        if (!($settings = TwofaHelper::getSettings())) {
            return false;
        }

        if (empty($value)) {
            // Remove empty setting from DB
            $settings->delete($name);
        } else {
            $settings->set($name, $value);
        }

        return true;
    }

    /**
     * Get Driver setting value of current User
     *
     * @return string|null
     */
    public static function getDriverSetting()
    {
        $driverClass = self::getSetting(self::USER_SETTING);

        /** @var TwofaModule $module */
        $module = Yii::$app->getModule('twofa');

        if (!in_array($driverClass, $module->getEnabledDrivers())) {
            $driverClass = null;
        }

        if (empty($driverClass) && self::isEnforcedUser()) {
            return $module->getEnforcedMethod();
        }

        return $driverClass;
    }

    /**
     * Get 2fa Driver by class name
     *
     * @param string Class name
     * @return BaseDriver|false
     */
    public static function getDriverByClassName($driverClassName)
    {
        if (empty($driverClassName)) {
            return false;
        }

        $driverClassName = '\\' . trim($driverClassName, '\\');

        if (class_exists($driverClassName)) {
            return new $driverClassName();
        }

        return false;
    }

    /**
     * Get 2fa Driver for current User
     *
     * @return BaseDriver|false
     */
    public static function getDriver()
    {
        return self::getDriverByClassName(self::getDriverSetting());
    }

    /**
     * Check if at least one Group of the current User is enforced to 2fa
     *
     * @return boolean
     */
    public static function isEnforcedUser()
    {
        if (Yii::$app->user->isGuest) {
            return false;
        }

        /** @var TwofaModule $module */
        $module = Yii::$app->getModule('twofa');

        $enforcedGroups = $module->getEnforcedGroups();
        if (empty($enforcedGroups)) {
            return false;
        }

        /** @var User $user */
        $user = Yii::$app->user->getIdentity();

        return $user->getGroups()->where(['in', 'id', $enforcedGroups])->exists();
    }

    /**
     * Get verifying code of current User
     *
     * @return string|null
     */
    public static function getCode()
    {
        return self::getSetting(self::CODE_SETTING);
    }

    /**
     * Returns a random code
     *
     * @param $len
     * @return string
     */
    public static function generateCode($len)
    {
        // To complex: return Yii::$app->security->generateRandomString($len);
        $noChars = strlen(static::CODE_CHARS);

        $code = '';
        for ($i = 0; $i < $len; $i++) {
            $code .= static::CODE_CHARS[rand(0, $noChars - 1)];
        }
        return $code;
    }

    /**
     * Hash code
     *
     * @param string $code Code value
     * @return string Hashed code
     */
    public static function hashCode($code)
    {
        return md5($code);
    }

    /**
     * Enable verifying by 2fa for current User
     *
     * @return bool true on success enabling
     */
    public static function enableVerifying()
    {
        $driver = self::getDriver();

        // Send a verifying code to use by driver
        if (!$driver || !$driver->send()) {
            // Impossible to send a verifying code by Driver,
            // because wrong driver OR current User has no enabled 2fa
            return false;
        }

        // Store the sending verifying code in DB to use this as flag to display a form to check the code
        if (!self::setSetting(self::CODE_SETTING, self::hashCode($driver->getCode()))) {
            return false;
        }

        // TODO: Inform user about way of sending the verifying code

        return true;
    }

    /**
     * Disable verifying by 2fa for current User
     *
     * @return bool true on success disabling
     */
    public static function disableVerifying()
    {
        // Remove the verifying code from DB:
        return self::setSetting(self::CODE_SETTING);
    }

    /**
     * Check if verifying by 2fa is required for current User
     *
     * @return bool
     * @throws \yii\base\NotSupportedException
     */
    public static function isVerifyingRequired()
    {
        // if impersonate mode of driver is not set up
        if (self::isImpersonateMode() || !self::getDriver()) {
            return false;
        }

        // if code is missing for a user, or user is trusted (ip whitelist)
        if (self::getCode() === null || self::isTrusted()) {
            return false;
        }

        // if user's ticked remember browser
        if (self::isBrowserRemembered()) {
            return false;
        }

        return true;
    }

    /**
     * Check if current User was logged in from administration action "Impersonate"
     *
     * @return bool
     */
    protected static function isImpersonateMode(): bool
    {
        $switchedUserId = Yii::$app->session->get('twofa.switchedUserId');
        if (empty($switchedUserId)) {
            return false;
        }

        if (Yii::$app->user->isGuest) {
            return false;
        }

        /* @var $adminModule AdminModule */
        $adminModule = Yii::$app->getModule('admin');
        if (!$adminModule->allowUserImpersonate) {
            return false;
        }

        /* @var $switchedUser User */
        if (!($switchedUser = User::findOne(['id' => $switchedUserId]))) {
            return false;
        }

        return $switchedUser->id != Yii::$app->user->id;
    }

    /**
     * Check the requested code is valid for current User
     *
     * @param string $code Code value
     * @return bool
     */
    public static function isValidCode($code)
    {
        $driver = self::getDriver();

        if (!$driver) {
            // Don't restrict current User if proper Driver is not selected
            return true;
        }

        return $driver->checkCode($code);
    }

    /**
     * Returns the display name for TwoFactor devices/apps
     *
     * @return string
     * @throws \Throwable
     */
    public static function getAccountName()
    {
        return Yii::$app->name . ' - ' . Yii::$app->user->getIdentity()->username;
    }

    /**
     * @return bool
     * @throws \yii\base\NotSupportedException
     */
    public static function isTrusted()
    {
        /** @var TwofaModule $module */
        $module = Yii::$app->getModule('twofa');
        foreach ($module->getTrustedNetworks() as $trustedNet) {
            if (BaseIpHelper::inRange(Yii::$app->request->userIP, $trustedNet)) {
                return true;
            }
            if (Yii::$app->request->userIP !== Yii::$app->request->remoteIP &&
                BaseIpHelper::inRange(Yii::$app->request->remoteIP, $trustedNet)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param int $days
     */
    public static function rememberBrowser($days = null)
    {
        // calculate expiration date
        $days = $days ?? Yii::$app->getModule('twofa')->getRememberMeDays();
        $expire = (new DateTime())->modify("+$days DAYS")->getTimestamp();

        // calculate array of remembered user's
        $twofaRememberCookie = Yii::$app->request->cookies->get('twofa_remember');
        $value = $twofaRememberCookie instanceof Cookie ? $twofaRememberCookie->value : [];
        $value[] = Yii::$app->user->id;

        // remember browser
        $cookie = new Cookie(['name' => 'twofa_remember', 'value' => $value, 'expire' => $expire]);
        Yii::$app->response->cookies->add($cookie);
    }

    /**
     * @return bool
     */
    public static function isBrowserRemembered()
    {
        if (empty(Yii::$app->getModule('twofa')->getRememberMeDays())) {
            return false;
        }

        if ($cookie = Yii::$app->request->cookies->get('twofa_remember')) {
            return in_array(Yii::$app->user->id, (array)$cookie->value);
        }

        return false;
    }
}

Zerion Mini Shell 1.0