Forums / Developer / Communication between extensions

Communication between extensions

Author Message

Quentin Villevieille

Tuesday 18 May 2010 3:22:22 am

Hi all,
I'm currently developing an extension to eZJSCore (called 'ajax'), in which I've defined a few AJAX methods that are called directly from Javascript on a specific URL.
I've got another extension that manages user authentication (called 'bizlogin'). It basically redirects to a specific website in which the user authentication is done.
I'm having trouble getting the current user in the 'ajax' extension. Actually, I always get the same "Anonymous" user. No matter what I do, I always get this bloody user... For example, I've tried to store the user info (basically its ID) in session at user authentication (in my 'bizlogin' extension, thus before the ajax call), and I get nothing in session in my 'ajax' extension.
I'm guessing that extensions have their own 'area', in which only them can work, and thus can't share anything between them. Please tell me I'm wrong!
Thank you in advance, guys!

Quentin Villevieille

Tuesday 18 May 2010 3:23:21 am

(I'm using eZPublish 4.2 if that's any help)

Nicolas Pastorino

Tuesday 18 May 2010 3:31:22 am

Hi Quentin, and welcome to the eZ Community !

Would you mind pasting here the backend code you are using ?

Cheers,

--
Nicolas Pastorino
Director Community - eZ
Member of the Community Project Board

eZ Publish Community on twitter: http://twitter.com/ezcommunity

t : http://twitter.com/jeanvoye
G+ : http://plus.tl/jeanvoye

Quentin Villevieille

Tuesday 18 May 2010 5:57:17 am

Thanks Nicolas!

No, I don't mind. There you go :

Here, I am in my "BizLogin" extension, checking if the user has already been authenticated. If so,

function checkUser( &$siteBasics, $url ) {

$this->initialiseSettings();

phpBIZ::setDebug($this->bizDebugLogFile);

phpBIZ::trace('Initialising phpBIZ...');
if (!isset($PHPBIZ_CLIENT) || !is_object($PHPBIZ_CLIENT)) {
phpBIZ::client(
$this->bizHost,
$this->bizPort,
$this->bizURI,
$this->wsHost,
$this->wsPort,
$this->wsURI
);
}
phpBIZ::trace('phpBIZ initialised.');

// check BIZ authentication
if (phpBIZ::checkAuthentication()) {
// get the username
$login = phpBIZ::getUser();
$user =& eZUser::fetchByName( $login );
if ( $user and $user->isEnabled( ) ) {
$userID = $user->attribute( 'contentobject_id' );
eZBizUser::setCurrentlyLoggedInUser( $user, $userID );
}
}
return parent::checkUser($siteBasics, $url);
}

...

And here, I am inside my AJAX extension, which is quite simple as you'll notice, and should return (as a json string) the current authenticated user.

public static function getClientTree() {

$items = array();

$user = eZUser::currentUser();

$text = "user: login=[$user->Login] email=[$user->Email]";

array_push($items, array(
text => $text,
leaf => true
));

return json_encode($items);
}

Instead of getting the current user, I get 'anonymous' all the time... :/

Nicolas Pastorino

Tuesday 18 May 2010 8:38:59 am

Hi again,

Could you tell us what's inside this :

$login = phpBIZ::getUser();

?

Cheers !

--
Nicolas Pastorino
Director Community - eZ
Member of the Community Project Board

eZ Publish Community on twitter: http://twitter.com/ezcommunity

t : http://twitter.com/jeanvoye
G+ : http://plus.tl/jeanvoye

Quentin Villevieille

Tuesday 18 May 2010 9:10:08 am

No probs!

The phpBIZ class is a simple container for the phpBIZ library. It provides BIZ authentication for web applications written in PHP.

Here's what's inside phpBIZ::getUser();

function getUser()
    {
        global $PHPBIZ_CLIENT, $PHPBIZ_AUTH_CHECK_CALL;
        if ( !is_object($PHPBIZ_CLIENT) ) {
            phpBIZ::error('this method should not be called before '.__CLASS__.'::client() or '.__CLASS__.'::proxy()');
        }
        if ( !$PHPBIZ_AUTH_CHECK_CALL['done'] ) {
            phpBIZ::error('this method should only be called after '.__CLASS__.'::forceAuthentication() or '.__CLASS__.'::isAuthenticated()');
        }
        if ( !$PHPBIZ_AUTH_CHECK_CALL['result'] ) {
            phpBIZ::error('authentication was checked (by '.$PHPBIZ_AUTH_CHECK_CALL['method'].'() at '.$PHPBIZ_AUTH_CHECK_CALL['file'].':'.$PHPBIZ_AUTH_CHECK_CALL['line'].') but the method returned FALSE');
        }
        return $PHPBIZ_CLIENT->getUser();
    }

where $PHPBIZ_CLIENT is a global object of the 'BIZClient' class which authenticates a user in the system. It basically returns the user which is set via a call to the setUser method... which is called by isAuthenticated or wasPreviouslyAuthenticated.

