3636import time
3737
3838class AuthBackend (ModelBackend ):
39- # We declare a fake backend that always fails direct authentication -
40- # since we should never be using direct authentication in the first place!
41- def authenticate (self , username = None , password = None ):
42- raise Exception ("Direct authentication not supported" )
39+ # We declare a fake backend that always fails direct authentication -
40+ # since we should never be using direct authentication in the first place!
41+ def authenticate (self , username = None , password = None ):
42+ raise Exception ("Direct authentication not supported" )
4343
4444
4545####
@@ -48,85 +48,85 @@ def authenticate(self, username=None, password=None):
4848
4949# Handle login requests by sending them off to the main site
5050def login (request ):
51- if request .GET .has_key ('next' ):
52- # Put together an url-encoded dict of parameters we're getting back,
53- # including a small nonce at the beginning to make sure it doesn't
54- # encrypt the same way every time.
55- s = "t=%s&%s" % (int (time .time ()), urllib .urlencode ({'r' : request .GET ['next' ]}))
56- # Now encrypt it
57- r = Random .new ()
58- iv = r .read (16 )
59- encryptor = AES .new (SHA .new (settings .SECRET_KEY ).digest ()[:16 ], AES .MODE_CBC , iv )
60- cipher = encryptor .encrypt (s + ' ' * (16 - (len (s ) % 16 ))) # pad to 16 bytes
61-
62- return HttpResponseRedirect ("%s?d=%s$%s" % (
63- settings .PGAUTH_REDIRECT ,
64- base64 .b64encode (iv , "-_" ),
65- base64 .b64encode (cipher , "-_" ),
66- ))
67- else :
68- return HttpResponseRedirect (settings .PGAUTH_REDIRECT )
51+ if request .GET .has_key ('next' ):
52+ # Put together an url-encoded dict of parameters we're getting back,
53+ # including a small nonce at the beginning to make sure it doesn't
54+ # encrypt the same way every time.
55+ s = "t=%s&%s" % (int (time .time ()), urllib .urlencode ({'r' : request .GET ['next' ]}))
56+ # Now encrypt it
57+ r = Random .new ()
58+ iv = r .read (16 )
59+ encryptor = AES .new (SHA .new (settings .SECRET_KEY ).digest ()[:16 ], AES .MODE_CBC , iv )
60+ cipher = encryptor .encrypt (s + ' ' * (16 - (len (s ) % 16 ))) # pad to 16 bytes
61+
62+ return HttpResponseRedirect ("%s?d=%s$%s" % (
63+ settings .PGAUTH_REDIRECT ,
64+ base64 .b64encode (iv , "-_" ),
65+ base64 .b64encode (cipher , "-_" ),
66+ ))
67+ else :
68+ return HttpResponseRedirect (settings .PGAUTH_REDIRECT )
6969
7070# Handle logout requests by logging out of this site and then
7171# redirecting to log out from the main site as well.
7272def logout (request ):
73- if request .user .is_authenticated ():
74- django_logout (request )
75- return HttpResponseRedirect ("%slogout/" % settings .PGAUTH_REDIRECT )
73+ if request .user .is_authenticated ():
74+ django_logout (request )
75+ return HttpResponseRedirect ("%slogout/" % settings .PGAUTH_REDIRECT )
7676
7777# Receive an authentication response from the main website and try
7878# to log the user in.
7979def auth_receive (request ):
80- if request .GET .has_key ('s' ) and request .GET ['s' ] == "logout" :
81- # This was a logout request
82- return HttpResponseRedirect ('/' )
83-
84- if not request .GET .has_key ('i' ):
85- return HttpResponse ("Missing IV in url!" , status = 400 )
86- if not request .GET .has_key ('d' ):
87- return HttpResponse ("Missing data in url!" , status = 400 )
88-
89- # Set up an AES object and decrypt the data we received
90- decryptor = AES .new (base64 .b64decode (settings .PGAUTH_KEY ),
91- AES .MODE_CBC ,
92- base64 .b64decode (str (request .GET ['i' ]), "-_" ))
93- s = decryptor .decrypt (base64 .b64decode (str (request .GET ['d' ]), "-_" )).rstrip (' ' )
94-
95- # Now un-urlencode it
96- try :
97- data = urlparse .parse_qs (s , strict_parsing = True )
98- except ValueError :
99- return HttpResponse ("Invalid encrypted data received." , status = 400 )
100-
101- # Check the timestamp in the authentication
102- if (int (data ['t' ][0 ]) < time .time () - 10 ):
103- return HttpResponse ("Authentication token too old." , status = 400 )
104-
105- # Update the user record (if any)
106- try :
107- user = User .objects .get (username = data ['u' ][0 ])
108- # User found, let's see if any important fields have changed
109- changed = False
110- if user .first_name != data ['f' ][0 ]:
111- user .first_name = data ['f' ][0 ]
112- changed = True
113- if user .last_name != data ['l' ][0 ]:
114- user .last_name = data ['l' ][0 ]
115- changed = True
116- if user .email != data ['e' ][0 ]:
117- user .email = data ['e' ][0 ]
118- changed = True
119- if changed :
120- user .save ()
121- except User .DoesNotExist :
122- # User not found, create it!
123-
124- # NOTE! We have some legacy users where there is a user in
125- # the database with a different userid. Instead of trying to
126- # somehow fix that live, give a proper error message and
127- # have somebody look at it manually.
128- if User .objects .filter (email = data ['e' ][0 ]).exists ():
129- return HttpResponse ("""A user with email %s already exists, but with
80+ if request .GET .has_key ('s' ) and request .GET ['s' ] == "logout" :
81+ # This was a logout request
82+ return HttpResponseRedirect ('/' )
83+
84+ if not request .GET .has_key ('i' ):
85+ return HttpResponse ("Missing IV in url!" , status = 400 )
86+ if not request .GET .has_key ('d' ):
87+ return HttpResponse ("Missing data in url!" , status = 400 )
88+
89+ # Set up an AES object and decrypt the data we received
90+ decryptor = AES .new (base64 .b64decode (settings .PGAUTH_KEY ),
91+ AES .MODE_CBC ,
92+ base64 .b64decode (str (request .GET ['i' ]), "-_" ))
93+ s = decryptor .decrypt (base64 .b64decode (str (request .GET ['d' ]), "-_" )).rstrip (' ' )
94+
95+ # Now un-urlencode it
96+ try :
97+ data = urlparse .parse_qs (s , strict_parsing = True )
98+ except ValueError :
99+ return HttpResponse ("Invalid encrypted data received." , status = 400 )
100+
101+ # Check the timestamp in the authentication
102+ if (int (data ['t' ][0 ]) < time .time () - 10 ):
103+ return HttpResponse ("Authentication token too old." , status = 400 )
104+
105+ # Update the user record (if any)
106+ try :
107+ user = User .objects .get (username = data ['u' ][0 ])
108+ # User found, let's see if any important fields have changed
109+ changed = False
110+ if user .first_name != data ['f' ][0 ]:
111+ user .first_name = data ['f' ][0 ]
112+ changed = True
113+ if user .last_name != data ['l' ][0 ]:
114+ user .last_name = data ['l' ][0 ]
115+ changed = True
116+ if user .email != data ['e' ][0 ]:
117+ user .email = data ['e' ][0 ]
118+ changed = True
119+ if changed :
120+ user .save ()
121+ except User .DoesNotExist :
122+ # User not found, create it!
123+
124+ # NOTE! We have some legacy users where there is a user in
125+ # the database with a different userid. Instead of trying to
126+ # somehow fix that live, give a proper error message and
127+ # have somebody look at it manually.
128+ if User .objects .filter (email = data ['e' ][0 ]).exists ():
129+ return HttpResponse ("""A user with email %s already exists, but with
130130a different username than %s.
131131
132132This is almost certainly caused by some legacy data in our database.
@@ -137,39 +137,39 @@ def auth_receive(request):
137137We apologize for the inconvenience.
138138""" % (data ['e' ][0 ], data ['u' ][0 ]), content_type = 'text/plain' )
139139
140- user = User (username = data ['u' ][0 ],
141- first_name = data ['f' ][0 ],
142- last_name = data ['l' ][0 ],
143- email = data ['e' ][0 ],
144- password = 'setbypluginnotasha1' ,
145- )
146- user .save ()
147-
148- # Ok, we have a proper user record. Now tell django that
149- # we're authenticated so it persists it in the session. Before
150- # we do that, we have to annotate it with the backend information.
151- user .backend = "%s.%s" % (AuthBackend .__module__ , AuthBackend .__name__ )
152- django_login (request , user )
153-
154- # Finally, check of we have a data package that tells us where to
155- # redirect the user.
156- if data .has_key ('d' ):
157- (ivs , datas ) = data ['d' ][0 ].split ('$' )
158- decryptor = AES .new (SHA .new (settings .SECRET_KEY ).digest ()[:16 ],
159- AES .MODE_CBC ,
160- base64 .b64decode (ivs , "-_" ))
161- s = decryptor .decrypt (base64 .b64decode (datas , "-_" )).rstrip (' ' )
162- try :
163- rdata = urlparse .parse_qs (s , strict_parsing = True )
164- except ValueError :
165- return HttpResponse ("Invalid encrypted data received." , status = 400 )
166- if rdata .has_key ('r' ):
167- # Redirect address
168- return HttpResponseRedirect (rdata ['r' ][0 ])
169- # No redirect specified, see if we have it in our settings
170- if hasattr (settings , 'PGAUTH_REDIRECT_SUCCESS' ):
171- return HttpResponseRedirect (settings .PGAUTH_REDIRECT_SUCCESS )
172- return HttpResponse ("Authentication successful, but don't know where to redirect!" , status = 500 )
140+ user = User (username = data ['u' ][0 ],
141+ first_name = data ['f' ][0 ],
142+ last_name = data ['l' ][0 ],
143+ email = data ['e' ][0 ],
144+ password = 'setbypluginnotasha1' ,
145+ )
146+ user .save ()
147+
148+ # Ok, we have a proper user record. Now tell django that
149+ # we're authenticated so it persists it in the session. Before
150+ # we do that, we have to annotate it with the backend information.
151+ user .backend = "%s.%s" % (AuthBackend .__module__ , AuthBackend .__name__ )
152+ django_login (request , user )
153+
154+ # Finally, check of we have a data package that tells us where to
155+ # redirect the user.
156+ if data .has_key ('d' ):
157+ (ivs , datas ) = data ['d' ][0 ].split ('$' )
158+ decryptor = AES .new (SHA .new (settings .SECRET_KEY ).digest ()[:16 ],
159+ AES .MODE_CBC ,
160+ base64 .b64decode (ivs , "-_" ))
161+ s = decryptor .decrypt (base64 .b64decode (datas , "-_" )).rstrip (' ' )
162+ try :
163+ rdata = urlparse .parse_qs (s , strict_parsing = True )
164+ except ValueError :
165+ return HttpResponse ("Invalid encrypted data received." , status = 400 )
166+ if rdata .has_key ('r' ):
167+ # Redirect address
168+ return HttpResponseRedirect (rdata ['r' ][0 ])
169+ # No redirect specified, see if we have it in our settings
170+ if hasattr (settings , 'PGAUTH_REDIRECT_SUCCESS' ):
171+ return HttpResponseRedirect (settings .PGAUTH_REDIRECT_SUCCESS )
172+ return HttpResponse ("Authentication successful, but don't know where to redirect!" , status = 500 )
173173
174174
175175# Perform a search in the central system. Note that the results are returned as an
@@ -180,26 +180,26 @@ def auth_receive(request):
180180# Unlike the authentication, searching does not involve the browser - we just make
181181# a direct http call.
182182def user_search (searchterm = None , userid = None ):
183- # If upsteam isn't responding quickly, it's not going to respond at all, and
184- # 10 seconds is already quite long.
185- socket .setdefaulttimeout (10 )
186- if userid :
187- q = {'u' : userid }
188- else :
189- q = {'s' : searchterm }
190-
191- u = urllib .urlopen ('%ssearch/?%s' % (
192- settings .PGAUTH_REDIRECT ,
193- urllib .urlencode (q ),
194- ))
195- (ivs , datas ) = u .read ().split ('&' )
196- u .close ()
197-
198- # Decryption time
199- decryptor = AES .new (base64 .b64decode (settings .PGAUTH_KEY ),
200- AES .MODE_CBC ,
201- base64 .b64decode (ivs , "-_" ))
202- s = decryptor .decrypt (base64 .b64decode (datas , "-_" )).rstrip (' ' )
203- j = json .loads (s )
204-
205- return j
183+ # If upsteam isn't responding quickly, it's not going to respond at all, and
184+ # 10 seconds is already quite long.
185+ socket .setdefaulttimeout (10 )
186+ if userid :
187+ q = {'u' : userid }
188+ else :
189+ q = {'s' : searchterm }
190+
191+ u = urllib .urlopen ('%ssearch/?%s' % (
192+ settings .PGAUTH_REDIRECT ,
193+ urllib .urlencode (q ),
194+ ))
195+ (ivs , datas ) = u .read ().split ('&' )
196+ u .close ()
197+
198+ # Decryption time
199+ decryptor = AES .new (base64 .b64decode (settings .PGAUTH_KEY ),
200+ AES .MODE_CBC ,
201+ base64 .b64decode (ivs , "-_" ))
202+ s = decryptor .decrypt (base64 .b64decode (datas , "-_" )).rstrip (' ' )
203+ j = json .loads (s )
204+
205+ return j
0 commit comments