-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ISLANDORA-1651: Caching respectful anonymous SESSION handling #101
base: 7.x
Are you sure you want to change the base?
Conversation
BookmarkDefaultSessionList::createNewList is being called with completely wrong arguments, passing the user as description (and storing it into the session)
This change pushes the $_SESSION creation logic deeper into the logic of the module, allowing anonymous users not making actual use of bookmarks to keep making use of existing cache. Also fixes some bugs.
Clean Up 1/X
5/x and some t() issues. See https://www.drupal.org/docs/7/api/localization-api/dynamic-or-static-lin ks-and-html-in-translatable-strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't gone through this in detail yet, just noticed this quickly.
islandora_bookmark.module
Outdated
$form['islandora_bookmark']['lists'] = array( | ||
'#type' => 'item', | ||
'#prefix' => '<h3>' . t('Bookmarked in') . ':</h3>', | ||
'#markup' => theme('item_list', array('items' => $links)), | ||
'#prefix' => t('<h3>Bookmarked in:</h3'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing closing tag here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this change existing translations, since its changing whats in the T?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonathangreen it is giving me
"Do not concatenate strings to translatable strings,
they should be part of the t() argument and you should use placeholders
". wonder if i should use place holders.. maybe? See https://www.drupal.org/docs/7/api/localization-api/dynamic-or-static-links-and-html-in-translatable-string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got away using #prefix and #sufix on the other few cases, but not possible here really.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonathangreen 7a598e4 should fix the issue so translation stays stable. Only way to have coder pass.
This will avoid having to -retranslate existing bits for “Bookmarked in”, note that : is kept out as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes are good. They solve the issue where if an anonymous user can use bookmarks, then they will never be able to use cached pages, even if they never use bookmark. That functionality works great.
I see a few issues, all somewhat related.
- When toggling variable_get('islandora_bookmark_create_user_default_lists', FALSE) the default list is always displayed
- anonymous users can no longer create new lists
- the default list disappears when a new list is created
@@ -38,14 +38,20 @@ function islandora_bookmark_get_user_owned_bookmarks($type = NULL) { | |||
|
|||
// User is anon, use session as well. | |||
if ($user->uid == 0) { | |||
if (!isset($_SESSION) || empty($_SESSION['islandora_bookmark']) && variable_get('islandora_bookmark_create_user_default_lists', FALSE)) { | |||
BookmarkDefaultSessionList::createNewList(t('My Default List'), 'bookmark_default', $user); | |||
if (!isset($_SESSION) || !isset($_SESSION['islandora_bookmark']) || empty($_SESSION['islandora_bookmark']) && variable_get('islandora_bookmark_create_user_default_lists', FALSE)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will always show the default list even if the variable islandora_bookmark_create_user_default_lists
is set to false. This is a regression from the old module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section also causes a problem when an anonymous user creates a list. If there is nothing stored in the default list it just disappears at that point, when it should stay in the list if variable_get('islandora_bookmark_create_user_default_lists', FALSE)
is TRUE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonathangreen true.This pull was made probably before. Can´t remember. But can fix that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonathangreen i'm looking at the logic right now.
According to myself:
if (
( // Open "("
!isset($_SESSION) || // No SESSION
!isset($_SESSION['islandora_bookmark']) || // OR at least not a SESSION with an islandora_bookmark entry
empty($_SESSION['islandora_bookmark']) // OR it is there but it is empty
)//close ")"
&& variable_get('islandora_bookmark_create_user_default_lists', FALSE)) // and create default list is TRUE
So adding extra () around the session conditionals should be ok?. Which would mean in human language:
If all the session stuff is empty AND i´m asked to create a default list (evaluated to TRUE), then do it.
I wonder if you would be ok if I move all the anonymous user functionality directly into cookies? The original patch was to avoid the issue in a less disruptive way (seems like I had no luck in that department! but I read that there are a lot of expectations for anonymous user bookmark lists management. Like renaming and adding new ones. It's a bit novel for me since that type of behavior is normally reserved to logged in users in other systems, really can't find right now any other system hat allows so much freedom.
} | ||
|
||
if (!empty($_SESSION['islandora_bookmark'])) { | ||
foreach (array_keys($_SESSION['islandora_bookmark']) as $id) { | ||
$bookmark_list[] = BookmarkSession::getList($id); | ||
} | ||
if (count($_SESSION['islandora_bookmark']) == 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section poses problems if you try to create a list as an anonymous user. Since when you create a list it is always empty, this immediately deletes the list that was just created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to look at that because I can´t remember really the exact "why" of this. I slightly remember thinking anonymous users, which are a "bookmarking" burden, should not trust or rely on having multiple lists around and having them to be kept safely around because it depends on cookies) and we don´t even notify them that this storage is just session based and volatile. But again, need to dig deeper to know the why? Will have a solution/answer tomorrow. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Original implementation details was dealing with an end user who may have forgotten to log in before doing actions. Granted I 100% agree that session based management is not the correct route but turfing functionality is a tough sell imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will work on keeping existing use case alive. Just avoiding creation a session just because the form is presented. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonathangreen ok, true. Legacy code to remove stuck sessions and i don´t find any self notes that make that piece relevant anymore. Will fix somehow, i do need a functionality to clear $_SESSIONS if created and not in use to avoid stuff being carried over and over, but this is not the way. Also, if i move all to user cookies...
@jonathangreen still on this, have not forgotten it, just slow, very slow here. |
@@ -662,7 +668,7 @@ function islandora_bookmark_detailed_form_manage(array $form, array &$form_state | |||
$bookmark = Bookmark::getList($list_id); | |||
|
|||
// Manage. | |||
if ($bookmark->bookmarkOwner === $user->uid) { | |||
if ($bookmark->bookmarkOwner === $user->uid && $bookmark->getIsDeletable()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this not limit some actions below from being changed such as the name and descriptions, seeing as there is in access check in https://github.com/Islandora/islandora_bookmark/pull/101/files#diff-119271b109bd4f411bd92328c14d451eR697
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jordandukart will look at it tomorrow. I have some new code to pull in here to address @jonathangreen concerns. Also, some of this is a bit old and needs to brought up to date.
@jonathangreen. Side note, to debug islandora_usage_stats (vangrant) needs to be disabled, SESSION is used there too! https://github.com/ryersonlibrary/islandora_usage_stats/blob/d1bf50a62f2cc92a58fa882268bd48bc125d750c/includes/utilities.inc#L119-L124 Anyway. I will move 100% to cookies for anonymous users. This swapping between SESSIONS and cookies makes everything even more complicated. I noticed a security concern also with the current (not this pull) implementation. We don´t have a limit at all for how many anonymous lists can be created. Well happens that I could basically mimic n+1 submissions and fill a SESSION database with data that will persist for a long time (happens that there is no session invalidation per default since there is no log out for anonymous). Have this stuff on my cutting bench now, so please be patient until I got it solved, thanks |
Hey @DiegoPino any movement on this? |
@jordandukart will be done before code freeze. Got derailed but I have a working solution that addresses @jonathangreen concerns, but now I need to clean it up. If you have any ongoing/needed pulls you want to push now, go on, I can always rebase. Thanks |
@jordandukart also, sorry, time flies and I'm over committed with other stuff. I was not even aware this is from August. Will deal with this before our next committers call. |
No worries @DiegoPino, nothing pressing on our end! |
@DiegoPino Is this PR still relevant? |
Yes, it is. Not a simple issue to fix, but it is. |
Re assigning to me.... i will fix it this week (year 2018) |
ISLANDORA-1651: https://jira.duraspace.org/browse/ISLANDORA-1651
What does this Pull Request do?
Islandora bookmark allows anonymous users to manage Bookmarks by displaying a Block to add PIDS and keeping Bookmark info available using the global $_SESSION PHP variable. When that happens, Drupal initialises a full blown SESSION using SESSxxxx cookie,
(see https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_settings_initialize/7)
same used by Drupal to track current logged in users.
This prevents caching systems like Varnish or Memcached to detect correctly if a page is being viewed by an anonymous user (and candidate for caching) or by a logged User (different caching strategy, if any).
A Drupal session in place for anonymous users adds performance penalties. Read
http://facingworlds.com/drupal-7-bootstrap-explained-drupalbootstrapsession-and-drupals-session-handling.
This PULL request avoids initializing the SESSION in question at all when not needed and only makes use of it when an Anonymous user actually saves something to a Bookmark session, instead of when just exposed to the functionality as before. This fix has been in production at DCMNY.org for over a year already.
Relevant to cookie creation:
https://github.com/Islandora/islandora_bookmark/pull/101/files#diff-3196d324ec7e08230f97233bfabca6ffR95
What's new?
Islandora Bookmark Drupal Block for Anonymous users can be used without caching penalties.
How should this be tested?
If running under Varnish/Memcached and without this fix, verify Session cookies when the Bookmark Block provided by this module is enabled for anonymous users. You should see SESSxxxx even if not using bookmarks at all, just by accessing an object's page that displays the block. Look at your caching headers. You will see that Varnish simply skips caching once the Block is displayed (even once) for all the lifespan of that cookie, on any page of an islandora Site.
Enable this module and reset your browser ( the previous cookie will survive even an Atomic bomb). make sure the cookie is gone. All existing functionality should still work, but if anonymous does not add an Object to PID then SESSxxxx should not be around.
If you want to be even finer, you can test page loading times with and without patch when displaying the Bookmark Block. With the Fix it should be faster, the amount will vary of course.
Additional Notes:
This Pull request includes a lot of Drupal Coding Standards fixes because:
No
No
No
No
Interested parties
@Islandora/7-x-1-x-committers @jonathangreen @adam-vessey @jordandukart