Skip to content

Commit

Permalink
feat: Added management command to update UIDs
Browse files Browse the repository at this point in the history
  • Loading branch information
zamanafzal committed Dec 9, 2024
1 parent 7ca0731 commit 4b6a174
Showing 1 changed file with 132 additions and 0 deletions.
132 changes: 132 additions & 0 deletions enterprise/management/commands/update_ccb_enterprise_uids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import logging
import csv
from django.db import transaction
from django.core.management.base import BaseCommand
from django.core.exceptions import ValidationError
from social_django.models import UserSocialAuth

Check warning on line 6 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L1-L6

Added lines #L1 - L6 were not covered by tests

logger = logging.getLogger(__name__)

Check warning on line 8 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L8

Added line #L8 was not covered by tests


class CSVUpdateError(Exception):

Check warning on line 11 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L11

Added line #L11 was not covered by tests
"""Custom exception for CSV update process."""
pass

Check warning on line 13 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L13

Added line #L13 was not covered by tests


class Command(BaseCommand):

Check warning on line 16 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L16

Added line #L16 was not covered by tests
"""
Update the CCB enterprise related social auth records UID to the new one.
Example usage:
./manage.py lms update_ccb_enterprise_uids csv_file_path
"""

help = 'Records update from CSV with console logging'

Check warning on line 24 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L24

Added line #L24 was not covered by tests

def add_arguments(self, parser):
parser.add_argument('csv_file', type=str, help='Path to the CSV file')
parser.add_argument(

Check warning on line 28 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L26-L28

Added lines #L26 - L28 were not covered by tests
'--no-dry-run',
action='store_false',
dest='dry_run',
default=True,
help='Actually save changes instead of simulating'
)

def handle(self, *args, **options):
logger.info("Command has started...")
csv_path = options['csv_file']
dry_run = options['dry_run']

Check warning on line 39 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L36-L39

Added lines #L36 - L39 were not covered by tests

total_processed = 0
total_updated = 0
total_errors = 0

Check warning on line 43 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L41-L43

Added lines #L41 - L43 were not covered by tests

try:
with open(csv_path, 'r') as csvfile:
reader = csv.DictReader(csvfile)

Check warning on line 47 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L45-L47

Added lines #L45 - L47 were not covered by tests

for row_num, row in enumerate(reader, start=1):
total_processed += 1

Check warning on line 50 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L50

Added line #L50 was not covered by tests

try:
with transaction.atomic():

Check warning on line 53 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L52-L53

Added lines #L52 - L53 were not covered by tests
if self.update_record(row, dry_run):
total_updated += 1

Check warning on line 55 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L55

Added line #L55 was not covered by tests

except Exception as row_error:
total_errors += 1
error_msg = f"Row {row_num} update failed: {row} - Error: {str(row_error)}"
logger.error(error_msg, exc_info=True)

Check warning on line 60 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L57-L60

Added lines #L57 - L60 were not covered by tests

summary_msg = (

Check warning on line 62 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L62

Added line #L62 was not covered by tests
f"CSV Update Summary:\n"
f"Total Records Processed: {total_processed}\n"
f"Records Successfully Updated: {total_updated}\n"
f"Errors Encountered: {total_errors}\n"
f"Dry Run Mode: {'Enabled' if dry_run else 'Disabled'}"
)
logger.info(summary_msg)
except IOError as io_error:
logger.critical(f"File I/O error: {str(io_error)}")

Check warning on line 71 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L69-L71

Added lines #L69 - L71 were not covered by tests

except Exception as e:
logger.critical(f"Critical error in CSV processing: {str(e)}")

Check warning on line 74 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L73-L74

Added lines #L73 - L74 were not covered by tests

def update_record(self, row, dry_run=True):

Check warning on line 76 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L76

Added line #L76 was not covered by tests
"""
Update a single record with detailed error handling.
Args:
row (dict): CSV row data
dry_run (bool): Whether to simulate or actually save changes
Returns:
bool: Whether the update was successful
"""
try:
old_uid = row.get('old-uid')
new_uid = row.get('new-uid')

Check warning on line 89 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L87-L89

Added lines #L87 - L89 were not covered by tests

# Validating that both values are present
if not old_uid or not new_uid:
raise CSVUpdateError("Missing required UID fields")

Check warning on line 93 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L93

Added line #L93 was not covered by tests

old_uid_with_prefix = f'sf-ccb:{old_uid}'
new_uid_with_prefix = f'ccb:samlp|ccb-c52b6697-57da-492b-8d17-7d5f0c0290f2|{new_uid}@ccb.org.co'

Check warning on line 96 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L95-L96

Added lines #L95 - L96 were not covered by tests

instance_with_old_uid = UserSocialAuth.objects.filter(uid=old_uid_with_prefix).first()

Check warning on line 98 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L98

Added line #L98 was not covered by tests

if not instance_with_old_uid:
raise CSVUpdateError(f"No record found with old UID {old_uid_with_prefix}")

Check warning on line 101 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L101

Added line #L101 was not covered by tests

instance_with_new_uid = UserSocialAuth.objects.filter(uid=new_uid_with_prefix).first()

Check warning on line 103 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L103

Added line #L103 was not covered by tests
if instance_with_new_uid:
log_entry = f"Warning: Existing record with new UID {new_uid_with_prefix} is deleting."
logger.info(log_entry)

Check warning on line 106 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L105-L106

Added lines #L105 - L106 were not covered by tests
if not dry_run:
instance_with_new_uid.delete()

Check warning on line 108 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L108

Added line #L108 was not covered by tests

if not dry_run:
instance_with_old_uid.uid = new_uid_with_prefix
instance_with_old_uid.save()

Check warning on line 112 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L111-L112

Added lines #L111 - L112 were not covered by tests

log_entry = f"Successfully updated record: Old UID {old_uid_with_prefix} → New UID {new_uid_with_prefix}"
logger.info(log_entry)

Check warning on line 115 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L114-L115

Added lines #L114 - L115 were not covered by tests

return True

Check warning on line 117 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L117

Added line #L117 was not covered by tests

except ValidationError as ve:
error_msg = f"Validation error: {ve}"
logger.error(error_msg)
raise

Check warning on line 122 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L119-L122

Added lines #L119 - L122 were not covered by tests

except CSVUpdateError as update_error:
error_msg = f"Update processing error: {update_error}"
logger.error(error_msg)
raise

Check warning on line 127 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L124-L127

Added lines #L124 - L127 were not covered by tests

except Exception as e:
error_msg = f"Unexpected error during record update: {e}"
logger.error(error_msg, exc_info=True)
raise

Check warning on line 132 in enterprise/management/commands/update_ccb_enterprise_uids.py

View check run for this annotation

Codecov / codecov/patch

enterprise/management/commands/update_ccb_enterprise_uids.py#L129-L132

Added lines #L129 - L132 were not covered by tests

0 comments on commit 4b6a174

Please sign in to comment.