source: subversion/sites/other/tilesAtHome_tahngo/user/auth.py @ 10690

Last change on this file since 10690 was 10615, checked in by spaetz, 11 years ago

snapshot with changes that make it work with django 1.0 release

File size: 3.7 KB
Line 
1#custom authentication system that checks OSM users and creates them as needed.
2from django.conf import settings
3#from django.core.validators import email_re
4from django.forms.fields import email_re
5from django.contrib.auth.models import User, check_password
6from tah.user.models import TahUser
7import logging
8import urllib2
9import re
10
11class OSMBackend:
12    def get_user(self, user_id):
13        try:
14            return User.objects.get(pk=user_id)
15        except User.DoesNotExist:
16            return None
17
18    def authenticate(self, username=None, password=None):
19        #If username is an email address, then try to pull it up
20        if email_re.search(username):
21            try:
22                user = User.objects.get(email__iexact=username)
23            except User.DoesNotExist:
24                #user not found locally. check OSM
25                usernick = self.checkOSMpasswd(username, password)
26                if usernick == None:
27                   #Not locally known and wrong OSM password too
28                   logging.info("Authentication with unknown local username '%s' failed." % username)
29                   return None
30                logging.info("Imported user '%s' from OpenStreetMap successfully" % username)
31                user = self.insertOSMuser(usernick, username, password)
32                t = TahUser(user = user)
33                t.save()
34        else:
35            #We have a non-email address username we should try username
36            try:
37                user = User.objects.get(username=username)
38            except User.DoesNotExist:
39                return None
40
41        if user.check_password(password):
42           if user.is_active:
43             return user
44           else:
45             logging.info("Deactivated user '%s' tried to login" % username)
46             return None
47        else:
48          #user exists, but password was wrong. try to update from OSM
49          usernick = self.checkOSMpasswd(user.username, password)
50          if usernick == None:
51            # OSM auth failed too
52             logging.info("user '%s' failed to authenticate (even after checking OSM)" % username)
53             return None
54          else:
55            #OSM auth succeeded, user must have updated password
56            logging.info("user '%s' updated password from OSM successfully" % username)
57            user.set_password(password)
58            user.save()
59            return user
60    #-------------------------------------------------------------
61
62    def checkOSMpasswd(self,username=None, password=None):
63        password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
64        top_level_url = "http://www.openstreetmap.org/api/0.5"
65        password_mgr.add_password(None, top_level_url, username, password)
66        handler = urllib2.HTTPBasicAuthHandler(password_mgr)
67
68        opener = urllib2.build_opener(handler)
69        try:
70            data = opener.open('http://www.openstreetmap.org/api/0.5/user/details').read() 
71        except urllib2.HTTPError, e:
72            # if e.code == 404: could be used for more specific action
73            # The OSM auth was unsuccessful. Bail out without auth.
74            return None 
75
76        #reply line looks like this
77        #<user display_name="spaetz" account_created="2007-03-19T19:00:56+00:00">
78
79        p = re.compile('<user display_name="(\w+)"')
80        m = p.search(data)
81
82        if (m):
83            return m.group(1)
84        else:
85            # Authentication was OK, but we did not find a valid username.
86            # weird!!! construct username from email
87            p = re.compile('\W+')
88            return p.sub('_', username)
89
90
91    def insertOSMuser(self, usernick, email, password):
92        ###TODO: if user already exists, just update passwd
93        user = User.objects.create_user(usernick, email, password)
94        user.save()
95        return user
Note: See TracBrowser for help on using the repository browser.