User tests: Successful: Unsuccessful:
Overcoming the issue that changes to a user's authorised groups are not detected and applied immediately to the related user while it is logged in i created a workaround with the following flow:
This allows for immediately applied groups- and levels updates through an admin in the backend to a logged in user without this user having to log out and in again for the changes to take effect (tested with storage handlers 'Database' and 'XCache').
EDIT
I feel unsure if this solution is stable or might pull up new issues. I got the idea that some kind of collision might occur while i inject the refresh-flag, because an active user actively uses its session, which means, data is got and set by the JSession handler. This must somehow be circumvented (yet).
Another idea was to use a semaphore like text file in the file system to track the ACL change and force the user session to refresh. This might prevent from direct user session data manipulation.
Ideas and impressions are highly welcome!
Find the related tracker item as well as testing instructions at joomlacode.org
Thanks Nicholas for your feedback. Here is what i have tested so far:
APC
not tested ... cannot be tested since it is getting uninstalled as soon as XCache is getting installed.
Database
works ... simply enabled this handler in the backend (no further configuration made)
XCache
works ... simply enabled this handler in the backend (no further configuration made - no data caching with XCache)
Memcache and Memcached
not tested ... require some issues to get fixed first.
WinCache
not tested ... cannot be tested since my devel machine is a linux machine and this handler requires Windows.
Also these handlers appear incomplete to me. They lack the 'read'-, 'write'- and 'gc'-methods one can find in the Database- and XCache-handlers. From what i read they require sort of a TCP connection to allow for reading/writing data. But mabe i'm mixing this up with the cache handler. I feel pretty unsure about them as session handlers and am not sure if i'm giving wrong information here - especially as i suppose that incomplete classes wouldn't get released. So, mabe the session handlers are properly working and i'm just making something wrong, but i couldn't figure out what so far.
What i could successfully test was to get them activated and registered as session handlers through the backend after applying the above mentioned patch. But that's it. I couldn't (yet) figure out where the session data is stored nor how to retrieve the serialized session data string to hack in my little tweak. There is pretty less information about Memcache(d) as session handler available.
When i inspected the self named cache handlers from /libraries/joomla/cache/storage/ folder i noticed much more CRUD functionality and immediately got the idea that part of it should be ported to the session handlers - at least the getConnection method. So, i suggest not to use them as session handlers until futher clarity. Correct me, if i'm wrong, please! I'm always willing to learn and open for constructive criticism. I have to state that my knowledge in these handlers is pretty low, which is why i depend on other users' input and suggest to collaborate. But i'll keep trying to figure out how to adopt my Database-/XCache-ready PR to it.
My intention was to provide a working base (beside the requirement for my own project) and trigger the motivation of others to participate and provide knowledge, ideas and experience once the first step was taken. I'm sure there are many experienced coders around that might be very helpful. And to be honest, i also hoped for you as i know your extensions and the quality code you deliver. ;-)
I'm almost sure that my solution could be adopted to other handlers as the workflow is simple. One reason for previous issues were the JUser::getAuthorizedGroups() and JUser::getAuthorizedViewLevels() methods where the related object properties were updated only when been empty. This was changed to a forced update thus ensuring they always hold the latest state. With that in place the only one question left was: "How to propagate this change from within the backend to the frontend and there to the logged in user?"
I think, we have to create session unserializers for the Memcache(d) handlers first before we can do further testing and development. With them available the problem should be almost solved as the rest stays always the same: Inject the 'refresh' flag into the unserialized session data object of the related user in the backend and find this flag in the user session in the frontend thus triggering the the user object replacement in the session data object.
Like i said my knowledge regarding the Memcache(d) handlers is very limited, as is my time to spend on 'em. So i depend on other developers' support. Also, i think that we should consider how urgent/important/expensive it is to adopt to the other handlers as i suppose that most users go with the database handler as preferred storage. Mabe we should start a poll about this aspect at google joomla-dev group and evaluate if the cost for a generic plugin development might (not) be too high.
Description | <p>Overcoming the issue that changes to a user's authorised groups are not detected and applied immediately to the related user while it is logged in i created a workaround with the following flow:</p> <ol> <li>Changes made to a user object's groups and levels are catched by the onUserBeforeSave handler and dumped in a temporary plugin property.</li> <li>After the changed data was stored, the user object's groups are newly loaded and compared to the previously dumped property. If something changed, the related user's session data is loaded from the database table by a new JSessionHelper, parsed into a human readable format and extended by a new entry indicating that the user's session must be refreshed. This data is then stored back into the session table.</li> <li>If the related user is logged in while this change is made, its session is automatically updated on the next page reload, thus receiving the refresh-flag previously set in step 2. A newly added system plugin evaluates the user's session and in case this flag is detected, updates the user's groups and levels, loads it's session data from the database, replaces it's user object property by the currently logged in user's object data and stores the update back into the database.</li> </ol><p>This allows for immediately applied groups- and levels updates through an admin in the backend to a logged in user without this user having to log out and in again for the changes to take effect <em>(tested with storage handlers 'Database' and 'XCache')</em>.</p> <p><strong>EDIT</strong><br> I feel unsure if this solution is stable or might pull up new issues. I got the idea that some kind of collision might occur while i inject the refresh-flag, because an active user actively uses its session, which means, data is got and set by the JSession handler. This must somehow be circumvented (yet).<br> Another idea was to use a semaphore like text file in the file system to track the ACL change and force the user session to refresh. This might prevent from direct user session data manipulation.<br> Ideas and impressions are highly welcome!</p> <p>Find the related tracker item as well as testing instructions at <a href="http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_id=8103&tracker_item_id=33293">joomlacode.org</a></p> | ⇒ | <p>Overcoming the issue that changes to a user's authorised groups are not detected and applied immediately to the related user while it is logged in i created a workaround with the following flow:</p> <ol class="task-list"> <li>Changes made to a user object's groups and levels are catched by the onUserBeforeSave handler and dumped in a temporary plugin property.</li> <li>After the changed data was stored, the user object's groups are newly loaded and compared to the previously dumped property. If something changed, the related user's session data is loaded from the database table by a new JSessionHelper, parsed into a human readable format and extended by a new entry indicating that the user's session must be refreshed. This data is then stored back into the session table.</li> <li>If the related user is logged in while this change is made, its session is automatically updated on the next page reload, thus receiving the refresh-flag previously set in step 2. A newly added system plugin evaluates the user's session and in case this flag is detected, updates the user's groups and levels, loads it's session data from the database, replaces it's user object property by the currently logged in user's object data and stores the update back into the database.</li> </ol><p>This allows for immediately applied groups- and levels updates through an admin in the backend to a logged in user without this user having to log out and in again for the changes to take effect <em>(tested with storage handlers 'Database' and 'XCache')</em>.</p> <p><strong>EDIT</strong><br> I feel unsure if this solution is stable or might pull up new issues. I got the idea that some kind of collision might occur while i inject the refresh-flag, because an active user actively uses its session, which means, data is got and set by the JSession handler. This must somehow be circumvented (yet).<br> Another idea was to use a semaphore like text file in the file system to track the ACL change and force the user session to refresh. This might prevent from direct user session data manipulation.<br> Ideas and impressions are highly welcome!</p> <p>Find the related tracker item as well as testing instructions at <a href="http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_id=8103&tracker_item_id=33293">joomlacode.org</a></p> |
Title |
|
Status | New | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2014-07-26 09:28:10 |
Note: commenting without having actually tested the code, for which I apologise in advance.
First off, thank you very much for this PR! I had been trying to solve the same issue on our own site for the last year and a half. Last week we wrote a plugin that forces a re-log in when a subscription is paid which is exactly when user group assignments do change. Basically, the same thinking as your plugin but only applied to a specific use case that was of interest to us. And yes, this idea works.
I only wonder about one small thing. This method works perfectly when you are storing the database session storage. I am wondering, does it also work when using APC, Memcache, XCache or any other kind of session storage that doesn't involve the db? That's the only reason I hadn't tried to write such a generic plugin so far (and I couldn't get these session storage drivers work at all on my development machines, killing my coding mood – bummer).