django-cms 2.0.2 and Django 1.2 – 1.3

If you are running an old version of django-cms, you can still upgrade Django. I would strongly suggest doing this since it’s very uncomplicated. However, if you are running django-cms 2.0, you should first upgrade to 2.0.2 and run the South migrations, which is also totally uncomplicated.

django-cms 1.x are most likely stuck on older versions of Django as well. I did once try to get them running on new Django versions but gave up.

Basically this guide just fixes a little bug in admin/pageadmin.py and a few issues regarding a missing csrf_token in the templates. It also means that django-cms 2.0.2 becomes SSL compatible. This is not backwards-compatible, however, so if you apply this stuff, your django-cms will no longer work with Django 1.1.

After upgrading to django 1.3.1 (also tested on 1.2.X btw), you need to make the following corrections manually in your django-cms installation.

1) Edit cms/admin/pageadmin.py, line 59 to say:

    exclude = []

2) Edit cms/templates/admin/cms/page/plugin_change_form.html, line 77, by adding the csrf_token tag:

<form id="{{ opts.module_name }}_form" action="{{ form_url }}" method="post" enctype="multipart/form-data">{% block form_top %}{% endblock %}
{% csrf_token %}

2.1) Do the same in cms/templates/admin/cms/page/change_form.html, line 99:

<form id="page_form" action="?language={{ language }}{%if request.GET.target %}&amp;target={{ request.GET.target }}{% endif %}&amp;{%if request.GET.target %}position={{ request.GET.position }}{% endif %}" method="post" enctype="multipart/form-data">{% block form_top %}{% endblock %}
{% csrf_token %}

2.2) Do the same in cms/templates/admin/cms/page/dialog/base.html, line 5:

                {% block form %}{% if form %}<form id="{{ dialog_id }}-form">{% csrf_token %}{{ form.as_p }}{% endif %}{% endblock %}

3) Ensure that you have CsrfViewMiddleware and CsrfResponseMiddleware installed. Your settings.py should contain something like this:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.csrf.CsrfResponseMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'cms.middleware.page.CurrentPageMiddleware',
    'cms.middleware.user.CurrentUserMiddleware',
)

5) Finally, you need to bring in a file from later django-cms, csrf.js (github revision that I used). Place it in media/cms/js/.

6) Add csrf.js to cms/admin/widgets.py in PluginEditor.media, around line 17:

    class Media:
        js = [join(settings.CMS_MEDIA_URL, path) for path in (
            'js/lib/jquery.js',
            'js/lib/ui.core.js',
            'js/lib/ui.sortable.js',
            'js/csrf.js',
            'js/plugin_editor.js',
        )]

