settings: Enable (phpbb) authentication.
authorMatthijs Kooijman <matthijs@stdin.nl>
Tue, 19 Oct 2010 08:38:15 +0000 (10:38 +0200)
committerMatthijs Kooijman <matthijs@stdin.nl>
Tue, 19 Oct 2010 09:03:20 +0000 (11:03 +0200)
This adds code for the phpbb authentication backend, enables the auth
contrib application, adds /login and /logout urls and adds a login form
template.

auth.py [new file with mode: 0644]
dbsettings.py.tmpl
settings.py
tickets/templates/tickets/login.html [new file with mode: 0644]
urls.py

diff --git a/auth.py b/auth.py
new file mode 100644 (file)
index 0000000..00c106d
--- /dev/null
+++ b/auth.py
@@ -0,0 +1,107 @@
+from django.conf import settings
+from django.contrib.auth.models import User, check_password
+import md5
+import MySQLdb
+
+
+"""
+This auth backend allows django to authenticate against an external phpbb
+database. If authentication is successful, the corresponding User from the
+normal django database is returned (linked on the username field). If no such
+User exists, it is created automatically.
+
+This class uses the following variables from you django settings:
+    PHPBB_DATABASE_HOST
+    PHPBB_DATABASE_PORT
+    PHPBB_DATABASE_USER
+    PHPBB_DATABASE_PASSWORD
+    PHPBB_DATABASE_NAME
+
+If any of these settings are missing, the corresponding setting from Django's
+own database settings are used. This means, that, usually, you only have to
+specify the database name where phpbb lives.
+"""
+class PhpBBBackend:
+    def connect(self):
+        host     = getattr(settings, 'PHPBB_DATABASE_HOST',     settings.DATABASE_HOST)
+        port     = getattr(settings, 'PHPBB_DATABASE_PORT',     settings.DATABASE_PORT)
+        user     = getattr(settings, 'PHPBB_DATABASE_USER',     settings.DATABASE_USER)
+        password = getattr(settings, 'PHPBB_DATABASE_PASSWORD', settings.DATABASE_PASSWORD)
+        name     = getattr(settings, 'PHPBB_DATABASE_NAME',     settings.DATABASE_NAME)
+
+        # This code was shamelessly stolen from
+        # django.db.backends.mysql.base.cursor
+        kwargs = {
+            #'conv': django_conversions,
+            'charset': 'utf8',
+            'use_unicode': False,
+        }
+        if user:
+            kwargs['user'] = user
+        if name:
+            kwargs['db'] = name
+        if password:
+            kwargs['passwd'] = password
+        if host.startswith('/'):
+            kwargs['unix_socket'] = host
+        elif host:
+            kwargs['host'] = host
+        if port:
+            kwargs['port'] = int(port)
+
+        conn = MySQLdb.connect (**kwargs)
+        # End stolen code
+
+        return conn
+
+    def check_login(self, username, password):
+        conn = self.connect()
+
+        # Get some data
+        cursor = conn.cursor ()
+        cursor.execute ("SELECT user_password,user_email FROM users WHERE username=%s", username)
+
+        # No data? No login.
+        if (cursor.rowcount == 0):
+            conn.close()
+            return False
+       
+        # Check password
+        row = cursor.fetchone()
+        conn.close()
+
+        if (md5.new(password).hexdigest() == row[0]):
+            return row[1]
+        else:
+            return False
+            
+
+    """
+    Authenticate against a PhpBB database.
+
+    Most of this code has been taken from Django's user auth tutorial.
+    """
+    def authenticate(self, username=None, password=None):
+        email = self.check_login(username, password)
+        if email:
+            try:
+                user = User.objects.get(username=username)
+            except User.DoesNotExist:
+                # Create a new user. Note that we can set password
+                # to anything, because it won't be checked; the password
+                # from settings.py will.
+                user = User(username=username, password='get from settings.py')
+                user.email = email
+                user.set_unusable_password()
+                user.save()
+            return user
+        else:
+            return None
+
+    def get_user(self, user_id):
+        try:
+            return User.objects.get(pk=user_id)
+        except User.DoesNotExist:
+            return None
+    
+# vim: set sts=4 sw=4 expandtab:
index bf6ae6e888803e28e4f03ec7eccc8e6b43fa1b4f..566d2fd815e42dcd49c16dc5bc65daaea50caecc 100644 (file)
@@ -7,3 +7,7 @@ DATABASE_USER = 'ee_bookings'       # Not used with sqlite3.
 DATABASE_PASSWORD = ''              # Not used with sqlite3.
 DATABASE_HOST = ''                  # Set to empty string for localhost. Not used with sqlite3.
 DATABASE_PORT = ''                  # Set to empty string for default. Not used with sqlite3.