/**
     * This method is called to check if the user is authenticated (previously or by
     * tickets given in the URL
     *
     * @return TRUE when the user is authenticated; otherwise halt.
     *
     * @public
     */
    function isAuthenticated()
    {
        phpBIZ::traceBegin();
        $res = FALSE;
        $validate_url = '';
        if ( $this->wasPreviouslyAuthenticated() ) {
            phpBIZ::trace('The user is already authenticated.');
            $res = TRUE;
        }
        else
        {
            // calls the WS with the sessID got from the url.
            phpBIZ::trace('not previously authenticated');
            if (isset($_GET['sessID']))
            {
                phpBIZ::trace('there\'s a sessID : verifying it! ');
                $res = $this->checkSessionId( $_GET['sessID'] );
            }
        }
        phpBIZ::traceEnd($res);
        return $res;
    }
/**
     * This method tells if the user has already been (previously) authenticated
     * by looking into the session variables.
     *
     * @return TRUE when the user has already been authenticated; FALSE otherwise.
     *
     * @private
     */
    function wasPreviouslyAuthenticated()
    {
        phpBIZ::traceBegin();

        $auth = FALSE;

        // `simple' BIZ client (not a proxy): username must be present
        if ($_SESSION['force_logout']==1)
        {
            phpBIZ::trace('force_logout detected: force user disconnection.');
            unset($_SESSION['phpBIZ']['user']);
            $auth = FALSE;
        }
        
        if ( !empty($_SESSION['phpBIZ']['user']) ) {
            // authentication already done
            $this->setUser($_SESSION['phpBIZ']['user']);
            phpBIZ::trace('user = `'.$_SESSION['phpBIZ']['user'].'\'');
            $auth = TRUE;
        } 
        else 
        {
            phpBIZ::trace('no user found');
        }

        phpBIZ::traceEnd($auth);
        return $auth;
    }

Enjoy... ^^

Having said that, I still don't know whether it's possible to share data between extensions or not... Does someone have any clue about that?

Quentin Villevieille

Tuesday 18 May 2010 9:18:06 am

Sorry, I forgot to tell you, the following method is called, at first;

/** 
     * This method is called to check whether the ser is authenticated or not. 
     * @return TRUE when the user is authenticated, FALSE otherwise. 
     * @public 
     */ 
    function checkAuthentication() 
    { 
        phpBIZ::traceBegin(); 
         
        if ( $this->isAuthenticated() ) { 
            phpBIZ::trace('user is authenticated'); 
            $res = TRUE; 
        } 
        else 
        {
            // redirects to the Biz website, where authentication is done (or not!)
            $this->redirectToBiz(); 
             
            // never reached 
            $res = FALSE; 
        } 
         
        phpBIZ::traceEnd($res); 
        return $res; 
    }

Nicolas Pastorino

Thursday 20 May 2010 2:55:15 am

Hi Quentin,

From what i see i can understand you are not relying on eZ's built-in user management API. Hence your issue, probably. If i were you, and not knowing about all your development constraints, i'd stick to the normal user API, and retrieve the currently logged-in user as follows :

$currentUser = eZUser::currentUser();

This returns an eZUser object, with a bunch of useful information about the user, and the ability to check her access rights against what you are trying to achieve in your custom backend code.

Per your other question : "Is it possible to share data between extensions ?", i am not sure to properly understand. Would you mind giving a concrete example of what led you to this conclusion (and of what you would like to achieve) ?

Let us know,
Cheers !

--
Nicolas Pastorino
Director Community - eZ
Member of the Community Project Board

eZ Publish Community on twitter: http://twitter.com/ezcommunity

t : http://twitter.com/jeanvoye
G+ : http://plus.tl/jeanvoye

Paul Leclercq

Thursday 20 May 2010 4:29:06 am

Hello Quentin,

>> Instead of getting the current user, I get 'anonymous' all the time... :/

We also faced this issue once in the past, our issue was to create multiple uploads in the backoffice, also using 2 extensions, which had different rights.

The ajax would recreate an anonymous user to deal with the request.

I believe there are 2 workarounds for this issue

1) either you give anonymous access, to this function which will allow you to transfert the data as you which.

Or else

2) you send your users ID, and reconnect with the user you wish to use using
$user = eZUser::fetchByName( $userLogin );
$user->loginCurrent();
Then replace the session variable with the initial one, which you can send in your ajax request.

I believe that if this function, is not highly critical, the first workaround may be the simplest

Quentin Villevieille

Tuesday 25 May 2010 5:47:41 am

@Nicolas
You're right, I don't use eZPublish authentication system. This must be done via an external site. In my website (called "ajax_bizviewer"), after the authentication process has been done, when i ask for the current user, i get the correct user (in this case, i never get "Anonymous").
I do use the "eZUser::currentUser()" method. If I call it inside my BizLogin extension, I do get the current user. But if I call it inside my "ajax" extension, i get the anonymous user....
When I wrote about "sharing data between extensions", I meant "Is there a way to share the user's ID/info or to store it somewhere?" ...
What I try to do is fairly simple. First, I want the authentication to be done by a external website. It's working fine. Secondly, I want the "ajax" extension to know which user is connected, so as to get filtered data according to his rights.
@Paul
Are you saying that there's no way for an extension to know the current user?
As for your workarounds, I don't think it's gonna work. I have to know what user is logged in ( so as to get filtered data according to his rights)...
By the way, thanks again for your help, guys! Hope I'll find a way!