def signup(request): user = request.user if user.is_authenticated(): return HttpResponseRedirect(reverse_lazy('dashboard')) form = RegistrationForm() if request.method == 'POST': form = RegistrationForm(data=request.POST) if form.is_valid(): email = form.cleaned_data['email'] password = form.cleaned_data['password'] existing_user = get_object_or_None(AuthUser, email=email) if existing_user: msg = _('That email already belongs to someone, please login:'******'Login Successful') messages.success(request, msg) return HttpResponseRedirect(reverse_lazy('dashboard')) elif request.method == 'GET': # Preseed name and/or email if passed through GET string email = request.GET.get('e') full_name = request.GET.get('name') if email or full_name: form = RegistrationForm(initial={ 'email': email, 'full_name': full_name, }) return { 'form': form, 'is_input_page': True, }
def reset_pw(request, verif_code): ''' Page you arrive on after clicking a link to (re)set your password ''' sent_email = get_object_or_404(SentEmail, verif_code=verif_code) if now() - sent_email.sent_at > timedelta(hours=72): msg = _('Sorry, that link has expired. Please try again.') messages.warning(request, msg) return HttpResponseRedirect(reverse_lazy('forgot_password')) if sent_email.verified_at and (now() - sent_email.verified_at > timedelta(minutes=60)): msg = _('Sorry, that was already used. Please try again.') messages.warning(request, msg) return HttpResponseRedirect(reverse_lazy('forgot_password')) else: form = SetPWForm() if request.method == 'POST': form = SetPWForm(data=request.POST) if form.is_valid(): sent_email.verify_user_email(request) password = form.cleaned_data['password'] auth_user = sent_email.auth_user auth_user.set_password(password) auth_user.save() msg = _('Your password has been set.') messages.success(request, msg) # login user user_to_login = authenticate(email=auth_user.email, password=password) login(request, user_to_login) # Log the login LoggedLogin.record_login(request) # All done return HttpResponseRedirect(reverse_lazy('dashboard')) return { # 'user': sent_email.auth_user, 'form': form, 'verif_code': verif_code, 'is_input_page': True, }
def confirm_subscription(request, verif_code): ''' New user onboarding where they confirm their email and then we ask for a PW ''' sent_email = get_object_or_404(SentEmail, verif_code=verif_code) auth_user = sent_email.auth_user # Login the user # http://stackoverflow.com/a/3807891/1754586 auth_user.backend = 'django.contrib.auth.backends.ModelBackend' login(request, auth_user) # Log the login LoggedLogin.record_login(request) if sent_email.verified_at and auth_user.email_verified: # already verified msg = _('<b>%(email_address)s</b> already verified' % {'email_address': sent_email.to_email}) messages.info(request, msg, extra_tags='safe') return HttpResponseRedirect(reverse_lazy('dashboard')) else: # not yet verified sent_email.verify_user_email(request) if sent_email.address_forwarding: b58_address = sent_email.address_forwarding.initial_address else: b58_address = sent_email.address_subscription.b58_address msg_merge = { 'email_address': sent_email.to_email, 'b58_address': b58_address, } msg = _( '<b>%(email_address)s</b> verified, you will now receive email notifications for <b>%(b58_address)s</b>.' % msg_merge) messages.info(request, msg, extra_tags='safe') # Ask them to create a new PW return HttpResponseRedirect(reverse_lazy('password_upsell'))
def unsubscribe_address(request, unsub_code): ''' 1-click unsubscribe an address via email ''' sent_email = get_object_or_404(SentEmail, unsub_code=unsub_code) auth_user = sent_email.auth_user # Login the user # http://stackoverflow.com/a/3807891/1754586 auth_user.backend = 'django.contrib.auth.backends.ModelBackend' login(request, auth_user) # Log the login LoggedLogin.record_login(request) if sent_email.unsubscribed_at: msg = _("You've already unsubscribed from this alert") messages.info(request, msg) else: address_subscription = sent_email.address_subscription assert address_subscription address_subscription.user_unsubscribe_subscription() addr_uri = reverse('address_overview', kwargs={ 'coin_symbol': address_subscription.coin_symbol, 'address': address_subscription.b58_address, }) msg = _( 'You have been unsubscribed from notifications on <a href="%(addr_uri)s">%(b58_address)s</a>' % { 'b58_address': address_subscription.b58_address, 'addr_uri': addr_uri, }) messages.info(request, msg, extra_tags='safe') return HttpResponseRedirect(reverse('dashboard'))
def setup_address_forwarding(request, coin_symbol): # kind of tricky because we have to deal with both logged in and new users already_authenticated = request.user.is_authenticated() initial = {'coin_symbol': coin_symbol} if already_authenticated: form = KnownUserAddressForwardingForm(initial=initial) else: form = NewUserAddressForwardingForm(initial=initial) if request.method == 'POST': if already_authenticated: form = KnownUserAddressForwardingForm(data=request.POST) else: form = NewUserAddressForwardingForm(data=request.POST) if form.is_valid(): coin_symbol = form.cleaned_data['coin_symbol'] destination_address = form.cleaned_data['coin_address'] user_email = form.cleaned_data.get('email') # optional. null in case of KnownUserAddressForwardingForm if already_authenticated: auth_user = request.user else: auth_user = None if user_email: # Check for existing user with that email existing_user = get_object_or_None(AuthUser, email=user_email) if existing_user: msg = _( 'Please first login to this account to create a notification' ) messages.info(request, msg) return HttpResponseRedirect( existing_user.get_login_uri()) else: # Create user with unknown (random) password auth_user = AuthUser.objects.create_user( email=user_email, password=None, # it will create a random pw creation_ip=get_client_ip(request), creation_user_agent=get_user_agent(request), ) # Login the user # http://stackoverflow.com/a/3807891/1754586 auth_user.backend = 'django.contrib.auth.backends.ModelBackend' login(request, auth_user) # Log the login LoggedLogin.record_login(request) else: # No user email given, proceed anonymously # FIXME: confirm this pass # Setup Payment Forwarding forwarding_address_details = get_forwarding_address_details( destination_address=destination_address, api_key=BLOCKCYPHER_API_KEY, callback_url= None, # notifications happen separately (and not always) coin_symbol=coin_symbol, ) if 'error' in forwarding_address_details: # Display error message back to user messages.warning(request, forwarding_address_details['error'], extra_tags='safe') else: initial_address = forwarding_address_details['input_address'] # create forwarding object address_forwarding_obj = AddressForwarding.objects.create( coin_symbol=coin_symbol, initial_address=initial_address, destination_address=destination_address, auth_user=auth_user, blockcypher_id=forwarding_address_details['id'], ) subscribe_uri = reverse('subscribe_address', kwargs={'coin_symbol': coin_symbol}) uri_qs = {'a': initial_address} if user_email: uri_qs['e'] = user_email if already_authenticated: uri_qs['e'] = auth_user.email subscribe_uri = '%s?%s' % (subscribe_uri, urlencode(uri_qs)) initial_addr_uri = reverse('address_overview', kwargs={ 'coin_symbol': coin_symbol, 'address': initial_address, }) destination_addr_uri = reverse('address_overview', kwargs={ 'coin_symbol': coin_symbol, 'address': destination_address, }) msg_merge_dict = { 'initial_address': initial_address, 'initial_addr_uri': initial_addr_uri, 'destination_address': destination_address, 'destination_addr_uri': destination_addr_uri, 'subscribe_uri': subscribe_uri, 'small_payments_msg': SMALL_PAYMENTS_MSG, } if auth_user: msg_merge_dict['user_email'] = auth_user.email if user_email or ( already_authenticated and form.cleaned_data['wants_email_notification']): # Create an address subscription for all of these cases # Hit blockcypher and return subscription id callback_uri = reverse( 'address_webhook', kwargs={ 'secret_key': WEBHOOK_SECRET_KEY, # hack for rare case of two webhooks requested on same address: 'ignored_key': simple_pw_generator(num_chars=10), }) callback_url = uri_to_url(callback_uri) bcy_id = subscribe_to_address_webhook( subscription_address=initial_address, callback_url=callback_url, coin_symbol=coin_symbol, api_key=BLOCKCYPHER_API_KEY, ) # only notify for deposits AddressSubscription.objects.create( coin_symbol=coin_symbol, b58_address=initial_address, auth_user=auth_user, blockcypher_id=bcy_id, notify_on_deposit=True, notify_on_withdrawal=False, address_forwarding_obj=address_forwarding_obj, ) if user_email: # New signup msg = _(''' Transactions sent to <a href="%(initial_addr_uri)s">%(initial_address)s</a> will now be automatically forwarded to <a href="%(destination_addr_uri)s">%(destination_address)s</a>, but you must confirm your email to receive notifications. <br /><br /> <i>%(small_payments_msg)s</i> ''' % msg_merge_dict) messages.success(request, msg, extra_tags='safe') address_forwarding_obj.send_forwarding_welcome_email() return HttpResponseRedirect( reverse('unconfirmed_email')) else: if auth_user.email_verified: msg = _(''' Transactions sent to <a href="%(initial_addr_uri)s">%(initial_address)s</a> will now be automatically forwarded to <a href="%(destination_addr_uri)s">%(destination_address)s</a>, and you will immediately receive an email notification at <b>%(user_email)s</b>. <br /><br /> <i>%(small_payments_msg)s</i> ''' % msg_merge_dict) messages.success(request, msg, extra_tags='safe') return HttpResponseRedirect(reverse('dashboard')) else: # existing unconfirmed user msg = _(''' Transactions sent to <a href="%(initial_addr_uri)s">%(initial_address)s</a> will now be automatically forwarded to <a href="%(destination_addr_uri)s">%(destination_address)s</a>, but you must confirm your email to receive notifications. <br /><br /> <i>%(small_payments_msg)s</i> ''' % msg_merge_dict) messages.success(request, msg, extra_tags='safe') address_forwarding_obj.send_forwarding_welcome_email( ) return HttpResponseRedirect( reverse('unconfirmed_email')) elif already_authenticated: # already authenticated and doesn't want subscriptions msg = _(''' Transactions sent to <a href="%(initial_addr_uri)s">%(initial_address)s</a> will now be automatically forwarded to <a href="%(destination_addr_uri)s">%(destination_address)s</a>. You will not receive email notifications (<a href="%(subscribe_uri)s">subscribe</a>). <br /><br /> <i>%(small_payments_msg)s</i> ''' % msg_merge_dict) messages.success(request, msg, extra_tags='safe') return HttpResponseRedirect(reverse('dashboard')) else: # New signup sans email msg = _(''' Transactions sent to <a href="%(initial_addr_uri)s">%(initial_address)s</a> will now be automatically forwarded to <a href="%(destination_addr_uri)s">%(destination_address)s</a>. You will not receive email notifications (<a href="%(subscribe_uri)s">subscribe</a>). <br /><br /> <i>%(small_payments_msg)s</i> ''' % msg_merge_dict) messages.success(request, msg, extra_tags='safe') return HttpResponseRedirect(destination_addr_uri) elif request.method == 'GET': coin_address = request.GET.get('a') subscriber_email = request.GET.get('e') if coin_address: initial['coin_address'] = coin_address if subscriber_email and not already_authenticated: initial['email'] = subscriber_email if coin_address or subscriber_email: if already_authenticated: form = KnownUserAddressForwardingForm(initial=initial) else: form = NewUserAddressForwardingForm(initial=initial) return { 'form': form, 'coin_symbol': coin_symbol, 'is_input_page': True, }
def subscribe_address(request, coin_symbol): already_authenticated = request.user.is_authenticated() # kind of tricky because we have to deal with both logged in and new users initial = {'coin_symbol': coin_symbol} if already_authenticated: form = KnownUserAddressSubscriptionForm(initial=initial) else: form = NewUserAddressSubscriptionForm(initial=initial) if request.method == 'POST': if already_authenticated: form = KnownUserAddressSubscriptionForm(data=request.POST) else: form = NewUserAddressSubscriptionForm(data=request.POST) if form.is_valid(): coin_symbol = form.cleaned_data['coin_symbol'] coin_address = form.cleaned_data['coin_address'] if already_authenticated: auth_user = request.user else: user_email = form.cleaned_data['email'] # Check for existing user with that email existing_user = get_object_or_None(AuthUser, email=user_email) if existing_user: msg = _( 'Please first login to this account to create a notification' ) messages.info(request, msg) return HttpResponseRedirect(existing_user.get_login_uri()) else: # Create user with unknown (random) password auth_user = AuthUser.objects.create_user( email=user_email, password=None, # it will create a random pw creation_ip=get_client_ip(request), creation_user_agent=get_user_agent(request), ) # Login the user # http://stackoverflow.com/a/3807891/1754586 auth_user.backend = 'django.contrib.auth.backends.ModelBackend' login(request, auth_user) # Log the login LoggedLogin.record_login(request) existing_subscription_cnt = AddressSubscription.objects.filter( auth_user=auth_user, b58_address=coin_address, unsubscribed_at=None, disabled_at=None, ).count() if existing_subscription_cnt: msg = _( "You're already subscribed to that address. Please choose another address." ) messages.warning(request, msg) else: # TODO: this is inefficiently happening before email verification # Hit blockcypher and return subscription id callback_uri = reverse( 'address_webhook', kwargs={ 'secret_key': WEBHOOK_SECRET_KEY, # hack for rare case of two webhooks requested on same address: 'ignored_key': simple_pw_generator(num_chars=10), }) callback_url = uri_to_url(callback_uri) bcy_id = subscribe_to_address_webhook( subscription_address=coin_address, callback_url=callback_url, coin_symbol=coin_symbol, api_key=BLOCKCYPHER_API_KEY, ) address_subscription = AddressSubscription.objects.create( coin_symbol=coin_symbol, b58_address=coin_address, auth_user=auth_user, blockcypher_id=bcy_id, ) address_uri = reverse('address_overview', kwargs={ 'coin_symbol': coin_symbol, 'address': coin_address, }) if already_authenticated and auth_user.email_verified: msg = _( 'You will now be emailed notifications for <a href="%(address_uri)s">%(coin_address)s</a>' % { 'coin_address': coin_address, 'address_uri': address_uri, }) messages.success(request, msg, extra_tags='safe') return HttpResponseRedirect(reverse('dashboard')) else: address_subscription.send_notifications_welcome_email() return HttpResponseRedirect(reverse('unconfirmed_email')) elif request.method == 'GET': coin_address = request.GET.get('a') subscriber_email = request.GET.get('e') if coin_address: initial['coin_address'] = coin_address if subscriber_email and not already_authenticated: initial['email'] = subscriber_email if coin_address or subscriber_email: if already_authenticated: form = KnownUserAddressSubscriptionForm(initial=initial) else: form = NewUserAddressSubscriptionForm(initial=initial) return { 'form': form, 'coin_symbol': coin_symbol, 'is_input_page': True, }
def user_login(request): user = request.user if user.is_authenticated(): # TODO: notification return HttpResponseRedirect(reverse_lazy('dashboard')) form = LoginForm() if request.method == 'POST': form = LoginForm(data=request.POST) if form.is_valid(): email = form.cleaned_data['email'] password = form.cleaned_data['password'] auth_user = get_object_or_None(AuthUser, email=email) if auth_user: if auth_user.has_usable_password(): user = authenticate(email=email, password=password) if user: login(request, user) LoggedLogin.record_login(request) if user.is_staff: return HttpResponseRedirect('/admin/') else: post_login_url = reverse_lazy('dashboard') return HttpResponseRedirect(post_login_url) else: pw_reset_uri = reverse_lazy('forgot_password') pw_reset_uri = '%s?e=%s' % (pw_reset_uri, escape(email)) msg = _( 'Sorry, that password is incorrect. Would you like to <a href="%(pw_reset_uri)s">reset your password</a>?' % { 'pw_reset_uri': pw_reset_uri, }) messages.warning(request, msg, extra_tags='safe') else: msg = _( "Sorry, that account doesn't have a password set yet.") messages.info(request, msg, extra_tags='safe') redir_uri = reverse_lazy('forgot_password') redir_uri = '%s?e=%s' % (redir_uri, escape(email)) return HttpResponseRedirect(redir_uri) else: signup_base = reverse_lazy('signup') signup_uri = '%s?e=%s' % (signup_base, escape(email)) msg = _( 'Account not found. Did you mean to <a href="%(signup_uri)s">sign up</a>?' % { 'signup_uri': signup_uri, }) messages.warning(request, msg, extra_tags='safe') elif request.method == 'GET': email = request.GET.get('e') if email: form = LoginForm(initial={'email': email}) return { 'form': form, 'is_input_page': True, }