Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ref #492, Fix #734: drop write support of legacy vpn_waitlist and relay_waitlist fields #722

Merged
merged 7 commits into from
Aug 6, 2024
139 changes: 0 additions & 139 deletions ctms/backport_legacy_waitlists.py

This file was deleted.

13 changes: 0 additions & 13 deletions ctms/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from sqlalchemy.sql import func

from .auth import hash_password
from .backport_legacy_waitlists import format_legacy_vpn_relay_waitlist_input
from .models import (
AmoAccount,
ApiClient,
Expand Down Expand Up @@ -440,10 +439,6 @@ def create_contact(
if contact.mofo:
create_mofo(db, email_id, contact.mofo)

contact = format_legacy_vpn_relay_waitlist_input(
db, email_id, contact, ContactInSchema, metrics
)

for newsletter in contact.newsletters:
create_newsletter(db, email_id, newsletter)

Expand All @@ -459,10 +454,6 @@ def create_or_update_contact(
create_or_update_fxa(db, email_id, contact.fxa)
create_or_update_mofo(db, email_id, contact.mofo)

contact = format_legacy_vpn_relay_waitlist_input(
db, email_id, contact, ContactPutSchema, metrics
)

create_or_update_newsletters(db, email_id, contact.newsletters)
create_or_update_waitlists(db, email_id, contact.waitlists)

Expand Down Expand Up @@ -518,10 +509,6 @@ def update_contact( # noqa: PLR0912
db.delete(existing)
setattr(email, group_name, None)

update_data = format_legacy_vpn_relay_waitlist_input(
db, email_id, update_data, dict, metrics
)

if "newsletters" in update_data:
if update_data["newsletters"] == "UNSUBSCRIBE":
for newsletter in getattr(email, "newsletters", []):
Expand Down
7 changes: 0 additions & 7 deletions ctms/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,6 @@
],
},
),
"legacy_waitlists_requests": (
Counter,
{
"name": "ctms_legacy_waitlists_requests_total",
"documentation": "Total count of API calls that use the legacy waitlists format",
},
),
"contacts": (
Gauge,
{
Expand Down
8 changes: 1 addition & 7 deletions ctms/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,7 @@
)
from .mofo import MozillaFoundationInSchema, MozillaFoundationSchema
from .newsletter import NewsletterInSchema, NewsletterSchema, NewsletterTableSchema
from .waitlist import (
RelayWaitlistInSchema,
VpnWaitlistInSchema,
WaitlistInSchema,
WaitlistSchema,
WaitlistTableSchema,
)
from .waitlist import WaitlistInSchema, WaitlistSchema, WaitlistTableSchema
from .web import (
BadRequestResponse,
NotFoundResponse,
Expand Down
32 changes: 0 additions & 32 deletions ctms/schemas/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,12 @@
NewsletterTimestampedSchema,
)
from .waitlist import (
RelayWaitlistInSchema,
RelayWaitlistSchema,
VpnWaitlistInSchema,
VpnWaitlistSchema,
WaitlistInSchema,
WaitlistSchema,
WaitlistTableSchema,
WaitlistTimestampedSchema,
validate_waitlist_newsletters,
)

if TYPE_CHECKING:
Expand Down Expand Up @@ -157,19 +154,6 @@ class ContactInBase(ComparableBase):
]
],
)
# TODO waitlist: remove once Basket leverages the `waitlists` field.
vpn_waitlist: Optional[VpnWaitlistInSchema] = None
relay_waitlist: Optional[RelayWaitlistInSchema] = None

@model_validator(mode="after")
def check_fields(self):
"""
This makes sure a Relay country is specified when one of the `relay-*-waitlist`
newsletter is subscribed.

TODO waitlist: remove once Basket leverages the `waitlists` field.
"""
return validate_waitlist_newsletters(self)

