Skip to content

Commit

Permalink
Merge branch 'main' into stage
Browse files Browse the repository at this point in the history
  • Loading branch information
MelissaAutumn committed Jan 8, 2024
2 parents 5df1237 + 4c3a0b7 commit c1efe99
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
5 changes: 4 additions & 1 deletion backend/src/appointment/controller/apis/fxa_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from requests_oauthlib import OAuth2Session
import requests
from ...database import models, repo
from ...exceptions.fxa_api import NotInAllowListException
from ...exceptions.fxa_api import NotInAllowListException, MissingRefreshTokenException


class FxaConfig:
Expand Down Expand Up @@ -146,6 +146,9 @@ def logout(self):
# I assume a refresh token will destroy its access tokens
refresh_token = self.client.token.get('refresh_token')

if refresh_token is None:
raise MissingRefreshTokenException()

# This route doesn't want auth! (Because we're destroying it)
resp = requests.post(self.config.destroy_url, json={
'refresh_token': refresh_token,
Expand Down
3 changes: 3 additions & 0 deletions backend/src/appointment/exceptions/fxa_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
class NotInAllowListException(Exception):
"""Is raised when a given email is not in the allow list"""
pass

class MissingRefreshTokenException(Exception):
pass
21 changes: 18 additions & 3 deletions backend/src/appointment/routes/webhooks.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import json
import logging

import requests
from fastapi import APIRouter, Depends, Request
from sqlalchemy.orm import Session

from ..controller.apis.fxa_client import FxaClient
from ..database import repo, models
from ..dependencies.database import get_db
from ..dependencies.fxa import get_webhook_auth, get_fxa_client
from ..exceptions.fxa_api import MissingRefreshTokenException

router = APIRouter()

Expand All @@ -25,13 +28,25 @@ def fxa_process(
logging.warning("Webhook event received for non-existent user.")
return

fxa_client.setup(subscriber.id, subscriber.get_external_connection(models.ExternalConnectionType.fxa).token)
subscriber_external_connection = subscriber.get_external_connection(models.ExternalConnectionType.fxa)
fxa_client.setup(subscriber.id, token=subscriber_external_connection.token)

for event, event_data in decoded_token.get('events', {}).items():
match event:
case 'https://schemas.accounts.firefox.com/event/password-change':
# We also get `changeTime` in event_data, but let's just log them out.
fxa_client.logout()
# TODO: What timezone is this in? UTC?
logging.info(f">> Event Data -> {json.dumps(event_data)}")
# Ensure we ignore out of date requests
if subscriber_external_connection.time_updated < event_data.get('changeTime'):
logging.info("Ignoring out of date logout request.")
break

try:
fxa_client.logout()
except MissingRefreshTokenException:
logging.warning("Subscriber doesn't have refresh token.")
except requests.exceptions.HTTPError as ex:
logging.error(f"Error logging out user: {ex.response}")
case 'https://schemas.accounts.firefox.com/event/profile-change':
if event_data.get('email') is not None:
# Update the subscriber's email (and username for now)
Expand Down

0 comments on commit c1efe99

Please sign in to comment.