def get(self, request, conversation): # TODO: Ideally we should display a nice message to the user # if they access the page for a conversation that has # already been started. Currently we just display a 404 # page if the token no longer exists because it has # already been used. token_manager = DjangoTokenManager(request.user_api.api.token_manager) token = request.GET.get('token') token_data = token_manager.verify_get(token) if not token_data: raise Http404 params = token_data['extra_params'] action_name = params.get('action_display_name') action_details = params.get('action_data').get('display', {}) return self.render_to_response({ 'success': False, 'conversation': conversation, 'action_name': action_name, 'action_details': action_details, 'form': ConfirmConversationForm(initial={'token': token}), })
def post(self, request, conversation): token = request.POST.get('token') token_manager = DjangoTokenManager(request.user_api.api.token_manager) token_data = token_manager.verify_get(token) if not token_data: raise Http404 action_name = token_data['extra_params'].get('action_name') action_data = token_data['extra_params'].get('action_data', {}) action = self.view_def.get_action(action_name) action_view = ConversationActionView( view_def=self.view_def, action=action) user_token, sys_token = token_manager.parse_full_token(token) confirmation_form = ConfirmConversationForm(request.POST) success = False if confirmation_form.is_valid(): try: if token_manager.delete(user_token): return action_view.perform_action( request, conversation, action_data) else: messages.warning("Conversation already confirmed!") # TODO: Better exception handling except ConversationSendError as error: messages.error(request, str(error)) else: messages.error('Invalid confirmation form.') return self.render_to_response({ 'form': confirmation_form, 'success': success, 'conversation': conversation, })
def setUp(self): self.vumi_helper = self.add_helper(DjangoVumiApiHelper()) self.user_helper = self.vumi_helper.make_django_user() self.user_pk = self.user_helper.get_django_user().pk self.client = Client() self.tm = DjangoTokenManager(TokenManager( self.vumi_helper.get_redis_manager().sub_manager('token_manager')))
def _confirm_action(self, request, conv, user_account, action_data): # The URL the user will be redirected to post-confirmation redirect_to = self.get_view_url('confirm', conversation_key=conv.key) # The token to be sent. params = { 'action_data': action_data, 'action_name': self.action.action_name, 'action_display_name': self.action.action_display_name, } token_manager = DjangoTokenManager(request.user_api.api.token_manager) token = token_manager.generate(redirect_to, user_id=request.user.id, extra_params=params) conv.send_token_url( token_manager.url_for_token(token), user_account.msisdn) messages.info(request, 'Confirmation request sent.') return self.redirect_to('show', conversation_key=conv.key)
class TestDjangoTokenManager(GoDjangoTestCase): def setUp(self): self.vumi_helper = self.add_helper(DjangoVumiApiHelper()) self.user_helper = self.vumi_helper.make_django_user() self.user_pk = self.user_helper.get_django_user().pk self.client = Client() self.tm = DjangoTokenManager(TokenManager( self.vumi_helper.get_redis_manager().sub_manager('token_manager'))) def test_generate_callback(self): token = self.tm.generate_callback_token('/foo/', 'It worked', callback_for_test, callback_args=['arg'], callback_kwargs={'kwarg': 'kwarg'}, message_level=messages.SUCCESS, user_id=self.user_pk) token_data = self.tm.get(token) self.assertEqual(token_data['redirect_to'], reverse('token_task')) self.assertEqual(token_data['user_id'], str(self.user_pk)) self.assertEqual(token_data['extra_params'], { 'callback_args': ['arg'], 'callback_kwargs': {'kwarg': 'kwarg'}, 'callback_name': '%s.%s' % (callback_for_test.__module__, callback_for_test.__name__), 'return_to': '/foo/', 'message_level': messages.SUCCESS, 'message': 'It worked', }) def test_url_for_token(self): url = self.tm.url_for_token('foo') self.assertTrue(url.endswith(reverse('token', kwargs={'token': 'foo'}))) def test_token_require_login(self): token = self.tm.generate('/path/', user_id=self.user_pk) token_url = reverse('token', kwargs={'token': token}) response = self.client.get(token_url) self.assertRedirects(response, '%s?%s' % (reverse('auth_login'), urllib.urlencode({ 'next': reverse('token', kwargs={'token': token}), }))) def test_token_with_login(self): token = self.tm.generate('/path/', user_id=self.user_pk) token_url = reverse('token', kwargs={'token': token}) token_data = self.tm.get(token) self.client.login(email='*****@*****.**', password='******') response = self.client.get(token_url) self.assertTrue( response['Location'].endswith('/path/?token=%s-%s%s' % ( len(token), token, token_data['system_token']))) def test_token_with_invalid_login(self): token = self.tm.generate('/path/', user_id=-1) token_url = reverse('token', kwargs={'token': token}) self.client.login(username='******', password='******') response = self.client.get(token_url) self.assertRedirects(response, '%s?%s' % (reverse('auth_login'), urllib.urlencode({ 'next': reverse('token', kwargs={'token': token}), }))) def test_invalid_token(self): token = self.tm.generate('/foo/', user_id=self.user_pk) token_url = reverse('token', kwargs={'token': token}) response = self.client.get(token_url) self.assertTrue(response.status_code, 404)
def details(request): profile = request.user.get_profile() token_manager = DjangoTokenManager(request.user_api.api.token_manager) account = profile.get_user_account() account_form = AccountForm(request.user, initial={ 'name': request.user.first_name, 'surname': request.user.last_name, 'email_address': request.user.email, 'msisdn': account.msisdn, 'confirm_start_conversation': account.confirm_start_conversation, 'email_summary': account.email_summary, }) email_form = EmailForm() password_change_form = PasswordChangeForm(request.user) if request.method == 'POST': if '_account' in request.POST: account_form = AccountForm(request.user, request.POST) if account_form.is_valid(): data = account_form.cleaned_data params = { 'first_name': data['name'], 'last_name': data['surname'], 'email_address': data['email_address'], 'msisdn': data['msisdn'], 'email_summary': data['email_summary'], 'confirm_start_conversation': data['confirm_start_conversation'], } token = token_manager.generate_callback_token(request.path, 'Your details are being updated', update_account_details, callback_args=(request.user.id,), callback_kwargs=params, user_id=request.user.id) context = params.copy() context.update({ 'token_url': token_manager.url_for_token(token), }) send_mail( 'Vumi Go account detail change confirmation', render_to_string( 'account/change_account_details_mail.txt', context), settings.DEFAULT_FROM_EMAIL, [request.user.email, '*****@*****.**']) messages.info(request, 'Please confirm this change by clicking on the link ' 'that was just sent to your mailbox.') return redirect('account:details') elif '_email' in request.POST: email_form = EmailForm(request.POST) if email_form.is_valid(): subject = email_form.cleaned_data['subject'] message = email_form.cleaned_data['message'] _from = request.user.email send_mail(subject, message, _from, ['*****@*****.**']) messages.info(request, 'Thanks for your email. We will be in ' 'touch shortly.') return redirect(reverse('account:details')) else: messages.error(request, 'We didn\'t understand some of the ' 'values your provided in the email form, please try ' 'again.') elif '_password' in request.POST: password_change_form = PasswordChangeForm(request.user, request.POST) if password_change_form.is_valid(): password_change_form.save() return render(request, 'account/details.html', { 'email_form': email_form, 'account_form': account_form, 'password_change_form': password_change_form, 'account_key': request.user_api.user_account_key, })