From c7ee305fcf6ba03a61875f75706907db6b94fb99 Mon Sep 17 00:00:00 2001 From: chrystinne Date: Tue, 21 Jan 2025 19:04:59 -0500 Subject: [PATCH] Enforcing uniqueness of AWSAccessPointUser for (user, aws) and adding migration files necessary for this change. --- physionet-django/project/cloud/s3.py | 33 +++++++++++++------ ...ccesspointuser_unique_together_and_more.py | 33 +++++++++++++++++++ .../0081_alter_awsaccesspointuser_aws.py | 22 +++++++++++++ .../project/modelcomponents/storage.py | 7 +++- 4 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 physionet-django/project/migrations/0080_alter_awsaccesspointuser_unique_together_and_more.py create mode 100644 physionet-django/project/migrations/0081_alter_awsaccesspointuser_aws.py diff --git a/physionet-django/project/cloud/s3.py b/physionet-django/project/cloud/s3.py index 06f35f95f..c693da821 100644 --- a/physionet-django/project/cloud/s3.py +++ b/physionet-django/project/cloud/s3.py @@ -1235,14 +1235,13 @@ def initialize_access_points(project): def associate_aws_users_with_data_access_point(access_point, aws_accounts): """ - Associates a list of `aws_accounts` with the - `AWSAccessPoint`. + Associates a list of `aws_accounts` with the `AWSAccessPoint`. Args: - access_point (AWSAccessPoint): The access point to - which the accounts will be associated. - aws_accounts (list): List of dictionaries containing - `aws_id` and `aws_userid` to be associated. + access_point (AWSAccessPoint): The access point to which + the accounts will be associated. + aws_accounts (list): List of dictionaries containing `aws_id` + and `aws_userid` to be associated. Returns: bool: True if the association was successfully created, @@ -1258,17 +1257,31 @@ def associate_aws_users_with_data_access_point(access_point, aws_accounts): cloud_info = CloudInformation.objects.filter( Q(aws_id=aws_id) | Q(aws_userid=aws_userid) ).first() + if not cloud_info: print(f"User not found for aws_id: {aws_id} or aws_userid: {aws_userid}") continue user = cloud_info.user + + # Get the AWS instance associated with the access point + aws_instance = access_point.aws + # Check if the user is already associated with the access_point - if not AWSAccessPointUser.objects.filter(access_point=access_point, user=user).exists(): - AWSAccessPointUser.objects.create(access_point=access_point, user=user) + existing_association = AWSAccessPointUser.objects.filter( + access_point=access_point, + user=user, + aws=aws_instance + ).first() + + if not existing_association: + # Create the association with the required fields + AWSAccessPointUser.objects.create( + access_point=access_point, + user=user, + aws=aws_instance + ) - # After iterating through all the AWS accounts, save the access_point - access_point.save() return True except Exception as e: print(f"Error associating aws_accounts with access_point: {str(e)}") diff --git a/physionet-django/project/migrations/0080_alter_awsaccesspointuser_unique_together_and_more.py b/physionet-django/project/migrations/0080_alter_awsaccesspointuser_unique_together_and_more.py new file mode 100644 index 000000000..570e5b9a2 --- /dev/null +++ b/physionet-django/project/migrations/0080_alter_awsaccesspointuser_unique_together_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 4.1.10 on 2025-01-21 22:35 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("project", "0079_awsaccesspoint_awsaccesspointuser_and_more"), + ] + + operations = [ + migrations.AlterUniqueTogether( + name="awsaccesspointuser", + unique_together=set(), + ), + migrations.AddField( + model_name="awsaccesspointuser", + name="aws", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="access_point_users", + to="project.aws", + ), + ), + migrations.AlterUniqueTogether( + name="awsaccesspointuser", + unique_together={("user", "aws")}, + ), + ] diff --git a/physionet-django/project/migrations/0081_alter_awsaccesspointuser_aws.py b/physionet-django/project/migrations/0081_alter_awsaccesspointuser_aws.py new file mode 100644 index 000000000..4a42084b1 --- /dev/null +++ b/physionet-django/project/migrations/0081_alter_awsaccesspointuser_aws.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1.10 on 2025-01-21 22:41 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("project", "0080_alter_awsaccesspointuser_unique_together_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="awsaccesspointuser", + name="aws", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="access_point_users", + to="project.aws", + ), + ), + ] diff --git a/physionet-django/project/modelcomponents/storage.py b/physionet-django/project/modelcomponents/storage.py index 681c6b5b9..955f4fe8c 100644 --- a/physionet-django/project/modelcomponents/storage.py +++ b/physionet-django/project/modelcomponents/storage.py @@ -105,9 +105,14 @@ class AWSAccessPointUser(models.Model): related_name='aws_access_point_users', on_delete=models.CASCADE ) + aws = models.ForeignKey( + AWS, + related_name='access_point_users', + on_delete=models.CASCADE + ) class Meta: - unique_together = [('access_point', 'user')] + unique_together = [('user', 'aws')] def __str__(self): return f"User: {self.user}, Access Point: {self.access_point}"