phpbb: Make the username case-insensitve on login again.
[matthijs/projects/dorestad-bookings.git] / auth.py
1 from django.conf import settings
2 from django.contrib.auth.models import User, check_password
3 import MySQLdb
4 import tools.phpass
5
6 """
7 This auth backend allows django to authenticate against an external phpbb
8 database. If authentication is successful, the corresponding User from the
9 normal django database is returned (linked on the username field). If no such
10 User exists, it is created automatically.
11
12 This class uses the following variables from you django settings:
13     PHPBB_DATABASE_HOST
14     PHPBB_DATABASE_PORT
15     PHPBB_DATABASE_USER
16     PHPBB_DATABASE_PASSWORD
17     PHPBB_DATABASE_NAME
18
19 If any of these settings are missing, the corresponding setting from Django's
20 own database settings are used. This means, that, usually, you only have to
21 specify the database name where phpbb lives.
22 """
23 class PhpBBBackend:
24     def __init__(self):
25         self.hash = tools.phpass.PasswordHash()
26
27     def connect(self):
28         host     = getattr(settings, 'PHPBB_DATABASE_HOST',     settings.DATABASE_HOST)
29         port     = getattr(settings, 'PHPBB_DATABASE_PORT',     settings.DATABASE_PORT)
30         user     = getattr(settings, 'PHPBB_DATABASE_USER',     settings.DATABASE_USER)
31         password = getattr(settings, 'PHPBB_DATABASE_PASSWORD', settings.DATABASE_PASSWORD)
32         name     = getattr(settings, 'PHPBB_DATABASE_NAME',     settings.DATABASE_NAME)
33
34         # This code was shamelessly stolen from
35         # django.db.backends.mysql.base.cursor
36         kwargs = {
37             #'conv': django_conversions,
38             'charset': 'utf8',
39             'use_unicode': False,
40         }
41         if user:
42             kwargs['user'] = user
43         if name:
44             kwargs['db'] = name
45         if password:
46             kwargs['passwd'] = password
47         if host.startswith('/'):
48             kwargs['unix_socket'] = host
49         elif host:
50             kwargs['host'] = host
51         if port:
52             kwargs['port'] = int(port)
53
54         conn = MySQLdb.connect (**kwargs)
55         # End stolen code
56
57         return conn
58
59     def check_login(self, username, password):
60         conn = self.connect()
61         prefix = getattr(settings, 'PHPBB_TABLE_PREFIX',   '')
62
63         # Get some data
64         cursor = conn.cursor ()
65         cursor.execute ("SELECT user_password,user_email FROM %susers WHERE LOWER(username)=LOWER(%%s)" % prefix, username)
66
67         # No data? No login.
68         if (cursor.rowcount == 0):
69             conn.close()
70             return False
71        
72         # Check password
73         row = cursor.fetchone()
74         conn.close()
75
76         if (self.hash.check_password(password, row[0])):
77             return row[1]
78         else:
79             return False
80             
81
82     """
83     Authenticate against a PhpBB database.
84
85     Most of this code has been taken from Django's user auth tutorial.
86     """
87     def authenticate(self, username=None, password=None):
88         email = self.check_login(username, password)
89         if email:
90             try:
91                 user = User.objects.get(username=username)
92             except User.DoesNotExist:
93                 # Create a new user. Note that we can set password
94                 # to anything, because it won't be checked; the password
95                 # from settings.py will.
96                 user = User(username=username, password='get from settings.py')
97                 user.email = email
98                 user.set_unusable_password()
99                 user.save()
100             return user
101         else:
102             return None
103
104     def get_user(self, user_id):
105         try:
106             return User.objects.get(pk=user_id)
107         except User.DoesNotExist:
108             return None
109     
110 # vim: set sts=4 sw=4 expandtab: