Disabling Comments for Blacklisted IP addresses
I was reading through the discussions on Codeplex for Blogengine.NET, and a user (ALBsharah) had an interesting idea for controlling spam: if we can already determine that a user is blacklisted based on the IP, do not even give them the ability to post new comments. The thread is available here.
Making this change to BE is relatively simple. The first change was actually creating a function which would return whether the user is blacklisted. Comment moderation methods seem to be located in the CommentHandlers.as file in the BlogEngine.Core project. All of this code was actually already written in another method ( ModeratedByRule ), I just needed to extract that code out of that method, and modify that method to use the new code – I hate having code that does the same thing in two different places. So, where before the function looked like the following:
static bool ModeratedByRule(Comment comment)
{
// trust authenticated users
if (Thread.CurrentPrincipal.Identity.IsAuthenticated)
{
comment.IsApproved = true;
comment.ModeratedBy = "Rule:authenticated";
return true;
}
int blackCnt = 0;
int whiteCnt = 0;
// check if this user already has approved or
// rejected comments and belongs to white/black list
foreach (Post p in Post.Posts)
{
foreach (Comment c in p.Comments)
{
if (c.Email.ToLowerInvariant() == comment.Email.ToLowerInvariant()
|| c.IP == comment.IP)
{
if (c.IsApproved)
whiteCnt++;
else
blackCnt++;
}
}
}
// user is in the white list - approve comment
if (whiteCnt >= BlogSettings.Instance.CommentWhiteListCount)
{
comment.IsApproved = true;
comment.ModeratedBy = "Rule:white list";
return true;
}
// user is in the black list - reject comment
if (blackCnt >= BlogSettings.Instance.CommentBlackListCount)
{
comment.IsApproved = false;
comment.ModeratedBy = "Rule:black list";
return true;
}
return false;
}
It now looks like this:
/// <summary>
/// Checks if the IP or email is blacklisted
/// </summary>
/// <param name="IP">The IP of the user</param>
/// <param name="Email">The Email of the user</param>
/// <returns>true if blacklisted, false if whitelisted, or null if undetermined</returns>
public static Nullable<bool> IsBlacklisted(string IP, string Email)
{
int blackCnt = 0;
int whiteCnt = 0;
// check if this user already has approved or
// rejected comments and belongs to white/black list
foreach (Post p in Post.Posts)
{
foreach (Comment c in p.Comments)
{
if (
( Email != String.Empty && c.Email.ToLowerInvariant() == Email.ToLowerInvariant())
|| c.IP == IP
)
{
if (c.IsApproved)
whiteCnt++;
else
blackCnt++;
}
}
}
// user is in the white list - approve comment
if (whiteCnt >= BlogSettings.Instance.CommentWhiteListCount)
{
return false;
}
// user is in the black list - reject comment
if (blackCnt >= BlogSettings.Instance.CommentBlackListCount)
{
return true;
}
return null;
}
static bool ModeratedByRule(Comment comment)
{
// trust authenticated users
if (Thread.CurrentPrincipal.Identity.IsAuthenticated)
{
comment.IsApproved = true;
comment.ModeratedBy = "Rule:authenticated";
return true;
}
Nullable<bool> isBlacklisted = IsBlacklisted(comment.IP, comment.Email);
// user is in the white list - approve comment
if (isBlacklisted == false)
{
comment.IsApproved = true;
comment.ModeratedBy = "Rule:white list";
return true;
}
// user is in the black list - reject comment
if (isBlacklisted == true)
{
comment.IsApproved = false;
comment.ModeratedBy = "Rule:black list";
return true;
}
return false;
}
Next, a very simple change needed to be made to the CommentView.ascx.cs file, which actually handles the viewing of the comment section.
The following line was modified ( in /User controls/CommentView.ascx.cs):
if (BlogSettings.Instance.IsCommentsEnabled)
To this:
if (
BlogSettings.Instance.IsCommentsEnabled &&
BlogEngine.Core.CommentHandlers.IsBlacklisted(Request.UserHostAddress, String.Empty) != true
)