Commit 0e030dfd authored by Open Science Conservation Fund's avatar Open Science Conservation Fund
Browse files

new model and extra logic to control the http uploader access

parent 0e5bf740
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ dependencies = [
    "rest-pandas==1.1.0",
    "sentry-sdk>=1.15,<1.16",
    "azure-storage-blob==1.5.0",
    "django-polymorphic==3.1.0",
    "django-polymorphic>=3.1.0",
    "dacite==1.6.0",
    "frictionless[parquet]==5.18.1",
    "boto3==1.26.95",
+2 −3
Original line number Diff line number Diff line
@@ -699,9 +699,8 @@ NOCAPTCHA = True

# Django allauth settings
ACCOUNT_ADAPTER = "trapper.apps.accounts.adapters.TrapperAdapter"
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_LOGIN_METHODS = {"email"}
ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]
ACCOUNT_SESSION_REMEMBER = False
ACCOUNT_EMAIL_VERIFICATION = "none"
ACCOUNT_LOGOUT_ON_GET = True
+13 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ from trapper.apps.accounts.models import (
    UserRemoteTask,
    UserDataPackage,
    UserFTPAccount,
    UserHttpUploaderAccount,
)
from trapper.apps.media_classification.models import (
    ClassificationProjectRole,
@@ -348,7 +349,7 @@ class TrapperUserAdmin(UserAdmin):
        n_users = len(queryset)
        for user in queryset:
            try:
                user.userftpaccount.delete()
                user.ftp_account.delete()
            except ObjectDoesNotExist:
                pass
            user.userprofile.has_ftp_account = False
@@ -487,6 +488,17 @@ class UserFTPAccountAdmin(admin.ModelAdmin):
    ]


@admin.register(UserHttpUploaderAccount)
class UserHttpUploaderAccountAdmin(admin.ModelAdmin):
    list_display = ("user", "quota_files", "quota_size", "created_at", "updated_at")
    search_fields = ("user__username", "user__email")
    readonly_fields = [
        "created_at",
        "updated_at",
    ]
    raw_id_fields = ("user",)


admin.site.register(User, TrapperUserAdmin)
admin.site.register(UserProfile)
admin.site.register(UserTask)
+45 −0
Original line number Diff line number Diff line
# Generated by Django 4.2.17 on 2025-10-13 17:22

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        ('accounts', '0027_userprofile_demo_alter_userprofile_timezone'),
    ]

    operations = [
        migrations.AlterField(
            model_name='userftpaccount',
            name='quota_files',
            field=models.IntegerField(default=0, help_text='Max number of files user can upload'),
        ),
        migrations.AlterField(
            model_name='userftpaccount',
            name='quota_size',
            field=models.BigIntegerField(default=0, help_text='Max size (in bytes) user can upload'),
        ),
        migrations.AlterField(
            model_name='userftpaccount',
            name='user',
            field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='ftp_account', to=settings.AUTH_USER_MODEL),
        ),
        migrations.CreateModel(
            name='UserHttpUploaderAccount',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('quota_files', models.IntegerField(default=0, help_text='Max number of files user can upload')),
                ('quota_size', models.BigIntegerField(default=0, help_text='Max size (in bytes) user can upload')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='http_uploader_account', to=settings.AUTH_USER_MODEL)),
            ],
            options={
                'verbose_name': 'User HTTP uploader account',
                'verbose_name_plural': 'User HTTP uploader accounts',
            },
        ),
    ]
+30 −6
Original line number Diff line number Diff line
@@ -142,8 +142,8 @@ class User(AbstractUser):

        # Delete user avatar and user FTP access
        user_profile.avatar.delete()
        if hasattr(user, "userftpaccount"):
            user.userftpaccount.delete()
        if hasattr(user, "ftp_account"):
            user.ftp_account.delete()

        # Delete user historical tasks, data packages and team memberships
        user.userremotetask_set.all().delete()
@@ -454,14 +454,20 @@ def submission_delete(sender, instance, **kwargs):


class UserFTPAccount(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    user = models.OneToOneField(
        User, on_delete=models.CASCADE, related_name="ftp_account"
    )
    username = models.CharField(max_length=255, unique=True)
    password = models.CharField(max_length=255)
    uid = models.SmallIntegerField(default=-1)
    gid = models.SmallIntegerField(default=-1)
    dir = models.CharField(max_length=255)
    quota_files = models.IntegerField(default=-1)
    quota_size = models.BigIntegerField(default=-1)
    quota_files = models.IntegerField(
        default=0, help_text=_("Max number of files user can upload")
    )
    quota_size = models.BigIntegerField(
        default=0, help_text=_("Max size (in bytes) user can upload")
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

@@ -470,7 +476,25 @@ class UserFTPAccount(models.Model):
        verbose_name_plural = _("User FTP accounts")


# Automatically mark citizen sciene useres as demo when DEMO_MODE is active.
class UserHttpUploaderAccount(models.Model):
    user = models.OneToOneField(
        User, on_delete=models.CASCADE, related_name="http_uploader_account"
    )
    quota_files = models.IntegerField(
        default=0, help_text=_("Max number of files user can upload")
    )
    quota_size = models.BigIntegerField(
        default=0, help_text=_("Max size (in bytes) user can upload")
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = _("User HTTP uploader account")
        verbose_name_plural = _("User HTTP uploader accounts")


# Automatically mark citizen science users as demo when DEMO_MODE is active.
@receiver(post_save, sender=UserProfile)
def ensure_demo_flag(sender, instance, created, **kwargs):
    """
Loading