Limit visit allows an administer to set a limit on how often a user can access a page or set of pages based on the path in an hour.
The use case this was developed for involves a directory of users which points back to the user's profile page. The user's profile page may contain more personal information and possibly contact information. Preventing the number of times an hour someone can visit a user profile page deters them from mining e-mail addresses.
Project page: https://drupal.org/sandbox/geekygnr/2242557
Git repository: git://git.drupal.org/sandbox/geekygnr/2242557.git
Review of other projects
I am putting down all the comments I made in the project review area. I don't count all of them as full reviews but I would like to show that I am looking at the applications and trying to help where I can.
Actual reviews
https://www.drupal.org/node/2299443#comment-9032559
https://www.drupal.org/node/2328483#comment-9098161
https://www.drupal.org/node/2328637#comment-9101379
Just trying to help out
https://www.drupal.org/node/2301609#comment-9031721
https://www.drupal.org/node/2238015#comment-9032355
https://www.drupal.org/node/2328637#comment-9098925
https://www.drupal.org/node/2328637#comment-9101129
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | pa_review_automate_issues.txt | 4.36 KB | pushpinderchauhan |
| #11 | z.png | 30.86 KB | gisle |
Comments
Comment #1
PA robot commentedThere are some errors reported by automated review tools, did you already check them? See http://pareview.sh/pareview/httpgitdrupalorgsandboxgeekygnr2242557git
We are currently quite busy with all the project applications and we prefer projects with a review bonus. Please help reviewing and put yourself on the high priority list, then we will take a look at your project right away :-)
Also, you should get your friends, colleagues or other community members involved to review this application. Let them go through the review checklist and post a comment that sets this issue to "needs work" (they found some problems with the project) or "reviewed & tested by the community" (they found no major flaws).
I'm a robot and this is an automated message from Project Applications Scraper.
Comment #2
geekygnr commentedI have corrected all issues except one.
I have been unable to find how to solve this problem and I believe this is a false positive because the code that generates this error is in a 8.x branch.
Comment #3
GoRoost commentedValidated that comment #2 fix is accurate. Testing on stable d7 and saw the same error on Pareview.sh.
Aside from doc comment, Both Coder (Code Sniffer) and Pareview.sh come back clean.
- Module appears to work as expected, but only for logged in users. If public post, did not honor restrictions set by module. Based on use case provided above, this is likely not an important feature, but wanted to note it anyways.
- Need to t() value on line 42 - limitvisit.admin.inc
- Need to t() titles / descriptions in limitvisit.module
Aside from those small house-keeping fixes, I think you're good.
Comment #4
gbisht commentedLike Roost.Me I also found that module is taking all anonymous users as same because you are using uid to count user visits and uid for all anonymous users is 0. For this I think you should maintain visit count for anonymous user with some random value and store that random value in session or cookie so that they are separate for all anonymous users.
One more thing you module could be more useful if you can add functionality to assign role to particular rule, so that multiple rules can be add for same url with different roles.
Other than this your module looks good.
Comment #5
geekygnr commentedI fixed the lines Roost.Me pointed out that needed t().
I am aware of the point Roost.Me and gulab.bisht made about anonymous users. Perhaps I should have added that as an issue on the project page or something. Like Roost.Me said it isn't a part of my use case so it isn't an issue for me. It is an improvement I would like to make and gulab.bisht your suggestion about a value in a cookie or session is a good one. Since dealing with anonymous users is out side my use case I have had a hard time finding the time to dedicate to it. Gulab.bisht, your suggestion about role specific rules is also good.
My hope was to get approval on the module as it functions now and then improve upon it later or accept community contributions. From what I read on the review process I wasn't expecting this to be a problem. If it is please let me know what functionality needs to be added for it to meet the requirements of the review process and I will see what time I can pull together to complete it.
Thank you for your input.
Comment #6
gisleUnfortunately, Roost.me gave you some bad advice about adding the
t()function to "titles / descriptions".Manual review
You should not be using
t()in thehook_menu()title and description declarations. Menu automatically pushes title and description throught(), you'll end up with things being double-translated. See: function hook_menu in the API documentation.t()inhook_menu().Comment #7
geekygnr commentedThat may have been partially my fault, I was also missing them from the
hook_permissions()so I got carried away with adding them.I took out the
t()fromhook_menu().Comment #8
gisleManual review
Comment #9
gisleSorry, but I felt I had to do a more thorough review of this one, and the result of my second code walk-through is that it needs some work.
Automated Review
PAReview reported one issue (IMHO, this is a false positive).
Manual review
In function
limitvisit_admin_redirect, the fieldvalueis not sanitized. Entering<script>alert('XSS');</script>triggers an immediate XSS.hook_permission()("Implements hook_permissions().")variable_get(), it is best practice to use it. If you don't provide a default value, there will be an error if the variable requested does not exist.time(). UseREQUEST_TIMEinstead.Not:
$form_state['values']['value'] . ' ' . t('is not a valid path.'), but:t('@value is not a valid path.', array('@value' => $form_state['values']['value'])).limitvisit_admin_formis not validated before they're inserted into the database. Putting "X" in the field for hours triggers an PDOexception.The starred items (*) are fairly big issues and warrant going back to Needs Work. The rest of the comments in the code walkthrough are recommendations.
Please don't remove the
PAReview: securitysecurity tag, we keep that for statistics and to show examples of security problems.Comment #10
geekygnr commentedgisle can you walk me through how you got the XSS. I put that string in the field and submitted but it gave me the error that it wasn't a valid path and an alert didn't pop up.
I even tried making that the #default_value to see if that is what you meant and I didn't get an XSS.
The rest of the stuff... ya I really should have known better. Thanks for spotting it for me I will clean that up.
Comment #11
gisleIt comes from the "is not a valid path" error in the message area (note that the part of the message that should have echoed the path is missing).
To reproduce, put the CSS exploit in the textfield and press "Save Redirect" (as shown below):
Using the correct placeholder for variables in a translated string fixes it. Do not have:
But instead:
Comment #12
geekygnr commentedWell it is a little scary that I haven't been able to reproduce this but I made the change.
The latest change should cover everything on your list gisle. I need to look up and see if there is a way to have form_set_error highlight a field that is part of a array but that is a small UI issue.
Comment #13
geekygnr commentedI found the solution to my form_set_error problem. I was also able to reproduce the XSS on a friends mac.
The problem seems to be on my work station.
Comment #14
gisleYour code is still not secure:
Insecure (your code):
Secure:
Please read Altered the behaviour of placeholders in t() calls and notice that placeholders starting with "!" are not sanitized, but inserted as-is. Only placeholders starting with "@" and "%" are sanitized.
The rest is OK.
Comment #15
geekygnr commentedThat's weird I went off the e-mail notification I got about your comment and it !value as the example. My bad I have looked at the difference between in them in the past I just wasn't thinking.
I made the change.
Comment #16
deviantintegral commentedI don't think anything below blocks this from being promoted - it's mostly "would be nice" suggestions. They could probably be forked into new issues in the project queue. Everything else looks totally fine to me, so +1 on promoting this.
In README.txt:
This isn't a complete sentence - how about "For example, this can be used to help limit simple scraping of profile information from users with public profiles."
It's "Drupal" throughout the file :)
Typo here.
In limitvisit.admin.inc:
Drupal uses sentence case for buttons - so "Save redirect". There's probably a few other places for this too.
In
limitvisit_admin_redirect_validate()- you could simplify that a little by using an #element_validate callback on the text field. Then you can use form_error() directly. What you have is still perfectly functional though.In limitvisit.module:
In limitvisit_boot() - you could probably use the caching API to save on a DB call to load rules, especially as you can easily clear / reset it when you save the admin form.
You might be able to simplify some of this by using the Flood API - https://api.drupal.org/api/drupal/includes!common.inc/function/flood_is_...
Comment #17
geekygnr commentedI fixed the deviantintegral's points on README.txt and limitvisit.admin.inc
I am going to have to do some reading about the cache API and Flood API before I get to those changes.
Comment #18
geekygnr commentedI applied the cache API as per deviantintegral's suggestion and fixed some bugs I came across.
Comment #19
pushpinderchauhan commented@geekygnr, thankyou for your contribution.
Automated Review
PAReview reported some issues. See attachment.
Manual Review
Individual user account
Yes: Follows the guidelines for individual user accounts.
No multiple applications
Yes: No multiple application found.
No duplication
Yes: Not found any similar project.
Master Branch
Yes: Follows the guidelines for master branch.
3rd party code
Yes: Follows the guidelines for 3rd party code.
README.txt
Yes.
Code long/complex enough for review
Yes. Follows the guidelines for project length and complexity.
Secure code
Yes.
Coding style & Drupal API usage
1. You are opening up your README.txt file in hook_help() that's incorrect. I would personally recommend you, just give specific information about your module inside hook_help().
2. In following if statement, this code
&& !empty($element['#value'])can be removed becausedrupal_valid_path()take care of this. Also you can use#required => TRUEproperty with your form element.3. IMO, both field should be mandatory in
limitvisit_admin_form()form. Also Allowed visits per hour field contains validation for numeric value, it should be required. Because If it accept blank value then it contradict with your validation.As above point looks blocker to me so I am moving this to "NEED WORK".
As I am not a git administrator, so I would recommend you, please help to review other project applications to get a review bonus. This will put you on the high priority list, then git administrators will take a look at your project right away :-)
Thanks Again!
Comment #20
gisleer.pushpinderrana wrote:
@er.pushpinderrana, why are you saying that? Can you refer to a documentation guideline stating that showing the
README.txtfile inhook_help()is incorrect?Here is a link to the text about
hook_help()in the official Module documentation guidelines. There is even an example showing how to displayREADME.txtorREADME.mdinhook_help().Comment #21
pushpinderchauhan commented@gisle, thank you for correcting me.
Comment #22
geekygnr commented@er.pushpinderrana the !empty condition is there to accept an empty field. When that field is empty there is a defined behavior.
I have fixed the errors pareview.sh found and added some required field flags to the form. I couldn't add them to the fields used to create a new rule since that would force a user to create a new rule when all they want to do is edit an existing rule.
Comment #23
geekygnr commentedComment #24
geekygnr commentedComment #25
Michael Hodge Jr commentedAutomated Review
There is one error, but from comment #2 and #3, it's a false positive so you are good to go on the automated review front.
Manual Review
In your .install file, you define schema for storing data, but don't get rid of that schema when uninstalling the module. I would suggest adding drupal_uninstall_schema('limitvisit'); to hook_uninstall
Other than that I didn't see any issues as I went through and reviewed your code. I'm going to set this to RTBC as I don't feel the lack of the uninstall_schema warrants holding up the review process.
Comment #26
geekygnr commented@Michael Hodge Jr, from what I have read the drupal_uninstall_schema is a practice from D6 that is no longer needed in D7 (https://www.drupal.org/update/modules/6/7#install-schema). I did a complete uninstall of my module and the database tables were removed.
Comment #27
Michael Hodge Jr commentedAh you are correct! I wasn't aware that it wasn't needed anymore. Thanks for pointing that out!
Comment #28
geekygnr commentedComment #29
geekygnr commentedComment #30
geekygnr commentedComment #31
geekygnr commentedComment #32
geekygnr commentedComment #33
klausimanual review:
But that are not critical application blockers, so ...
Thanks for your contribution, geekygnr!
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 #34
geekygnr commentedThank you for the approval klausi. In response to your questions.
It's been a while but I remember when first developing this modules I tried for hook_init and hook_boot. At the time everything worked in hook_boot but not in hook_init. I couldn't really figure out the reason for it and I haven't gone that in depth into the bootstrap process.
Right now I am forcing them to pick number of visits per hour but I will add this as a feature request to my project for future development.
I used the 307 Temporary Redirect because it is a temporary redirect since that redirect will only exist for an hour. It seemed the most appropriate to me when I first started. Re-reading the Status Code Definations I see the reason for your question and after further reading I found that rfc2616 is obsolete. I found rfc7231 and from those descriptions I will change the status code to 403. It will also keep it consistent with the access_denied default.
Thank you for that point I will mark the admin permission as you suggested.
Thanks to everyone for their reviews and help.
Comment #35
geekygnr commentedAn update on the http status 307. drupal_goto doesn't work with 4xx status code errors and I don't know of a way to get around this.