def idempotent_equal(self, other):
def _noneify(field):
Expand Down Expand Up @@ -239,22 +223,6 @@ class ContactPatchSchema(ComparableBase):
]
],
)
vpn_waitlist: Optional[Union[Literal["DELETE"], VpnWaitlistInSchema]] = Field(
None, description='VPN Waitlist data to update, or "DELETE" to reset.'
)
relay_waitlist: Optional[Union[Literal["DELETE"], RelayWaitlistInSchema]] = Field(
None, description='Relay Waitlist data to update, or "DELETE" to reset.'
)

@model_validator(mode="after")
def check_fields(self):
"""
This makes sure a Relay country is specified when one of the `relay-*-waitlist`
newsletter is subscribed.

TODO waitlist: remove once Basket leverages the `waitlists` field.
"""
return validate_waitlist_newsletters(self)


class CTMSResponse(BaseModel):
Expand Down
73 changes: 4 additions & 69 deletions ctms/schemas/waitlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ class WaitlistBase(ComparableBase):

This is meant to serve as the common and generic schemas to
all waitlists.

In this implementation phase, it cohabits with individual (non-generic)
schemas of Relay and VPN.

TODO waitlist: once Basket leverages the `waitlists` field, we can drop
`RelayWaitlistBase` and `VpnWaitlistBase`.
"""

name: str = Field(
Expand Down Expand Up @@ -133,53 +127,9 @@ def PlatformField():
)


def validate_waitlist_newsletters(
contact: Union["ContactInBase", "ContactPatchSchema"],
):
"""
This helper validates that when subscribing to `relay-*-waitlist`
newsletters, the country is provided.
# TODO waitlist: remove once Basket leverages the `waitlists` field.
class RelayWaitlistSchema(ComparableBase):
"""
if not contact.newsletters:
return contact

if not isinstance(contact.newsletters, list):
return contact

relay_newsletter_found = False
for newsletter in contact.newsletters:
if newsletter.subscribed and newsletter.name.startswith("relay-"):
relay_newsletter_found = True
break

if not relay_newsletter_found:
return contact

# If specified using the legacy `relay_waitlist`
relay_country = None
relay_waitlist = contact.relay_waitlist
if relay_waitlist and relay_waitlist != "DELETE":
relay_country = relay_waitlist.geo
elif hasattr(contact, "waitlists"):
# If specified using the `waitlists` field (unlikely, but in our tests we do)
if isinstance(contact.waitlists, list):
for waitlist in contact.waitlists:
if waitlist.name == "relay":
relay_country = waitlist.fields.get("geo")

# Relay country not specified, check if a relay newsletter is being subscribed.
if not relay_country:
raise ValueError("Relay country missing")

return contact


class RelayWaitlistBase(ComparableBase):
"""
The Mozilla Relay Waitlist schema.

TODO waitlist: remove once Basket leverages the `waitlists` field.
The Mozilla Relay Waitlist schema for the read-only `relay_waitlist` field.
"""

geo: Optional[str] = Field(
Expand All @@ -191,19 +141,9 @@ class RelayWaitlistBase(ComparableBase):
model_config = ConfigDict(from_attributes=True)


# No need to change anything, just extend if you want to
RelayWaitlistInSchema = RelayWaitlistBase
RelayWaitlistSchema = RelayWaitlistBase


class VpnWaitlistBase(ComparableBase):
class VpnWaitlistSchema(ComparableBase):
"""
The Mozilla VPN Waitlist schema.

This was previously the Firefox Private Network (fpn) waitlist data,
with a similar purpose.

TODO waitlist: remove once Basket leverages the `waitlists` field.
The Mozilla VPN Waitlist schema for the read-only `vpn_waitlist` field
"""

geo: Optional[str] = Field(
Expand All @@ -222,8 +162,3 @@ class VpnWaitlistBase(ComparableBase):
examples=["ios,mac"],
)
model_config = ConfigDict(from_attributes=True)


# No need to change anything, just extend if you want to
VpnWaitlistInSchema = VpnWaitlistBase
VpnWaitlistSchema = VpnWaitlistBase
Loading