1. Description
Antispam module by CleanTalk to protect Drupal sites from spambot registraton and spam comments publication.
Key features.
- No needs in CAPTCHA, etc.
- Protection from spambots and manual spam comments.
- Automoderation - automatic publication of relevant comments.
Similar projects.
Mollom, Akismet.
What CleanTalk is.
CleanTalk is a SaaS spam protection service for Web-sites.
CleanTalk uses protection methods which are invisible for site visitors.
Using CleanTalk eliminates needs in CAPTCHA, questions and answers, and other methods of protection, complicating the exchange of information on the site.
How it works.
Messages or registration requests are sent to the CleanTalk cloud, data is tested with several methods on the cloud, then the site receives a response decision - to approve or deny the message/registration.
Requirements.
This module depends on both Libraries API module and CleanTalk PHP-antispam classes.
- Libraries API module - http://drupal.org/project/libraries
- CleanTalk PHP-antispam classes - https://github.com/CleanTalk/php-antispam
How to use.
- Get access key on CleanTalk.org;
- Install CleanTalk module and put access key into it's settings.
2. Sandbox link
https://drupal.org/sandbox/znaeff/2116907
3. Git link
git clone --branch 7.x-1.x http://git.drupal.org/sandbox/znaeff/2116907.git cleantalk
4. Reviews of other projects
https://drupal.org/node/2241231#comment-8791447
https://drupal.org/node/2129709#comment-8791465
https://drupal.org/node/2234281#comment-8791471
https://drupal.org/node/2193035#comment-8791459
https://drupal.org/node/2215325#comment-8791413
https://drupal.org/node/2243429#comment-8791419
Comments
Comment #1
PA robot commentedThere are some errors reported by automated review tools, did you already check them? See http://pareview.sh/pareview/httpgitdrupalorgsandboxznaeff2116907git
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
znaeff commentedAll automated review recommendations applied for all files except 2 ones: cleantalk.class.php and JSON.php :
Can I keep these files unchanged?
Comment #3
Vik commentedHi,
Please remove master branch and create new branch (like 7.x-1.x) then delete master branch also provide new link for git in issue summary.
Please change line
git clone --branch master znaeff@git.drupal.org:sandbox/znaeff/2116907.git cleantalk
to line
git clone http://git.drupal.org/sandbox/znaeff/2116907.git cleantalk
Thanks,
Vitaliy Sytnik
Comment #4
kamleshpatidar commentedHi znaeff,
First move your sandbox project from Master branch to Version branch. If you don't know, follow this Moving from a master to a major version branch.
Second thing, i have reviewd your project on pareview with your master git branch, it shows number of errors, that must be address first.
Kamlesh Patidar
Comment #5
znaeff commentedHi all.
1. Sandbox project seems to be moved from Master branch to Version branch.
2. Again:
I fixed pareview recommendation for all Drupal-specific fiels:
But these 2 files are not Drupal-specific:
And they both are looking as wrong for pareview of course.
So I'm asking - Can I keep these 2 files unchanged?
Comment #6
tr33m4n commentedHave you considered importing those files using Libraries? This would eliminate the pareview issues and would be a much more Drupal way of doing things
Comment #7
znaeff commentedWell, OK, thank you.
Comment #8
znaeff commentedHi All.
Project has been turned to Libraries module, all non-Drupal files are removed.
http://pareview.sh/pareview/httpgitdrupalorgsandboxznaeff2116907git reports no error now, just 3 warnings.
Please review project again.
Alexey.
Comment #8.0
znaeff commentedGit link changed.
Comment #9
bogdan1988 commentedHi , very nice module. While installation I had some problems but README.txt helped a lot.
Suggestions :
1) Please mention in description about libraries and CleanTalk PHP-antispam classes dependencies;
2) While I tried to install cleantalk through drush and I got message about cleantalk php classes. Please put some space before "'Make sure 2 files cleantalk.class.php and JSON.php are located there.";
3) In cleantalk_form_alter() you can use
4) In automated reviews there are some warnings about $form_state['input']. Do you really need this array and $form_state['values'] does not contain info you need.
Thank you, very nice module!
Comment #10
znaeff commentedHi Bogdan, thanks a lot for testing.
1. README.txt information added.
2. Spaces are added in messages.
3. Existing == operations are much faster than in_array() function call (up to 11,6 times on my local machine). So I'll keep current code here.
4. I need to alter the form exactly once in two cases: new rendered form and after Preview button pressed. But both $form_state['submitted'] and $form_state['executed'] cannot show correct form state unfortunately. But existing or omitted $form_state['input'] array can. I don't need its values, I just check existing of this array.
Thank you again!
Comment #11
znaeff commentedComment #12
znaeff commentedHi!
Is there any activity in reviewing this project?
Or there are some problems and I need to do something more?
Please let me know if any.
Regards.
Comment #13
znaeff commentedDear Drupal, all recommendations are done. Please continue to review thes module.
Comment #14
znaeff commentedComment #15
tr33m4n commentedHello there, please be patient, there are many other projects undergoing the review process and it can take a little time. If you want to speed up the process please help in reviewing other modules and themes and gain a review bonus as mentioned here https://drupal.org/node/1975228 ... Having a review bonus will put your module application on the high priority list
Comment #16
a_thakur commentedis used many times, using db_select() instead would be good idea.
Just a suggestion, will get back with detailed review.
Comment #17
klausiUsing db_query("SELECT .."); is fine and is preferred for simple static queries, see https://drupal.org/node/310075
Comment #18
znaeff commentedHi all, thanks a lot for your participation!
tr33m4n, no problem.
a_thakur, klausi - yes, there are 9 static select queries with placeholders, and performance is very important there.
https://drupal.org/node/310072
Comment #19
a_thakur commentedIn the above code change, remove 'access callback' => TRUE, setting access callback key of the menu item to TRUE, means that anyone can access the menu
and the cleantalk_settings_form($form, &$form_state) should go in a separate file called cleantalk.admin.inc
So the complete change should be
In the above code 'access callback' would be user_access which I have skipped as in case access callback is not included it is user_access and access argument is set to array('administer site configuration')
Comment #20
klausiGood catch, a_thakur!
Of course that is an access bypass security issue currently blocking this application. And please don't remove the security tag, we keep that for statistics and to show examples of security problems.'
Comment #21
znaeff commentedHi!
cleantalk_menu security fixes done,
cleantalk_settings_form moved to cleantalk.admin.inc file.
Comment #22
znaeff commentedComment #23
znaeff commentedPriority is increased to Major according to this article:
https://drupal.org/node/539608
Comment #24
ram4nd commentedJust a code review.
Comment #25
ram4nd commentedComment #26
znaeff commentedram4nd, thank you for reviewing.
Please explain next:
p.1, p.2 - "Do pareview bonus" and "Do pareview issues" - what does it mean? Give some links if any.
Comment #27
ram4nd commentedPareview issues - http://pareview.sh/pareview/httpgitdrupalorgsandboxznaeff2116907git
Review bonus - https://drupal.org/node/1975228
Comment #28
znaeff commentedram4nd, all pareview errors are fixed long time ago.
3 warnings are because of $form_state['input'] array using.
Due to this CMS behavior I need to use this array.
See my post #10 here for details.
Or suggest the better way to determine form state exactly.
Comment #29
ram4nd commentedSo $form_state['values'] won't work in your case?
Comment #30
znaeff commentedUnfortunately no.
Using $form_state['values'] results in double callings of my function.
These callings differ in $form_state['input'] values only so I need to use $form_state['input'].
It was a big surprise for me but it seems to be true.
Comment #31
znaeff commentedram4nd,
I use database abstraction layer in any cases but select queries. See discussion above, post #17:
Do you think that it's better to use database abstraction here?
Variables are deleted one by one, that's OK.
drupal_exit() instead of exit() is done also.
Comment #32
znaeff commentedram4nd,
>Do pareview issues.
All is done. PAReview is clear. http://pareview.sh/node/554161/repeat (if you see old information just go to 'Repeat review' and press 'Submit branch').
>Use database abstraction layer instead of regular queries so your project supports different kinds of databases.
All is done. There are no db_query() calls at all.
>It is suggested to remove your variables one by one instead of using LIKE.
Done.
>Use drupal_exit insead of exit.
Done.
>Consider making templates out of bigger chunks of html.
This is just empty white page with short informational string. I think template is excess here. Do you?
Comment #33
znaeff commentedComment #34
duozerskCode review:
*** cleantalk.info
configure = admin/config/cleantalk(Minor) I would advise to change it to "admin/config/content/cleantalk" so it gets positioned under "Content authoring" + change hook_menu() accordingly (like Mollom does).
*** cleantalk.install
(Normal) Use variable_del() function instead of DB queries and remove cache_clear_all() call.
(Minor) Variables should be starting with full module name (to prevent namespace collision); it's better to rename them before the 1st stable release or you would need to implement hook_update_N() to rename them. Marked as minor as I don't think there will be a module named "ct".
function cleantalk_requirements()(Minor) You don't need to use the DRUPAL_ROOT in the file_exists() calls - just $path should be enough.
function cleantalk_enable()(Normal) Why do you need it? - hook_requirements() should be enough, right?
*** cleantalk.module
(Normal) Why do you need these constants?
function cleantalk_form_alter()// drupal_set_message($form_id); // print form ID - great for gebug!(Minor) While it is great for debug - xdebug is much better :) I would recommend to remove this line.
(Major) Looks like you are protecting comment forms only for article and page content types.
You'd better use the hook_form_BASE_FORM_ID_alter() for comments - https://api.drupal.org/api/drupal/modules%21system%21system.api.php/func...
It will be
function cleantalk_form_comment_form_alter(&$form, &$form_state, $form_id)that will action on all comment forms.function cleantalk_entity_presave()(Minor) HUGE... might be good to move chunks of code to separate functions.
function cleantalk_comment_view_alter()(Major) Completely wrong permissions checking. You should use just user_access('administer comments').
You shouldn't check if user is logged in or not; you shouldn't check if user has administrator role; and you definitely don't need to calculate what roles have the 'administer comments' permission. Just simple plain user_access('administer comments').
You can also use your own permission if you want - see hook_permission() and user_access().
*** cleantalk.admin.inc
(Minor) variable_get('ct_key', 'enter key') - these calls should be consistent; here you use 'enter key', in 2 other places just ''
You can do this in the form element:
'#default_value' => $ct_key ? ct_key : 'enter key',(Normal)
<a target="__blank" ...- why do you use 2 underscores here?(Normal) You should use
'#element_validate' => array('element_validate_integer_positive')for the 'ct_comments' form element - then the $ct_comments_min variable won't be needed and your checks at the start can be removed. It will simplify this function.*** Overall:
(Minor) Hard to read the complex if () statements - need to check what Drupal code standard tells about it.
README.txt
(Minor) Typo "registraton"
(Minor) "it's" should be changes to "its":
- "3. Install CleanTalk module as usual and put access key into it's settings."
- "* Try to put comment with "stop_word" in it's body."
I'm ready to mark it RTBC after the "Normal" and "Major" issues are fixed - all the others can be discussed and fixed later using the issue queue.
Thanks
AndyB
Comment #35
znaeff commentedduozersk (AndyB):
Thanks for detailed review.
Please check new code and comments below.
Unfortunately no. When I erase my library files manually, and then enable the module, hook_requirements() doesn't catch this, but hook_enable() does.
I see this is very unusual situation but I have to be sure that all needed files are present and admin is informed when not. I think it's better to keep this function. Do you?
I made 3 functions because of exactly 3 needed forms.
'enter key' is needed in admin form only.
So 4 minor your issues and 1 normal one are not fixed for now.
Comment #36
duozerskAlexey,
Good-good - marking as RTBC. My main concern was with permissions checking and you have fixed it. The next step is to wait for the project application admin to process this request. You can try to find one on IRC to speed up the process.
Regarding the comments:
Good to know. If it works this way when you test it and you are completely sure you need it - keep it. I would need to do my own check on this as in the modules I wrote in the past the hook_requirements() implementation can block the installation of the module.
Looks like misunderstanding here. I was talking that you are protecting comment forms only for the article and page content type. And if the user will create some custom content type and enable comments for it - then this content type comment form won't be protected by your module. And I was suggesting you the solution on how to hook on every comment form for any content type created by the user.
As for the fix you have implemented - you have created the 3 implementations of hook_form_FORM_ID_alter() - so you should fix the comment for them, it should be "Implements hook_form_FORM_ID_alter()." for all 3 functions. And then in the
_cleantalk_form_alter()you don't need to check for these 3 form ids (the first if statement) - you will for sure get only one of these 3 ids there.Yes, I do understand this. What I was talking is that it should be the same default value in every call to variable_get() - so it should be
variable_get('cleantalk_authkey', '')and then the 'enter key' text should be used only in the form element - see above on the code I wrote for this.Also, as you have added the
'#element_validate' => array('element_validate_integer_positive')you don't need to keep the checks in the beginning of thecleantalk_settings_form()function. This element validation will ensure that the value is not lower than 1.Thanks
AndyB
Comment #37
znaeff commentedduozersk (AndyB),
First of all - may I make changes now or I have to keep code unchanged until admin processing?
Next:
I guess, it's good idea.
Comment #38
duozerskAlexey,
Sure, you can continue to improve the code. Hope your project will be approved soon.
AndyB
Comment #39
znaeff commentedduozersk (AndyB) and all,
Improvements:
Minor fixes:
Comment #40
znaeff commentedComment #41
znaeff commentedMajor fixes:
Fixed typo in table names w/prefixes.
Minor fixes:
Changed comment forms altering to a single hook_form_BASE_FORM_ID_alter.
Comment #42
znaeff commentedComment #43
klausiReview of the 7.x-1.x branch:
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:
Comment #44
znaeff commentedklausi:
Huge tanks!
Space is removed, descriptions are added.
About cleantalk_enable() - one question.
I explained cleantalk_enable() existing in comment #35:
It would be better to keep it IMHO.
Can I keep or not?
Comment #45
znaeff commentedklausi:
1. Done.
2. Done. Removed cleantalk_enable().
3. Done. Removed cleantalk_entity_presave(), use cleantalk_validate_register() and cleantalk_validate_comment() instead. CleanTalk server response is shown as form error.
4. Done.
5. Done. Long function is splitted to 3 shorter ones: cleantalk_validate_register(), cleantalk_validate_comment() and _cleantalk_check_spam().
6. Done.
7. Done in cleantalk_validate_register() and cleantalk_validate_comment().
8. Done where possible - in _cleantalk_check_spam(). But not in _cleantalk_set_ws() - cannot use db_merge because there are no key fields to merge. Comments are added.
9. Done.
10. Done, I store sanitazed value, see _cleantalk_filter_response().
11. Done, removed, it was from previous non-libreries code.
12. I cannot place JS in separate file. Because it is not static - I have to use generated values.
13. I need hidden element with id. But I cannot set this id by standard way.
Comment #46
mpdonadiopareview.sh came up clean, but there are a lot of long lines and some bad indentations. Fix these if possible.
cleantalk_settings_form(). Just use a blank value for the default; your description is fine.
Avoid HTML in t(). Make the link with l() and pass in as a placeholder. This occurs in a few places.
cleantalk_requirements(), avoid passing in variables to t().
(*) Don't disable the module just b/c the library dependency is missing. Just make it not functional. You have useful
info in that message which will go away.
Shouldn't comment be a dependency in the .info?
The number in cleantalk_validate_comment() should probably be a setting.
The query in cleantalk_validate_comment could be a single db_query(). It's not a dynamic query.
The syntax of your second query is a little weird. Instead of {comment}.subject you normallu set
your own table alias and then just use comment.subject
cleantalk_validate_comment() should use the Field API instead of direct access to the $node properties.
(*) You have a dependency on the Libraries API, but you aren't using it. See https://drupal.org/node/1342238,
in particular hook_libaries_info().
_cleantalk_form_alter(), use REQUEST_TIME instead of time().
_cleantalk_form_alter(), use drupal_html_id()?
The setTimeout() in _cleantalk_form_alter is bad. You can probably use inline JS to add something better.
(*) The hidden element and JS in _cleantalk_form_alter, along with directly accessing $_POST, is a
serious API issue.
(*) Figure out how to get rid of $GLOBALS['ct_request_id']. This will be really buggy in some situations. Same goes
for session variables. This really seems like it should be a fairly simple, synchronous process that is overcomplicated
right now. I would read through Mollom and Akisment for inspiration.
Can you just use variables for the server changes?
Use drupal_json_encode() instead of json_encode().
Comment #47
znaeff commentedDone when possible. Splitting of line 91 results in PAReview issue "Possible SQL injection".
Done
Done when possible. But I use t() according to official recommendation https://api.drupal.org/api/drupal/includes!common.inc/function/l/7
Done
No.
1. Such not functional modules result in huge amount of messages to our support. People don't like to understand any messages.
2. Functionality checking was present in previous module builds, but it was removed according to kalusi comment #43.
No because comment module is optional, we can protect registrations without comment enabled.
Done
Done
Done
Done, 'body' is a field so it's accessed by Fields API, but 'title' is not a field, it is property.
Done
Done, not only in _cleantalk_form_alter().
Done, removed at all because JavaScript checking algorithm is changed.
Done, JavaScript checking algorithm is changed.
Done. JavaScript checking algorithm is changed, hidden element is removed, $_POST access is removed.
Done, $_GLOBALS is gone. I use $_SESSION just to store request timestamp, now all $_SESSIONs are prefixed by drupal_session_start().
Done
Done
Comment #48
klausimanual review:
Looks like you forgot to commit and push the changes? Please work through my and mpdonadio's feedback again.
Comment #49
znaeff commentedAdded table fields descriptions.
Removed cleantalk_enable() at all, cleantalk_requirements() is enought, sure.
Comment #50
klausimanual review:
But that are not critical application blockers, so I think this is RTBC.
Assigning to dman as he might have time to take a final look at this.
Comment #51
dman commentedLooks like there has been lots of direct code review. I also visually scanned things, including the additional library (mixed tabs and spaces and other stuff there) but it doesn't look like there are any blockers left. I won't do another line-by-line.
Direct access to the SESSION and calling drupal_session_start() inside form_alter confuses me, but I can't understand the code well enough to see if there is a good reason for that. It's probably necessary I guess.
* I installed the module, and the library, and got an access key from the service...
* I simply could not find any menu item for configuration - not even on /admin/config . Even after checking permissions (despite being UID1) and flushing cache etc.
* I had to get into the code to find that the expected URL was /admin/config/cleantalk (It's not in the readme) . I don't know why this is hidden in this way.
* I pasted in the Access key, and it seemed to be valid.
* testing a registration with the blacklisted email was successfully blocked, but I could not see how to change the text that was displayed to the user.
* Also, and importantly, this action was not logged locally in the watchdog. Without that, I certainly would not be recommending anyone use this service as-is. You really need to log when a rejection like this happens so that admins have a chance of troubleshooting.
* I found that if the network or the remote service was unavailable for any period, the application that would normally be blocked was allowed straight through immediately, leaving forms that were previously protected unprotected. This connection failure was not logged either, meaning it looks possible for some bad submissions to go through which would otherwise be blocked, and leave no way to diagnose why they got through while others did not.
* I enabled comments and posted a comment with " stop_word in the body" but it went through. Wondered if that was my user account.
* I created and logged in with a new lesser user account in a new browser session, I was still able to post with " stop_word in the body " in that accounts first post and it got through.
* I gave that user ability to add articles, and fount that they could also still post nodes with stop_word in the body.
So, my current user assessment is that:
If you want to update the project description and clarify that the issues I think are pretty big are just "by design" or something then maybe the code can go up as a project, but generally we expect that a module actually works as advertised before that happens.
Given the time that has been spent on this project, the *code* looking OK, and the previous reviews, I'd really wanted to just give it a quick run-through and then promote it right now.
But right now it still seems unfit-for-purpose: "does not work for me". I'm not keen to promote a module that does not yet do what it says.
Comment #52
klausiOK, let's put this to "needs work" then and wait for znaeff to look into the issues. Thanks for the thorough review dman!
Comment #53
dman commentedAlexey has been in touch and we identified that my worst issues were due to a configuration issue on the server side. So that goes down to some documentation, and a policy adjustment on their end - not a code bug.
I still want to see some logging when this system is sending my submissions around the world and back, but I'm OK with that being a feature request. Same with the need to scan actual node or forum body submissions.
Whatever "Needs Work" I listed and is left can be dealt with in the project issue queue before a stable point release. And will be easier to work on there as individual issues.
Code presented here meets the project application standards, and the module is usable. Thanks for your patience and cooperation - so lets get this up finally!
--------------------
Thanks for your contribution, znaeff!
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 #54
znaeff commentedThanks a lot to all Drupal community, especially to klausi, dman, mpdonadio, duozersk, a_thakur!