Spam protection (CAPTCHA)
http://www.sitefinity.com/full-features-list.aspx states that there is spam protection.
As of which version is this available and on what modules.
Somehow I have missed that feature in the past.
Markus
Given some of the spam posts in this forum...
Good point, I dont know if Ive ever seen captcha anywhere (but my memory sucks). I havent played with the forums module though...definatly not in forms
@Telerik
Any answer on this
- Am I missing it
- If not Captchas can we expect them to come to 5.2 at least?
- Is the full-feature list wrong?
Markus
RadControls are included in Sitefinity, so I guess that strictly speaking, Captcha is included.
Hi Markus,
I think you can create a form field which holds a captcha?
Regards,
Daniel
@Daniel,
I think that's the problem we're talking about... :)
Captcha is promoted as a feature of SF, but there's no captcha IN sf outside of "do it yourself"
Still no answer from Telerik
Markus
Yeah, I'm getting just blasted by spam on my sites new feedback tab
I'm finding official forum responses are down these days...
Dear Steve
They are probably all working on the next verision and do forget about us :-) Just kidding.
Quote
In observance of Bulgarian Education and Culture Day, the Telerik Headquarter office in Bulgaria will be working with limited capacity on May 24th and 25th. All international offices will be open and working extended hours to assist during this time to ensure you receive the high level of service expected of Telerik.
We apologize for any inconvenience this may cause.
Telerik Team
Unquote
Markus
@Everyone,
01.
<
toolbox
name
=
"FormControls"
>
02.
<
sections
>
03.
<
add
name
=
"Common"
>
04.
<
tools
>
05.
<
add
enabled
=
"True"
06.
type
=
"Telerik.Web.UI.RadCaptcha, Telerik.Web.UI, Version=2012.1.215.40, Culture=neutral, PublicKeyToken=121fae78165ba3d4"
07.
title
=
"RadCaptchaForms"
08.
description
=
"RadCaptchaDescription"
09.
visibilityMode
=
"None"
10.
name
=
"RadCaptchaForms"
/>
11.
</
tools
>
12.
</
add
>
13.
</
sections
>
14.
</
toolbox
>
Nope...ok that works...but again...it's a hack. You're just adding in a custom control from Telerik.Web.UI, which means...
1) There's no designer
2) It's not in there by default on a new install
For all intents and purposes it's just a custom control
It also doesn't solve no captcha on comments. It's in fact a checkbox here: "/Sitefinity/Administration/Settings/Basic/Comments/" ...but does nothing. As far as I can tell the other checkboxes for fields also don't seem to work right either (website required, etc)
It's like saying Sitefinity can use WebAPI because you can reference the DLL
@Steve,
Hi all,
You can implement CAPTCHA for Sitefinity Forms the only thing that you have to do is to follow the instructions bellow:
1. Download the project for the custom control from the blog post.
2. Include it in your solution
3. Add in the SitefinityWebApp the Telerik.Sitefinity.Samples.Forms reference (Add Reference -> Projects)
2. Add in the Telerik.Sitefinity.Samples.Forms the following reference: Telerik.OpenAccess, Telerik.Sitefinity, Telerik.Sitefinity.Model, Telerik.Sitefinity.Resources, Telerik.Sitefinity.Utilities, Telerik.Web.UI if it is necessary.
3. Build the solution and run the project.
4. Go to Administration -> Settings -> Advanced -> VirtualPathSettings -> Virtual paths and add a new virtual path for the control, then restart the website. The virtual path should exist in your computer. If you use ~/SfControls/* you have to create SfControl folder in your project and include the Telerik.Sitefinity.Samples.Forms there. The resorce location should be Telerik.Sitefinity.Samples.Forms and the ResolverName: EmbeddedResourceResolver .
5. After that go to Administration -> Settings -> Advanced -> Toolboxes -> FormControls -> Sections -> Common -> Tools and register the custom control. The Control CLR Type or Virtual Path must be: Telerik.Sitefinity.Samples.Forms.FormQapTchaControl (namespace.class), the name of the control should be FormQapTchaControl. Type a title and save the changes.
6. Go to you project in Visual Studio.
5. Change your web configurations (web.config) by simply making a dummy change and save them.
8. Build the solution of your project.
9. Open your project and the changes should be made.
For you convenience that is working I have recorded s sample video demonstration.
As for the Captcha control in Sitefinity we have a feature request logged. You can track it at this public URL bellow and vote for its popularity:
http://www.telerik.com/support/pits.aspx#/public/sitefinity/10655
I hope we will be able to include such functionality for the next releases.
Kind regards,
Stefani Tacheva
the Telerik team
Dear Stefani
Thanks for the detailed answer. The original question was why CAPTCHA is promoted as a feature if you have to go through 9 steps to get it working :-)
http://www.sitefinity.com/full-features-list.aspx Under Security bottom right.
Again looking forward to missing stuff on up to date CMS system SF 5.2 or latest 5.3 (along with some other long awaited approvments that are NOT under the hood.
Markus
@Markus,
STEP 1)
Go to administration >> settings >> advanced >> toolboxes >> toolboxes >> page controls >> sections >> Radcontrols and check the 'enabled' checkbox :)
STEP 2)
Enjoy using RadCaptcha :)
---
Dear Jochem
LOL
a) I use RadControls on every project - for example for verticale menu with flyout :-)
b) telling me that since RadControls are included so it makes sense to mention CAPTCHA as feature is a bit far fetched and I say missleading.
Its like saying SF can send mails on forms submissions because there is an control on marketplace.
This even more then it mentions it has Spam Protection. And I don't see that. However you are right with rad controls and usercontrols SF realy is powerfull.
Markus
:)
All I'm saying is that we shouldn't get hung up on a marketing sales list, there's tons of good stuff I consider to be missing from the list and several items I consider sales talk...
Hi,
The JavaSctript should be enabled, because the captcha we are using is a jQuery QapTcha. It is a simple draggable captcha system which is build with jQuery and jQuery UI.
As for the Captcha control built into widgets in Sitefinity we have a feature request logged. You can track it at this public URL bellow and vote for its popularity:
http://www.telerik.com/support/pits.aspx#/public/sitefinity/10655
I hope we will be able to include such functionality for the next releases.
Regards,
Stefani Tacheva
the Telerik team
Couple things:
1) A 10 step process shouldn't be required when the CMS is marketed as having captcha
2) There are already backend settings captcha options which just don't work, and the 10 step add captcha to forms doesn't resolve that problem.
@Jochem,
Sure there's tons of small things...but why not get to work on putting them in over continually making blog posts to hack in the stuff after the fact. So like Rado made a nice blog post on adding captcha to SF in december...why not put that control into SF (it's now almost June). You have the code for it...have a dev plop it in over lunch or something... :)
@Steve
Rado probably didn't because it doesn't work. He's smarter than just clutter the code with a hack :)
@Steve: "why not put that control into SF (it's now almost June). You have the
code for it...have a dev plop it in over lunch or something... :)"
Because that would be to easy! ;)
Last comment by adam on that page is awesome :)
Just to verify then: the enable captcha for e.g. blog comments isn't working? This suggest that the captcha control should be enabled on the comments detail view, but I as far I'm seeing this is not doing anything.
So, can be 2 things:
1. I forgot some thing to configure
2. This checkbox is just for decoration. Can it be removed then please?!
Regards,
Daniel
The funny part about the checkbox is that in another thread when we pointed out a check that did nothing it wasn't classified as a bug...since it was never implemented :)
Well, there actually is a RadCaptcha control available inside the blog comment detail list.
Strange...
@Steve
LOL
I remember that and thought it was a rather strange answer back then.
Markus
The part I find most bemusing is that while this discussion of whether or not CAPTCHA is actually part of Sitefinity, this very forum continues to be spammed.
Ok, so turns out there IS captcha for the comments...but it only shows up when you are not logged in (FYI)
Hey Jochem - i added the RadCaptcha field to the toolbox, and to my form, but i can still submit the form without it being filled in. How do i go about making sure it actually gets validated?
Hi,
You have to validate whether the page is valid. Please take a look at this demo.
All the best,
Ivan Dimitrov
the Telerik team
Since there are no Sweeds in the thread, I'm just going to say it:
Blonde question but how do you envision this kind of validation on a Sitefinity form ?
On content>forms you can't add this validation. On the Forms widget you can't add extra validation.
So the only way something like that could work is by dropping a Javascript widget on the page where you drop the widget and mimic the code inside that script block.
Which is fun since that totally negates the re-use of forms as a widget because you'd manually need to add script widgets for each page where you post a form and it means the end-user can never create a new page with a form...
Or am I missing something here?
Jochem
You have to use a custom control (until they can just implement this...) that inherits from the regular forms control and then check the captcha on the BeforeFormSave event
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Linq;
using
System.Net;
using
System.Net.Mail;
using
System.Text;
using
System.Text.RegularExpressions;
using
Telerik.Microsoft.Practices.EnterpriseLibrary.Logging;
using
Telerik.Sitefinity.Configuration;
using
Telerik.Sitefinity.Modules.Forms;
using
Telerik.Sitefinity.Modules.Forms.Web.UI;
using
Telerik.Sitefinity.Modules.Forms.Web.UI.Fields;
using
Telerik.Sitefinity.Services;
using
Telerik.Sitefinity.Web.UI;
using
Telerik.Sitefinity.Web.UI.Fields;
using
Telerik.Web.UI;
namespace
FormsNotification
[Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesigner(
typeof
(FormsControlCustomDesigner))]
public
class
FormsControlCustom : FormsControl
private
const
string
LAYOUT_TEMPLATE_NAME =
"FormsNotification.Resources.FormsControl.ascx"
;
private
const
string
CLIENT_EMAIL_SUBJECT =
"Form Submission"
;
private
string
_clientEmailField;
protected
override
void
InitializeControls(GenericContainer container)
if
(!SystemManager.IsDesignMode)
//Hide the form if JS is disabled, it'll let them bypass the required fields.
base
.InitializeControls(container);
this
.BeforeFormSave +=
new
EventHandler<CancelEventArgs>(FormsControlCustom_BeforeFormSave);
#region EVENTS
protected
void
FormsControlCustom_BeforeFormSave(
object
sender, CancelEventArgs e)
bool
canSendEmail =
true
;
if
(
this
.MyCaptcha !=
null
)
if
(!
this
.MyCaptcha.IsValid)
e.Cancel =
true
;
this
.MyCaptcha.ErrorMessage =
this
.CaptchaErrorMessage;
canSendEmail =
false
;
if
(canSendEmail)
SendEmail();
/*
/// <summary>
/// Handles the submit button click event.
/// </summary>
/// <param name="control">The submit control.</param>
/// <param name="validationGroup">The validation group.</param>
protected override void ConfigureSubmitButton(System.Web.UI.Control control, string validationGroup)
//var submit = control as FormSubmitButton;
//submit.Click += new EventHandler(OnSubmitButton_Click);
base.ConfigureSubmitButton(control, validationGroup);
*/
/*
/// <summary>
/// The submit button click event handler.
/// </summary>
/// <param name="sender">Calling control.</param>
/// <param name="e">Event arguments.</param>
void OnSubmitButton_Click(object sender, EventArgs e)
SendEmail();
* */
private
void
SendEmail()
try
//String to hold the message content
var msgContent =
new
StringBuilder();
if
(!
string
.IsNullOrEmpty(Message))
msgContent.Append(
string
.Format(
"<p>0</p>"
, Message));
if
(IncludeFields)
//Start reading fields controls starting with the built-in types then the custom or generic types)
foreach
(var fieldControl
in
this
.FieldControls)
if
(fieldControl
is
FormTextBox)
msgContent.Append(String.Format(
"<p><strong>0:</strong> 1</p>"
,
((FormTextBox)fieldControl).Title,
((FormTextBox)fieldControl).Value));
if
(fieldControl.MetaField.FieldName.ToLower().Contains(
"email"
))
_clientEmailField = ((FormTextBox)fieldControl).Value.ToString().Trim();
else
if
(fieldControl
is
FormParagraphTextBox)
msgContent.Append(String.Format(
"<p><strong>0:</strong> 1</p>"
,
((FormParagraphTextBox)fieldControl).Title,
((FormParagraphTextBox)fieldControl).Value));
else
if
(fieldControl
is
FormCheckboxes)
string
choices = ((List<String>)((FormCheckboxes)fieldControl).Value).Aggregate(
string
.Empty,
(current, item) =>
current +
String.Format(
"0,"
,
item));
msgContent.Append(String.Format(
"<p><strong>0:</strong> 1</p>"
,
((FormCheckboxes)fieldControl).Title, choices));
else
if
(fieldControl
is
FormChoiceField)
msgContent.Append(String.Format(
"<p><strong>0:</strong> 1</p>"
,
((FormChoiceField)fieldControl).Title,
((FormChoiceField)fieldControl).Value));
else
if
(fieldControl
is
FieldControl)
var fldControl = fieldControl
as
FieldControl;
msgContent.Append(String.Format(
"<p><strong>0:</strong> 1</p>"
, fldControl.Title,
fldControl.Value));
else
foreach
(var fieldControl
in
FieldControls.OfType<FormTextBox>().Where(fieldControl => fieldControl.MetaField.FieldName.ToLower().Contains(
"email"
)))
_clientEmailField = (fieldControl).Value.ToString().Trim();
try
//Finally attempt to send the email(s)
var isMsgSent = SendEmailMsg(FromAddress, ToAddresses, CCAddresses, Subject, msgContent.ToString());
if
(!isMsgSent)
//TODO: add action when the email was not sent.
catch
(Exception ex)
if
(EnableLogging)
Logger.Writer.Write(CreateLogEntry(ex));
catch
(Exception ex)
Logger.Writer.Write(CreateLogEntry(ex));
private
LogEntry CreateLogEntry(Exception ex,
string
title =
"Email on form submission failed"
)
var logEntry =
new
LogEntry();
logEntry.Categories.Add(
"ErrorLog"
);
logEntry.Message = ex.ToString();
logEntry.Title = title;
return
logEntry;
#endregion
#region METHODS
/// <summary>
/// Determines whether the email address provided is valid using regular expression.
/// </summary>
/// <param name="email">Email address to validate</param>
/// <returns>True if valid, false otherwise</returns>
private
bool
IsValidEmail(
string
email)
//regular expression pattern for valid email
var pattern = @
"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
;
//Regular expression object
var check =
new
Regex(pattern, RegexOptions.IgnorePatternWhitespace);
//boolean variable to return to calling method
var valid =
false
;
//make sure an email address was provided
valid = !
string
.IsNullOrEmpty(email) && check.IsMatch(email);
//return the value to the calling method
return
valid;
/// <summary>
/// Attempts to sends an email message. If success, returns true. Else returns false.
/// </summary>
/// <param name="fromAddr">Who the email is from</param>
/// <param name="toAddr">Who the email is to (comma separate if more than one)</param>
/// <param name="ccAddr">Who should be cc'ed (comma separate if more than one)</param>
/// <param name="subject">Subject line of the email</param>
/// <param name="msgBody">content of the email</param>
/// <returns></returns>
private
bool
SendEmailMsg(
string
fromAddr,
string
toAddr,
string
ccAddr,
string
subject,
string
msgBody)
if
(!
string
.IsNullOrEmpty(fromAddr) && !
string
.IsNullOrEmpty(toAddr))
var mailServer =
new
SmtpClient();
var mailMsg =
new
MailMessage();
var clientMailMsg =
new
MailMessage();
var smtpSettings = Config.Get<SystemConfig>().SmtpSettings;
if
(!smtpSettings.Host.IsNullOrWhitespace())
mailServer.Host = smtpSettings.Host;
mailServer.Port = smtpSettings.Port;
mailServer.EnableSsl = smtpSettings.EnableSSL;
mailServer.Timeout = smtpSettings.Timeout;
if
(!
string
.IsNullOrEmpty(smtpSettings.UserName))
mailServer.UseDefaultCredentials =
false
;
mailServer.Credentials =
new
NetworkCredential(smtpSettings.UserName, smtpSettings.Password);
if
(IsValidEmail(fromAddr))
mailMsg.From =
new
MailAddress(fromAddr);
clientMailMsg.From =
new
MailAddress(fromAddr);
//Split the addresses into an array and check whether the specified addresses are valid
var arrToAddr = toAddr.Split(
new
string
[]
","
,
";"
, StringSplitOptions.RemoveEmptyEntries);
var arrCCAddr = ccAddr.Split(
new
string
[]
","
,
";"
, StringSplitOptions.RemoveEmptyEntries);
foreach
(var emailAddr
in
arrToAddr.Select(s => s.Trim()).Where(IsValidEmail))
mailMsg.To.Add(
new
MailAddress(emailAddr));
foreach
(var emailAddr
in
arrCCAddr.Select(s => s.Trim()).Where(IsValidEmail))
mailMsg.CC.Add(
new
MailAddress(emailAddr));
mailMsg.IsBodyHtml =
true
;
mailMsg.Subject = subject;
mailMsg.Body =
"<div style='font-family: verdana;font-size: .8em;'>"
+ msgBody +
"</div>"
;
if
(SendEmailToClient && IsValidEmail(_clientEmailField))
clientMailMsg.To.Add(_clientEmailField);
clientMailMsg.IsBodyHtml =
true
;
clientMailMsg.Subject = CLIENT_EMAIL_SUBJECT;
clientMailMsg.Body = ClientMailMessage;
try
mailServer.Send(mailMsg);
if
(SendEmailToClient && IsValidEmail(_clientEmailField))
mailServer.Send(clientMailMsg);
catch
(Exception ex)
if
(EnableLogging)
Logger.Writer.Write(CreateLogEntry(ex));
return
false
;
return
true
;
#endregion
#region Properties
private
RadCaptcha _captcha =
null
;
protected
RadCaptcha MyCaptcha
get
if
(!SystemManager.IsDesignMode)
foreach
(var control
in
this
.FormControls.Controls[1].Controls)
if
(control.GetType() ==
typeof
(RadCaptcha))
_captcha = control
as
RadCaptcha;
break
;
return
_captcha;
private
string
_captchaErrorMessage =
"Invalid Code, please try again"
;
public
string
CaptchaErrorMessage
get
return
_captchaErrorMessage;
set
_captchaErrorMessage = value;
/// <summary>
/// Gets or Sets the layout template name for the control.
/// </summary>
protected
override
string
LayoutTemplateName
get
return
FormsControlCustom.LAYOUT_TEMPLATE_NAME;
/// <summary>
/// Gets or Sets the address(es) to which the email will be delivered.
/// </summary>
[Category(
"Email Options"
)]
public
string
Subject
get
var propertyValue =
string
.Empty;
object
obj = ViewState[
"Subject"
];
if
(obj !=
null
)
propertyValue = obj.ToString();
else
var formId =
this
.FormId;
var formMgr =
new
FormsManager();
var formDescr = formMgr.GetForm(formId);
propertyValue = String.Format(
"0 1 - Submission"
, formDescr.ApplicationName.TrimEnd(
'/'
), formDescr.Title);
return
propertyValue;
set
ViewState[
"Subject"
] = value;
/// <summary>
/// Gets or Sets the message that is included in the body.
/// </summary>
[Category(
"Email Options"
)]
public
string
Message
get
var propertyValue =
string
.Empty;
object
obj = ViewState[
"Message"
];
if
(obj !=
null
)
propertyValue = obj.ToString();
else
var formId =
this
.FormId;
var formMgr =
new
FormsManager();
var formDescr = formMgr.GetForm(formId);
propertyValue = String.Format(
"A 0 has been submitted, login to your CMS to view the results"
, formDescr.Title);
return
propertyValue;
set
ViewState[
"Message"
] = value;
/// <summary>
/// Gets or Sets the address(es) to which the email will be delivered.
/// </summary>
[Category(
"Email Options"
)]
public
string
ToAddresses
get
var propertyValue =
string
.Empty;
object
obj = ViewState[
"ToAddresses"
];
if
(obj !=
null
)
propertyValue = obj.ToString();
return
propertyValue.Trim();
set
ViewState[
"ToAddresses"
] = value;
/// <summary>
/// Gets or Sets the address from which the email will be delivered.
/// </summary>
[Category(
"Email Options"
)]
public
String FromAddress
get
var propertyValue =
string
.Empty;
var obj = ViewState[
"FromAddress"
];
if
(obj !=
null
)
propertyValue = obj.ToString();
else
var smtpSettings = Config.Get<SystemConfig>().SmtpSettings;
if
(
string
.IsNullOrEmpty(propertyValue) && !
string
.IsNullOrEmpty(smtpSettings.DefaultSenderEmailAddress))
propertyValue = smtpSettings.DefaultSenderEmailAddress;
return
propertyValue.Trim();
set
ViewState[
"FromAddress"
] = value;
/// <summary>
/// Gets or Sets the address(es) of the CC to which the email will be delivered.
/// </summary>
[Category(
"Email Options"
)]
public
String CCAddresses
get
var propertyValue =
string
.Empty;
object
obj = ViewState[
"CCAddresses"
];
if
(obj !=
null
)
propertyValue = obj.ToString();
return
propertyValue.Trim();
set
ViewState[
"CCAddresses"
] = value;
/// <summary>
/// Gets or Sets the flag indicating whether error will be logged.
/// </summary>
[Category(
"Additional"
)]
public
bool
EnableLogging
get
var propertyValue =
false
;
object
obj = ViewState[
"EnableLogging"
];
if
(obj !=
null
)
propertyValue = (
bool
)obj;
return
propertyValue;
set
ViewState[
"EnableLogging"
] = value;
/// <summary>
/// Gets or Sets the flag indicating whether field names and values are included in the email
/// </summary>
[Category(
"Additional"
)]
public
bool
IncludeFields
get
var propertyValue =
true
;
object
obj = ViewState[
"IncludeFields"
];
if
(obj !=
null
)
propertyValue = (
bool
)obj;
return
propertyValue;
set
ViewState[
"IncludeFields"
] = value;
/// <summary>
/// Gets or Sets the flag indicating whether an email will be sent to the client after submission.
/// </summary>
[Category(
"Additional"
)]
public
bool
SendEmailToClient
get
var propertyValue =
false
;
object
obj = ViewState[
"SendEmailToClient"
];
if
(obj !=
null
)
propertyValue = (
bool
)obj;
return
propertyValue;
set
ViewState[
"SendEmailToClient"
] = value;
/// <summary>
/// Gets or Sets the message that is included in the body of the email that is sent to the client after submission.
/// </summary>
[Category(
"Email Options"
)]
public
string
ClientMailMessage
get
var propertyValue =
string
.Empty;
object
obj = ViewState[
"ClientMailMessage"
];
if
(obj !=
null
)
propertyValue = obj.ToString();
return
propertyValue;
set
ViewState[
"ClientMailMessage"
] = value;
#endregion
@Steve,
You've certainly earned your nickname today! Thanks for sharing, can't wait to see this in v5.2!
How importent CAPTCHAS are show this forum. anotheür 4 pages full of the same spam. I would $be embarresed as Telerik.
Markus
I just added the RadCaptcha control to the Forms toolbox as well. How do you force it to require and validate the captcha?
It looks like the solution in this thread have been outdated by the new forms subscription model. Does anyone have a workable captcha solution for 6.x?
I've asked support and was referred to this thread and this blog post that does not work when javascript has been turned off.
Hello,
I would suggest you to check the Akismet(http://akismet.com/) integration sample from the Sitefinity SDK.
Furthermore you could review this forum post:
www.sitefinity.com/.../how-to-add-captcha-in-custom-sitefinity-form-builder-
Regards,
Stefani Tacheva
Telerik