Skip to content

Commit bfa609e

Browse files
mikethemandi
andauthored
chore: remove remaining Basic Authentication stuff (#15196)
Co-authored-by: Dustin Ingram <[email protected]>
1 parent f83eaf2 commit bfa609e

File tree

11 files changed

+12
-339
lines changed

11 files changed

+12
-339
lines changed

tests/unit/email/test_init.py

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,88 +1384,6 @@ def test_password_compromised_email(
13841384
]
13851385

13861386

1387-
class TestBasicAuthWith2FAEmail:
1388-
@pytest.mark.parametrize("verified", [True, False])
1389-
def test_basic_auth_with_2fa_email(
1390-
self, pyramid_request, pyramid_config, monkeypatch, verified, metrics
1391-
):
1392-
stub_user = pretend.stub(
1393-
id="id",
1394-
username="username",
1395-
name="",
1396-
1397-
primary_email=pretend.stub(email="[email protected]", verified=verified),
1398-
)
1399-
subject_renderer = pyramid_config.testing_add_renderer(
1400-
"email/basic-auth-with-2fa/subject.txt"
1401-
)
1402-
subject_renderer.string_response = "Email Subject"
1403-
body_renderer = pyramid_config.testing_add_renderer(
1404-
"email/basic-auth-with-2fa/body.txt"
1405-
)
1406-
body_renderer.string_response = "Email Body"
1407-
html_renderer = pyramid_config.testing_add_renderer(
1408-
"email/basic-auth-with-2fa/body.html"
1409-
)
1410-
html_renderer.string_response = "Email HTML Body"
1411-
1412-
send_email = pretend.stub(
1413-
delay=pretend.call_recorder(lambda *args, **kwargs: None)
1414-
)
1415-
pyramid_request.task = pretend.call_recorder(lambda *args, **kwargs: send_email)
1416-
monkeypatch.setattr(email, "send_email", send_email)
1417-
1418-
pyramid_request.db = pretend.stub(
1419-
query=lambda a: pretend.stub(
1420-
filter=lambda *a: pretend.stub(
1421-
one=lambda: pretend.stub(user_id=stub_user.id)
1422-
)
1423-
),
1424-
)
1425-
pyramid_request.user = stub_user
1426-
pyramid_request.registry.settings = {"mail.sender": "[email protected]"}
1427-
project_name = "exampleproject"
1428-
result = email.send_basic_auth_with_two_factor_email(
1429-
pyramid_request, stub_user, project_name=project_name
1430-
)
1431-
1432-
assert result == {"project_name": project_name}
1433-
assert pyramid_request.task.calls == [pretend.call(send_email)]
1434-
assert send_email.delay.calls == [
1435-
pretend.call(
1436-
f"{stub_user.username} <{stub_user.email}>",
1437-
{
1438-
"subject": "Email Subject",
1439-
"body_text": "Email Body",
1440-
"body_html": (
1441-
"<html>\n<head></head>\n"
1442-
"<body><p>Email HTML Body</p></body>\n</html>\n"
1443-
),
1444-
},
1445-
{
1446-
"tag": "account:email:sent",
1447-
"user_id": stub_user.id,
1448-
"additional": {
1449-
"from_": "[email protected]",
1450-
"to": stub_user.email,
1451-
"subject": "Email Subject",
1452-
"redact_ip": False,
1453-
},
1454-
},
1455-
)
1456-
]
1457-
assert metrics.increment.calls == [
1458-
pretend.call(
1459-
"warehouse.emails.scheduled",
1460-
tags=[
1461-
"template_name:basic-auth-with-2fa",
1462-
"allow_unverified:True",
1463-
"repeat_window:86400.0",
1464-
],
1465-
)
1466-
]
1467-
1468-
14691387
class TestGPGSignatureUploadedEmail:
14701388
def test_gpg_signature_uploaded_email(
14711389
self, pyramid_request, pyramid_config, monkeypatch

tests/unit/forklift/test_legacy.py

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333

3434
from warehouse.admin.flags import AdminFlag, AdminFlagValue
3535
from warehouse.classifiers.models import Classifier
36-
from warehouse.errors import BasicAuthTwoFactorEnabled
3736
from warehouse.forklift import legacy
3837
from warehouse.metrics import IMetricsService
3938
from warehouse.oidc.interfaces import SignedClaims
@@ -50,7 +49,6 @@
5049
Role,
5150
)
5251
from warehouse.packaging.tasks import sync_file_to_cache, update_bigquery_release_files
53-
from warehouse.utils.security_policy import AuthenticationMethod
5452

5553
from ...common.db.accounts import EmailFactory, UserFactory
5654
from ...common.db.classifiers import ClassifierFactory
@@ -2591,58 +2589,6 @@ def test_upload_fails_without_oidc_publisher_permission(
25912589
"See /the/help/url/ for more information."
25922590
).format(project.name)
25932591

2594-
def test_basic_auth_upload_fails_with_2fa_enabled(
2595-
self, pyramid_config, db_request, metrics, monkeypatch
2596-
):
2597-
user = UserFactory.create(totp_secret=b"secret")
2598-
EmailFactory.create(user=user)
2599-
project = ProjectFactory.create()
2600-
RoleFactory.create(user=user, project=project)
2601-
2602-
pyramid_config.testing_securitypolicy(identity=user)
2603-
db_request.user = user
2604-
db_request.user_agent = "warehouse-tests/6.6.6"
2605-
db_request.POST = MultiDict(
2606-
{
2607-
"metadata_version": "1.2",
2608-
"name": project.name,
2609-
"version": "1.0.0",
2610-
"summary": "This is my summary!",
2611-
"filetype": "sdist",
2612-
"md5_digest": _TAR_GZ_PKG_MD5,
2613-
"content": pretend.stub(
2614-
filename="{}-{}.tar.gz".format(project.name, "1.0.0"),
2615-
file=io.BytesIO(_TAR_GZ_PKG_TESTDATA),
2616-
type="application/tar",
2617-
),
2618-
}
2619-
)
2620-
db_request.authentication_method = AuthenticationMethod.BASIC_AUTH
2621-
2622-
send_email = pretend.call_recorder(lambda *a, **kw: None)
2623-
monkeypatch.setattr(legacy, "send_basic_auth_with_two_factor_email", send_email)
2624-
2625-
storage_service = pretend.stub(store=lambda path, filepath, meta: None)
2626-
db_request.find_service = lambda svc, name=None, context=None: {
2627-
IFileStorage: storage_service,
2628-
IMetricsService: metrics,
2629-
}.get(svc)
2630-
2631-
with pytest.raises(BasicAuthTwoFactorEnabled) as excinfo:
2632-
legacy.file_upload(db_request)
2633-
2634-
resp = excinfo.value
2635-
2636-
assert resp.status_code == 401
2637-
assert resp.status == (
2638-
f"401 User { user.username } has two factor auth enabled, "
2639-
"an API Token or Trusted Publisher must be used to upload "
2640-
"in place of password."
2641-
)
2642-
assert send_email.calls == [
2643-
pretend.call(db_request, user, project_name=project.name)
2644-
]
2645-
26462592
@pytest.mark.parametrize(
26472593
"plat",
26482594
[

tests/unit/test_config.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@
2121

2222
from pyramid import renderers
2323
from pyramid.authorization import Allow, Authenticated
24-
from pyramid.httpexceptions import HTTPForbidden, HTTPUnauthorized
2524
from pyramid.tweens import EXCVIEW
2625

2726
from warehouse import config
28-
from warehouse.errors import BasicAuthBreachedPassword, BasicAuthFailedPassword
2927
from warehouse.utils.wsgi import ProxyFixer, VhmRootRemover
3028

3129

@@ -78,24 +76,6 @@ def test_activate_hook(path, expected):
7876
assert config.activate_hook(request) == expected
7977

8078

81-
@pytest.mark.parametrize(
82-
("exc_info", "expected"),
83-
[
84-
(None, False),
85-
((ValueError, ValueError(), None), True),
86-
((HTTPForbidden, HTTPForbidden(), None), True),
87-
((HTTPUnauthorized, HTTPUnauthorized(), None), True),
88-
((BasicAuthBreachedPassword, BasicAuthBreachedPassword(), None), False),
89-
((BasicAuthFailedPassword, BasicAuthFailedPassword(), None), False),
90-
],
91-
)
92-
def test_commit_veto(exc_info, expected):
93-
request = pretend.stub(exc_info=exc_info)
94-
response = pretend.stub()
95-
96-
assert bool(config.commit_veto(request, response)) == expected
97-
98-
9979
@pytest.mark.parametrize("route_kw", [None, {}, {"foo": "bar"}])
10080
def test_template_view(route_kw):
10181
configobj = pretend.stub(
@@ -405,7 +385,6 @@ def __init__(self):
405385
{
406386
"tm.manager_hook": mock.ANY,
407387
"tm.activate_hook": config.activate_hook,
408-
"tm.commit_veto": config.commit_veto,
409388
"tm.annotate_user": False,
410389
}
411390
),

warehouse/config.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
from pyramid.tweens import EXCVIEW
3030
from pyramid_rpc.xmlrpc import XMLRPCRenderer
3131

32-
from warehouse.errors import BasicAuthBreachedPassword, BasicAuthFailedPassword
3332
from warehouse.utils.static import ManifestCacheBuster
3433
from warehouse.utils.wsgi import ProxyFixer, VhmRootRemover
3534

@@ -98,19 +97,6 @@ def activate_hook(request):
9897
return True
9998

10099

101-
def commit_veto(request, response):
102-
# By default pyramid_tm will veto the commit anytime request.exc_info is not None,
103-
# we are going to copy that logic with one difference, we are still going to commit
104-
# if the exception was for a BasicAuthFailedPassword or BreachedPassword.
105-
# TODO: We should probably use a registry or something instead of hardcoded.
106-
allowed_types = (BasicAuthBreachedPassword, BasicAuthFailedPassword)
107-
108-
try:
109-
return not isinstance(request.exc_info[1], allowed_types)
110-
except (AttributeError, TypeError):
111-
return False
112-
113-
114100
def template_view(config, name, route, template, route_kw=None, view_kw=None):
115101
if route_kw is None:
116102
route_kw = {}
@@ -553,7 +539,6 @@ def configure(settings=None):
553539
{
554540
"tm.manager_hook": lambda request: transaction.TransactionManager(),
555541
"tm.activate_hook": activate_hook,
556-
"tm.commit_veto": commit_veto,
557542
"tm.annotate_user": False,
558543
}
559544
)

warehouse/email/__init__.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -333,15 +333,6 @@ def send_token_compromised_email_leak(request, user, *, public_url, origin):
333333
return {"username": user.username, "public_url": public_url, "origin": origin}
334334

335335

336-
@_email(
337-
"basic-auth-with-2fa",
338-
allow_unverified=True,
339-
repeat_window=datetime.timedelta(days=1),
340-
)
341-
def send_basic_auth_with_two_factor_email(request, user, *, project_name):
342-
return {"project_name": project_name}
343-
344-
345336
@_email(
346337
"two-factor-not-yet-enabled",
347338
allow_unverified=True,

warehouse/errors.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,9 @@
1010
# See the License for the specific language governing permissions and
1111
# limitations under the License.
1212

13-
from pyramid.httpexceptions import HTTPForbidden, HTTPUnauthorized
1413
from pyramid.security import Denied
1514

1615

17-
class BasicAuthFailedPassword(HTTPForbidden):
18-
pass
19-
20-
21-
class BasicAuthBreachedPassword(HTTPUnauthorized):
22-
pass
23-
24-
25-
class BasicAuthTwoFactorEnabled(HTTPUnauthorized):
26-
pass
27-
28-
2916
class WarehouseDenied(Denied):
3017
def __new__(cls, s, *args, reason=None, **kwargs):
3118
inner = super().__new__(cls, s, *args, **kwargs)

warehouse/forklift/legacy.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,9 @@
4848
from warehouse.admin.flags import AdminFlagValue
4949
from warehouse.classifiers.models import Classifier
5050
from warehouse.email import (
51-
send_basic_auth_with_two_factor_email,
5251
send_gpg_signature_uploaded_email,
5352
send_two_factor_not_yet_enabled_email,
5453
)
55-
from warehouse.errors import BasicAuthTwoFactorEnabled
5654
from warehouse.events.tags import EventTag
5755
from warehouse.metrics import IMetricsService
5856
from warehouse.packaging.interfaces import IFileStorage, IProjectService
@@ -70,7 +68,6 @@
7068
from warehouse.rate_limiting.interfaces import RateLimiterException
7169
from warehouse.utils import http, readme
7270
from warehouse.utils.project import PROJECT_NAME_RE, validate_project_name
73-
from warehouse.utils.security_policy import AuthenticationMethod
7471

7572
ONE_MB = 1 * 1024 * 1024
7673
ONE_GB = 1 * 1024 * 1024 * 1024
@@ -993,25 +990,6 @@ def file_upload(request):
993990
)
994991
raise _exc_with_message(HTTPForbidden, msg)
995992

996-
# Check if the user has 2FA and used basic auth
997-
# NOTE: We don't need to guard request.user here because basic auth
998-
# can only be used with user identities.
999-
if (
1000-
request.authentication_method == AuthenticationMethod.BASIC_AUTH
1001-
and request.user.has_two_factor
1002-
):
1003-
send_basic_auth_with_two_factor_email(
1004-
request, request.user, project_name=project.name
1005-
)
1006-
raise _exc_with_message(
1007-
BasicAuthTwoFactorEnabled,
1008-
(
1009-
f"User { request.user.username } has two factor auth enabled, "
1010-
"an API Token or Trusted Publisher must be used to upload "
1011-
"in place of password."
1012-
),
1013-
)
1014-
1015993
# Update name if it differs but is still equivalent. We don't need to check if
1016994
# they are equivalent when normalized because that's already been done when we
1017995
# queried for the project.

0 commit comments

Comments
 (0)