def post_banning_tasks(own_id, target_id): """ Remove's banner's notifications from from the bannee's inbox, also unfans them, and a bunch of other tasks! """ # this ensures they can't 1on1 chat with eachother # 1) Exit yourself if group is non-exited # 2) If 'target' has already exited group, tell them they can't re-enter because the other party outright blocked them! # 3) No notifications will be generated since we already sanitized each user's activity group_id, group_exists = exit_user_from_targets_priv_chat(own_id,target_id) if group_id: remove_1on1_direct_responses(group_id=group_id, first_user_id=target_id, second_user_id=own_id) ################################################################################ # remove any direct responses exchanged between the two (except for 1on1, which is handled in the previous step) delete_all_direct_responses_between_two_users(first_user_id=target_id, second_user_id=own_id)# order of passing user IDs does not matter ################################################################################ # ensure users custom home feeds are rid of eachother's content! sanitize_posts_after_pvp_ban(own_id, target_id) sanitize_posts_after_pvp_ban(target_id, own_id) ################################################################################ # remove eachother from follower lists verification_status = '1' if is_mobile_verified(target_id) else '0' remove_follower(follower_id=own_id,star_id=target_id,follower_verification_status=verification_status) verification_status = '1' if is_mobile_verified(own_id) else '0' remove_follower(follower_id=target_id,star_id=own_id,follower_verification_status=verification_status) ################################################################################ # remove locations owned by each other from 'reply history' cleanse_replier_history_when_pvp_blocked(replier_id_1=target_id, replier_id_2=own_id) ################################################################################ # we did a LOT of work, ensure banner didn't ban in vain! ratelimit_banner_from_unbanning_target(own_id,target_id)
def forgot_password(request, lang=None, *args, **kwargs): """ This initiates the 'forgot password' flow It takes user's username and phone number (one-by-one) as an input """ if request.user.is_authenticated(): return redirect("home") elif request.method == "POST": form = ForgettersNicknameForm(data=request.POST, lang=lang) if form.is_valid(): username, user_id = form.cleaned_data.get("username") if is_mobile_verified(user_id): request.session["forgetters_username"] = username request.session["forgetters_userid"] = user_id request.session.modified = True template_name = "unauth/verify_forgetters_account_ur.html" if lang == 'ur' else "unauth/verify_forgetters_account.html" return render(request,template_name,{'form':ForgettersMobileNumber()}) else: template_name = "unauth/nick_unassociated_with_mobnum_ur.html" if lang == 'ur' else "unauth/nick_unassociated_with_mobnum.html" return render(request,template_name,{'nick':username}) else: template_name = "unauth/forgot_password_ur.html" if lang == 'ur' else "unauth/forgot_password.html" return render(request,template_name,{'form':form}) else: template_name = "unauth/forgot_password_ur.html" if lang == 'ur' else "unauth/forgot_password.html" return render(request,template_name,{'form':ForgettersNicknameForm()})
def clean_phonenumber(self): phonenumber = self.cleaned_data.get('phonenumber') user_id = self.user_id already_verified = is_mobile_verified(user_id) mobile_length = len(phonenumber) if phonenumber[0] != '0': raise forms.ValidationError('Mobile number "0" se start karein') elif phonenumber[0:2] != '03': raise forms.ValidationError('Mobile number "03" se start karein') elif mobile_length < 11: raise forms.ValidationError('Pura mobile number likhein') elif phonenumber == '03451234567': raise forms.ValidationError('Apna real mobile number likhein') elif already_verified: if not self.allow_reverification: raise forms.ValidationError('Ap pehley se verified hain') ttl = is_sms_sending_rate_limited(user_id) if ttl: raise forms.ValidationError('Ap dubara SMS receive kar sakein ge {0} baad'.format(secs_to_mins(ttl))) check = someone_elses_number(phonenumber[-10:],user_id) if check: raise forms.ValidationError('Ye number kisi aur user ka hai, koi aur number likhien') #Check if phone number associated with another profile return phonenumber[-11:]
def clean_pinnumber(self): user_id = self.user_id pinnumber = self.cleaned_data.get('pinnumber') already_verified = is_mobile_verified(user_id) if already_verified and not self.allow_reverification: raise forms.ValidationError('Ap pehley se verified hain') elif len(pinnumber) < 5: raise forms.ValidationError('Pura pin code likhien') else: logged, ttl = log_pin_attempt(user_id) if logged: exists, status = verify_user_pin(user_id, pinnumber) if exists: return status else: if status == 'pin_incorrect': raise forms.ValidationError('Apki pin ghalat hai') else: #return when pin is invalid or has expired invalidate_user_pin(user_id) return status else: raise forms.ValidationError( 'Ziyada ghalat tries ho gaien, {0} baad wapis aien'.format( secs_to_mins(ttl)))
def clean_phonenumber(self): phonenumber = self.cleaned_data.get('phonenumber') user_id = self.user_id already_verified = is_mobile_verified(user_id) mobile_length = len(phonenumber) if phonenumber[0] != '0': raise forms.ValidationError('Mobile number "0" se start karein') elif phonenumber[0:2] != '03': raise forms.ValidationError('Mobile number "03" se start karein') elif mobile_length < 11: raise forms.ValidationError('Pura mobile number likhein') elif phonenumber == '03451234567': raise forms.ValidationError('Apna real mobile number likhein') elif already_verified: if not self.allow_reverification: raise forms.ValidationError('Ap pehley se verified hain') ttl = is_sms_sending_rate_limited(user_id) if ttl: raise forms.ValidationError( 'Ap dubara SMS receive kar sakein ge {0} baad'.format( secs_to_mins(ttl))) check = someone_elses_number(phonenumber[-10:], user_id) if check: raise forms.ValidationError( 'Ye number kisi aur user ka hai, koi aur number likhien') #Check if phone number associated with another profile return phonenumber[-11:]
def verify_user_mobile_unpaid(request): """ This renders a template where user puts her number that she wants verified """ if is_mobile_verified(request.user.id): # not allowed to proceed return redirect("missing_page") else: return render(request,'verification/user_mobile_verification.html',{'form':MobileVerificationForm()})
def clean_user_id(self): user_id = self.cleaned_data.get("user_id") try: user_id = int(user_id) except (ValueError,TypeError): raise forms.ValidationError('Does not compute') if User.objects.filter(id=user_id).exists(): # go on if is_mobile_verified(user_id): return user_id else: raise forms.ValidationError('This dude is already unverified') else: raise forms.ValidationError('Fraudulent activity detected')
def clean_user_id(self): user_id = self.cleaned_data.get("user_id") try: user_id = int(user_id) except (ValueError, TypeError): raise forms.ValidationError('Does not compute') if User.objects.filter(id=user_id).exists(): # go on if is_mobile_verified(user_id): return user_id else: raise forms.ValidationError('This dude is already unverified') else: raise forms.ValidationError('Fraudulent activity detected')
def forgot_password(request, *args, **kwargs): """ This initiates the 'forgot password' flow It takes user's username and federated ID provider (FB, Google or Mobile) as an input """ if request.user.is_authenticated(): # already logged in fp_log_firebase_user_verification_outcome( 'id_already_logged_in_firebase') return redirect('home') elif request.method == "POST": form = ForgettersNicknameForm(data=request.POST, lang=None) if form.is_valid(): username, user_id = form.cleaned_data.get("username") verified_status, is_legacy_verification = is_mobile_verified( user_id, with_legacy_verification=True) if verified_status: request.session["forgetters_username"] = username request.session["forgetters_userid"] = user_id request.session.modified = True if is_legacy_verification: fp_log_firebase_entered() return render( request, "unauth/verify_forgetters_account_via_firebase.html", {'provider_type': 'phone'}) else: fp_log_firebase_entered() provider = get_provider( user_id ) # what kind of provider was used (FB, Goog, Mobile) if provider == 'artificial': return redirect('missing_page') else: return render( request, "unauth/verify_forgetters_account_via_firebase.html", {'provider_type': provider}) else: return render(request, "unauth/nick_unassociated_with_mobnum.html", {'nick': username}) else: return render(request, "unauth/forgot_password.html", {'form': form}) else: return render(request, "unauth/forgot_password.html", {'form': ForgettersNicknameForm()})
def clean_user_id(self): user_id = self.cleaned_data.get("user_id") user_id = user_id.strip() try: user_id = int(user_id) except (ValueError, TypeError): raise forms.ValidationError('Does not compute') ttl = is_artificial_verification_ratelimited() if ttl: raise forms.ValidationError('Not possible till %s years' % ttl) else: # does user exist if User.objects.filter(id=user_id).exists(): # go on if is_mobile_verified(user_id): raise forms.ValidationError('This dude is already king') else: return user_id else: raise forms.ValidationError('Is gone with the wind')
def clean_user_id(self): user_id = self.cleaned_data.get("user_id") user_id = user_id.strip() try: user_id = int(user_id) except (ValueError,TypeError): raise forms.ValidationError('Does not compute') ttl=is_artificial_verification_ratelimited() if ttl: raise forms.ValidationError('Not possible till %s years' % ttl) else: # does user exist if User.objects.filter(id=user_id).exists(): # go on if is_mobile_verified(user_id): raise forms.ValidationError('This dude is already king') else: return user_id else: raise forms.ValidationError('Is gone with the wind')
def clean_pinnumber(self): user_id = self.user_id pinnumber = self.cleaned_data.get('pinnumber') already_verified = is_mobile_verified(user_id) if already_verified and not self.allow_reverification: raise forms.ValidationError('Ap pehley se verified hain') elif len(pinnumber) < 5: raise forms.ValidationError('Pura pin code likhien') else: logged, ttl = log_pin_attempt(user_id) if logged: exists, status = verify_user_pin(user_id,pinnumber) if exists: return status else: if status == 'pin_incorrect': raise forms.ValidationError('Apki pin ghalat hai') else: #return when pin is invalid or has expired invalidate_user_pin(user_id) return status else: raise forms.ValidationError('Ziyada ghalat tries ho gaien, {0} baad wapis aien'.format(secs_to_mins(ttl)))
def clean_defender_id(self): defender_id = self.cleaned_data.get("defender_id") defender_id = defender_id.strip() is_rl = is_rate_limited_from_adding_defender(self.user_id) if is_rl: # disallow due to hitting rate limit raise forms.ValidationError('You have been removed from the system') else: try: defender_id = int(defender_id) except (ValueError,TypeError): raise forms.ValidationError('Invalid entry') if not is_mobile_verified(defender_id): # not mobile verified - disallow raise forms.ValidationError('Mobile verification non-existent') elif in_defenders(defender_id): # already a defender raise forms.ValidationError('Duplication of effort') elif not User.objects.filter(id=defender_id).exists(): # defender id is invalid raise forms.ValidationError('Hypothetical entity') else: return defender_id
def verify_user_mobile_unpaid(request): """ This renders a template where user selects verification method (FB, Goog, Mobile) """ if is_mobile_verified(request.user.id): # not allowed to proceed log_firebase_user_verification_outcome('id_already_verified_firebase') return redirect("home") else: if request.META.get('HTTP_X_IORG_FBS', False): template_name = 'verification/user_mobile_verification_fbs.html' action = 'Z.f.u' log_firebase_entered(not_supported=True) elif request.is_opera_mini: template_name = 'verification/user_mobile_verification_fbs.html' action = 'Z.o.u' log_firebase_entered(not_supported=True) else: template_name = 'verification/user_mobile_verification.html' action = 'Z.u' log_firebase_entered() ################### Retention activity logging ################### user_id = request.user.id if user_id > SEGMENT_STARTING_USER_ID: time_now = time.time() activity_dict = { 'm': 'GET', 'act': action, 't': time_now } # defines what activity just took place log_user_activity.delay(user_id=user_id, activity_dict=activity_dict, time_now=time_now) ################################################################## return render(request, template_name, {'form': MobileVerificationForm()})
def wait_before_verifying(request): """ Prompt shown to FBS based would-be verifiers, chiding them to wait 24 hours before dipping their beaks in the verification bucket """ user_id = request.user.id if request.method == "POST": if is_mobile_verified(user_id): return redirect("home") else: on_fbs = request.META.get('HTTP_X_IORG_FBS',False) if on_fbs: joining_epoch_time = convert_to_epoch(request.user.date_joined) expire_at = joining_epoch_time + FBS_VERIFICATION_WAIT_TIME ttw = expire_at - time.time() if ttw > 0: # expiry of this lock is a 'future' event return render(request,'verification/wait_before_verifying.html',{'redirect_to_paid_internet':True}) else: # this lock has expired! return redirect("verify_user_mobile") else: return redirect("verify_user_mobile") else: try: joining_epoch_time = convert_to_epoch(request.user.date_joined) expire_at = joining_epoch_time + FBS_VERIFICATION_WAIT_TIME ttw = expire_at - time.time() if ttw > 0: # expiry of this lock is a 'future' event log_fbs_please_wait(user_id=user_id, expire_at=int(expire_at)) return render(request, "verification/wait_before_verifying.html", {'time_to_wait':int(ttw)}) else: # this lock has expired! return redirect("verify_user_mobile") except (ValueError, TypeError): return redirect('missing_page')
def clean_defender_id(self): defender_id = self.cleaned_data.get("defender_id") defender_id = defender_id.strip() is_rl = is_rate_limited_from_adding_defender(self.user_id) if is_rl: # disallow due to hitting rate limit raise forms.ValidationError( 'You have been removed from the system') else: try: defender_id = int(defender_id) except (ValueError, TypeError): raise forms.ValidationError('Invalid entry') if not is_mobile_verified(defender_id): # not mobile verified - disallow raise forms.ValidationError('Mobile verification non-existent') elif in_defenders(defender_id): # already a defender raise forms.ValidationError('Duplication of effort') elif not User.objects.filter(id=defender_id).exists(): # defender id is invalid raise forms.ValidationError('Hypothetical entity') else: return defender_id
def pin_verification(request): """ This will verify the pin entered by the user """ if request.method == "POST": on_fbs = request.META.get('HTTP_X_IORG_FBS',False) if on_fbs: joining_epoch_time = convert_to_epoch(request.user.date_joined) if joining_epoch_time + FBS_VERIFICATION_WAIT_TIME - time.time() > 0: # rate limited from verifying currently, inform accordingly return redirect("wait_before_verifying") ########################################################################### user_id = request.user.id if is_mobile_verified(user_id): target_id = get_personal_group_target_id(user_id) if can_change_number(user_id) and target_id: form = PinVerifyForm(request.POST,user_id=user_id,allow_reverification=True) phonenumber = request.session.get('phonenumber'+str(user_id),None) if form.is_valid(): pin_state = form.cleaned_data.get("pinnumber") if pin_state == 'pin_matched': request.session.pop("newbie_flag",None)# verified users aren't newbies by definition request.session.pop("newbie_lang",None)# verified users aren't newbies by definition for_personal_group = request.session.pop("for_personal_group",None) own_anon_status, their_anon_status, group_id = get_personal_group_anon_state(user_id, target_id) if for_personal_group == '1': request.session.pop('phonenumber'+str(user_id),None) account_kid_id = 'twilio_verification' national_number = phonenumber[-10:] number ='+92'+national_number mobile_data = {'national_number':national_number,'number':number,'country_prefix':'92'} save_consumer_credentials.delay(account_kid_id, mobile_data, user_id) set_personal_group_mobile_num_cooloff(user_id) if their_anon_status is None: return redirect("home") else: twiliolog_user_reverified() log_fbs_user_verification(user_id, on_fbs=on_fbs, time_now=time.time()) return render(request,"personal_group/sms_settings/personal_group_successful_mob_verification.html",\ {'tid':target_id,'their_anon':their_anon_status,'name':retrieve_uname(target_id,decode=True),\ 'avatar':None if their_anon_status else UserProfile.objects.filter(user_id=target_id).values_list('avatar',flat=True)[0]}) else: # maybe the key has already been popped, send the person back to the relevant personal group request.session["personal_group_gid_key:"+target_id] = group_id#checked request.session.modified = True return redirect("enter_personal_group") else: # pin_state is 'invalid' or 'expired' request.session['start_verification_again'+str(user_id)] = '1' request.session.modified = True return redirect("verify_user_mobile") else: return render(request,"verification/enter_pin_code.html",{'form':form}) else: return redirect('missing_page') else: form = PinVerifyForm(request.POST,user_id=user_id,allow_reverification=False) phonenumber = request.session.get('phonenumber'+str(user_id),None) if form.is_valid(): pin_state = form.cleaned_data.get("pinnumber") if pin_state == 'pin_matched': request.session.pop("newbie_flag",None)# verified users aren't newbies by definition request.session.pop("newbie_lang",None)# verified users aren't newbies by definition request.session.pop('phonenumber'+str(user_id),None) account_kid_id = 'twilio_verification' national_number = phonenumber[-10:] number ='+92'+national_number mobile_data = {'national_number':national_number,'number':number,'country_prefix':'92'} save_consumer_credentials.delay(account_kid_id, mobile_data, user_id) increase_user_points.delay(user_id=user_id, increment=NUMBER_VERIFICATION_BONUS) twiliolog_user_verified() log_fbs_user_verification(user_id, on_fbs=on_fbs, time_now=time.time()) return render(request,"verification/reward_earned.html",{}) else: # pin_state is 'invalid' or 'expired' request.session['start_verification_again'+str(user_id)] = '1' request.session.modified = True return redirect("verify_user_mobile") else: return render(request,"verification/enter_pin_code.html",{'form':form}) else: # not a POST request return redirect('missing_page') ############################## Pink star verification #################################
def prelim_account_verification(request, *args, **kwargs): """ Used to confirm user's account before allowing them to change their forgotten password """ if request.user.is_authenticated(): # already logged in fp_log_firebase_user_verification_outcome( 'id_already_logged_in_firebase') return redirect('home') elif request.method == "POST": is_ajax = request.is_ajax() if is_ajax: username = request.session.get('forgetters_username', None) user_id = request.session.get('forgetters_userid', None) uid = request.POST.get('uid') stored_id = get_firebase_id(user_id) verified_status, is_legacy_verification = is_mobile_verified( user_id, with_legacy_verification=True) # this user verified via account kit if is_legacy_verification: mob_nums = get_user_verified_number(user_id) num = request.POST.get('phoneNumber') authentic_user = True if num[3:] in mob_nums else False if authentic_user: ################################################################################## # user previously verified using account kit - transition them to the new system # ################################################################################## provider = request.POST.get('Provider') puid = request.POST.get('ProviderUID') name = request.POST.get('Name') email = request.POST.get('email') purl = request.POST.get('PhotoURL') # remove user from the legacy system unverify_user_id(user_id=user_id) # add credentials to the new verification system user_verification_data = { 'uid': uid, 'provider': provider, 'puid': puid, 'name': name, 'email': email, 'purl': purl, 'num': num, 'verif_time': time.time() } save_consumer_details(user_verification_data, user_id) fp_log_firebase_user_verification_outcome('reverified') ################################################################################### return HttpResponse(json.dumps({ 'success': True, 'message': reverse("set_forgetters_password", kwargs={}) }), content_type='application/json') else: #Number provided does not belong to the user fp_log_firebase_user_verification_outcome( 'details_for_unrelated_account') request.session.pop('forgetters_username', None) request.session.pop('forgetters_userid', None) request.session["firebase_verification_failed"] = '1' request.session[ "firebase_verification_failure_reason"] = '3' #someone elses number, trying to dupe forgot password return HttpResponse( json.dumps({ 'success': True, 'message': reverse("firebase_forgot_pass_verification_failed", kwargs={}) }), content_type='application/json', ) elif stored_id == uid: # user is authentic - they have verified using firebase, redirect to set new password page fp_log_firebase_user_verification_outcome('reverified') return HttpResponse(json.dumps({ 'success': True, 'message': reverse("set_forgetters_password", kwargs={}) }), content_type='application/json') else: # not your account details fp_log_firebase_user_verification_outcome( 'details_for_unrelated_account') request.session.pop('forgetters_username', None) request.session.pop('forgetters_userid', None) request.session["firebase_verification_failed"] = '1' request.session[ "firebase_verification_failure_reason"] = '3' #someone elses number, trying to dupe forgot password return HttpResponse(json.dumps({ 'success': True, 'message': reverse("firebase_forgot_pass_verification_failed", kwargs={}) }), content_type='application/json') else: # TODO: show a prompt that non-JS environments don't support this functionality return redirect("forgot_password") else: # not a POST request return redirect("forgot_password")