1st addon

Hi all,

I'm trying to create my first addon after reading the Creating Addon post by Lawrence.

My goal is implement a way to authenticate users without hashing the passwords... I know it is not a good practice, there are many security concerns, etc. But I'm doing it as an exercise and to learn about creating addons and authenticating in xenForo.

Everything I did:

Created the Add-on on CP, created an event listener:
Listen to Event: load_class
Event Hint: XenForo_Authentication_Core12
Execute Callback: PlainPassword_Listener_LoadClass::loadClassListener

In library folder, I have created the folder/files:
/PlainPassword/Listener/LoadClass.php
/PlainPassword/Authentication/PlainPassword.php

LoadClass.php:
Code:
<?php

class PlainPassword_Listener_LoadClass
{
        public static function loadClassListener($class, array &$extend)
        {

                if ($class == 'XenForo_Authentication_Core12')
                {
                        $extend[] = 'PlainPassword_Authentication_PlainPassword';
                }

        }

}

PlainPassword.php:
Code:
<?php

class PlainPassword_Authentication_PlainPassword extends XFCP_PlainPassword_Authentication_PlainPassword
{

    public function generate($password)
    {
        $output = array('hash' => $password);
        return serialize($output);
    }

    public function authenticate($userId, $password)
    {
        if (!is_string($password) || $password === '' || empty($this->_data))
        {
            return false;
        }

        return ($password == $this->_data['hash']);
    }

}

Everything went nearly ok... I can save a new password and authenticate properly. In "data" field of the XF_USER_AUTHENTICATE table I can see the password unhashed. But after authenticating, the "scheme_class" field changes from "XenForo_Authentication_Core12" to "PlainPassword_Authentication_PlainPassword" and I cannot authenticate anymore. If I manually change the "scheme_class" field back to "XenForo_Authentication_Core12", I can authenticate one more time, and the field changes again. When I try to change my password (with the changed scheme), I get this error:

Server Error
Cannot load class using XFCP. Load the class using the correct loader first.

  1. XenForo_Autoloader->autoload()
  2. spl_autoload_call() in H:/XF/library/PlainPassword/Authentication/PlainPassword.php at line 4
  3. include() in H:/XF/library/XenForo/Autoloader.php at line 119
  4. XenForo_Autoloader->autoload() in H:/XF/library/XenForo/Application.php at line 1011
  5. XenForo_Application::autoload() in H:/XF/library/XenForo/Application.php at line 457
  6. XenForo_Application::resolveDynamicClass() in H:/XF/library/XenForo/Authentication/Abstract.php at line 116
  7. XenForo_Authentication_Abstract::create() in H:/XF/library/XenForo/Model/User.php at line 1270
  8. XenForo_Model_User->getUserAuthenticationObjectByUserId() in H:/XF/library/XenForo/ControllerPublic/Account.php at line 1042
  9. XenForo_ControllerPublic_Account->actionSecurity() in H:/XF/library/XenForo/FrontController.php at line 347
  10. XenForo_FrontController->dispatch() in H:/XF/library/XenForo/FrontController.php at line 134
  11. XenForo_FrontController->run() in H:/XF/index.php at line 13
I read this type of error occuers when trying to instantiate extended classes by their extension names... It looks like it works when the system reads the original class name in "scheme class" field... But then it changes to my extension class name and I get this error.

Why it is writing the "scheme name" everytime I try to autenticate? And why it is writting the "scheme name" of the extension class as it can't be instantiated directly? I found in the XenForo_DataWriter_User::setPassword function a $this->set('scheme_class', $auth->getClassName()) call... Is it writting the extension class name instead of the original class name? And why it's being called during common authentication?

Sorry about my poor english... I'm Brazillian and, so, my native language is portuguese. And also sorry about so many questions... It's my first addon and I'm a kind of lost. :)

If you guys can give me any advice about what I'm doing wrong, and what should be the right path to code it properly I would be very glad to know!

Thanks in advance!
 
This is because XFCP_ is an internal proxy class prefix... if you are changing the schema directly, just extend the class 'XenForo_Authentication_Core12' directly, you wont need a listener for that...

EDIT:
Something like this:

PHP:
class PlainPassword_Authentication_PlainPassword extends XenForo_Authentication_Core12
{
    //your code...
}
 
Hi guys!

Thank you very much for all replies!

@Nobita.Kun, what is the "type of Code Listener"? I used the "load_class" listener. And I'm also not sure if it was the best listener to use... If there is a better option, please let me know!

@Mr. Goodie2Shoes, I don't need a listener for that? I thought I would need a listener everytime, so the extended code of the class could be executed. When do I need one and when I don't? Do you have any tutorial or article to recommend about it?

@Chris D, nice! The bug report shows exactly what I thought it was the cause of my problem! I even said about the "getClassName()" function writting the extended class name, and not the base one! The bug report says it's fixed... As I'm using the 1.4 RC2 version for testing, it should be there, right?

Another question is: Why the authentication module keeps rewritting the "scheme_class" field of XF_USER_AUTHENTICATE table everytime I log in? I would understand a writting there on password change, but not every authentication attempt...
 
@Chris D, nice! The bug report shows exactly what I thought it was the cause of my problem! I even said about the "getClassName()" function writting the extended class name, and not the base one! The bug report says it's fixed... As I'm using the 1.4 RC2 version for testing, it should be there, right?
It was only fixed this morning, so no. You won't get it until 1.4 RC3 or 1.4 Stable depending on which version is next.
 
Top Bottom