Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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 dev/environment
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ TOKEN_PASSWORD_SECRET="an insecure password reset secret key"
TOKEN_EMAIL_SECRET="an insecure email verification secret key"
TOKEN_TWO_FACTOR_SECRET="an insecure two-factor auth secret key"
TOKEN_REMEMBER_DEVICE_SECRET="an insecure remember device auth secret key"
TOKEN_CONFIRM_LOGIN_SECRET="an insecure confirm login auth secret key"

WAREHOUSE_LEGACY_DOMAIN=pypi.python.org

Expand Down
10 changes: 10 additions & 0 deletions tests/common/db/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
TermsOfServiceEngagement,
User,
UserTermsOfServiceEngagement,
UserUniqueLogin,
)

from ...common.constants import REMOTE_ADDR
from .base import WarehouseFactory

fake = faker.Faker()
Expand Down Expand Up @@ -130,3 +132,11 @@ class Meta:
# TODO: Replace when factory_boy supports `unique`.
# See https://github.com/FactoryBoy/factory_boy/pull/997
name = factory.Sequence(lambda _: fake.unique.user_name())


class UserUniqueLoginFactory(WarehouseFactory):
class Meta:
model = UserUniqueLogin

user = factory.SubFactory(UserFactory)
ip_address = REMOTE_ADDR
6 changes: 5 additions & 1 deletion tests/functional/manage/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
from webob.multidict import MultiDict

from warehouse.accounts.interfaces import IPasswordBreachedService, IUserService
from warehouse.accounts.models import UniqueLoginStatus
from warehouse.manage import views
from warehouse.manage.views import organizations as org_views
from warehouse.organizations.interfaces import IOrganizationService
from warehouse.organizations.models import OrganizationType
from warehouse.utils.otp import _get_totp

from ...common.db.accounts import EmailFactory, UserFactory
from ...common.db.accounts import EmailFactory, UserFactory, UserUniqueLoginFactory


class TestManageAccount:
Expand Down Expand Up @@ -52,6 +53,9 @@ def test_changing_password_succeeds(self, webtest, socket_enabled):
with_terms_of_service_agreement=True,
clear_pwd="password",
)
UserUniqueLoginFactory.create(
user=user, ip_address="1.2.3.4", status=UniqueLoginStatus.CONFIRMED
)

# visit login page
login_page = webtest.get("/account/login/", status=HTTPStatus.OK)
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/accounts/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ def test_includeme(monkeypatch):
pretend.call(
TokenServiceFactory(name="two_factor"), ITokenService, name="two_factor"
),
pretend.call(
TokenServiceFactory(name="confirm_login"),
ITokenService,
name="confirm_login",
),
pretend.call(
TokenServiceFactory(name="remember_device"),
ITokenService,
Expand Down
20 changes: 19 additions & 1 deletion tests/unit/accounts/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,21 @@

from pyramid.authorization import Authenticated

from warehouse.accounts.models import Email, RecoveryCode, User, UserFactory, WebAuthn
from warehouse.accounts.models import (
Email,
RecoveryCode,
User,
UserFactory,
WebAuthn,
)
from warehouse.authnz import Permissions
from warehouse.utils.security_policy import principals_for

from ...common.db.accounts import (
EmailFactory as DBEmailFactory,
UserEventFactory as DBUserEventFactory,
UserFactory as DBUserFactory,
UserUniqueLoginFactory,
)
from ...common.db.packaging import (
ProjectFactory as DBProjectFactory,
Expand Down Expand Up @@ -309,3 +316,14 @@ def test_user_projects_is_ordered_by_name(self, db_session):
DBRoleFactory.create(project=project3, user=user)

assert user.projects == [project2, project3, project1]


class TestUserUniqueLogin:
def test_repr(self, db_session):
unique_login = UserUniqueLoginFactory.create()
assert (
repr(unique_login)
== f"<UserUniqueLogin(user={unique_login.user.username!r}, "
f"ip_address={unique_login.ip_address!r}, "
f"status={unique_login.status!r})>"
)
Loading