7) Add this around line 97 in cms/media/cms/js/change_list.js:

	$(document).ready(function() {
		$.fn.cmsPatchCSRF();
	    selected_page = false;
	    action = false;

8) Do the same in cms/media/cms/js/plugin_editor.js at the first line:

$(document).ready(function() {
  	$.fn.cmsPatchCSRF();

9) In /cms/templates/admin/cms/page/change_list.html you should also include csrf.js, around line 33:

<script type="text/javascript" src="{{ CMS_MEDIA_URL }}js/csrf.js"></script>
<script type="text/javascript" src="{{ CMS_MEDIA_URL }}js/change_list.js"></script>
Posted in Django | Tagged , | Leave a comment

Stopforumspam Django Middleware

I have created a new Django app for keeping out spammers on the basis of data collected by stopforumspam.com. Read all about it here ยป

It’s free, open source, and I hope people will make it better on github.

Posted in Django, Ubuntu, Web | Leave a comment

Automating stopforumspam.com ASAP (updated!)

In case you need a quick way of getting rid of spammers on your apache server, use this method as a temporary solution until you find a better one.

Please take not that it will evaluate EVERY SINGLE REQUEST through a Deny policy in Apache’s mod_access – it does not halt your performance much if you’re just running a site with few requests. But I only suggest this solution as a temporary one until you have a better integration. I am currently working on a Django middleware that will only check the client’s IP address in case it is a POST request directed at a certain URL.

Since I’ve been told that Apache doesn’t use /etc/hosts.deny, you should probably use this method instead, unless you have a webserver that actually uses hosts.deny. Another method would be to add the IP addresses to iptables, if you’re running that — this is probably more efficient than using Apache configuration policies.

This method creates a file that you can include in httpd.conf (to cover ALL your virtual hosts). The overall goal is to avoid .htaccess files since they are evaluated at runtime. Thus, you won’t have to configure each site, and you save a but of CPU time.

  1. Copy the script below to a file on your server, eg. /usr/sbin/stopforumspam.py. You might want to read it quickly as it will pretty much explain itself…
  2. Make the file executable, eg. chmod +x /usr/sbin/stopforumspam.py
  3. Add it to your crontab for automatic execution each night, eg. crontab -e and then insert the line 0 0 * * * /usr/sbin/stopforumspam.py && /etc/init.d/apache2 reload
  4. By default, we will ban an entire class C subnet if more than 5 IP addresses are in this space. You can configure this behavior by giving stopforumspam.py a single argument, ie. /usr/sbin/stopforumspam.py 10 would mean that at least 10 IPs have to be within the class C subnet to qualify it for a ban.
  5. By default stopforumspam.py creates /etc/apache2/stopforumspam.conf – you can change this by editing the script.
  6. Add Include /etc/apache2/stopforumspam.conf to /etc/apache2/httpd.conf (Debian/Ubuntu).
  7. Caution! Make sure that you DO NOT change the Order Deny,Allow option in VirtualHost directives or .htaccess files as this unblock the deny policies.
#!/usr/bin/python
 
import re
import urllib
import zipfile
import sys
 
if len(sys.argv) &gt; 1:
    SUBNET_THRESHOLD = int(sys.argv[1])
else:
    SUBNET_THRESHOLD = 5
 
DOWNLOAD_ZIP = "http://www.stopforumspam.com/downloads/listed_ip_7.zip"
ZIP_FILENAME = "listed_ip_7.txt"
 
HTTPD_CONFIG_INCLUDE = "/etc/apache2/stopforumspam.conf"
 
# For security purposes we test that each line is actually an IP address
IP_MATCH = re.compile(r"^(\d+)\.(\d+)\.(\d+)\.(\d+)$")
 
filename, headers = urllib.urlretrieve(DOWNLOAD_ZIP)
 
z = zipfile.ZipFile(filename)
ips = z.read(ZIP_FILENAME)
 
ips = ips.split("\n")
 
# Remove non-ip members
ips = filter(lambda ip: IP_MATCH.match(ip), ips)
 
def get_ip_segments(ip):
    segments_match = IP_MATCH.search(ip)
    return [int(segments_match.group(i)) for i in range(1,5)]
 
def convert_ip_to_number(ip):
    numeric_value = 0
    ip_segs = get_ip_segments(ip)
    for i in range(4):
      numeric_value += ip_segs[i]*(255**(4-i))
    return numeric_value
 
# Sort everything first
ips.sort(key=convert_ip_to_number)
 
subnets = {}
 
for ip in ips:
    ip_segs = get_ip_segments(ip)
    key = (ip_segs[0], ip_segs[1], ip_segs[2])
    if not key in subnets.keys():
        subnets[key] = [ip]
    else:
        subnets[key].append(ip)
 
final_list = []
 
for subnet, subnet_ips in subnets.items():
    if len(subnet_ips) &gt; SUBNET_THRESHOLD:
        # Ban the whole subnet
        final_list.append(".".join(map(str, subnet)) + ".0/24")
    else:
        final_list = final_list + subnet_ips
 
print ""
print "Lengh of original list: %d" % len(ips)
print "Lengh of final list: %d" % len(final_list)
 
apache_conf_file = file(HTTPD_CONFIG_INCLUDE, "w")
apache_conf_file.write("\n")
apache_conf_file.write("    Order Deny,Allow\n")
 
for entry in final_list:
    apache_conf_file.write("    Deny from %s\n" % entry)
 
apache_conf_file.write("\n")
 
apache_conf_file.close()
Posted in Python, Ubuntu, Web | Tagged , , | 1 Comment

Automating stopforumspam.com

THIS DOES NOT WORK WITH APACHE SINCE IT DOES NOT USE /etc/hosts.denySee this post instead

Use the following Python script to maintain a file in the hosts.deny syntax so that your Debian/Ubuntu box (or other Linux server) is kept undisturbed by forum spammers — COMPLETELY undisturbed, as the spammer is disallowed all access to the system.

1. Copy the script to a file on your server, eg. /usr/sbin/stopforumspam.py
2. Make the file executable, eg. chmod +x /usr/sbin/stopforumspam.py
3. Add it to your crontab for automatic execution each night, eg. crontab -e and then insert the line 0 0 * * * /usr/sbin/stopforumspam.py
4. Add the path to the file containing the ip list to /etc/hosts.deny by inserting this line: ALL: /etc/hosts.deny.stopforumspam

The script itself is here, modify it as you need.

#!/usr/bin/python
 
import re
import urllib
import zipfile
 
DOWNLOAD_ZIP = "http://www.stopforumspam.com/downloads/listed_ip_7.zip"
ZIP_FILENAME = "listed_ip_7.txt"
 
HOSTS_DENY = "hosts.deny.stopforumspam"
 
# For security purposes we test that each line is actually an IP address
IP_MATCH = re.compile(r"\d+\.\d+\.\d+\.\d+")
 
filename, headers = urllib.urlretrieve(DOWNLOAD_ZIP)
 
z = zipfile.ZipFile(filename)
ips = z.read(ZIP_FILENAME)
 
deny_file = file(HOSTS_DENY, "w")
 
for ip in ips.split("\n"):
    if IP_MATCH.match(ip):
        deny_file.write("%s\n" % ip)
 
deny_file.close()
Posted in Python, Ubuntu, Web | Leave a comment

Boycutt Paypal: Installing BitCoin on Ubuntu

BitCoin is a free and open currency that will exist safely and decentralized online. Read about it.

This method is reported to work on 10.04 (Lucid), and I can confirm that it works on 10.10 (Maverick). I don’t yet know about 11.04 (Natty).

  1. Open a terminal
  2. Type:
    sudo apt-add-repository ppa:stretch/bitcoin
    sudo apt-get update
    sudo apt-get install bitcoin
  3. To run BitCoin, navigate to Applications -> Internet -> BitCoin.

Also, remember there’s Flattr, too!

Posted in Ubuntu | Leave a comment