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.is_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) msg = _('<b>%(email_address)s</b> verified, you will now receive email notifications for <b>%(b58_address)s</b>.' % { 'email_address': sent_email.to_email, 'b58_address': sent_email.address_subscription.b58_address, }) 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.unsubscribed_at = now() address_subscription.save() msg = _("You've been unsubscribed from notifications on %(b58_address)s" % { 'b58_address': address_subscription.b58_address, }) messages.info(request, msg) return HttpResponseRedirect(reverse('dashboard'))
def register_merchant(request): user = request.user if user.is_authenticated(): merchant = user.get_merchant() if merchant and merchant.has_finished_registration(): return HttpResponsePermanentRedirect(reverse_lazy('customer_dashboard')) else: return HttpResponsePermanentRedirect(reverse_lazy('register_bitcoin')) initial = { 'country': 'USA', 'currency_code': 'USD', } form = MerchantRegistrationForm(AuthUser=AuthUser, initial=initial) form_valid = True # used to decide whether we run the JS or not if request.method == 'POST': form = MerchantRegistrationForm(AuthUser=AuthUser, data=request.POST) if form.is_valid(): email = form.cleaned_data['email'] password = form.cleaned_data['password'] full_name = form.cleaned_data['full_name'] business_name = form.cleaned_data['business_name'] country = form.cleaned_data['country'] currency_code = form.cleaned_data['currency_code'] # create user user = AuthUser.objects.create_user( username=email.lower(), email=email, password=password, full_name=full_name, ) # Create merchant merchant = Merchant.objects.create( user=user, business_name=business_name, country=country, currency_code=currency_code, ) # login user user_to_login = authenticate(username=email, password=password) login(request, user_to_login) # Log the login LoggedLogin.record_login(request) return HttpResponseRedirect(reverse_lazy('register_bitcoin')) else: form_valid = False elif request.method == 'GET': email = request.GET.get('e') if email: initial['email'] = email form = MerchantRegistrationForm(AuthUser=AuthUser, initial=initial) return {'form': form, 'user': user, 'form_valid': form_valid}
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.unsubscribed_at = now() address_subscription.save() msg = _( "You've been unsubscribed from notifications on %(b58_address)s" % { 'b58_address': address_subscription.b58_address, }) messages.info(request, msg) return HttpResponseRedirect(reverse('dashboard'))
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}
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, }
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 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 login_request(request): if request.user and request.user.is_authenticated(): return HttpResponseRedirect(reverse_lazy('customer_dashboard')) if request.method == 'POST': form = LoginForm(data=request.POST) if form.is_valid(): # Log in user email = form.cleaned_data['email'] password = form.cleaned_data['password'] user_found = get_object_or_None(AuthUser, username=email) if user_found: user = authenticate(username=email, password=password) if user: if user.is_staff: return HttpResponseRedirect(reverse_lazy('two_factor:login')) login(request, user) request.session['last_password_validation'] = now().ctime() # Log the login LoggedLogin.record_login(request) redir_path = form.cleaned_data['redir_path'] if redir_path: # add leading/trailling slashes redir_path = '/%s/' % redir_path else: redir_path = reverse_lazy('customer_dashboard') return HttpResponseRedirect(redir_path) else: reset_uri = '%s?e=%s' % (reverse_lazy('request_new_password'), user_found.email) msg = _('''Sorry, that's not the right password for <b>%(email)s</b>. <a href="%(reset_uri)s">Reset password?</a>''') % { 'email': escape(email), 'reset_uri': reset_uri} messages.warning(request, msg, extra_tags='safe') else: msg = _("No account found for <b>%(email)s</b>.") % {'email': escape(email)} messages.warning(request, msg, extra_tags='safe') elif request.method == 'GET': initial = {'email': request.GET.get('e')} if request.GET.get('next'): initial['redir_path'] = request.GET.get('next').strip('/') form = LoginForm(initial=initial) else: form = LoginForm() return {'form': form}
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 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).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 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, }
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).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, }
def set_new_password(request): if request.user.is_authenticated(): msg = _( '''You're already logged in. You must <a href="/logout/">logout</a> before you can reset your password.''' ) messages.error(request, msg, extra_tags='safe') return HttpResponseRedirect(reverse_lazy('home')) # none of these things *should* ever happen, hence the cryptic error message (to figure out how that's possible) email_auth_token_id = request.session.get('email_auth_token_id') if not email_auth_token_id: msg = _('Token cookie not found. Please generate a new link.') messages.warning(request, msg) return HttpResponseRedirect(reverse_lazy('request_new_password')) ea_token = get_object_or_None(EmailAuthToken, id=email_auth_token_id) if not ea_token: msg = _('Token not found. Please generate a new link.') messages.warning(request, msg) return HttpResponseRedirect(reverse_lazy('request_new_password')) if ea_token.key_deleted_at: msg = _('Token deleted. Please generate a new link.') messages.warning(request, msg) return HttpResponseRedirect( reverse_lazy('request_new_password') + '?e=' + ea_token.auth_user.email) if not ea_token.key_used_at: msg = _('Site error. Please generate a new link.') messages.warning(request, msg) return HttpResponseRedirect( reverse_lazy('request_new_password') + '?e=' + ea_token.auth_user.email) if now() - ea_token.key_used_at > timedelta(minutes=15): msg = _('Time limit expired. Please generate a new link.') messages.warning(request, msg) return HttpResponseRedirect( reverse_lazy('request_new_password') + '?e=' + ea_token.auth_user.email) else: # We're good to go! form = SetPWForm() if request.method == 'POST': form = SetPWForm(data=request.POST) if form.is_valid(): new_pw = form.cleaned_data['newpassword'] user = ea_token.auth_user user.set_password(new_pw) user.save() # login user user_to_login = authenticate(username=user.username, password=new_pw) login(request, user_to_login) LoggedLogin.record_login(request) # delete the token from the session del request.session['email_auth_token_id'] merchant = user.get_merchant() if merchant: api_cred = merchant.get_api_credential() if api_cred: try: if api_cred.get_balance() > SATOSHIS_PER_BTC: merchant.disable_all_credentials() # TODO: poor UX, but let's wait until we actually have people doing this msg = _( 'Your API credentials were unlinked from your CoinSafe account for safety, please link your wallet again in order to sell bitcoin to customers.' ) messages.success(request, msg) except Exception as e: # TODO: log these somewhere when people start using this feature print 'Error was: %s' % e # Mark this + all other tokens for that user as expired ea_token.expire_outstanding_tokens() msg = _('Password succesfully updated.') messages.success(request, msg) return HttpResponseRedirect(reverse_lazy('customer_dashboard')) return {'form': form}