born05 / craft-twofactorauthentication

Craft plugin for two-factor or two-step login using Time Based OTP.
MIT License
36 stars 26 forks source link

Enforce usage for users #12

Closed baileydoestech closed 5 years ago

baileydoestech commented 6 years ago

Would it be possible for admins to enforce two factor authentication on users?

roelvanhintum commented 6 years ago

@lukebailey Not yet. For now you could do this manually by not granting rights other than cp util the user has activated 2FA. But this would be a good feature. So, this is going on the todo list.

RichardJong commented 6 years ago

I enforce it by redirecting users to the 2FA setup page if they're not verified, with the following module:

<?php

namespace modules\TwoFactorAuthentication;

use \Yii;

use Craft;
use born05\twofactorauthentication\services\Verify as VerifyService;
use craft\helpers\UrlHelper;

class TwoFactorAuthentication extends \yii\base\Module
{

    public function init() {
        parent::init();

        // Register Components (Services)
        $this->setComponents([
            'verify' => VerifyService::class,
        ]);

        $request = Craft::$app->getRequest();
        $response = Craft::$app->getResponse();
        $actionSegs = $request->getActionSegments();

        // COPIED from \vendor\born05\craft-twofactorauthentication\src\Plugin.php::init()
        if (
            $request->getIsCpRequest() &&
            (
                $request->getPathInfo() !== '' &&
                $actionSegs !== ['app', 'migrate'] &&
                $actionSegs !== ['users', 'login'] &&
                $actionSegs !== ['users', 'logout'] &&
                $actionSegs !== ['users', 'set-password'] &&
                $actionSegs !== ['users', 'verify-email'] &&
                $actionSegs !== ['users', 'forgot-password'] &&
                $actionSegs !== ['users', 'send-password-reset-email'] &&
                $actionSegs !== ['users', 'save-user'] &&
                $actionSegs !== ['users', 'get-remaining-session-time'] &&
                $actionSegs[0] !== 'updater' &&
                $actionSegs[0] !== 'debug'
            ) &&
            !(
                $actionSegs[0] === 'two-factor-authentication' &&
                $actionSegs[1] === 'verify'
            ) &&
            ! (
                $actionSegs[0] === 'two-factor-authentication' &&
                $actionSegs[1] === 'settings'
            )
        ) {
            // Get the current user
            $user = Craft::$app->getUser()->getIdentity(false);

            // Only redirect two-factor enabled users who aren't verified yet.
            if (isset($user) &&
                !$this->verify->isEnabled($user)
            ) {
                $url = UrlHelper::actionUrl('two-factor-authentication/settings/index');
                $response->redirect($url);
            }
        }
    }
}
roelvanhintum commented 6 years ago

@RichardFrontwise that is similar to what i had in mind. Probably would render a separate page without the rest of the ui, to clean it up. Hopefully i can write it this week.

roelvanhintum commented 6 years ago

I've added support for forcing 2fa for front end or CP users. Please let me know if you have any feedback!

baileydoestech commented 6 years ago

Thanks for the update, seeing an unknown error when non admins try to enable 2FA. For an admin this actually locked me out of the CP and I couldn't login so needed to restore the DB :-(

Also should there be anywhere in the CP where an admin can enforce 2FA per user or is this a global config setting?

roelvanhintum commented 6 years ago

@lukebailey Thanks, i'll check the non-admin thing. Remember, simply remove the user's twofactorauthentication_user record for disabling 2fa when you are locked out. You don't have to completely restore a db for this.

Forcing is a global setting for CP and front end seprated (forceFrontEnd and forceBackEnd).

baileydoestech commented 6 years ago

Ah good shout

roelvanhintum commented 6 years ago

@lukebailey 2.0.0-beta.10 Should fix the locking out issue.