This is a simple module that allows a site admin to change the page text that a user sees after following the reset password one time email link.
Options allow for a few html tags, tokens, and site admin picture which may also be added by custom token created by this module.
Project page:
https://www.drupal.org/sandbox/ethant/2298305
Clone:
git clone http://git.drupal.org/sandbox/EthanT/2298305.git
Review Bonus Program reviews:
https://www.drupal.org/node/2151429#comment-8942309
https://www.drupal.org/node/2237645#comment-8942337
https://www.drupal.org/node/2224023#comment-8942393
https://www.drupal.org/node/2298389#comment-8943829
Post "Reviewed and Tested by Community" Tag reviews:
https://www.drupal.org/node/2295233#comment-8967121
https://www.drupal.org/node/2288977#comment-8967157
https://www.drupal.org/node/2284835#comment-8967213
https://www.drupal.org/node/2301217#comment-8967943
Comments
Comment #1
ethantComment #2
ethantComment #3
gisleYour git clone command contains your username and is for you only. It will not allow others to clone your project.
Had it worked it would have created a clone named "2298161" instead of a clone bearing your project's name.
Comment #4
ethantComment #5
ethantComment #6
ethantComment #7
ethantApologies, @gisle - I've updated and added a link to repo to be accessed by others.
Comment #8
gislePlease read the: Project application checklist before requesting a review.
For instance:
Your repo is currently non-existing: http://cgit.drupalcode.org/sandbox-EthanT-2298305/commit/?id=24afd04
Comment #9
ethantSorry for the confusion, @gisle, but I have pushed all files, and it can be checked out:
git clone http://git.drupal.org/sandbox/EthanT/2298305.gitThis returns module with all files.
I created a sandbox last night (that I scrapped), and it took more than 3 hours for my code to appear in the repository, however it was immediately available to clone.
Comment #10
ethantComment #11
gisleWell, it is available now, but it was not when I checked last time. Reviewers should be able to check out the project on the web as well as via git.
Btw, you need to remove the license blurb fro README.txt. Drupal will add the appropriate version automatically during packaging so your repository should not include it. See also: licensing requirements.
Comment #12
ethantThanks, @gisle - I've removed the licensing text from the README.
Comment #13
ethantComment #14
gwprod commented1.1 Ensure your application contains a repository and project page link.
Yes.
1.2 Ensure your project is not a duplication.
There might be, but I haven't seen any.
1.3 Ensure you don't have multiple applications.
Yes
2.1 Ensure the repository actually contains code.
Yes
2.2 Ensure you are working in a version specific branch.
Yes
3.1 Ensure the project does not contain any security issues.
I don't see any obvious security problems except for wrapping HTML in t(), but since it calls check_plain, they should be stripped.
4.1 Ensure the repository does not contain a ‘LICENSE.txt’ file.
It doesn't.
4.2 Ensure the repository does not contain any 3rd party (non-GPL) code.
It doesn't.
5.1 Ensure the project page contains detailed information.
The information isn't that advanced, but the use-case seems pretty straightforward.
5.2 Ensure the repository contains a detailed README.txt.
The information isn't that advanced, but the use-case seems pretty straightforward.
5.3 Ensure the code contains a well-balanced amount of inline-comments.
Contains inline comments, but some of these could be expanded to help reviewers understand what is being done.
6.1 Run an automated review and ensure there are no major issues.
FILE: /var/www/drupal-7-pareview/pareview_temp/README.txt
--------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
--------------------------------------------------------------------------------
21 | ERROR | Files must end in a single new line character
--------------------------------------------------------------------------------
The above is pretty trivial.
7.1 Ensure you are using Drupals API correctly.
Aside from the specific issues I've included below, everything seems in order.
Specific issues:
I don't really understand why you are using variable_del('new_user_load') and variable_set('new_user_load') in password_reset_form_tweaks_form_alter. variable_del and variable_set should be used for site_wide variables, but it looks like you're using them to store data on an instance-by-instance basis.
HTML should not be used in t() as you do in password_reset_form_tweaks_form() on line 131. https://www.drupal.org/node/2117055#comment-8838743
In password_reset_form_tweaks_form(), you have an array of elements, which could be laid out one line per element, as is required by the drupal coding standards.
You could also alter your description of password_reset_form_tweaks_message to use a replacement like "@allowed_tags" and then pass '@allowed_tags' => implode(', ', $allowed_tags)
Comment #15
ethantHey, @gwprod. Thank you for taking the time to review my code - I greatly appreciate it :-) .
I made the changes you suggested above, with one exception - I think I do have an ideal use case for variable_get, and variable_del. I'm passing one off user values to be available to tokens, so these vars do need to be available sitewide, however, since these are one-offs, I don't think I should be creating a table and storing said values - seems too heavy. Also, using cookies or session vars is messy, so I want to avoid this approach. I added a more expansive explanation for my thought process relating to this issue inside of my module notes. See this conversation, here: http://drupal.stackexchange.com/questions/36496/best-way-to-store-custom...
Thanks again!
Comment #16
ethantComment #17
dbcollies commented@EthanT I'm afraid I have to agree with @gwprod on the variable_get()/variable_set() issue. In reviewing the code, it looks to me like you have a potential race condition. If two (or more) users hit the password reset form at the same time, isn't it possible that user A will cause the variable to be set to their data, but, before the code gets to the token substitution, user B has set THEIR data in that variable, resulting in user A seeing user B's data. I know the code execution looks atomic, but you need to consider the multi process/multi threaded nature of most web servers.
]I'm not marking this as "Needs Work" because I'm certainly willing to be proven wrong. Besides, I'm not positive this is an actual blocker, though it certainly IS something I'd like to see resolved before a production version was released.
Comment #18
ethantYeah, you are right @dbcollies / @gwprod. I've now removed the variable_set / variable_del approach for the user name info, and have replaced with a global variable, ensuring that there won't be any potential for a race condition.
Thanks!
Comment #19
gwprod commentedI'll review your code again, it may be that there is no need for a global variable at all.
Comment #20
gwprod commentedI tested this module manually, and so far this is what I've gotten:
Notice: Trying to get property of non-object in password_reset_form_tweaks_tokens() (line 87 of
I think this problem lies in the fact that you are doing
Before testing to see that
Also, its unclear if this message should be generated on the confirmation dialogue from the reset link or on the login form after confirmation, or both.
The global user object is available on the second step, but not on the confirmation dialogue.
Regarding using the global variable $_user_load, you can pass data to the token_replace command, so you can do something like this:
And in password_reset_form_tweaks_tokens(), you can retrieve it by doing
No globals required.
Comment #21
ethantThanks, @gwprod.
-----------------------------------------------------------------------------
Notice: Trying to get property of non-object in password_reset_form_tweaks_tokens() (line 87 of
I moved this:
inside of the conditional, and it fixed the notice.
------------------------------------------------------------------------------
Also, its unclear if this message should be generated on the confirmation dialogue from the reset link or on the login form after confirmation, or both.
It's for both, and I added notes to .info description addressing this.
------------------------------------------------------------------------------
Regarding using the global variable $_user_load, you can pass data to the token_replace command, so you can do something like this:
Now I'm concerned about potential for race conditions, and when entering a second value in variable_get, you are essentially setting a persistent variable like you would with variable_set (if I understand the function notes). To be safe, I think I should stick with the global variable method.
Thanks!
Comment #22
gwprod commentedI don't see any potential for a race condition in the method I specified, since the request executes through and there is no sharing of data between requests in the way caused by the variable_set/get
By using the variable_set/get method, you were opening up to a potential situation where 1 user was setting the variable, which was then being read by another user, which is a security issue.
There is no good reason to use a global variable here. But that is my simple opinion.
Comment #23
ethantI don't see any potential for a race condition in the method I specified, since the request executes through and there is no sharing of data between requests...
Good point, @gwprod - I've updated my code per your suggestion.
Comment #24
gwprod commentedLooks good!
Comment #25
pushpinderchauhan commented@EthanT, your module looks good to me as well. As I reviewed your code and also installed on my local machine found, it throwing following warning after message submission on
admin/config/password-reset-form-tweakspage.Theme hook token_tree_link not found.Severity:
warningYou can also check the same on
admin/reports/dblogpage.Thankyou!
Comment #26
gwprod commentedGood catch, er.pushpinderrana. This module should have token as a dependency
Comment #27
ethantGood catch, @er.pushpinderrana - token is one of those things that I take for granted is part of core! I've added it as a dependency. Thanks to you too, @gwprod.
Comment #28
ethantComment #29
ethantSeems like the status of my project should now be "Reviewed and Tested by Community." I've addressed all concerns, and it has been 5 days since any new issues have been raised, or I've received a reply - prior to this comment, my project is the oldest on the "Needs Review" list that has the PAReview Bonus, but I've seen quite a few other issues (some without the review bonus) in the "Needs Review" column that are more recent than mine get moved along. It would be great if someone could help me with this.
I apologize if I seem impatient, I'm just worried that my issue has gotten lost in the fray.
Comment #30
dmouseI tested this module and working properly, good work =)
Maybe you could add the hook_help.
Comment #31
ethantThanks, @dmouse. Do you think this project qualifies for "Reviewed and Tested by the Community" status? I can't seem to get my project tagged as such, but I feel like I've gotten the thumbs up a couple / few times now. I'm not sure why my project isn't being moved.
Comment #32
pushpinderchauhan commented@EthanT, Thanks for your contribution.
I did manual review of your module and here are my notes:
1. At line 18 and 21, you are using user_load function, I think you can use this function single time instead twice.
2. I would recommend you, you must write a hook_help() function for your module.
3. I think in following code, you must check whether user have uploaded any picture.
If yes then following two line would be inside that if statement:
Rest looks good to me. Once you will do these change, I'll move to this RTBC :-)
I am not moving this to "Need Work" because these issues are not blocker, so you please do these changes.
Thanks again!
Comment #33
gwprod commented@er.pushpinderrana:
His module is loading two separate users, so two calls to user_load makes sense.
@EthanT:
I can see no good reason to create a variable for the admin thumb, then retrieve it in password_reset_form_tweaks_tokens. Either pass it as a replacement to token, or generate it inside password_reset_form_tweaks_tokens.
Is 'field_user_picture' a guaranteed user field? Is thumbnail a guaranteed style?
Look at https://api.drupal.org/api/drupal/modules%21user%21user.module/function/...
Comment #34
pushpinderchauhan commented@gwprod, thanks for correcting me, I missed that.
Comment #35
ethant@gwprod, are your comments blockers to move this over to Reviewed and Tested by Community?
Comment #36
mpdonadioReviewers, please remember to set the issue status when you are done with a review. Set it back to Needs Work if you find a major issue that needs to be fixed before the application get approved, or Reviewed and Tested By Community if you don't see any show stoppers. The Drupal.org project application workflow page has more information on this.
Comment #37
gwprod commented@EthanT
I don't think so, personally.
Comment #38
ethanthttps://www.drupal.org/node/2298271#comment-8965549
"I can see no good reason to create a variable for the admin thumb, then retrieve it in password_reset_form_tweaks_tokens."
1) I may want to reuse as I extend this module.
https://www.drupal.org/node/2298271#comment-8965549
"Is 'field_user_picture' a guaranteed user field?"
2) This is the default user picture field provided by User module that comes with core.
https://www.drupal.org/node/2298271#comment-8965549
"Is thumbnail a guaranteed style?"
3) Thumbnail is a default style provided by Image module that comes with core.
Comment #39
ethantComment #40
ethantComment #41
klausimanual review:
Comment #42
ethant"password_reset_form_tweaks_form_alter(): if you are only targeting one form you should use hook_form_FORM_ID_alter() instead."
DONE
""Set the value for the acct that will be passed to the token.": you mean account instead of acct?"
DONE
""$admin_pic_load->field_user_picture[LANGUAGE_NONE][0]['uri']": this will throw PHP notices if no admin picture is set on the admin user account, right?"
DONE - Implemented check for value to prevent errors.
"password_reset_form_tweaks_form_alter(): why do you perform a variable_set('admin_greeting_thumb', $admin_greeting_thumb); here? Please add a comment.
"variable_set('admin_greeting_thumb', $admin_greeting_thumb);": All variables defined by your module need to be removed in hook_uninstall().
variable_set('admin_greeting_thumb', $admin_greeting_thumb);: all variables used by your module need to be prefixed with your module's name to avoid name clashes with other modules."
DONE - all issues above addressed by following suggestion, here: https://www.drupal.org/node/2298271#comment-8965549
"password_reset_form_tweaks_form(): doc block is wrong, this is not a hook. See http://drupal.org/node/1354#forms"
DONE
"'access arguments' => array('access site configuration'),": that permission is not defined in drupal core. Did you mean "administer site configuration?"
DONE - yes
"'#default_value' => filter_xss(...),": filter_xss() is wrong here, #default_value will be automatically escaped by the form API. Make sure to read https://www.drupal.org/node/28984 again. password_reset_form_tweaks_form_alter() is the place where you must apply the sanitization (when user provided content is printed to HTML). Currently you don't sanitize there, so this would be an XSS security issue, but since you use a permission right now that does not exist only user 1 is able to input malicious stuff - and that user has all site-owning permissions anyway.
DONE
Comment #43
miroslavbanov commentedHi EthanT,
So I will proceed to do a manual testing of the functionality:
Fatal error: Unsupported operand types in includes/theme.inc on line 1087Also a suggestion:
Rather than using the administrator account picture, it would be more useful to upload a picture for this specific purpose.
Comment #44
ethantWhen the admin account doesn't have a picture, and I use tokens for the reset message, when the tokens are displayed, I get:
Fatal error: Unsupported operand types in includes/theme.inc on line 1087
Fixed - moved "$admin_pic_thumb" into conditional statement on line 88.
Why do you use such a restricted set of tags? I can't use paragraph. You should get the tags from filter_xss_admin() function instead
Done
Edit: forgot to mention before, I didn't see the configuration page "Password Reset Form Tweaks Settings" in admin/config, while using the default admin theme. I think you should move the menu callback from "admin/config/password-reset-form-tweaks" to "admin/config/people/password-reset-form-tweaks".
Done
Also a suggestion:
Rather than using the administrator account picture, it would be more useful to upload a picture for this specific purpose.
Thank you for the suggestion, but for now I only want to make the admin profile pic available - the idea is that the message is coming from the site's admin.
Comment #45
miroslavbanov commentedLooks OK to me.
Comment #46
mpdonadioAssigning to myself for next review.
Comment #47
mpdonadioAutomated Review
Review of the 7.x-1.x branch (commit a0efc56):
This automated report was generated with PAReview.sh, your friendly project application review script. You can also use the online version to check your project. You have to get a review bonus to get a review from me.
Manual Review
(+) The module name / short name is pretty bad :) I would think about a better one. I think you could generalize this to some of the other user forms that anon users see
so, maybe User Forms Help (user_forms_help) would be better?
A hook_help() would be nice.
I think a separate permission for this would also be handy. With the organizations I work with, this type of text wouldn't necesarilly be handled by someone
with full admin rights on the site.
In password_reset_form_tweaks_form(), your variable get needs a default value.
(+) You need a hook_uninstall() to delete the variable that you set in password_reset_form_tweaks_form().
You can move password_reset_form_tweaks_form() into a separate include, and then set the 'file' value on the menu $item. This helps with memory usage on live sites.
The docblock is wrong for password_reset_form_tweaks_form_user_pass_reset_alter(). It implements hook_form_FORM_ID_alter().
In password_reset_form_tweaks_tokens(), use REQUEST_TIME instead of time().
(+) password_reset_form_tweaks_tokens() should really use the Field API to get at values. See https://api.drupal.org/api/drupal/modules!field!field.module/group/field/7, and field_get_items and field_view_value.
The starred items (*) are fairly big issues and warrant going back to Needs Work. Items marked with a plus sign (+) are important and should be addressed before a stable project release. The rest of the comments in the code walkthrough are recommendations.
If added, please don't remove the security tag, we keep that for statistics and to show examples of security problems.
Blocking issues from #41 have been addressed. Been sitting at RTBC for a while now, so...
Comment #48
mpdonadioThanks for your contribution, EthanT!
I updated your account so you can promote this to a full project and also create new projects as either a sandbox or a "full" project.
Here are some recommended readings to help with excellent maintainership:
You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and stay involved!
Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.
Thanks to the dedicated reviewer(s) as well.
Comment #49
ethantAwesome! Thanks a bunch mpdonadio!
Comment #50
gwprod commentedCongrats on Fixed, @EthanT
Comment #51
pushpinderchauhan commentedCongrats @EthanT , Great thanks for your contribution!