<s> from django . http import HttpResponseRedirect as Redirect , Http404 <EOL> from django_openid import consumer , signed <EOL> from django_openid . utils import hex_to_int , int_to_hex <EOL> from django . conf import settings <EOL> from django . contrib . auth import authenticate <EOL> from django . core . mail import send_mail <EOL> import datetime <EOL> from urlparse import urljoin <EOL> class AuthConsumer ( consumer . SessionConsumer ) : <EOL> """<STR_LIT>""" <EOL> after_login_redirect_url = '<STR_LIT:/>' <EOL> associations_template = '<STR_LIT>' <EOL> login_plus_password_template = '<STR_LIT>' <EOL> recover_template = '<STR_LIT>' <EOL> already_logged_in_template = '<STR_LIT>' <EOL> pick_account_template = '<STR_LIT>' <EOL> show_associate_template = '<STR_LIT>' <EOL> recovery_email_template = '<STR_LIT>' <EOL> recovery_expired_template = '<STR_LIT>' <EOL> recovery_complete_template = '<STR_LIT>' <EOL> recovery_email_from = None <EOL> recovery_email_subject = '<STR_LIT>' <EOL> password_logins_enabled = True <EOL> account_recovery_enabled = True <EOL> need_authenticated_user_message = '<STR_LIT>' '<STR_LIT>' <EOL> csrf_failed_message = '<STR_LIT>' <EOL> associate_tampering_message = '<STR_LIT>' <EOL> association_deleted_message = '<STR_LIT>' <EOL> openid_now_associated_message = '<STR_LIT>' <EOL> bad_password_message = '<STR_LIT>' <EOL> invalid_token_message = '<STR_LIT>' <EOL> recovery_email_sent_message = '<STR_LIT>' <EOL> recovery_not_found_message = '<STR_LIT>' <EOL> recovery_multiple_found_message = '<STR_LIT>' <EOL> r_user_not_found_message = '<STR_LIT>' <EOL> account_recovery_url = None <EOL> associate_salt = '<STR_LIT>' <EOL> associate_delete_salt = '<STR_LIT>' <EOL> recovery_link_salt = '<STR_LIT>' <EOL> recovery_link_secret = None <EOL> recovery_origin_date = datetime . date ( <NUM_LIT> , <NUM_LIT:1> , <NUM_LIT:1> ) <EOL> recovery_expires_after_days = <NUM_LIT:3> <EOL> def show_login ( self , request , extra_message = None ) : <EOL> if request . user . is_authenticated ( ) : <EOL> return self . show_already_logged_in ( request ) <EOL> response = super ( AuthConsumer , self ) . show_login ( <EOL> request , extra_message <EOL> ) <EOL> if self . password_logins_enabled : <EOL> response . template_name = self . login_plus_password_template <EOL> response . template_context . update ( { <EOL> '<STR_LIT>' : self . account_recovery_enabled and ( <EOL> self . account_recovery_url or ( request . path + '<STR_LIT>' ) <EOL> ) , <EOL> } ) <EOL> return response <EOL> def show_already_logged_in ( self , request ) : <EOL> return self . render ( request , self . already_logged_in_template ) <EOL> def do_login ( self , request , extra_message = None ) : <EOL> if request . method == '<STR_LIT:POST>' and request . POST . get ( '<STR_LIT:username>' , '<STR_LIT>' ) . strip ( ) : <EOL> user = authenticate ( <EOL> username = request . POST . get ( '<STR_LIT:username>' ) , <EOL> password = request . POST . get ( '<STR_LIT:password>' ) <EOL> ) <EOL> if not user : <EOL> return self . show_login ( request , self . bad_password_message ) <EOL> else : <EOL> self . log_in_user ( request , user ) <EOL> return self . on_login_complete ( request , user , openid = None ) <EOL> else : <EOL> return super ( AuthConsumer , self ) . do_login ( request , extra_message ) <EOL> def lookup_openid ( self , request , identity_url ) : <EOL> from django . contrib . auth . models import User <EOL> return list ( <EOL> User . objects . filter ( openids__openid = identity_url ) . distinct ( ) <EOL> ) <EOL> def log_in_user ( self , request , user ) : <EOL> from django . contrib . auth import login <EOL> user . backend = '<STR_LIT>' <EOL> login ( request , user ) <EOL> def on_login_complete ( self , request , user , openid = None ) : <EOL> response = self . redirect_if_valid_next ( request ) <EOL> if not response : <EOL> response = Redirect ( self . after_login_redirect_url ) <EOL> return response <EOL> def on_logged_in ( self , request , openid , openid_response ) : <EOL> matches = self . lookup_openid ( request , openid ) <EOL> if request . user . is_authenticated ( ) : <EOL> if request . user . id in [ u . id for u in matches ] : <EOL> response = self . redirect_if_valid_next ( request ) <EOL> if not response : <EOL> response = Redirect ( self . after_login_redirect_url ) <EOL> return response <EOL> else : <EOL> return self . show_associate ( request , openid ) <EOL> if matches : <EOL> if len ( matches ) == <NUM_LIT:1> : <EOL> user = matches [ <NUM_LIT:0> ] <EOL> if self . user_can_login ( request , user ) : <EOL> self . log_in_user ( request , user ) <EOL> return self . on_login_complete ( request , user , openid ) <EOL> else : <EOL> return self . show_you_cannot_login ( request , user , openid ) <EOL> else : <EOL> return self . show_pick_account ( request , openid ) <EOL> else : <EOL> return self . show_unknown_openid ( request , openid ) <EOL> def user_can_login ( self , request , user ) : <EOL> "<STR_LIT>" <EOL> return user . is_active <EOL> def show_pick_account ( self , request , openid ) : <EOL> """<STR_LIT>""" <EOL> return self . render ( request , self . pick_account_template , { <EOL> '<STR_LIT:action>' : urljoin ( request . path , '<STR_LIT>' ) , <EOL> '<STR_LIT>' : openid , <EOL> '<STR_LIT>' : self . lookup_openid ( request , openid ) , <EOL> } ) <EOL> def do_pick ( self , request ) : <EOL> if not request . openid : <EOL> return self . show_error ( request , '<STR_LIT>' ) <EOL> users = self . lookup_openid ( request , request . openid . openid ) <EOL> try : <EOL> user_id = [ <EOL> v . split ( '<STR_LIT:->' ) [ <NUM_LIT:1> ] for v in request . POST if v . startswith ( '<STR_LIT>' ) <EOL> ] [ <NUM_LIT:0> ] <EOL> user = [ u for u in users if str ( u . id ) == user_id ] [ <NUM_LIT:0> ] <EOL> except IndexError , e : <EOL> return self . show_error ( request , "<STR_LIT>" ) <EOL> self . log_in_user ( request , user ) <EOL> return self . on_login_complete ( request , user , request . openid . openid ) <EOL> def on_logged_out ( self , request ) : <EOL> from django . contrib . auth import logout <EOL> response = super ( AuthConsumer , self ) . on_logged_out ( request ) <EOL> logout ( request ) <EOL> return response <EOL> def show_unknown_openid ( self , request , openid ) : <EOL> return self . show_message ( <EOL> request , '<STR_LIT>' , '<STR_LIT>' % openid <EOL> ) <EOL> def show_you_cannot_login ( self , request , user , openid ) : <EOL> return self . show_message ( <EOL> request , '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) <EOL> def show_associate ( self , request , openid = None ) : <EOL> "<STR_LIT>" <EOL> if not request . user . is_authenticated ( ) : <EOL> return self . need_authenticated_user ( request ) <EOL> return self . render ( request , self . show_associate_template , { <EOL> '<STR_LIT:action>' : urljoin ( request . path , '<STR_LIT>' ) , <EOL> '<STR_LIT:user>' : request . user , <EOL> '<STR_LIT>' : openid , <EOL> '<STR_LIT>' : signed . dumps ( <EOL> openid , extra_key = self . associate_salt + str ( request . user . id ) <EOL> ) , <EOL> } ) <EOL> def do_associate ( self , request ) : <EOL> if request . method == '<STR_LIT:POST>' : <EOL> try : <EOL> openid = signed . loads ( <EOL> request . POST . get ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> extra_key = self . associate_salt + str ( request . user . id ) <EOL> ) <EOL> except signed . BadSignature : <EOL> return self . show_error ( request , self . csrf_failed_message ) <EOL> if not request . user . openids . filter ( openid = openid ) : <EOL> request . user . openids . create ( openid = openid ) <EOL> return self . show_associate_done ( request , openid ) <EOL> return self . show_error ( request , '<STR_LIT>' ) <EOL> def show_associate_done ( self , request , openid ) : <EOL> response = self . redirect_if_valid_next ( request ) <EOL> if not response : <EOL> response = self . show_message ( request , '<STR_LIT>' , <EOL> self . openid_now_associated_message % openid <EOL> ) <EOL> return response <EOL> def need_authenticated_user ( self , request ) : <EOL> return self . show_error ( request , self . need_authenticated_user_message ) <EOL> def do_associations ( self , request ) : <EOL> "<STR_LIT>" <EOL> if not request . user . is_authenticated ( ) : <EOL> return self . need_authenticated_user ( request ) <EOL> message = None <EOL> if request . method == '<STR_LIT:POST>' : <EOL> if '<STR_LIT>' in request . POST : <EOL> try : <EOL> todelete = signed . loads ( <EOL> request . POST [ '<STR_LIT>' ] , <EOL> extra_key = self . associate_delete_salt <EOL> ) <EOL> if todelete [ '<STR_LIT>' ] != request . user . id : <EOL> message = self . associate_tampering_message <EOL> else : <EOL> request . user . openids . filter ( <EOL> pk = todelete [ '<STR_LIT>' ] <EOL> ) . delete ( ) <EOL> message = self . association_deleted_message % ( <EOL> todelete [ '<STR_LIT>' ] <EOL> ) <EOL> except signed . BadSignature : <EOL> message = self . associate_tampering_message <EOL> openids = [ ] <EOL> for association in request . user . openids . all ( ) : <EOL> openids . append ( { <EOL> '<STR_LIT>' : association . openid , <EOL> '<STR_LIT>' : signed . dumps ( { <EOL> '<STR_LIT>' : request . user . id , <EOL> '<STR_LIT>' : association . id , <EOL> '<STR_LIT>' : association . openid , <EOL> } , extra_key = self . associate_delete_salt ) , <EOL> } ) <EOL> return self . render ( request , self . associations_template , { <EOL> '<STR_LIT>' : openids , <EOL> '<STR_LIT:user>' : request . user , <EOL> '<STR_LIT:action>' : request . path , <EOL> '<STR_LIT:message>' : message , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : self . sign_next ( request . path ) , <EOL> } ) <EOL> def do_recover ( self , request , extra_message = None ) : <EOL> if request . method == '<STR_LIT:POST>' : <EOL> submitted = request . POST . get ( '<STR_LIT>' , '<STR_LIT>' ) . strip ( ) <EOL> user = None <EOL> if '<STR_LIT:@>' not in submitted : <EOL> user = self . lookup_user_by_username ( submitted ) <EOL> else : <EOL> users = self . lookup_users_by_email ( submitted ) <EOL> if users : <EOL> if len ( users ) > <NUM_LIT:1> : <EOL> extra_message = self . recovery_multiple_found_message <EOL> user = None <EOL> else : <EOL> user = users [ <NUM_LIT:0> ] <EOL> if user : <EOL> self . send_recovery_email ( request , user ) <EOL> return self . show_message ( <EOL> request , '<STR_LIT>' , self . recovery_email_sent_message <EOL> ) <EOL> else : <EOL> extra_message = self . recovery_not_found_message <EOL> return self . render ( request , self . recover_template , { <EOL> '<STR_LIT:action>' : request . path , <EOL> '<STR_LIT:message>' : extra_message , <EOL> } ) <EOL> def lookup_users_by_email ( self , email ) : <EOL> from django . contrib . auth . models import User <EOL> return list ( User . objects . filter ( email = email ) ) <EOL> def lookup_user_by_username ( self , username ) : <EOL> from django . contrib . auth . models import User <EOL> try : <EOL> return User . objects . get ( username = username ) <EOL> except User . DoesNotExist : <EOL> return None <EOL> def lookup_user_by_id ( self , id ) : <EOL> from django . contrib . auth . models import User <EOL> try : <EOL> return User . objects . get ( pk = id ) <EOL> except User . DoesNotExist : <EOL> return None <EOL> def do_r ( self , request , token = '<STR_LIT>' ) : <EOL> if not token : <EOL> raise Http404 <EOL> token = token . rstrip ( '<STR_LIT:/>' ) . encode ( '<STR_LIT:utf8>' ) <EOL> try : <EOL> value = signed . unsign ( token , key = ( <EOL> self . recovery_link_secret or settings . SECRET_KEY <EOL> ) + self . recovery_link_salt ) <EOL> except signed . BadSignature : <EOL> return self . show_message ( <EOL> request , self . invalid_token_message , <EOL> self . invalid_token_message + '<STR_LIT>' + token <EOL> ) <EOL> hex_days , hex_user_id = ( value . split ( '<STR_LIT:.>' ) + [ '<STR_LIT>' , '<STR_LIT>' ] ) [ : <NUM_LIT:2> ] <EOL> days = hex_to_int ( hex_days ) <EOL> user_id = hex_to_int ( hex_user_id ) <EOL> user = self . lookup_user_by_id ( user_id ) <EOL> if not user : <EOL> return self . show_error ( request , r_user_not_found_message ) <EOL> now_days = ( datetime . date . today ( ) - self . recovery_origin_date ) . days <EOL> if ( now_days - days ) > self . recovery_expires_after_days : <EOL> return self . render ( request , self . recovery_expired_template , { <EOL> '<STR_LIT>' : self . recovery_expires_after_days , <EOL> '<STR_LIT>' : urljoin ( request . path , '<STR_LIT>' ) , <EOL> } ) <EOL> self . log_in_user ( request , user ) <EOL> return self . render ( request , self . recovery_complete_template , { <EOL> '<STR_LIT>' : urljoin ( request . path , '<STR_LIT>' ) , <EOL> '<STR_LIT>' : urljoin ( request . path , '<STR_LIT>' ) , <EOL> '<STR_LIT:user>' : user , <EOL> } ) <EOL> do_r . urlregex = '<STR_LIT>' <EOL> def generate_recovery_code ( self , user ) : <EOL> days = int_to_hex ( <EOL> ( datetime . date . today ( ) - self . recovery_origin_date ) . days <EOL> ) <EOL> token = '<STR_LIT>' % ( days , int_to_hex ( user . id ) ) <EOL> return signed . sign ( token , key = ( <EOL> self . recovery_link_secret or settings . SECRET_KEY <EOL> ) + self . recovery_link_salt ) <EOL> def send_recovery_email ( self , request , user ) : <EOL> code = self . generate_recovery_code ( user ) <EOL> path = urljoin ( request . path , '<STR_LIT>' % code ) <EOL> url = request . build_absolute_uri ( path ) <EOL> email_body = self . render ( request , self . recovery_email_template , { <EOL> '<STR_LIT:url>' : url , <EOL> '<STR_LIT:code>' : code , <EOL> '<STR_LIT>' : user , <EOL> } ) . content <EOL> send_mail ( <EOL> subject = self . recovery_email_subject , <EOL> message = email_body , <EOL> from_email = self . recovery_email_from or settings . DEFAULT_FROM_EMAIL , <EOL> recipient_list = [ user . email ] <EOL> ) <EOL> def make_display_login_form_with_openid ( bind_to_me , openid_path ) : <EOL> "<STR_LIT>" <EOL> from django . contrib . admin . sites import AdminSite <EOL> def display_login_form ( request , error_message = '<STR_LIT>' , <EOL> extra_context = None ) : <EOL> extra_context = extra_context or { } <EOL> extra_context [ '<STR_LIT>' ] = openid_path <EOL> return AdminSite . display_login_form ( <EOL> bind_to_me , request , error_message , extra_context <EOL> ) <EOL> return display_login_form <EOL> def monkeypatch_adminsite ( admin_site , openid_path = '<STR_LIT>' ) : <EOL> admin_site . display_login_form = make_display_login_form_with_openid ( <EOL> admin_site , openid_path <EOL> ) </s>
