refactor: Add logging, exception handling to Apple migration commands (#32390)

* refactor: Add logging, exception handling to Apple migration commands
* refactor: pylint fixes
This commit is contained in:
Moeez Zahid
2023-06-07 17:07:13 +05:00
committed by GitHub
parent 698506cb99
commit 6ab9e497fc
3 changed files with 64 additions and 25 deletions

View File

@@ -21,6 +21,8 @@ from common.djangoapps.third_party_auth.appleid import AppleIdAuth
log = logging.getLogger(__name__)
INVALID_GRANT_ERROR = "invalid_grant"
class AccessTokenExpiredException(Exception):
"""
@@ -28,6 +30,12 @@ class AccessTokenExpiredException(Exception):
"""
class BadRequestException(Exception):
"""
Raised when access token has been expired.
"""
class Command(BaseCommand):
"""
Management command to generate transfer identifiers for apple users using their apple_id
@@ -115,7 +123,11 @@ class Command(BaseCommand):
}
response = requests.post(migration_url, data=payload, headers=headers)
if response.status_code == 400:
raise AccessTokenExpiredException
error = response.json().get('error')
log.info("Error while fetching transfer_id for uid %s. Error: %s", apple_id, error)
if error == INVALID_GRANT_ERROR:
raise AccessTokenExpiredException
raise BadRequestException
return response.json().get('transfer_sub')
@@ -123,6 +135,9 @@ class Command(BaseCommand):
"""
Given an Apple ID from the old transferring team,
create and return its respective transfer id.
Update access token if expired.
Skip the current apple_id in case of a malformed
request error and log info.
"""
try:
transfer_id = self._fetch_transfer_id(apple_id, target_team_id)
@@ -130,12 +145,15 @@ class Command(BaseCommand):
log.info('Access token expired. Re-creating access token.')
self._update_token_and_secret()
transfer_id = self._fetch_transfer_id(apple_id, target_team_id)
except BadRequestException:
log.info('Bad request for uid %s.', apple_id)
transfer_id = ''
return transfer_id
def add_arguments(self, parser):
parser.add_argument('target_team_id', help='Team ID to which the app is to be migrated to.')
@transaction.atomic
def handle(self, *args, **options):
target_team_id = options['target_team_id']
@@ -148,11 +166,13 @@ class Command(BaseCommand):
apple_ids = UserSocialAuth.objects.filter(provider=AppleIdAuth.name).exclude(
uid__in=already_processed_apple_ids).values_list('uid', flat=True)
for apple_id in apple_ids:
log.info("Begin processing uid %s", apple_id)
transfer_id = self._get_transfer_id_for_apple_id(apple_id, target_team_id)
if transfer_id:
apple_user_id_info, _ = AppleMigrationUserIdInfo.objects.get_or_create(old_apple_id=apple_id)
apple_user_id_info.transfer_id = transfer_id
apple_user_id_info.save()
log.info('Updated transfer_id for uid %s', apple_id)
with transaction.atomic():
apple_user_id_info, _ = AppleMigrationUserIdInfo.objects.get_or_create(old_apple_id=apple_id)
apple_user_id_info.transfer_id = transfer_id
apple_user_id_info.save()
log.info('Updated transfer_id for uid %s', apple_id)
else:
log.info('Unable to fetch transfer_id for uid %s', apple_id)
log.info('Unable to fetch transfer_id for uid %s. Skipping.', apple_id)

View File

@@ -19,6 +19,8 @@ from common.djangoapps.third_party_auth.appleid import AppleIdAuth
log = logging.getLogger(__name__)
INVALID_GRANT_ERROR = "invalid_grant"
class AccessTokenExpiredException(Exception):
"""
@@ -26,13 +28,19 @@ class AccessTokenExpiredException(Exception):
"""
class BadRequestException(Exception):
"""
Raised when access token has been expired.
"""
class Command(BaseCommand):
"""
Management command to exchange transfer identifiers for new team-scoped identifier for
the user in new migrated team.
Usage:
manage.py generate_and_store_apple_transfer_ids
manage.py generate_and_store_new_apple_ids
"""
def _generate_client_secret(self):
@@ -112,7 +120,11 @@ class Command(BaseCommand):
}
response = requests.post(migration_url, data=payload, headers=headers)
if response.status_code == 400:
raise AccessTokenExpiredException
error = response.json().get('error')
log.info("Error while fetching apple_id for transfer_id %s. Error: %s", transfer_id, error)
if error == INVALID_GRANT_ERROR:
raise AccessTokenExpiredException
raise BadRequestException
return response.json().get('sub')
@@ -120,6 +132,9 @@ class Command(BaseCommand):
"""
For a Transfer ID obtained from the transferring team,
return the correlating Apple ID belonging to the recipient team.
Update access token if expired.
Skip the current transfer_id in case of a malformed request
error and log info.
"""
try:
new_apple_id = self._fetch_new_apple_id(transfer_id)
@@ -127,10 +142,12 @@ class Command(BaseCommand):
log.info('Access token expired. Re-creating access token.')
self._update_token_and_secret()
new_apple_id = self._fetch_new_apple_id(transfer_id)
except BadRequestException:
log.info('Bad request for transfer_id %s.', transfer_id)
new_apple_id = ''
return new_apple_id
@transaction.atomic
def handle(self, *args, **options):
self._update_token_and_secret()
if not self.access_token:
@@ -139,12 +156,14 @@ class Command(BaseCommand):
apple_user_ids_info = AppleMigrationUserIdInfo.objects.filter(Q(new_apple_id__isnull=True) | Q(new_apple_id=""),
~Q(transfer_id=""), transfer_id__isnull=False)
for apple_user_id_info in apple_user_ids_info:
new_apple_id = self._exchange_transfer_id_for_new_apple_id(apple_user_id_info.transfer_id)
transfer_id = apple_user_id_info.transfer_id
old_apple_id = apple_user_id_info.old_apple_id
log.info("Begin processing old_apple_id %s, transfer_id %s", old_apple_id, transfer_id)
new_apple_id = self._exchange_transfer_id_for_new_apple_id(transfer_id)
if new_apple_id:
apple_user_id_info.new_apple_id = new_apple_id
apple_user_id_info.save()
log.info('Updated new Apple ID for uid %s',
apple_user_id_info.old_apple_id)
with transaction.atomic():
apple_user_id_info.new_apple_id = new_apple_id
apple_user_id_info.save()
log.info('Updated new Apple ID for uid %s', old_apple_id)
else:
log.info('Unable to fetch new Apple ID for uid %s',
apple_user_id_info.old_apple_id)
log.info('Unable to fetch new Apple ID for uid %s', old_apple_id)

View File

@@ -23,7 +23,6 @@ class Command(BaseCommand):
manage.py update_new_apple_ids_in_social_auth
"""
@transaction.atomic
def handle(self, *args, **options):
apple_user_ids_info = AppleMigrationUserIdInfo.objects.filter(
~Q(new_apple_id=''), new_apple_id__isnull=False
@@ -35,10 +34,11 @@ class Command(BaseCommand):
uid=apple_user_id_info.old_apple_id, provider=AppleIdAuth.name
).first()
if user_social_auth:
user_social_auth.uid = apple_user_id_info.new_apple_id
user_social_auth.save()
log.info(
'Replaced Apple ID %s with %s',
apple_user_id_info.old_apple_id,
apple_user_id_info.new_apple_id
)
with transaction.atomic():
user_social_auth.uid = apple_user_id_info.new_apple_id
user_social_auth.save()
log.info(
'Replaced Apple ID %s with %s',
apple_user_id_info.old_apple_id,
apple_user_id_info.new_apple_id
)