3c97dce787aba69d73a2a32585662f00757037fa
[matthijs/projects/wipi.git] / conf / auth / mysql_login.py
1 # -*- coding: iso-8859-1 -*-
2 """
3     MoinMoin - auth plugin doing a check against MySQL db
4
5     @copyright: 2008 Matthijs Kooijman
6     @license: GNU GPL, see COPYING for details.
7 """
8
9 import MySQLdb
10 import md5
11 from MoinMoin import user
12
13 class mysql_login:
14
15     def __init__(self, dbhost=None, dbuser=None, dbpass=None, dbname=None, dbport=None, method='mysql', verbose=False):
16         """
17             Authenticate using credentials from a mysql database
18         """
19         self.verbose = verbose
20         self.dbhost  = dbhost
21         self.dbuser  = dbuser
22         self.dbpass  = dbpass
23         self.dbname  = dbname
24         self.dbport  = dbport
25         self.method  = method
26     
27     def check_login(self, request, username, password):
28         """ Checks the given username password combination. Returns the
29         corresponding emailaddress, or False if authentication failed.
30         """
31         conn = self.connect(request)
32
33         if not conn:
34             return False
35
36         # Get some data
37         cursor = conn.cursor ()
38         cursor.execute ("SELECT user_password,user_email FROM lex_users WHERE username=%s", username)
39
40         # No data? No login.
41         if (cursor.rowcount == 0):
42             conn.close()
43             return False
44        
45         # Check password
46         row = cursor.fetchone()
47         conn.close()
48
49         if (md5.new(password).hexdigest() == row[0]):
50             return row[1]
51         else:
52             return False
53
54     def connect(self, request):
55         # This code was shamelessly stolen from
56         # django.db.backends.mysql.base.cursor
57         kwargs = {
58             'charset': 'utf8',
59             'use_unicode': False,
60         }
61         if self.dbuser:
62             kwargs['user'] = self.dbuser
63         if self.dbname:
64             kwargs['db'] = self.dbname
65         if self.dbpass:
66             kwargs['passwd'] = self.dbpass
67         if self.dbhost.startswith('/'):
68             kwargs['unix_socket'] = self.dbhost
69         elif self.dbhost:
70             kwargs['host'] = self.dbhost
71         if self.dbport:
72             kwargs['port'] = int(self.dbport)
73
74         # End stolen code
75
76         try:
77             conn = MySQLdb.connect (**kwargs)
78         except:
79             import sys
80             import traceback
81             info = sys.exc_info()
82             request.log("mysql_login: authentication failed due to exception connecting to DB, traceback follows...")
83             request.log(''.join(traceback.format_exception(*info)))
84             return False
85
86         return conn
87
88     def __call__(self, request, **kw):
89         try:
90             username = kw.get('name')
91             password = kw.get('password')
92             login = kw.get('login')
93             user_obj = kw.get('user_obj')
94
95             if self.verbose: request.log("mysql_login: got name=%r login=%r" % (username, login))
96             
97             # Only handle login
98             if not login:
99                 return user_obj, True
100
101             # Deny empty passwords
102             if not password:
103                 return None, False
104
105             email = self.check_login(request, username, password)
106             
107             # Login incorrect
108             if (not email):
109                 if self.verbose: request.log("mysql_login: authentication failed for %s" % (username))
110                 return None, True
111
112             if self.verbose: request.log("mysql_login: authenticated %s (email %s)" % (username, email))
113
114             u = user.User(request, auth_username=username, auth_method=self.method, auth_attribs=('password', 'email', ))
115             u.email = email
116             #u.remember_me = 0 # 0 enforces cookie_lifetime config param
117             u.create_or_update(True)
118
119             return u, True # moin_session has to set the cookie
120         except:
121             import sys
122             import traceback
123             info = sys.exc_info()
124             request.log("mysql_login: authentication failed due to unexpected exception, traceback follows...")
125             request.log(''.join(traceback.format_exception(*info)))
126             return None, False
127
128 # vim: set sw=4 expandtab sts=4:vim