diff --git a/pyproject.toml b/pyproject.toml index 868a78724bb8..b5b94dec1310 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ module = [ "sqlalchemy.*", # https://docs.sqlalchemy.org/en/14/orm/extensions/mypy.html "transaction.*", "venusian.*", + "webob.*", # https://github.com/python/typeshed/pull/9874 "whitenoise.*", "wtforms.*", # https://github.com/wtforms/wtforms/issues/618 "yara.*", diff --git a/tests/unit/accounts/test_forms.py b/tests/unit/accounts/test_forms.py index 850dd3f678b4..6d5d67dbc244 100644 --- a/tests/unit/accounts/test_forms.py +++ b/tests/unit/accounts/test_forms.py @@ -17,6 +17,8 @@ import pytest import wtforms +from webob.multidict import MultiDict + from warehouse import recaptcha from warehouse.accounts import forms from warehouse.accounts.interfaces import ( @@ -36,7 +38,9 @@ def test_creation(self): user_service = pretend.stub() breach_service = pretend.stub() form = forms.LoginForm( - request=request, user_service=user_service, breach_service=breach_service + request=request, + user_service=user_service, + breach_service=breach_service, ) assert form.request is request @@ -84,7 +88,7 @@ def test_validate_password_no_user(self): ) breach_service = pretend.stub() form = forms.LoginForm( - data={"username": "my_username"}, + formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, @@ -110,7 +114,7 @@ def test_validate_password_disabled_for_compromised_pw(self, db_session): ) breach_service = pretend.stub(failure_message="Bad Password!") form = forms.LoginForm( - data={"username": "my_username"}, + formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, @@ -141,7 +145,7 @@ def test_validate_password_ok(self): check_password=pretend.call_recorder(lambda pw, tags: False) ) form = forms.LoginForm( - data={"username": "my_username"}, + formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, @@ -183,7 +187,7 @@ def test_validate_password_notok(self, db_session): ) breach_service = pretend.stub() form = forms.LoginForm( - data={"username": "my_username"}, + formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, @@ -226,7 +230,7 @@ def test_validate_password_too_many_failed(self): ) breach_service = pretend.stub() form = forms.LoginForm( - data={"username": "my_username"}, + formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, @@ -268,7 +272,7 @@ def test_password_breached(self, monkeypatch): ) form = forms.LoginForm( - data={"password": "password"}, + MultiDict({"password": "password"}), request=request, user_service=user_service, breach_service=breach_service, @@ -302,7 +306,7 @@ def test_validate_password_ok_ip_banned(self): check_password=pretend.call_recorder(lambda pw, tags: False) ) form = forms.LoginForm( - data={"username": "my_username"}, + formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, @@ -335,7 +339,7 @@ def test_validate_password_notok_ip_banned(self, db_session): ) breach_service = pretend.stub() form = forms.LoginForm( - data={"username": "my_username"}, + formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, @@ -357,7 +361,7 @@ def test_create(self): breach_service = pretend.stub() form = forms.RegistrationForm( - data={}, + formdata=MultiDict(), user_service=user_service, recaptcha_service=recaptcha_service, breach_service=breach_service, @@ -368,7 +372,7 @@ def test_create(self): def test_password_confirm_required_error(self): form = forms.RegistrationForm( - data={"password_confirm": ""}, + formdata=MultiDict({"password_confirm": ""}), user_service=pretend.stub( find_userid_by_email=pretend.call_recorder(lambda _: pretend.stub()) ), @@ -384,7 +388,9 @@ def test_passwords_mismatch_error(self, pyramid_config): find_userid_by_email=pretend.call_recorder(lambda _: pretend.stub()) ) form = forms.RegistrationForm( - data={"new_password": "password", "password_confirm": "mismatch"}, + formdata=MultiDict( + {"new_password": "password", "password_confirm": "mismatch"} + ), user_service=user_service, recaptcha_service=pretend.stub(enabled=True), breach_service=pretend.stub(check_password=lambda pw, tags=None: False), @@ -401,10 +407,12 @@ def test_passwords_match_success(self): find_userid_by_email=pretend.call_recorder(lambda _: pretend.stub()) ) form = forms.RegistrationForm( - data={ - "new_password": "MyStr0ng!shPassword", - "password_confirm": "MyStr0ng!shPassword", - }, + formdata=MultiDict( + { + "new_password": "MyStr0ng!shPassword", + "password_confirm": "MyStr0ng!shPassword", + } + ), user_service=user_service, recaptcha_service=pretend.stub(enabled=True), breach_service=pretend.stub(check_password=lambda pw, tags=None: False), @@ -416,7 +424,7 @@ def test_passwords_match_success(self): def test_email_required_error(self): form = forms.RegistrationForm( - data={"email": ""}, + formdata=MultiDict({"email": ""}), user_service=pretend.stub( find_userid_by_email=pretend.call_recorder(lambda _: pretend.stub()) ), @@ -430,7 +438,7 @@ def test_email_required_error(self): @pytest.mark.parametrize("email", ["bad", "foo]bar@example.com", ""]) def test_invalid_email_error(self, pyramid_config, email): form = forms.RegistrationForm( - data={"email": email}, + formdata=MultiDict({"email": email}), user_service=pretend.stub( find_userid_by_email=pretend.call_recorder(lambda _: None) ), @@ -445,7 +453,7 @@ def test_invalid_email_error(self, pyramid_config, email): def test_exotic_email_success(self): form = forms.RegistrationForm( - data={"email": "foo@n--tree.net"}, + formdata=MultiDict({"email": "foo@n--tree.net"}), user_service=pretend.stub( find_userid_by_email=pretend.call_recorder(lambda _: None) ), @@ -458,7 +466,7 @@ def test_exotic_email_success(self): def test_email_exists_error(self, pyramid_config): form = forms.RegistrationForm( - data={"email": "foo@bar.com"}, + formdata=MultiDict({"email": "foo@bar.com"}), user_service=pretend.stub( find_userid_by_email=pretend.call_recorder(lambda _: pretend.stub()) ), @@ -475,7 +483,7 @@ def test_email_exists_error(self, pyramid_config): def test_prohibited_email_error(self, pyramid_config): form = forms.RegistrationForm( - data={"email": "foo@bearsarefuzzy.com"}, + formdata=MultiDict({"email": "foo@bearsarefuzzy.com"}), user_service=pretend.stub( find_userid_by_email=pretend.call_recorder(lambda _: None) ), @@ -492,7 +500,7 @@ def test_prohibited_email_error(self, pyramid_config): def test_recaptcha_disabled(self): form = forms.RegistrationForm( - data={"g_recpatcha_response": ""}, + formdata=MultiDict({"g_recpatcha_response": ""}), user_service=pretend.stub(), recaptcha_service=pretend.stub( enabled=False, @@ -507,7 +515,7 @@ def test_recaptcha_disabled(self): def test_recaptcha_required_error(self): form = forms.RegistrationForm( - data={"g_recaptcha_response": ""}, + formdata=MultiDict({"g_recaptcha_response": ""}), user_service=pretend.stub(), recaptcha_service=pretend.stub( enabled=True, @@ -520,7 +528,7 @@ def test_recaptcha_required_error(self): def test_recaptcha_error(self): form = forms.RegistrationForm( - data={"g_recaptcha_response": "asd"}, + formdata=MultiDict({"g_recaptcha_response": "asd"}), user_service=pretend.stub(), recaptcha_service=pretend.stub( verify_response=pretend.raiser(recaptcha.RecaptchaError), @@ -533,7 +541,7 @@ def test_recaptcha_error(self): def test_username_exists(self, pyramid_config): form = forms.RegistrationForm( - data={"username": "foo"}, + formdata=MultiDict({"username": "foo"}), user_service=pretend.stub( find_userid=pretend.call_recorder(lambda name: 1), username_is_prohibited=lambda a: False, @@ -553,7 +561,7 @@ def test_username_exists(self, pyramid_config): def test_username_prohibted(self, pyramid_config): form = forms.RegistrationForm( - data={"username": "foo"}, + formdata=MultiDict({"username": "foo"}), user_service=pretend.stub( username_is_prohibited=lambda a: True, ), @@ -573,7 +581,7 @@ def test_username_prohibted(self, pyramid_config): @pytest.mark.parametrize("username", ["_foo", "bar_", "foo^bar"]) def test_username_is_valid(self, username, pyramid_config): form = forms.RegistrationForm( - data={"username": username}, + formdata=MultiDict({"username": username}), user_service=pretend.stub( find_userid=pretend.call_recorder(lambda _: None), username_is_prohibited=lambda a: False, @@ -601,7 +609,7 @@ def test_password_strength(self): ) for pwd, valid in cases: form = forms.RegistrationForm( - data={"new_password": pwd, "password_confirm": pwd}, + formdata=MultiDict({"new_password": pwd, "password_confirm": pwd}), user_service=pretend.stub(), recaptcha_service=pretend.stub( enabled=False, @@ -614,7 +622,7 @@ def test_password_strength(self): def test_password_breached(self): form = forms.RegistrationForm( - data={"new_password": "password"}, + formdata=MultiDict({"new_password": "password"}), user_service=pretend.stub( find_userid=pretend.call_recorder(lambda _: None) ), @@ -638,7 +646,7 @@ def test_password_breached(self): def test_name_too_long(self, pyramid_config): form = forms.RegistrationForm( - data={"full_name": "hello " * 50}, + formdata=MultiDict({"full_name": "hello " * 50}), user_service=pretend.stub( find_userid=pretend.call_recorder(lambda _: None) ), @@ -703,7 +711,7 @@ def test_validate_username_or_email_with_none(self): class TestResetPasswordForm: def test_password_confirm_required_error(self): form = forms.ResetPasswordForm( - data={"password_confirm": ""}, + formdata=MultiDict({"password_confirm": ""}), breach_service=pretend.stub(check_password=lambda pw, tags=None: False), ) @@ -712,13 +720,15 @@ def test_password_confirm_required_error(self): def test_passwords_mismatch_error(self, pyramid_config): form = forms.ResetPasswordForm( - data={ - "new_password": "password", - "password_confirm": "mismatch", - "username": "username", - "full_name": "full_name", - "email": "email", - }, + formdata=MultiDict( + { + "new_password": "password", + "password_confirm": "mismatch", + "username": "username", + "full_name": "full_name", + "email": "email", + } + ), breach_service=pretend.stub(check_password=lambda pw, tags=None: False), ) @@ -734,13 +744,15 @@ def test_passwords_mismatch_error(self, pyramid_config): ) def test_password_strength(self, password, expected): form = forms.ResetPasswordForm( - data={ - "new_password": password, - "password_confirm": password, - "username": "username", - "full_name": "full_name", - "email": "email", - }, + formdata=MultiDict( + { + "new_password": password, + "password_confirm": password, + "username": "username", + "full_name": "full_name", + "email": "email", + } + ), breach_service=pretend.stub(check_password=lambda pw, tags=None: False), ) @@ -748,13 +760,15 @@ def test_password_strength(self, password, expected): def test_passwords_match_success(self): form = forms.ResetPasswordForm( - data={ - "new_password": "MyStr0ng!shPassword", - "password_confirm": "MyStr0ng!shPassword", - "username": "username", - "full_name": "full_name", - "email": "email", - }, + formdata=MultiDict( + { + "new_password": "MyStr0ng!shPassword", + "password_confirm": "MyStr0ng!shPassword", + "username": "username", + "full_name": "full_name", + "email": "email", + } + ), breach_service=pretend.stub(check_password=lambda pw, tags=None: False), ) @@ -762,13 +776,15 @@ def test_passwords_match_success(self): def test_password_breached(self): form = forms.ResetPasswordForm( - data={ - "new_password": "MyStr0ng!shPassword", - "password_confirm": "MyStr0ng!shPassword", - "username": "username", - "full_name": "full_name", - "email": "email", - }, + formdata=MultiDict( + { + "new_password": "MyStr0ng!shPassword", + "password_confirm": "MyStr0ng!shPassword", + "username": "username", + "full_name": "full_name", + "email": "email", + } + ), user_service=pretend.stub( find_userid=pretend.call_recorder(lambda _: None) ), @@ -803,8 +819,8 @@ def test_totp_secret_exists(self, pyramid_config): request = pretend.stub(remote_addr="1.2.3.4") form = forms.TOTPAuthenticationForm( + formdata=MultiDict({"totp_value": ""}), request=request, - data={"totp_value": ""}, user_id=pretend.stub(), user_service=pretend.stub(get_user=get_user), ) @@ -813,7 +829,7 @@ def test_totp_secret_exists(self, pyramid_config): form = forms.TOTPAuthenticationForm( request=request, - data={"totp_value": "not_a_real_value"}, + formdata=MultiDict({"totp_value": "not_a_real_value"}), user_id=pretend.stub(), user_service=pretend.stub( check_totp_value=lambda *a: True, get_user=get_user @@ -824,7 +840,7 @@ def test_totp_secret_exists(self, pyramid_config): form = forms.TOTPAuthenticationForm( request=request, - data={"totp_value": "1 2 3 4 5 6 7"}, + formdata=MultiDict({"totp_value": "1 2 3 4 5 6 7"}), user_id=pretend.stub(), user_service=pretend.stub( check_totp_value=lambda *a: True, get_user=get_user @@ -838,8 +854,8 @@ def test_totp_secret_exists(self, pyramid_config): get_user=get_user, ) form = forms.TOTPAuthenticationForm( + formdata=MultiDict({"totp_value": "123456"}), request=request, - data={"totp_value": "123456"}, user_id=1, user_service=user_service, ) @@ -855,8 +871,8 @@ def test_totp_secret_exists(self, pyramid_config): ] form = forms.TOTPAuthenticationForm( + formdata=MultiDict({"totp_value": "123456"}), request=request, - data={"totp_value": "123456"}, user_id=pretend.stub(), user_service=pretend.stub( check_totp_value=lambda *a: True, get_user=get_user @@ -866,7 +882,7 @@ def test_totp_secret_exists(self, pyramid_config): form = forms.TOTPAuthenticationForm( request=request, - data={"totp_value": " 1 2 3 4 5 6 "}, + formdata=MultiDict({"totp_value": " 1 2 3 4 5 6 "}), user_id=pretend.stub(), user_service=pretend.stub( check_totp_value=lambda *a: True, get_user=get_user @@ -876,7 +892,7 @@ def test_totp_secret_exists(self, pyramid_config): form = forms.TOTPAuthenticationForm( request=request, - data={"totp_value": "123 456"}, + formdata=MultiDict({"totp_value": "123 456"}), user_id=pretend.stub(), user_service=pretend.stub( check_totp_value=lambda *a: True, get_user=get_user @@ -1006,8 +1022,8 @@ def test_creation(self): def test_missing_value(self): request = pretend.stub() form = forms.RecoveryCodeAuthenticationForm( + formdata=MultiDict({"recovery_code_value": ""}), request=request, - data={"recovery_code_value": ""}, user_id=pretend.stub(), user_service=pretend.stub(), ) @@ -1038,8 +1054,8 @@ def test_invalid_recovery_code( get_user=pretend.call_recorder(lambda userid: user), ) form = forms.RecoveryCodeAuthenticationForm( + formdata=MultiDict({"recovery_code_value": "deadbeef00001111"}), request=request, - data={"recovery_code_value": "deadbeef00001111"}, user_id=1, user_service=user_service, ) @@ -1059,8 +1075,8 @@ def test_valid_recovery_code(self, monkeypatch): request = pretend.stub(remote_addr="1.2.3.4") user = pretend.stub(id=pretend.stub(), username="foobar") form = forms.RecoveryCodeAuthenticationForm( + formdata=MultiDict({"recovery_code_value": "deadbeef00001111"}), request=request, - data={"recovery_code_value": "deadbeef00001111"}, user_id=pretend.stub(), user_service=pretend.stub( check_recovery_code=pretend.call_recorder(lambda *a, **kw: True), @@ -1095,7 +1111,7 @@ def test_recovery_code_string_validation( user = pretend.stub(id=pretend.stub(), username="foobar") form = forms.RecoveryCodeAuthenticationForm( request=request, - data={"recovery_code_value": input_string}, + formdata=MultiDict({"recovery_code_value": input_string}), user_id=pretend.stub(), user_service=pretend.stub( check_recovery_code=pretend.call_recorder(lambda *a, **kw: True), diff --git a/tests/unit/admin/views/test_banners.py b/tests/unit/admin/views/test_banners.py index 29e81cbe9335..18586e6fdf29 100644 --- a/tests/unit/admin/views/test_banners.py +++ b/tests/unit/admin/views/test_banners.py @@ -218,13 +218,13 @@ def test_preview_banner(self, db_request): class TestBannerForm: def test_required_fields(self, banner_data): - form = views.BannerForm(data={}) + form = views.BannerForm(formdata=MultiDict()) assert form.validate() is False assert set(form.errors) == set(banner_data) def test_valid_data(self, banner_data): - form = views.BannerForm(data=banner_data) + form = views.BannerForm(formdata=MultiDict(banner_data)) assert form.validate() is True data = form.data defaults = { @@ -232,4 +232,7 @@ def test_valid_data(self, banner_data): "active": False, "link_label": Banner.DEFAULT_BTN_LABEL, } + + # Mash the `end` into a date object to match the form's coerced result. + banner_data["end"] = datetime.date.fromisoformat(banner_data["end"]) assert data == {**banner_data, **defaults} diff --git a/tests/unit/admin/views/test_sponsors.py b/tests/unit/admin/views/test_sponsors.py index 4a9fce60b45a..9e1baea092f2 100644 --- a/tests/unit/admin/views/test_sponsors.py +++ b/tests/unit/admin/views/test_sponsors.py @@ -260,29 +260,29 @@ def test_required_fields(self): assert field in form.errors def test_valid_data(self): - form = views.SponsorForm(data=self.data) + form = views.SponsorForm(formdata=MultiDict(self.data)) assert form.validate() is True def test_white_logo_is_required_for_footer_display(self): self.data["footer"] = True # don't validate without logo - form = views.SponsorForm(data=self.data) + form = views.SponsorForm(formdata=MultiDict(self.data)) assert form.validate() is False assert "white_logo" in form.errors self.data["white_logo_url"] = "http://domain.com/white-logo.jpg" - form = views.SponsorForm(data=self.data) + form = views.SponsorForm(formdata=MultiDict(self.data)) assert form.validate() is True def test_white_logo_is_required_for_infra_display(self): self.data["infra_sponsor"] = True # don't validate without logo - form = views.SponsorForm(data=self.data) + form = views.SponsorForm(formdata=MultiDict(self.data)) assert form.validate() is False assert "white_logo" in form.errors self.data["white_logo_url"] = "http://domain.com/white-logo.jpg" - form = views.SponsorForm(data=self.data) + form = views.SponsorForm(formdata=MultiDict(self.data)) assert form.validate() is True diff --git a/tests/unit/manage/test_forms.py b/tests/unit/manage/test_forms.py index d13e071a0ad0..c29a0c6601e4 100644 --- a/tests/unit/manage/test_forms.py +++ b/tests/unit/manage/test_forms.py @@ -57,7 +57,7 @@ def test_validate_username_with_user(self): [ ("", "Select role"), ("invalid", "Not a valid choice."), - (None, "Not a valid choice."), + (None, "Select role"), ], ) def test_validate_role_name_fails(self, value, expected): @@ -81,7 +81,7 @@ def test_creation(self): def test_email_exists_error(self, pyramid_config): user_id = pretend.stub() form = forms.AddEmailForm( - data={"email": "foo@bar.com"}, + formdata=MultiDict({"email": "foo@bar.com"}), user_id=user_id, user_service=pretend.stub(find_userid_by_email=lambda _: user_id), ) @@ -95,7 +95,7 @@ def test_email_exists_error(self, pyramid_config): def test_email_exists_other_account_error(self, pyramid_config): form = forms.AddEmailForm( - data={"email": "foo@bar.com"}, + formdata=MultiDict({"email": "foo@bar.com"}), user_id=pretend.stub(), user_service=pretend.stub(find_userid_by_email=lambda _: pretend.stub()), ) @@ -109,7 +109,7 @@ def test_email_exists_other_account_error(self, pyramid_config): def test_prohibited_email_error(self, pyramid_config): form = forms.AddEmailForm( - data={"email": "foo@bearsarefuzzy.com"}, + formdata=MultiDict({"email": "foo@bearsarefuzzy.com"}), user_service=pretend.stub(find_userid_by_email=lambda _: None), user_id=pretend.stub(), ) @@ -148,7 +148,7 @@ def test_verify_totp_invalid(self, monkeypatch): monkeypatch.setattr(otp, "verify_totp", verify_totp) form = forms.ProvisionTOTPForm( - data={"totp_value": "123456"}, totp_secret=pretend.stub() + formdata=MultiDict({"totp_value": "123456"}), totp_secret=pretend.stub() ) assert not form.validate() assert form.totp_value.errors.pop() == "Invalid TOTP code. Try again?" @@ -158,7 +158,7 @@ def test_verify_totp_valid(self, monkeypatch): monkeypatch.setattr(otp, "verify_totp", verify_totp) form = forms.ProvisionTOTPForm( - data={"totp_value": "123456"}, totp_secret=pretend.stub() + formdata=MultiDict({"totp_value": "123456"}), totp_secret=pretend.stub() ) assert form.validate() @@ -182,10 +182,9 @@ def test_validate_confirm_password(self): ), ) form = forms.DeleteTOTPForm( - username="username", + formdata=MultiDict({"username": "username", "password": "password"}), request=request, user_service=user_service, - password="password", ) assert form.validate() @@ -218,7 +217,7 @@ def test_verify_assertion_invalid_json(self): ) form = forms.ProvisionWebAuthnForm( - data={"credential": "invalid json", "label": "fake label"}, + formdata=MultiDict({"credential": "invalid json", "label": "fake label"}), user_service=user_service, user_id=pretend.stub(), challenge=pretend.stub(), @@ -239,7 +238,7 @@ def test_verify_assertion_invalid(self): get_webauthn_by_label=pretend.call_recorder(lambda *a: None), ) form = forms.ProvisionWebAuthnForm( - data={"credential": "{}", "label": "fake label"}, + formdata=MultiDict({"credential": "{}", "label": "fake label"}), user_service=user_service, user_id=pretend.stub(), challenge=pretend.stub(), @@ -255,7 +254,7 @@ def test_verify_label_missing(self): verify_webauthn_credential=lambda *a, **kw: pretend.stub() ) form = forms.ProvisionWebAuthnForm( - data={"credential": "{}"}, + formdata=MultiDict({"credential": "{}"}), user_service=user_service, user_id=pretend.stub(), challenge=pretend.stub(), @@ -272,7 +271,7 @@ def test_verify_label_already_in_use(self): get_webauthn_by_label=pretend.call_recorder(lambda *a: pretend.stub()), ) form = forms.ProvisionWebAuthnForm( - data={"credential": "{}", "label": "fake label"}, + formdata=MultiDict({"credential": "{}", "label": "fake label"}), user_service=user_service, user_id=pretend.stub(), challenge=pretend.stub(), @@ -290,7 +289,7 @@ def test_creates_validated_credential(self): get_webauthn_by_label=pretend.call_recorder(lambda *a: None), ) form = forms.ProvisionWebAuthnForm( - data={"credential": "{}", "label": "fake label"}, + formdata=MultiDict({"credential": "{}", "label": "fake label"}), user_service=user_service, user_id=pretend.stub(), challenge=pretend.stub(), @@ -323,7 +322,7 @@ def test_validate_label_not_in_use(self): get_webauthn_by_label=pretend.call_recorder(lambda *a: None) ) form = forms.DeleteWebAuthnForm( - data={"label": "fake label"}, + formdata=MultiDict({"label": "fake label"}), user_service=user_service, user_id=pretend.stub(), ) @@ -337,7 +336,7 @@ def test_creates_webauthn_attribute(self): get_webauthn_by_label=pretend.call_recorder(lambda *a: fake_webauthn) ) form = forms.DeleteWebAuthnForm( - data={"label": "fake label"}, + formdata=MultiDict({"label": "fake label"}), user_service=user_service, user_id=pretend.stub(), ) @@ -363,7 +362,7 @@ def test_creation(self): def test_validate_description_missing(self): form = forms.CreateMacaroonForm( - data={"token_scope": "scope:user"}, + formdata=MultiDict({"token_scope": "scope:user"}), user_id=pretend.stub(), macaroon_service=pretend.stub(), project_names=pretend.stub(), @@ -374,7 +373,7 @@ def test_validate_description_missing(self): def test_validate_description_in_use(self): form = forms.CreateMacaroonForm( - data={"description": "dummy", "token_scope": "scope:user"}, + formdata=MultiDict({"description": "dummy", "token_scope": "scope:user"}), user_id=pretend.stub(), macaroon_service=pretend.stub( get_macaroon_by_description=lambda *a: pretend.stub() @@ -387,7 +386,7 @@ def test_validate_description_in_use(self): def test_validate_token_scope_missing(self): form = forms.CreateMacaroonForm( - data={"description": "dummy"}, + formdata=MultiDict({"description": "dummy"}), user_id=pretend.stub(), macaroon_service=pretend.stub(get_macaroon_by_description=lambda *a: None), project_names=pretend.stub(), @@ -398,7 +397,9 @@ def test_validate_token_scope_missing(self): def test_validate_token_scope_unspecified(self): form = forms.CreateMacaroonForm( - data={"description": "dummy", "token_scope": "scope:unspecified"}, + formdata=MultiDict( + {"description": "dummy", "token_scope": "scope:unspecified"} + ), user_id=pretend.stub(), macaroon_service=pretend.stub(get_macaroon_by_description=lambda *a: None), project_names=pretend.stub(), @@ -412,7 +413,7 @@ def test_validate_token_scope_unspecified(self): ) def test_validate_token_scope_invalid_format(self, scope): form = forms.CreateMacaroonForm( - data={"description": "dummy", "token_scope": scope}, + formdata=MultiDict({"description": "dummy", "token_scope": scope}), user_id=pretend.stub(), macaroon_service=pretend.stub(get_macaroon_by_description=lambda *a: None), project_names=pretend.stub(), @@ -423,7 +424,9 @@ def test_validate_token_scope_invalid_format(self, scope): def test_validate_token_scope_invalid_project(self): form = forms.CreateMacaroonForm( - data={"description": "dummy", "token_scope": "scope:project:foo"}, + formdata=MultiDict( + {"description": "dummy", "token_scope": "scope:project:foo"} + ), user_id=pretend.stub(), macaroon_service=pretend.stub(get_macaroon_by_description=lambda *a: None), project_names=["bar"], @@ -434,7 +437,7 @@ def test_validate_token_scope_invalid_project(self): def test_validate_token_scope_valid_user(self): form = forms.CreateMacaroonForm( - data={"description": "dummy", "token_scope": "scope:user"}, + formdata=MultiDict({"description": "dummy", "token_scope": "scope:user"}), user_id=pretend.stub(), macaroon_service=pretend.stub(get_macaroon_by_description=lambda *a: None), project_names=pretend.stub(), @@ -444,7 +447,9 @@ def test_validate_token_scope_valid_user(self): def test_validate_token_scope_valid_project(self): form = forms.CreateMacaroonForm( - data={"description": "dummy", "token_scope": "scope:project:foo"}, + formdata=MultiDict( + {"description": "dummy", "token_scope": "scope:project:foo"} + ), user_id=pretend.stub(), macaroon_service=pretend.stub(get_macaroon_by_description=lambda *a: None), project_names=["foo"], @@ -478,7 +483,7 @@ def test_validate_macaroon_id_invalid(self): remote_addr="1.2.3.4", banned=pretend.stub(by_ip=lambda ip_address: False) ) form = forms.DeleteMacaroonForm( - data={"macaroon_id": pretend.stub(), "password": "password"}, + formdata=MultiDict({"macaroon_id": pretend.stub(), "password": "password"}), request=request, macaroon_service=macaroon_service, user_service=user_service, @@ -499,10 +504,15 @@ def test_validate_macaroon_id(self): remote_addr="1.2.3.4", banned=pretend.stub(by_ip=lambda ip_address: False) ) form = forms.DeleteMacaroonForm( - data={"macaroon_id": pretend.stub(), "password": "password"}, + formdata=MultiDict( + { + "macaroon_id": pretend.stub(), + "username": "username", + "password": "password", + } + ), request=request, macaroon_service=macaroon_service, - username="username", user_service=user_service, ) diff --git a/warehouse/accounts/forms.py b/warehouse/accounts/forms.py index abbe4c8a0761..b81272c53d05 100644 --- a/warehouse/accounts/forms.py +++ b/warehouse/accounts/forms.py @@ -48,7 +48,7 @@ class UsernameMixin: - username = wtforms.StringField(validators=[wtforms.validators.DataRequired()]) + username = wtforms.StringField(validators=[wtforms.validators.InputRequired()]) def validate_username(self, field): userid = self.user_service.find_userid(field.data) @@ -62,7 +62,7 @@ def validate_username(self, field): class TOTPValueMixin: totp_value = wtforms.StringField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Regexp( rf"^ *([0-9] *){{{TOTP_LENGTH}}}$", message=_( @@ -75,13 +75,13 @@ class TOTPValueMixin: class WebAuthnCredentialMixin: - credential = wtforms.StringField(wtforms.validators.DataRequired()) + credential = wtforms.StringField(wtforms.validators.InputRequired()) class RecoveryCodeValueMixin: recovery_code_value = wtforms.StringField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Regexp( rf"^ *([0-9a-f] *){{{2*RECOVERY_CODE_BYTES}}}$", message=_( @@ -96,7 +96,7 @@ class RecoveryCodeValueMixin: class NewUsernameMixin: username = wtforms.StringField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Length( max=50, message=_("Choose a username with 50 characters or less.") ), @@ -131,7 +131,7 @@ def validate_username(self, field): class PasswordMixin: password = wtforms.PasswordField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Length( max=MAX_PASSWORD_SIZE, message=_("Password too long."), @@ -180,7 +180,7 @@ def validate_password(self, field): class NewPasswordMixin: new_password = wtforms.PasswordField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Length( max=MAX_PASSWORD_SIZE, message=_("Password too long."), @@ -193,7 +193,7 @@ class NewPasswordMixin: password_confirm = wtforms.PasswordField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Length( max=MAX_PASSWORD_SIZE, message=_("Password too long."), @@ -208,8 +208,8 @@ class NewPasswordMixin: # PasswordStrengthValidator of the new_password field, to ensure that the # newly set password doesn't contain any of them full_name = wtforms.StringField() # May be empty - username = wtforms.StringField(validators=[wtforms.validators.DataRequired()]) - email = wtforms.StringField(validators=[wtforms.validators.DataRequired()]) + username = wtforms.StringField(validators=[wtforms.validators.InputRequired()]) + email = wtforms.StringField(validators=[wtforms.validators.InputRequired()]) def __init__(self, *args, breach_service, **kwargs): super().__init__(*args, **kwargs) @@ -227,7 +227,7 @@ def validate_new_password(self, field): class NewEmailMixin: email = wtforms.fields.EmailField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Regexp( r".+@.+\..+", message=_("The email address isn't valid. Try again.") ), @@ -423,13 +423,13 @@ class ReAuthenticateForm(PasswordMixin, forms.Form): __params__ = ["username", "password", "next_route", "next_route_matchdict"] username = wtforms.fields.HiddenField( - validators=[wtforms.validators.DataRequired()] + validators=[wtforms.validators.InputRequired()] ) next_route = wtforms.fields.HiddenField( - validators=[wtforms.validators.DataRequired()] + validators=[wtforms.validators.InputRequired()] ) next_route_matchdict = wtforms.fields.HiddenField( - validators=[wtforms.validators.DataRequired()] + validators=[wtforms.validators.InputRequired()] ) def __init__(self, *args, user_service, **kwargs): @@ -472,7 +472,7 @@ def validate_recovery_code_value(self, field): class RequestPasswordResetForm(forms.Form): username_or_email = wtforms.StringField( - validators=[wtforms.validators.DataRequired()] + validators=[wtforms.validators.InputRequired()] ) def __init__(self, *args, user_service, **kwargs): diff --git a/warehouse/accounts/views.py b/warehouse/accounts/views.py index 2f7db82b372f..d3301d1f7466 100644 --- a/warehouse/accounts/views.py +++ b/warehouse/accounts/views.py @@ -29,6 +29,7 @@ from pyramid.view import view_config, view_defaults from sqlalchemy.exc import NoResultFound from webauthn.helpers import bytes_to_base64url +from webob.multidict import MultiDict from warehouse.accounts import REDIRECT_FIELD_NAME from warehouse.accounts.forms import ( @@ -559,10 +560,12 @@ def register(request, _form_class=RegistrationForm): # the form contains an auto-generated field from recaptcha with # hyphens in it. make it play nice with wtforms. - post_body = {key.replace("-", "_"): value for key, value in request.POST.items()} + post_body = MultiDict( + {key.replace("-", "_"): value for key, value in request.POST.items()} + ) form = _form_class( - data=post_body, + formdata=post_body, user_service=user_service, recaptcha_service=recaptcha_service, breach_service=breach_service, diff --git a/warehouse/admin/views/banners.py b/warehouse/admin/views/banners.py index f90aa0cec5d7..e7df2e57d29e 100644 --- a/warehouse/admin/views/banners.py +++ b/warehouse/admin/views/banners.py @@ -148,18 +148,18 @@ class BannerForm(Form): name = wtforms.fields.StringField( validators=[ wtforms.validators.Length(max=100), - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), ], ) text = wtforms.fields.StringField( validators=[ wtforms.validators.Length(max=280), - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), ], ) link_url = wtforms.fields.StringField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), URIValidator(), ] ) @@ -179,4 +179,4 @@ class BannerForm(Form): active = wtforms.fields.BooleanField( validators=[wtforms.validators.Optional()], default=False ) - end = wtforms.fields.DateField(validators=[wtforms.validators.DataRequired()]) + end = wtforms.fields.DateField(validators=[wtforms.validators.InputRequired()]) diff --git a/warehouse/admin/views/sponsors.py b/warehouse/admin/views/sponsors.py index c9da0ce7cf07..b2d3451c166d 100644 --- a/warehouse/admin/views/sponsors.py +++ b/warehouse/admin/views/sponsors.py @@ -30,7 +30,7 @@ class SponsorForm(Form): name = wtforms.fields.StringField( validators=[ wtforms.validators.Length(max=100), - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), ], ) service = wtforms.fields.StringField( @@ -39,7 +39,7 @@ class SponsorForm(Form): link_url = wtforms.fields.StringField( validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), URIValidator(), ] ) diff --git a/warehouse/admin/views/users.py b/warehouse/admin/views/users.py index 5c06843a1616..163295c00e24 100644 --- a/warehouse/admin/views/users.py +++ b/warehouse/admin/views/users.py @@ -74,7 +74,7 @@ def user_list(request): class EmailForm(forms.Form): - email = wtforms.fields.EmailField(validators=[wtforms.validators.DataRequired()]) + email = wtforms.fields.EmailField(validators=[wtforms.validators.InputRequired()]) primary = wtforms.fields.BooleanField() verified = wtforms.fields.BooleanField() public = wtforms.fields.BooleanField() diff --git a/warehouse/forklift/legacy.py b/warehouse/forklift/legacy.py index c16c1d7d922f..729d8cfb680a 100644 --- a/warehouse/forklift/legacy.py +++ b/warehouse/forklift/legacy.py @@ -421,7 +421,7 @@ class MetadataForm(forms.Form): metadata_version = wtforms.StringField( description="Metadata-Version", validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.AnyOf( # Note: This isn't really Metadata 2.0, however bdist_wheel # claims it is producing a Metadata 2.0 metadata when in @@ -436,7 +436,7 @@ class MetadataForm(forms.Form): name = wtforms.StringField( description="Name", validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Regexp( PROJECT_NAME_RE, re.IGNORECASE, @@ -450,7 +450,7 @@ class MetadataForm(forms.Form): version = wtforms.StringField( description="Version", validators=[ - wtforms.validators.DataRequired(), + wtforms.validators.InputRequired(), wtforms.validators.Regexp( r"^(?!\s).*(?