0

Hi I'm trying to build a custom authentication plugin for an organization, and I'm having a hard time figuring out how to override the craft\controllers\UserController.actionLogin method. I tried hooking into AuthenticateUserEvent however this is fired after craft has already checked to see if a user exists. For our purposes we want to skip that entirely and solely use ldap to authenticate users. Here's ideally what I need to do.

  1. Check if the user with the given creds exists in ldap.
  2. If so, and they don't exist in craft, create a new user with those same creds.
  3. Forward the creds of the new or existing user to craft\controllers\UserController.actionLogin to finish logging them in to the admin panel.

Essentially I need to override that controller action and I can't find in the docs how to go about doing that. It also doesn't seem possible to override the login form template either? I realize if I could override that template then I can just call my own controller action.

Thanks for any help you can give!

1

Alright so I was actually misunderstanding how modules work with craft and yii. The init function in your module actually fires before crafts core controllers do, so you could use that to do whatever you need to do before the request continues on. I'm coming from WordPress so I thought I had to 'hook' into something. Here's an example of how you would override the login action on a post request. In the real world you would probably want to extract this logic to a Service but for the sake of clarity I'm just putting it in the init function here.

So, I guess the way to override any core controller is to look for that url or action in your modules init function and do whatever you need to do to override it.

namespace ldap;

use Craft;
use craft\elements\User;

class LdapModule extends \yii\base\Module
{
    public function init()
    {
        Craft::setAlias('@ldap', __DIR__);

        if (Craft::$app->getRequest()->getIsConsoleRequest()) {
            $this->controllerNamespace = 'ldap\\console\\controllers';
        } else {
            $this->controllerNamespace = 'ldap\\controllers';
        }

        parent::init();

        $isActionRequest = Craft::$app->getRequest()->getIsActionRequest();
        $isLoginAttempt = Craft::$app->getRequest()->getFullPath() === 'admin/actions/users/login';
        $isPostRequest = Craft::$app->getRequest()->getIsPost();

        if ($isLoginAttempt && $isPostRequest && $isActionRequest) {
            //...Ldap functionality and creating/activating new user if need be goes here. The request
            // will then continue on to crafts core UserController to log them in.

            // As an aside, if you want to create a user programmatically to login 
            // here's more or less how to do it.
            // @reference craft\controllers\UsersController.actionSaveUser
            $user = new User();
            $user->email = 'wolf@inyourface.com';
            $user->username = 'wolf';
            $user->firstName = 'Wolf';
            $user->lastName = 'Face';
            $user->pending = true;
            $user->newPassword = 'secret';
            if ($user->validate(null, false)) {
                Craft::$app->getElements()->saveElement($user, false);
                Craft::$app->getUsers()->activateUser($user);
                Craft::$app->getUserPermissions()->saveUserPermissions($user->id, ['accessCp']);
            }
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.