+
+# Database to use for phpbb authentication. Other variables from above
+# (except for ENGINE) can similarly be overridden.
+PHPBB_DATABASE_NAME = 'ee_forum'
index 7a10053a7c27dbf02022c8183deea39b0cb9fbb4..fbe3df40e8d80d38935fdcb3fa2891c0f9c990e1 100644 (file)
@@ -74,10 +74,20 @@ TEMPLATE_DIRS = (
     os.path.join(PROJECT_DIR, 'templates'),
 )
 
+LOGIN_URL = "/reserveren/login/"
+LOGIN_REDIRECT_URL = "/reserveren/"
+
 INSTALLED_APPS = (
+    'django.contrib.auth',
     'tickets',
 )
 
+# Allow authentication against the phpb user accounts
+
+AUTHENTICATION_BACKENDS = (
+    'dorestad-bookings.auth.PhpBBBackend',
+)
+
 # Import local settings, that are specific to this installation. These
 # can override any settings specified here.
 try:
diff --git a/tickets/templates/tickets/login.html b/tickets/templates/tickets/login.html
new file mode 100644 (file)
index 0000000..74127b9
--- /dev/null
@@ -0,0 +1,33 @@
+{% extends "tickets/base.html" %}
+{% load i18n %}
+
+{% block content %}
+{% if form.errors %}
+<p>{% trans "Your username and password didn't match. Please try again." %}</p>
+{% endif %}
+
+{% if user.is_authenticated %}
+       <p>{% blocktrans with user.username as username %}You are currently logged in as {{ username }}{% endblocktrans %}</p>
+       <p><a href="{% url logout %}">{% trans "Logout" %}</a></p>
+{% endif %}
+
+<p>
+{% blocktrans with "http://www.evolution-events.nl" as ee_url and "http://www.evolution-events.nl/forum" as forum_url and "http://www.evolution-events.nl/forum/phpbb/profile.php?mode=register" as register_url %}
+You can login with your <a href="{{ ee_url }} ">Evolution Events</a>
+<a href="{{ forum_url }}">forum</a> account. If you don't have a forum
+account yet, first <a href="{{ register_url }}">register</a>.
+{% endblocktrans %}
+</p>
+<form method="post" action=".">
+{% csrf_token %}
+<table>
+<tr><td><label for="id_username">{% trans "Username" %}</label></td><td>{{ form.username }}</td></tr>
+<tr><td><label for="id_password">{% trans "Password" %}</label></td><td>{{ form.password }}</td></tr>
+</table>
+
+<input type="submit" value="{% trans "Login" %}" />
+<input type="hidden" name="next" value="{{ next }}" />
+
+</form>
+
+{% endblock %}
diff --git a/urls.py b/urls.py
index b79f80222f8b0cb5e92af6d1dd5fe3d3d052ba25..3770765e7206dd777cadc24247c6672778d43d11 100644 (file)
--- a/urls.py
+++ b/urls.py
@@ -15,4 +15,6 @@ urlpatterns = patterns('',
 
     # Uncomment the next line to enable the admin:
     # (r'^admin/(.*)', admin.site.root),
+    url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'tickets/login.html'}, name='login'),
+    url(r'^logout/$', 'django.contrib.auth.views.logout_then_login', name='logout'),
 )