BlogEngine: Ban Users and Block Ratings Per Articles

by Jon Davis 3. January 2009 03:28

A reader (or two or three etc?) of my blog here makes the occasional one-star rating without sharing a comment. Sometimes this is fair and deserved.

Sometimes, however, I don't care what the heck you guys think of a few of my posts, because these occasional posts might be very personal, UNLESS you share your thoughts in comments. Thumbs-down is generally rude unless you post a comment with constructive criticism. I can take constructive criticism far better than I can take "this post sucks".

So I decided I wanted to be able to both ban visitors by IP address and disable ratings per post. The ban list can be maintained in SQL, and by the way the solution here is usable anywhere, not just BlogEngine.net (although it has no effect for FeedBurner RSS/Atom subscribers), but the other feature of per-post ratings disablement I felt should complement the "Enable Comments" feature in the post editor. These were two easy changes, so I'll make this quick.

Banning Users (Usable On Any ASP.NET Web Site)

 

Add a SQL table (IPAddress column is nullable so that other types of bans can be added later):

/****** Object:  Table [dbo].[Bans] ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Bans](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[IPAddress] [varchar](15) NULL,
 CONSTRAINT [PK_Bans] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

Add a new class file in the App_Code directory:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Data.SqlClient;
using System.Configuration;

public class SiteUtil
{
    public static bool IPIsBanned
    {
        get
        {
            try {
                IPAddress remoteIP = IPAddress.Parse(HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]);
                return BannedIPs.Find(addr => addr.ToString() == remoteIP.ToString()) != null;
            } catch {
                return false;
            }
        }
    }

    private static List<IPAddress> _BannedIPs = null;
    private static DateTime? _BannedIPs_TimeStamp = null;
    public static List<IPAddress> BannedIPs
    {
        get
        {
            if (_BannedIPs == null || (_BannedIPs_TimeStamp != null && 
                ((TimeSpan)(DateTime.Now - _BannedIPs_TimeStamp.Value)).Ticks > TimeSpan.TicksPerHour))
            {
                _BannedIPs = new List<IPAddress>();
                using (SqlConnection conn = new SqlConnection(
                    ConfigurationManager.ConnectionStrings["BlogEngine"].ConnectionString))
                {
                    conn.Open();
                    string ssql = "SELECT IPAddress FROM Bans WHERE IPAddress IS NOT NULL";
                    using (SqlCommand cmd = new SqlCommand(ssql, conn))
                    {
                        using (SqlDataReader dr = cmd.ExecuteReader())
                        {
                            while (dr.Read())
                            {
                                _BannedIPs.Add(IPAddress.Parse((string)dr["IPAddress"]));
                            }
                            _BannedIPs_TimeStamp = DateTime.Now;
                        }
                    }
                }
            }

            return _BannedIPs;
        }
    }
}

Add to global.asax:

  protected void Application_BeginRequest(object sender, EventArgs e)
  {
      if (SiteUtil.IPIsBanned) Response.Redirect("http://www.albinoblacksheep.com/flash/youare");
  }

Per-Article Ratings

 

Add SQL column:

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.be_Posts ADD
	IsRatingEnabled bit NOT NULL CONSTRAINT DF_be_Posts_IsRatingEnabled DEFAULT 1
GO
COMMIT

Create ~/themes/{theme}/MyPostView.aspx.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Configuration;

public partial class MyPostView : BlogEngine.Core.Web.Controls.PostViewBase
{
    protected override string Rating
    {
        get
        {
            return this.IsRatable ? base.Rating : "";
        }
    }

    protected bool IsRatable
    {
        get
        {
            return BlogEngine.Core.BlogSettings.Instance.EnableRating
                && !RatingDisabled(this.Post.Id);
        }
    }

    protected List<Guid> _RatingDisabledPosts = null;
    protected DateTime? _RatingDisabledPosts_TimeStamp = null;
    protected bool RatingDisabled(Guid postId)
    {
        if (_RatingDisabledPosts == null || (_RatingDisabledPosts_TimeStamp.HasValue &&
            (DateTime.Now - _RatingDisabledPosts_TimeStamp.Value).Ticks > TimeSpan.TicksPerHour))
        {
            using (SqlConnection conn = new SqlConnection(
                ConfigurationManager.ConnectionStrings["BlogEngine"].ConnectionString))
            {
                conn.Open();
                string ssql = "SELECT PostID FROM be_Posts WHERE IsRatingEnabled = 0";
                using (SqlCommand cmd = new SqlCommand(ssql, conn))
                {
                    using (SqlDataReader dr = cmd.ExecuteReader())
                    {
                        _RatingDisabledPosts = new List<Guid>();
                        while (dr.Read())
                        {
                            _RatingDisabledPosts.Add((Guid)dr["PostID"]);
                        }
                        _RatingDisabledPosts_TimeStamp = DateTime.Now;
                    }
                }
            }
        }
        return _RatingDisabledPosts.Contains(postId);
    }

}

Modify header line of ~/themes/{theme}/PostView.ascx:

<%@ Control Language="C#" AutoEventWireup="true" EnableViewState="false" Inherits="MyPostView" 
    CodeFile="~/themes/Standard/MyPostView.aspx.cs" %>

Modify ~/admin/Pages/Add_entry.aspx (add cbEnableRating between the two other checkboxes):

<asp:CheckBox runat="server" ID="cbEnableComments" Text="<%$ Resources:labels, enableComments %>" Checked="true" TabIndex="14" />
<asp:CheckBox runat="server" ID="cbEnableRating" Text="<%$ Resources:labels, enableRating %>" Checked="true" TabIndex="15" />
<asp:CheckBox runat="server" ID="cbPublish" Text="<%$ Resources:labels, publish %>" Checked="true" TabIndex="16" />

Modify ~/admin/Pages/Add_entry.aspx.cs:

// cbEnableRating: generally follow cbEnableComments

protected void Page_Load(object sender, EventArgs e)
{
    ...
	if (!String.IsNullOrEmpty(Request.QueryString["id"]) && Request.QueryString["id"].Length == 36)
	{
		...
	}
	else
	{
		... 
        cbEnableRating.Checked = BlogSettings.Instance.EnableRating;
        ...
    }
    ...
    cbEnableRating.Enabled = BlogSettings.Instance.EnableRating;
}

private void btnSave_Click(object sender, EventArgs e)
{
    ...
	post.Save();

    using (SqlConnection conn = new SqlConnection(
        ConfigurationManager.ConnectionStrings["BlogEngine"].ConnectionString))
    {
        conn.Open();
        string ssql = "UPDATE be_Posts SET IsRatingEnabled = @enabled WHERE PostID = @PostID";
        using (SqlCommand cmd = new SqlCommand(ssql, conn))
        {
            cmd.Parameters.Add("@enabled", System.Data.SqlDbType.Bit).Value 
                = cbEnableRating.Checked;
            cmd.Parameters.Add("@PostID", System.Data.SqlDbType.UniqueIdentifier).Value
                = post.Id;
            cmd.ExecuteNonQuery();
        }
    }

    ...
}

private void BindPost(Guid postId)
{
    ...
    using (SqlConnection conn = new SqlConnection(
        ConfigurationManager.ConnectionStrings["BlogEngine"].ConnectionString))
    {
        conn.Open();
        string ssql = "SELECT IsRatingEnabled FROM be_Posts WHERE PostID = @PostID";
        using (SqlCommand cmd = new SqlCommand(ssql, conn))
        {
            cmd.Parameters.Add("@PostID", System.Data.SqlDbType.UniqueIdentifier).Value =
                post.Id;
            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                dr.Read();
                cbEnableRating.Checked = (bool)dr["IsRatingEnabled"];
            }
        }
    }
}

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Blog | Web Development

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading




 

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Jon Davis (aka "stimpy77") has been a programmer, developer, and consultant for web and Windows software solutions professionally since 1997, with experience ranging from OS and hardware support to DHTML programming to IIS/ASP web apps to Java network programming to Visual Basic applications to C# desktop apps.
 
Software in all forms is also his sole hobby, whether playing PC games or tinkering with programming them. "I was playing Defender on the Commodore 64," he reminisces, "when I decided at the age of 12 or so that I want to be a computer programmer when I grow up."

Jon was previously employed as a senior .NET developer at a very well-known Internet services company whom you're more likely than not to have directly done business with. However, this blog and all of jondavis.net have no affiliation with, and are not representative of, his former employer in any way.

Contact Me 


Tag cloud

Calendar

<<  August 2020  >>
MoTuWeThFrSaSu
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar

RecentPosts