From 8b55576c025382759bce08000dd36f4bf8b068cf Mon Sep 17 00:00:00 2001 From: Ee Durbin Date: Tue, 2 Apr 2024 10:39:08 -0400 Subject: [PATCH] Revert "feat: add captcha to login page (#15701)" (#15709) This reverts commit c577ab444de0201ecee0ea51e4a9b1ad2fe7488a. --- tests/conftest.py | 13 -- tests/unit/accounts/test_forms.py | 53 +------- tests/unit/accounts/test_views.py | 40 +----- warehouse/accounts/forms.py | 21 +-- warehouse/accounts/views.py | 3 - warehouse/locale/messages.pot | 164 ++++++++++++------------ warehouse/templates/accounts/login.html | 30 ++--- 7 files changed, 102 insertions(+), 222 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index d7f7243d054b..43ba6c0e13ca 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -43,7 +43,6 @@ from warehouse.accounts import services as account_services from warehouse.accounts.interfaces import ITokenService, IUserService from warehouse.admin.flags import AdminFlag, AdminFlagValue -from warehouse.csp import CSPPolicy from warehouse.email import services as email_services from warehouse.email.interfaces import IEmailSender from warehouse.macaroons import services as macaroon_services @@ -155,16 +154,6 @@ def __init__(self): def register_service(self, service_obj, iface=None, context=None, name=""): self._services[iface][context][name] = service_obj - def register_service_factory( - self, config_or_request, iface=None, context=None, name="" - ): - # TODO: This is a bit of a hack, but it's good enough for now. - # It doesn't implement the depth of logic that Pyramid's service - # factories do, but it's good enough for our tests. - # It's functionally equivalent to `register_service()`, but it - # Makes it clear that we're using a factory. - self._services[iface][context][name] = config_or_request - def find_service(self, iface=None, context=None, name=""): return self._services[iface][context][name] @@ -202,8 +191,6 @@ def pyramid_services( activestate_oidc_service, IOIDCPublisherService, None, name="activestate" ) services.register_service(macaroon_service, IMacaroonService, None, name="") - # CSP is a special case, as it's a service that's not registered globally. - services.register_service_factory(CSPPolicy({}), name="csp") return services diff --git a/tests/unit/accounts/test_forms.py b/tests/unit/accounts/test_forms.py index 39490ecc7f4f..7cecb64ebb07 100644 --- a/tests/unit/accounts/test_forms.py +++ b/tests/unit/accounts/test_forms.py @@ -50,19 +50,11 @@ def test_validate(self): breach_service = pretend.stub( check_password=pretend.call_recorder(lambda pw, tags: False) ) - captcha_service = pretend.stub(enabled=True, verify_response=lambda _: None) form = forms.LoginForm( - MultiDict( - { - "username": "user", - "password": "password", - "g_recaptcha_response": "success", - } - ), + MultiDict({"username": "user", "password": "password"}), request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, ) assert form.request is request @@ -76,12 +68,8 @@ def test_validate_username_with_no_user(self): find_userid=pretend.call_recorder(lambda userid: None) ) breach_service = pretend.stub() - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( - request=request, - user_service=user_service, - breach_service=breach_service, - captcha_service=captcha_service, + request=request, user_service=user_service, breach_service=breach_service ) field = pretend.stub(data="my_username") @@ -104,12 +92,8 @@ def test_validate_username_with_user(self, input_username, expected_username): request = pretend.stub() user_service = pretend.stub(find_userid=pretend.call_recorder(lambda userid: 1)) breach_service = pretend.stub() - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( - request=request, - user_service=user_service, - breach_service=breach_service, - captcha_service=captcha_service, + request=request, user_service=user_service, breach_service=breach_service ) field = pretend.stub(data=input_username) form.validate_username(field) @@ -127,13 +111,11 @@ def test_validate_password_no_user(self): find_userid=pretend.call_recorder(lambda userid: None) ) breach_service = pretend.stub() - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, ) field = pretend.stub(data="password") @@ -158,13 +140,11 @@ def test_validate_password_disabled_for_compromised_pw(self, db_session): ), ) breach_service = pretend.stub(failure_message="Bad Password!") - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, ) field = pretend.stub(data="pw") @@ -194,13 +174,11 @@ def test_validate_password_ok(self): breach_service = pretend.stub( check_password=pretend.call_recorder(lambda pw, tags: False) ) - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, check_password_metrics_tags=["bar"], ) field = pretend.stub(data="pw") @@ -238,13 +216,11 @@ def test_validate_password_notok(self, db_session): is_disabled=pretend.call_recorder(lambda userid: (False, None)), ) breach_service = pretend.stub() - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, ) field = pretend.stub(data="pw") @@ -281,13 +257,11 @@ def test_validate_password_too_many_failed(self): is_disabled=pretend.call_recorder(lambda userid: (False, None)), ) breach_service = pretend.stub() - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, ) field = pretend.stub(data="pw") @@ -323,14 +297,12 @@ def test_password_breached(self, monkeypatch): breach_service = pretend.stub( check_password=lambda pw, tags=None: True, failure_message="Bad Password!" ) - captcha_service = pretend.stub(enabled=False, verify_response=lambda _: None) form = forms.LoginForm( MultiDict({"password": "password"}), request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, ) assert not form.validate() assert form.password.errors.pop() == "Bad Password!" @@ -360,14 +332,12 @@ def test_validate_password_ok_ip_banned(self): breach_service = pretend.stub( check_password=pretend.call_recorder(lambda pw, tags: False) ) - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, check_password_metrics_tags=["bar"], - captcha_service=captcha_service, ) field = pretend.stub(data="pw") @@ -395,13 +365,11 @@ def test_validate_password_notok_ip_banned(self, db_session): record_event=pretend.call_recorder(lambda *a, **kw: None), ) breach_service = pretend.stub() - captcha_service = pretend.stub(enabled=False) form = forms.LoginForm( formdata=MultiDict({"username": "my_username"}), request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, ) field = pretend.stub(data="pw") @@ -412,21 +380,6 @@ def test_validate_password_notok_ip_banned(self, db_session): assert user_service.is_disabled.calls == [] assert user_service.check_password.calls == [] - @pytest.mark.parametrize("response_data", ["asd", None]) - def test_recaptcha_error(self, response_data): - form = forms.LoginForm( - request=pretend.stub(), - formdata=MultiDict({"g_recaptcha_response": response_data}), - user_service=pretend.stub(), - captcha_service=pretend.stub( - verify_response=pretend.raiser(recaptcha.RecaptchaError), - enabled=True, - ), - breach_service=pretend.stub(check_password=lambda pw, tags=None: False), - ) - assert not form.validate() - assert form.g_recaptcha_response.errors.pop() == "Recaptcha error." - class TestRegistrationForm: def test_validate(self): diff --git a/tests/unit/accounts/test_views.py b/tests/unit/accounts/test_views.py index e1aad8b51419..bc2a80abadd3 100644 --- a/tests/unit/accounts/test_views.py +++ b/tests/unit/accounts/test_views.py @@ -215,15 +215,11 @@ class TestLogin: def test_get_returns_form(self, pyramid_request, pyramid_services, next_url): user_service = pretend.stub() breach_service = pretend.stub() - captcha_service = pretend.stub(csp_policy={}) pyramid_services.register_service(user_service, IUserService, None) pyramid_services.register_service( breach_service, IPasswordBreachedService, None ) - pyramid_services.register_service( - captcha_service, ICaptchaService, name="captcha" - ) form_obj = pretend.stub() form_class = pretend.call_recorder(lambda d, **kw: form_obj) @@ -243,7 +239,6 @@ def test_get_returns_form(self, pyramid_request, pyramid_services, next_url): request=pyramid_request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, check_password_metrics_tags=["method:auth", "auth_method:login_form"], ) ] @@ -254,15 +249,11 @@ def test_post_invalid_returns_form( ): user_service = pretend.stub() breach_service = pretend.stub() - captcha_service = pretend.stub(csp_policy={}) pyramid_services.register_service(user_service, IUserService, None) pyramid_services.register_service( breach_service, IPasswordBreachedService, None ) - pyramid_services.register_service( - captcha_service, ICaptchaService, name="captcha" - ) pyramid_request.method = "POST" if next_url is not None: @@ -283,7 +274,6 @@ def test_post_invalid_returns_form( request=pyramid_request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, check_password_metrics_tags=["method:auth", "auth_method:login_form"], ) ] @@ -310,15 +300,11 @@ def test_post_validate_redirects( get_password_timestamp=lambda userid: 0, ) breach_service = pretend.stub(check_password=lambda password, tags=None: False) - captcha_service = pretend.stub(csp_policy={}) pyramid_services.register_service(user_service, IUserService, None) pyramid_services.register_service( breach_service, IPasswordBreachedService, None ) - pyramid_services.register_service( - captcha_service, ICaptchaService, name="captcha" - ) pyramid_request.method = "POST" pyramid_request.session = pretend.stub( @@ -365,7 +351,6 @@ def test_post_validate_redirects( request=pyramid_request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, check_password_metrics_tags=["method:auth", "auth_method:login_form"], ) ] @@ -411,15 +396,11 @@ def test_post_validate_no_redirects( get_password_timestamp=lambda userid: 0, ) breach_service = pretend.stub(check_password=lambda password, tags=None: False) - captcha_service = pretend.stub(csp_policy={}) pyramid_services.register_service(user_service, IUserService, None) pyramid_services.register_service( breach_service, IPasswordBreachedService, None ) - pyramid_services.register_service( - captcha_service, ICaptchaService, name="captcha" - ) pyramid_request.method = "POST" pyramid_request.POST["next"] = expected_next_url @@ -467,12 +448,7 @@ def test_redirect_authenticated_user(self): @pytest.mark.parametrize("redirect_url", ["test_redirect_url", None]) def test_two_factor_auth( - self, - monkeypatch, - pyramid_request, - pyramid_services, - redirect_url, - token_service, + self, monkeypatch, pyramid_request, redirect_url, token_service ): token_service.dumps = lambda d: "fake_token" @@ -488,16 +464,12 @@ def test_two_factor_auth( ) breach_service = pretend.stub(check_password=lambda pw: False) - captcha_service = pretend.stub(csp_policy={}) - pyramid_services.register_service( - token_service, ITokenService, name="two_factor" - ) - pyramid_services.register_service(user_service, IUserService) - pyramid_services.register_service(breach_service, IPasswordBreachedService) - pyramid_services.register_service( - captcha_service, ICaptchaService, name="captcha" - ) + pyramid_request.find_service = lambda interface, **kwargs: { + ITokenService: token_service, + IUserService: user_service, + IPasswordBreachedService: breach_service, + }[interface] pyramid_request.method = "POST" if redirect_url: diff --git a/warehouse/accounts/forms.py b/warehouse/accounts/forms.py index d36c457fa487..016e37a5f495 100644 --- a/warehouse/accounts/forms.py +++ b/warehouse/accounts/forms.py @@ -19,7 +19,6 @@ import disposable_email_domains import humanize import markupsafe -import sentry_sdk import wtforms import wtforms.fields @@ -367,31 +366,17 @@ def validate_g_recaptcha_response(self, field): raise wtforms.validators.ValidationError("Recaptcha error.") try: self.captcha_service.verify_response(field.data) - except recaptcha.RecaptchaError as exc: - sentry_sdk.capture_exception(exc) + except recaptcha.RecaptchaError: + # TODO: log error # don't want to provide the user with any detail raise wtforms.validators.ValidationError("Recaptcha error.") class LoginForm(PasswordMixin, UsernameMixin, forms.Form): - def __init__(self, *args, user_service, breach_service, captcha_service, **kwargs): + def __init__(self, *args, user_service, breach_service, **kwargs): super().__init__(*args, **kwargs) self.user_service = user_service self.breach_service = breach_service - self.captcha_service = captcha_service - - g_recaptcha_response = wtforms.StringField() - - def validate_g_recaptcha_response(self, field): - # do required data validation here due to enabled flag being required - if self.captcha_service.enabled and not field.data: - raise wtforms.validators.ValidationError("Recaptcha error.") - try: - self.captcha_service.verify_response(field.data) - except recaptcha.RecaptchaError as exc: - sentry_sdk.capture_exception(exc) - # don't want to provide the user with any detail - raise wtforms.validators.ValidationError("Recaptcha error.") def validate_password(self, field): # Before we try to validate anything, first check to see if the IP is banned diff --git a/warehouse/accounts/views.py b/warehouse/accounts/views.py index 827f5b2c1e6d..139976739111 100644 --- a/warehouse/accounts/views.py +++ b/warehouse/accounts/views.py @@ -233,8 +233,6 @@ def login(request, redirect_field_name=REDIRECT_FIELD_NAME, _form_class=LoginFor user_service = request.find_service(IUserService, context=None) breach_service = request.find_service(IPasswordBreachedService, context=None) - captcha_service = request.find_service(ICaptchaService, name="captcha") - request.find_service(name="csp").merge(captcha_service.csp_policy) redirect_to = request.POST.get( redirect_field_name, request.GET.get(redirect_field_name) @@ -245,7 +243,6 @@ def login(request, redirect_field_name=REDIRECT_FIELD_NAME, _form_class=LoginFor request=request, user_service=user_service, breach_service=breach_service, - captcha_service=captcha_service, check_password_metrics_tags=["method:auth", "auth_method:login_form"], ) diff --git a/warehouse/locale/messages.pot b/warehouse/locale/messages.pot index 5797c0807ede..b7d3047794af 100644 --- a/warehouse/locale/messages.pot +++ b/warehouse/locale/messages.pot @@ -14,103 +14,103 @@ msgstr "" msgid "Locale updated" msgstr "" -#: warehouse/accounts/forms.py:52 +#: warehouse/accounts/forms.py:51 msgid "The password is invalid. Try again." msgstr "" -#: warehouse/accounts/forms.py:53 +#: warehouse/accounts/forms.py:52 msgid "" "The username is invalid. Usernames must be composed of letters, numbers, " "dots, hyphens and underscores. And must also start and finish with a " "letter or number. Choose a different username." msgstr "" -#: warehouse/accounts/forms.py:71 +#: warehouse/accounts/forms.py:70 msgid "Null bytes are not allowed." msgstr "" -#: warehouse/accounts/forms.py:94 +#: warehouse/accounts/forms.py:93 msgid "No user found with that username" msgstr "" -#: warehouse/accounts/forms.py:105 +#: warehouse/accounts/forms.py:104 msgid "TOTP code must be ${totp_length} digits." msgstr "" -#: warehouse/accounts/forms.py:125 +#: warehouse/accounts/forms.py:124 msgid "Recovery Codes must be ${recovery_code_length} characters." msgstr "" -#: warehouse/accounts/forms.py:140 +#: warehouse/accounts/forms.py:139 msgid "Choose a username with 50 characters or less." msgstr "" -#: warehouse/accounts/forms.py:157 +#: warehouse/accounts/forms.py:156 msgid "" "This username is already being used by another account. Choose a " "different username." msgstr "" -#: warehouse/accounts/forms.py:171 warehouse/accounts/forms.py:220 -#: warehouse/accounts/forms.py:233 +#: warehouse/accounts/forms.py:170 warehouse/accounts/forms.py:219 +#: warehouse/accounts/forms.py:232 msgid "Password too long." msgstr "" -#: warehouse/accounts/forms.py:207 +#: warehouse/accounts/forms.py:206 msgid "" "There have been too many unsuccessful login attempts. You have been " "locked out for ${time}. Please try again later." msgstr "" -#: warehouse/accounts/forms.py:236 +#: warehouse/accounts/forms.py:235 msgid "Your passwords don't match. Try again." msgstr "" -#: warehouse/accounts/forms.py:270 +#: warehouse/accounts/forms.py:269 msgid "The email address is too long. Try again." msgstr "" -#: warehouse/accounts/forms.py:285 +#: warehouse/accounts/forms.py:284 msgid "The email address isn't valid. Try again." msgstr "" -#: warehouse/accounts/forms.py:298 +#: warehouse/accounts/forms.py:297 msgid "You can't use an email address from this domain. Use a different email." msgstr "" -#: warehouse/accounts/forms.py:309 +#: warehouse/accounts/forms.py:308 msgid "" "This email address is already being used by this account. Use a different" " email." msgstr "" -#: warehouse/accounts/forms.py:316 +#: warehouse/accounts/forms.py:315 msgid "" "This email address is already being used by another account. Use a " "different email." msgstr "" -#: warehouse/accounts/forms.py:349 warehouse/manage/forms.py:139 +#: warehouse/accounts/forms.py:348 warehouse/manage/forms.py:139 msgid "The name is too long. Choose a name with 100 characters or less." msgstr "" -#: warehouse/accounts/forms.py:454 +#: warehouse/accounts/forms.py:439 msgid "Invalid TOTP code." msgstr "" -#: warehouse/accounts/forms.py:471 +#: warehouse/accounts/forms.py:456 msgid "Invalid WebAuthn assertion: Bad payload" msgstr "" -#: warehouse/accounts/forms.py:540 +#: warehouse/accounts/forms.py:525 msgid "Invalid recovery code." msgstr "" -#: warehouse/accounts/forms.py:549 +#: warehouse/accounts/forms.py:534 msgid "Recovery code has been previously used." msgstr "" -#: warehouse/accounts/forms.py:579 +#: warehouse/accounts/forms.py:564 msgid "The username isn't valid. Try again." msgstr "" @@ -133,175 +133,175 @@ msgid "" " ${ip})" msgstr "" -#: warehouse/accounts/views.py:334 warehouse/accounts/views.py:403 -#: warehouse/accounts/views.py:405 warehouse/accounts/views.py:434 -#: warehouse/accounts/views.py:436 warehouse/accounts/views.py:542 +#: warehouse/accounts/views.py:331 warehouse/accounts/views.py:400 +#: warehouse/accounts/views.py:402 warehouse/accounts/views.py:431 +#: warehouse/accounts/views.py:433 warehouse/accounts/views.py:539 msgid "Invalid or expired two factor login." msgstr "" -#: warehouse/accounts/views.py:397 +#: warehouse/accounts/views.py:394 msgid "Already authenticated" msgstr "" -#: warehouse/accounts/views.py:477 +#: warehouse/accounts/views.py:474 msgid "Successful WebAuthn assertion" msgstr "" -#: warehouse/accounts/views.py:573 warehouse/manage/views/__init__.py:865 +#: warehouse/accounts/views.py:570 warehouse/manage/views/__init__.py:865 msgid "Recovery code accepted. The supplied code cannot be used again." msgstr "" -#: warehouse/accounts/views.py:665 +#: warehouse/accounts/views.py:662 msgid "" "New user registration temporarily disabled. See https://pypi.org/help" "#admin-intervention for details." msgstr "" -#: warehouse/accounts/views.py:803 +#: warehouse/accounts/views.py:800 msgid "Expired token: request a new password reset link" msgstr "" -#: warehouse/accounts/views.py:805 +#: warehouse/accounts/views.py:802 msgid "Invalid token: request a new password reset link" msgstr "" -#: warehouse/accounts/views.py:807 warehouse/accounts/views.py:920 -#: warehouse/accounts/views.py:1024 warehouse/accounts/views.py:1193 +#: warehouse/accounts/views.py:804 warehouse/accounts/views.py:917 +#: warehouse/accounts/views.py:1021 warehouse/accounts/views.py:1190 msgid "Invalid token: no token supplied" msgstr "" -#: warehouse/accounts/views.py:811 +#: warehouse/accounts/views.py:808 msgid "Invalid token: not a password reset token" msgstr "" -#: warehouse/accounts/views.py:816 +#: warehouse/accounts/views.py:813 msgid "Invalid token: user not found" msgstr "" -#: warehouse/accounts/views.py:838 +#: warehouse/accounts/views.py:835 msgid "Invalid token: user has logged in since this token was requested" msgstr "" -#: warehouse/accounts/views.py:856 +#: warehouse/accounts/views.py:853 msgid "" "Invalid token: password has already been changed since this token was " "requested" msgstr "" -#: warehouse/accounts/views.py:888 +#: warehouse/accounts/views.py:885 msgid "You have reset your password" msgstr "" -#: warehouse/accounts/views.py:916 +#: warehouse/accounts/views.py:913 msgid "Expired token: request a new email verification link" msgstr "" -#: warehouse/accounts/views.py:918 +#: warehouse/accounts/views.py:915 msgid "Invalid token: request a new email verification link" msgstr "" -#: warehouse/accounts/views.py:924 +#: warehouse/accounts/views.py:921 msgid "Invalid token: not an email verification token" msgstr "" -#: warehouse/accounts/views.py:933 +#: warehouse/accounts/views.py:930 msgid "Email not found" msgstr "" -#: warehouse/accounts/views.py:936 +#: warehouse/accounts/views.py:933 msgid "Email already verified" msgstr "" -#: warehouse/accounts/views.py:953 +#: warehouse/accounts/views.py:950 msgid "You can now set this email as your primary address" msgstr "" -#: warehouse/accounts/views.py:957 +#: warehouse/accounts/views.py:954 msgid "This is your primary address" msgstr "" -#: warehouse/accounts/views.py:962 +#: warehouse/accounts/views.py:959 msgid "Email address ${email_address} verified. ${confirm_message}." msgstr "" -#: warehouse/accounts/views.py:1020 +#: warehouse/accounts/views.py:1017 msgid "Expired token: request a new organization invitation" msgstr "" -#: warehouse/accounts/views.py:1022 +#: warehouse/accounts/views.py:1019 msgid "Invalid token: request a new organization invitation" msgstr "" -#: warehouse/accounts/views.py:1028 +#: warehouse/accounts/views.py:1025 msgid "Invalid token: not an organization invitation token" msgstr "" -#: warehouse/accounts/views.py:1032 +#: warehouse/accounts/views.py:1029 msgid "Organization invitation is not valid." msgstr "" -#: warehouse/accounts/views.py:1041 +#: warehouse/accounts/views.py:1038 msgid "Organization invitation no longer exists." msgstr "" -#: warehouse/accounts/views.py:1092 +#: warehouse/accounts/views.py:1089 msgid "Invitation for '${organization_name}' is declined." msgstr "" -#: warehouse/accounts/views.py:1155 +#: warehouse/accounts/views.py:1152 msgid "You are now ${role} of the '${organization_name}' organization." msgstr "" -#: warehouse/accounts/views.py:1189 +#: warehouse/accounts/views.py:1186 msgid "Expired token: request a new project role invitation" msgstr "" -#: warehouse/accounts/views.py:1191 +#: warehouse/accounts/views.py:1188 msgid "Invalid token: request a new project role invitation" msgstr "" -#: warehouse/accounts/views.py:1197 +#: warehouse/accounts/views.py:1194 msgid "Invalid token: not a collaboration invitation token" msgstr "" -#: warehouse/accounts/views.py:1201 +#: warehouse/accounts/views.py:1198 msgid "Role invitation is not valid." msgstr "" -#: warehouse/accounts/views.py:1216 +#: warehouse/accounts/views.py:1213 msgid "Role invitation no longer exists." msgstr "" -#: warehouse/accounts/views.py:1247 +#: warehouse/accounts/views.py:1244 msgid "Invitation for '${project_name}' is declined." msgstr "" -#: warehouse/accounts/views.py:1313 +#: warehouse/accounts/views.py:1310 msgid "You are now ${role} of the '${project_name}' project." msgstr "" -#: warehouse/accounts/views.py:1560 warehouse/accounts/views.py:1803 +#: warehouse/accounts/views.py:1557 warehouse/accounts/views.py:1800 #: warehouse/manage/views/__init__.py:1242 msgid "" "Trusted publishing is temporarily disabled. See https://pypi.org/help" "#admin-intervention for details." msgstr "" -#: warehouse/accounts/views.py:1581 +#: warehouse/accounts/views.py:1578 msgid "disabled. See https://pypi.org/help#admin-intervention for details." msgstr "" -#: warehouse/accounts/views.py:1597 +#: warehouse/accounts/views.py:1594 msgid "" "You must have a verified email in order to register a pending trusted " "publisher. See https://pypi.org/help#openid-connect for details." msgstr "" -#: warehouse/accounts/views.py:1610 +#: warehouse/accounts/views.py:1607 msgid "You can't register more than 3 pending trusted publishers at once." msgstr "" -#: warehouse/accounts/views.py:1626 warehouse/manage/views/__init__.py:1277 +#: warehouse/accounts/views.py:1623 warehouse/manage/views/__init__.py:1277 #: warehouse/manage/views/__init__.py:1390 #: warehouse/manage/views/__init__.py:1502 #: warehouse/manage/views/__init__.py:1612 @@ -310,29 +310,29 @@ msgid "" "again later." msgstr "" -#: warehouse/accounts/views.py:1637 warehouse/manage/views/__init__.py:1291 +#: warehouse/accounts/views.py:1634 warehouse/manage/views/__init__.py:1291 #: warehouse/manage/views/__init__.py:1404 #: warehouse/manage/views/__init__.py:1516 #: warehouse/manage/views/__init__.py:1626 msgid "The trusted publisher could not be registered" msgstr "" -#: warehouse/accounts/views.py:1651 +#: warehouse/accounts/views.py:1648 msgid "" "This trusted publisher has already been registered. Please contact PyPI's" " admins if this wasn't intentional." msgstr "" -#: warehouse/accounts/views.py:1678 +#: warehouse/accounts/views.py:1675 msgid "Registered a new pending publisher to create " msgstr "" -#: warehouse/accounts/views.py:1817 warehouse/accounts/views.py:1830 -#: warehouse/accounts/views.py:1837 +#: warehouse/accounts/views.py:1814 warehouse/accounts/views.py:1827 +#: warehouse/accounts/views.py:1834 msgid "Invalid publisher ID" msgstr "" -#: warehouse/accounts/views.py:1843 +#: warehouse/accounts/views.py:1840 msgid "Removed trusted publisher for project " msgstr "" @@ -951,7 +951,7 @@ msgid "Sponsors" msgstr "" #: warehouse/templates/accounts/login.html:18 -#: warehouse/templates/accounts/login.html:117 warehouse/templates/base.html:43 +#: warehouse/templates/accounts/login.html:103 warehouse/templates/base.html:43 #: warehouse/templates/base.html:57 msgid "Log in" msgstr "" @@ -1319,7 +1319,7 @@ msgstr "" msgid "Confirm password to continue" msgstr "" -#: warehouse/templates/accounts/login.html:79 +#: warehouse/templates/accounts/login.html:77 #: warehouse/templates/accounts/register.html:136 #: warehouse/templates/accounts/reset-password.html:38 #: warehouse/templates/manage/manage_base.html:408 @@ -1327,8 +1327,8 @@ msgstr "" msgid "Password" msgstr "" -#: warehouse/templates/accounts/login.html:53 -#: warehouse/templates/accounts/login.html:81 +#: warehouse/templates/accounts/login.html:51 +#: warehouse/templates/accounts/login.html:79 #: warehouse/templates/accounts/recovery-code.html:42 #: warehouse/templates/accounts/register.html:49 #: warehouse/templates/accounts/register.html:75 @@ -1408,18 +1408,18 @@ msgstr "" msgid "(required)" msgstr "" -#: warehouse/templates/accounts/login.html:90 +#: warehouse/templates/accounts/login.html:84 #: warehouse/templates/re-auth.html:57 msgid "Your password" msgstr "" -#: warehouse/templates/accounts/login.html:86 +#: warehouse/templates/accounts/login.html:107 #: warehouse/templates/manage/manage_base.html:411 #: warehouse/templates/re-auth.html:81 msgid "Show password" msgstr "" -#: warehouse/templates/accounts/login.html:120 +#: warehouse/templates/accounts/login.html:111 #: warehouse/templates/re-auth.html:85 msgid "Forgot password?" msgstr "" @@ -1486,12 +1486,12 @@ msgid "" "on your account before accepting an invitation to join a project." msgstr "" -#: warehouse/templates/accounts/login.html:32 +#: warehouse/templates/accounts/login.html:30 #, python-format msgid "Log in to %(title)s" msgstr "" -#: warehouse/templates/accounts/login.html:51 +#: warehouse/templates/accounts/login.html:49 #: warehouse/templates/accounts/profile.html:39 #: warehouse/templates/accounts/register.html:108 #: warehouse/templates/email/organization-member-added/body.html:30 @@ -1510,7 +1510,7 @@ msgstr "" msgid "Username" msgstr "" -#: warehouse/templates/accounts/login.html:57 +#: warehouse/templates/accounts/login.html:55 msgid "Your username" msgstr "" diff --git a/warehouse/templates/accounts/login.html b/warehouse/templates/accounts/login.html index 8330c4b77f71..5a0bcb6748c9 100644 --- a/warehouse/templates/accounts/login.html +++ b/warehouse/templates/accounts/login.html @@ -18,8 +18,6 @@ {% trans %}Log in{% endtrans %} {% endblock %} -{%- from "warehouse:templates/includes/input-captcha.html" import captcha_html, captcha_src %} - {% block content %} {% if testPyPI %} {% set title = "TestPyPI" %} @@ -74,17 +72,13 @@

{% trans title=title %}Log in to {{ title }}{% endtrans %
-
+
-
{{ form.password( placeholder=gettext("Your password"), @@ -103,30 +97,22 @@

{% trans title=title %}Log in to {{ title }}{% endtrans % {% endif %}

- - {# TODO: This is an empty div set used for consistent visual layout. #} -
- -
- {{ captcha_html(request, form) }} -
-
- - {% trans %}Forgot password?{% endtrans %} - +
+ + {% trans %}Forgot password?{% endtrans %} +
{% endblock %} - -{% block extra_js %} - {{ captcha_src(request) }} -{% endblock %}