Skip to content
This repository has been archived by the owner on Aug 21, 2019. It is now read-only.

Prevent duplicate captcha validation #337

Merged
merged 2 commits into from
Oct 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions company/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def clean_page(self):


class ContactCompanyForm(forms.Form):

error_css_class = 'input-field-container has-error'
TERMS_CONDITIONS_MESSAGE = (
'Tick the box to confirm you agree to the terms and conditions.'
Expand Down
6 changes: 6 additions & 0 deletions exportopportunity/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ class OpportunityNeedLegalForm(OpportunityNeedBaseForm):


class OpportunityContactDetailsForm(forms.Form):

def __init__(self, skip_captcha_errors=False, *args, **kwargs):
super().__init__(*args, **kwargs)
if skip_captcha_errors:
del self.fields['captcha']

error_css_class = 'input-field-container has-error'
MESSAGE_TERMS_CONDITIONS = (
'Tick the box to confirm you agree to the terms and conditions.'
Expand Down
15 changes: 9 additions & 6 deletions exportopportunity/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,10 @@ def test_campaign_language_switcher(
@patch.object(views.helpers, 'get_showcase_companies',
return_value=showcase_companies)
@patch.object(views.api_client.exportopportunity, 'create_opportunity_food')
@patch('captcha.fields.ReCaptchaField.clean')
def test_submit_export_opportunity_food(
mock_create_opportunity, mock_get_showcase_companies, client,
api_response_200, settings, captcha_stub, url, country
mock_clean_captcha, mock_create_opportunity, mock_get_showcase_companies,
client, api_response_200, settings, captcha_stub, url, country
):
settings.FEATURE_EXPORT_OPPORTUNITY_LEAD_GENERATION_ENABLED = True
mock_create_opportunity.return_value = api_response_200
Expand Down Expand Up @@ -296,7 +297,6 @@ def test_submit_export_opportunity_food(
'additional_requirements': 'give me things',
'business_model': ['distribution'],
'business_model_other': 'things',
'captcha': None,
'company_name': 'Jim corp',
'company_website': 'http://www.example.com',
'contact_preference': ['EMAIL', 'PHONE'],
Expand All @@ -321,6 +321,7 @@ def test_submit_export_opportunity_food(
assert mock_get_showcase_companies.call_args == call(
sector=sectors.FOOD_AND_DRINK
)
assert mock_clean_captcha.call_count == 1


@pytest.mark.parametrize('url,country', (
Expand All @@ -336,9 +337,10 @@ def test_submit_export_opportunity_food(
@patch.object(views.helpers, 'get_showcase_companies',
return_value=showcase_companies)
@patch.object(views.api_client.exportopportunity, 'create_opportunity_legal')
@patch('captcha.fields.ReCaptchaField.clean')
def test_submit_export_opportunity_legal(
mock_create_opportunity, mock_get_showcase_companies, client,
api_response_200, settings, captcha_stub, url, country
mock_clean_captcha, mock_create_opportunity, mock_get_showcase_companies,
client, api_response_200, settings, captcha_stub, url, country
):
settings.FEATURE_EXPORT_OPPORTUNITY_LEAD_GENERATION_ENABLED = True
mock_create_opportunity.return_value = api_response_200
Expand Down Expand Up @@ -390,7 +392,6 @@ def test_submit_export_opportunity_legal(
assert mock_create_opportunity.call_args == call(
form_data={
'company_name': 'Jim corp',
'captcha': None,
'full_name': 'jim example',
'phone_number': '07507605844',
'advice_type_other': 'things',
Expand All @@ -414,3 +415,5 @@ def test_submit_export_opportunity_legal(
assert mock_get_showcase_companies.call_args == call(
campaign_tag=lead_generation.LEGAL_IS_GREAT,
)

assert mock_clean_captcha.call_count == 1
17 changes: 17 additions & 0 deletions exportopportunity/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class BaseOpportunityWizardView(

language_form_class = forms.LanguageLeadGeneartionForm

should_skip_captcha = False

def dispatch(self, *args, **kwargs):
if not settings.FEATURE_EXPORT_OPPORTUNITY_LEAD_GENERATION_ENABLED:
raise Http404()
Expand Down Expand Up @@ -107,6 +109,21 @@ def done(self, *args, **kwargs):
}
)

def render_done(self, *args, **kwargs):
# django-forms runs form.is_valid() for all steps after the final step
# meaning the same captcha code is sent to google multiple times.
# Google rejects the code the second time as it's already seen it and
# thinks the second is a "replay attack" - so prevent formtools from
# validating the captcha twice.
self.should_skip_captcha = True
return super().render_done(*args, **kwargs)

def get_form_kwargs(self, step):
kwargs = super().get_form_kwargs(step=step)
if step == self.CONTACT and self.should_skip_captcha:
kwargs['skip_captcha_errors'] = True
return kwargs


class FoodIsGreatOpportunityWizardView(BaseOpportunityWizardView):
form_list = (
Expand Down