diff --git a/rodan-client/code/templates/Views/Master/Main/User/Individual/template-main_user_individual.html b/rodan-client/code/templates/Views/Master/Main/User/Individual/template-main_user_individual.html
index 63ce1f70b..3057cfedb 100644
--- a/rodan-client/code/templates/Views/Master/Main/User/Individual/template-main_user_individual.html
+++ b/rodan-client/code/templates/Views/Master/Main/User/Individual/template-main_user_individual.html
@@ -1,10 +1,20 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/rodan-main/code/rodan/admin/admin.py b/rodan-main/code/rodan/admin/admin.py
index 8d19942e3..4098e373f 100644
--- a/rodan-main/code/rodan/admin/admin.py
+++ b/rodan-main/code/rodan/admin/admin.py
@@ -1,8 +1,10 @@
from django.contrib import admin
+from django.contrib.auth import forms
+from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from guardian.admin import GuardedModelAdmin
from rodan.models.project import Project
-
+from rodan.models.user import User
from rodan.models.workflow import Workflow
from rodan.models.workflowjob import WorkflowJob
from rodan.models.workflowrun import WorkflowRun
@@ -12,27 +14,14 @@
from rodan.models.resource import Resource
from rodan.models.resourcelist import ResourceList
-# from rodan.models.rodanuser import RodanUser
-
-
-# class WorkflowJobInline(admin.StackedInline):
-# model = WorkflowJob
-# extra = 5
-
-
-# class WorkflowAdmin(admin.ModelAdmin):
-# inlines = [WorkflowJobInline]
-
class JobAdmin(admin.ModelAdmin):
list_display = ('name', 'enabled', 'category')
-# @admin.register(Project)
class ProjectAdmin(GuardedModelAdmin):
list_display = ('name', 'uuid', 'creator', 'created', 'updated')
readonly_fields = ('uuid',)
-# @admin.register(Workflow)
class WorkflowJobAdmin(admin.ModelAdmin):
list_display = ('job_name', 'created', 'updated')
list_filter = ('workflow__name',)
@@ -56,20 +45,31 @@ class ResourceAdmin(admin.ModelAdmin):
class ResourceListAdmin(admin.ModelAdmin):
list_display = ('created', 'updated')
+class UserChangeForm(forms.UserChangeForm):
+ class Meta(forms.UserChangeForm.Meta):
+ model = User
+
+class UserCreationForm(forms.UserCreationForm):
+ class Meta(forms.UserCreationForm.Meta):
+ model = User
-# class UserProfileInline(admin.StackedInline):
-# model = RodanUser
-# can_delete = False
-# verbose_name_plural = 'profile'
+class UserAdmin(BaseUserAdmin):
+ form = UserChangeForm
+ add_form = UserCreationForm
+ list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
+ list_filter = ('is_staff', 'is_superuser', 'is_active')
-# class RodanUserAdmin(UserAdmin):
-# inlines = (UserProfileInline, )
+ add_fieldsets = (
+ (None, {
+ 'classes': ('wide',),
+ 'fields': ('username', 'email', 'password1', 'password2'),
+ }),
+ )
-# admin.site.unregister(User)
-# admin.site.register(User, RodanUserAdmin)
+ search_fields = ('username', 'email')
+ ordering = ('username', 'email')
-# admin.site.register(RodanUser)
admin.site.register(Project, ProjectAdmin)
admin.site.register(WorkflowRun, WorkflowRunAdmin)
admin.site.register(RunJob, RunJobAdmin)
@@ -79,3 +79,4 @@ class ResourceListAdmin(admin.ModelAdmin):
admin.site.register(ResultsPackage, ResultsPackageAdmin)
admin.site.register(Resource)
admin.site.register(ResourceList, ResourceListAdmin)
+admin.site.register(User, UserAdmin)
\ No newline at end of file
diff --git a/rodan-main/code/rodan/migrations/0001_initial.py b/rodan-main/code/rodan/migrations/0001_initial.py
index 341cd216b..7e07789dd 100644
--- a/rodan-main/code/rodan/migrations/0001_initial.py
+++ b/rodan-main/code/rodan/migrations/0001_initial.py
@@ -1,10 +1,11 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.29 on 2022-07-13 19:44
-from __future__ import unicode_literals
+# Generated by Django 2.0.13 on 2023-06-26 17:12
from django.conf import settings
+import django.contrib.auth.models
+import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
+import django.utils.timezone
import jsonfield.fields
import rodan.models.resource
import sortedm2m.fields
@@ -16,11 +17,34 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
- ('auth', '0008_alter_user_username_max_length'),
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('auth', '0009_alter_user_last_name_max_length'),
]
operations = [
+ migrations.CreateModel(
+ name='User',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('password', models.CharField(max_length=128, verbose_name='password')),
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
+ ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
+ ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
+ ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
+ ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
+ ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
+ ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
+ ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
+ ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
+ ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
+ ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
+ ],
+ options={
+ 'db_table': 'auth_user',
+ },
+ managers=[
+ ('objects', django.contrib.auth.models.UserManager()),
+ ],
+ ),
migrations.CreateModel(
name='Connection',
fields=[
diff --git a/rodan-main/code/rodan/migrations/0003_auto_20230627_1526.py b/rodan-main/code/rodan/migrations/0003_auto_20230627_1526.py
new file mode 100644
index 000000000..939acd00b
--- /dev/null
+++ b/rodan-main/code/rodan/migrations/0003_auto_20230627_1526.py
@@ -0,0 +1,35 @@
+from django.db import migrations, models
+import rodan.models.user
+
+
+class Migration(migrations.Migration):
+ """
+ This migration makes the email field unique and non-blank and adds permissions to custom user model.
+ """
+
+ dependencies = [
+ ('rodan', '0002_auto_20230522_1420'),
+ ]
+
+ operations = [
+ migrations.AlterModelManagers(
+ name='user',
+ managers=[
+ ('objects', rodan.models.user.UserManager()),
+ ],
+ ),
+ migrations.AlterModelOptions(
+ name='user',
+ options={'permissions': (('view_user', 'View User'),)},
+ ),
+ # Make sure there are no empty email fields by giving them a default value
+ migrations.RunSQL(
+ sql="UPDATE auth_user SET email = CONCAT(username, '@rodan2.simssa.ca') WHERE email = ''",
+ reverse_sql="UPDATE auth_user SET email = '' WHERE email LIKE '%@rodan2.simssa.ca'"
+ ),
+ migrations.AlterField(
+ model_name='user',
+ name='email',
+ field=models.EmailField(error_messages={'unique': 'A user with that email already exists.'}, max_length=254, unique=True, verbose_name='email address'),
+ ),
+ ]
diff --git a/rodan-main/code/rodan/models/__init__.py b/rodan-main/code/rodan/models/__init__.py
index a5e86a18f..e6a4a4500 100644
--- a/rodan-main/code/rodan/models/__init__.py
+++ b/rodan-main/code/rodan/models/__init__.py
@@ -5,7 +5,7 @@
import subprocess
from django.contrib.contenttypes.models import ContentType
-from django.contrib.auth.models import Permission, User, Group
+from django.contrib.auth.models import Permission, Group
from django.db.models.signals import (
pre_migrate,
post_migrate,
@@ -41,6 +41,7 @@
from rodan.models.resourcetype import ResourceType
from rodan.models.connection import Connection
from rodan.models.tempauthtoken import Tempauthtoken
+from rodan.models.user import User
if sys.version_info.major == 2:
@@ -57,7 +58,7 @@ def add_view_user_permission(sender, **kwargs):
"""
# don't set permissions in test database
if not settings.TEST and sender.name == 'guardian':
- content_type = ContentType.objects.get(app_label='auth', model='user')
+ content_type = ContentType.objects.get(app_label='rodan', model='user')
Permission.objects.get_or_create(codename='view_user', name='View User', content_type=content_type)
group = Group.objects.get_or_create(name="view_user_permission")
diff --git a/rodan-main/code/rodan/models/project.py b/rodan-main/code/rodan/models/project.py
index 84031282e..c6c4a2eb1 100644
--- a/rodan-main/code/rodan/models/project.py
+++ b/rodan-main/code/rodan/models/project.py
@@ -4,9 +4,10 @@
import traceback
import uuid
from django.conf import settings
-from django.contrib.auth.models import User, Group
+from django.contrib.auth.models import Group
from django.urls import reverse
from django.db import models
+from rodan.models.user import User
logger = logging.getLogger("rodan")
diff --git a/rodan-main/code/rodan/models/resource.py b/rodan-main/code/rodan/models/resource.py
index fb30b6306..422cf1547 100644
--- a/rodan-main/code/rodan/models/resource.py
+++ b/rodan-main/code/rodan/models/resource.py
@@ -3,10 +3,10 @@
import shutil
from django.conf import settings
from django.db import models
-from django.contrib.auth.models import User
from django.urls import reverse
from rodan.constants import task_status
from rodan.models.resourcelabel import ResourceLabel
+from rodan.models.user import User
import logging
diff --git a/rodan-main/code/rodan/models/resourcelist.py b/rodan-main/code/rodan/models/resourcelist.py
index 4663e7af0..5ccfcc79f 100644
--- a/rodan-main/code/rodan/models/resourcelist.py
+++ b/rodan-main/code/rodan/models/resourcelist.py
@@ -1,8 +1,8 @@
import uuid
from django.db import models
from sortedm2m.fields import SortedManyToManyField
-from django.contrib.auth.models import User
from django.apps import apps
+from rodan.models.user import User
import logging
diff --git a/rodan-main/code/rodan/models/resultspackage.py b/rodan-main/code/rodan/models/resultspackage.py
index 2811dbdaa..739646c06 100644
--- a/rodan-main/code/rodan/models/resultspackage.py
+++ b/rodan-main/code/rodan/models/resultspackage.py
@@ -77,7 +77,7 @@ class Meta:
)
packaging_mode = models.IntegerField(choices=PACKAGING_MODE_CHOICES, db_index=True)
creator = models.ForeignKey(
- "auth.User",
+ settings.AUTH_USER_MODEL,
related_name="results_packages",
on_delete=models.SET_NULL,
blank=True,
diff --git a/rodan-main/code/rodan/models/runjob.py b/rodan-main/code/rodan/models/runjob.py
index d7667efae..6aae91d81 100644
--- a/rodan-main/code/rodan/models/runjob.py
+++ b/rodan-main/code/rodan/models/runjob.py
@@ -3,7 +3,7 @@
from jsonfield import JSONField
from rodan.models.job import Job
from rodan.constants import task_status
-from django.contrib.auth.models import User
+from rodan.models.user import User
class RunJob(models.Model):
diff --git a/rodan-main/code/rodan/models/tempauthtoken.py b/rodan-main/code/rodan/models/tempauthtoken.py
index c850d3b5b..66719cb8b 100644
--- a/rodan-main/code/rodan/models/tempauthtoken.py
+++ b/rodan-main/code/rodan/models/tempauthtoken.py
@@ -1,6 +1,6 @@
import uuid
from django.db import models
-from django.contrib.auth.models import User
+from rodan.models.user import User
class Tempauthtoken(models.Model):
diff --git a/rodan-main/code/rodan/models/user.py b/rodan-main/code/rodan/models/user.py
new file mode 100644
index 000000000..bd5e87aab
--- /dev/null
+++ b/rodan-main/code/rodan/models/user.py
@@ -0,0 +1,59 @@
+from django.db import models
+from django.contrib.auth.models import AbstractUser, BaseUserManager
+
+class UserManager(BaseUserManager):
+ """
+ Custom user model manager where email is the unique identifiers
+ for authentication instead of usernames.
+ """
+
+ use_in_migrations = True
+
+ def _create_user(self, username, email, password, **extra_fields):
+ """
+ Creates and saves a User with the given username, email and password.
+ """
+ if not username:
+ raise ValueError('The given username must be set')
+ if not email:
+ raise ValueError('The given email must be set')
+ email = self.normalize_email(email)
+ username = self.model.normalize_username(username)
+ user = self.model(username=username, email=email, **extra_fields)
+ user.set_password(password)
+ user.save()
+ return user
+
+ def create_user(self, username, email, password=None, **extra_fields):
+ extra_fields.setdefault('is_staff', False)
+ extra_fields.setdefault('is_superuser', False)
+ return self._create_user(username, email, password, **extra_fields)
+
+ def create_superuser(self, username, email, password, **extra_fields):
+ extra_fields.setdefault('is_staff', True)
+ extra_fields.setdefault('is_superuser', True)
+
+ if extra_fields.get('is_staff') is not True:
+ raise ValueError('Superuser must have is_staff=True.')
+ if extra_fields.get('is_superuser') is not True:
+ raise ValueError('Superuser must have is_superuser=True.')
+
+ return self._create_user(username, email, password, **extra_fields)
+
+class User(AbstractUser):
+ """
+ A custom user model that uses email as the username field.
+ """
+
+ email = models.EmailField(verbose_name="email address", unique=True, error_messages={"unique": "A user with that email already exists."})
+
+ USERNAME_FIELD = "email"
+ REQUIRED_FIELDS = ["username"]
+
+ objects = UserManager()
+
+ class Meta:
+ db_table = "auth_user"
+ permissions = (
+ ("view_user", "View User"),
+ )
diff --git a/rodan-main/code/rodan/models/userpreference.py b/rodan-main/code/rodan/models/userpreference.py
index d172f9b73..5e3a5bffe 100644
--- a/rodan-main/code/rodan/models/userpreference.py
+++ b/rodan-main/code/rodan/models/userpreference.py
@@ -1,6 +1,6 @@
import uuid
from django.db import models
-from django.contrib.auth.models import User
+from rodan.models.user import User
class UserPreference(models.Model):
diff --git a/rodan-main/code/rodan/models/workflow.py b/rodan-main/code/rodan/models/workflow.py
index 881b3544e..c556eca80 100644
--- a/rodan-main/code/rodan/models/workflow.py
+++ b/rodan-main/code/rodan/models/workflow.py
@@ -3,6 +3,7 @@
import uuid
from django.db import models
from django.apps import apps
+from django.conf import settings
class Workflow(models.Model):
@@ -42,7 +43,7 @@ class Meta:
)
description = models.TextField(blank=True, null=True)
creator = models.ForeignKey(
- "auth.User",
+ settings.AUTH_USER_MODEL,
related_name="workflows",
null=True,
blank=True,
diff --git a/rodan-main/code/rodan/models/workflowrun.py b/rodan-main/code/rodan/models/workflowrun.py
index 9ce0050e3..10ea25e0a 100644
--- a/rodan-main/code/rodan/models/workflowrun.py
+++ b/rodan-main/code/rodan/models/workflowrun.py
@@ -2,6 +2,7 @@
import logging
import uuid
from django.db import models
+from django.conf import settings
from rodan.constants import task_status
# import shutil
@@ -69,7 +70,7 @@ class Meta:
db_index=True,
)
creator = models.ForeignKey(
- "auth.User",
+ settings.AUTH_USER_MODEL,
related_name="workflow_runs",
blank=True,
null=True,
diff --git a/rodan-main/code/rodan/serializers/user.py b/rodan-main/code/rodan/serializers/user.py
index 3a0962e38..3675f1c2d 100644
--- a/rodan-main/code/rodan/serializers/user.py
+++ b/rodan-main/code/rodan/serializers/user.py
@@ -1,5 +1,5 @@
-from django.contrib.auth.models import User
from rest_framework import serializers
+from rodan.models.user import User
class UserSerializer(serializers.HyperlinkedModelSerializer):
diff --git a/rodan-main/code/rodan/settings.py b/rodan-main/code/rodan/settings.py
index ad1dcc350..7db0c72a5 100644
--- a/rodan-main/code/rodan/settings.py
+++ b/rodan-main/code/rodan/settings.py
@@ -113,6 +113,9 @@
# trailing slash.
MEDIA_URL = "/uploads/"
+# Custom user model
+AUTH_USER_MODEL = "rodan.User"
+
###############################################################################
# 1.b General Rodan Configuration
###############################################################################
@@ -368,15 +371,13 @@
"DEFAULT_PAGINATION_CLASS": "rodan.paginators.pagination.CustomPagination",
}
-# used by django-guardian
AUTHENTICATION_BACKENDS = [
- "django.contrib.auth.backends.ModelBackend", # defaults
+ "django.contrib.auth.backends.ModelBackend", # Authenticate with User.USERNAME_FIELD and password
"guardian.backends.ObjectPermissionBackend",
]
-# [TODO] This is completely depricated.
-# https://django-guardian.readthedocs.io/en/stable/develop/changes.html?highlight=User%20ID#release-1-4-2-mar-09-2016
-# Fix it per the suggestions above.
-ANONYMOUS_USER_ID = -1
+
+# Disable anonymous user for django-guardian
+ANONYMOUS_USER_NAME = None
###############################################################################
# 2.b CORS Configuration
diff --git a/rodan-main/code/rodan/test/helpers.py b/rodan-main/code/rodan/test/helpers.py
index 7f5507c9d..43822804b 100644
--- a/rodan-main/code/rodan/test/helpers.py
+++ b/rodan-main/code/rodan/test/helpers.py
@@ -3,13 +3,13 @@
# import uuid
# import time
from model_mommy import mommy
-from django.contrib.auth.models import User
from rodan.models import Job, ResourceType
from django.core.files.base import ContentFile
from django.conf import settings
from importlib import reload
from rodan.celery import app
+from rodan.models.user import User
class RodanTestSetUpMixin(object):
def url(self, obj):
@@ -53,10 +53,10 @@ def setUp_rodan(self):
def setUp_user(self):
self.test_user = User.objects.create_user(
- username="ahankins", password="hahaha"
+ username="ahankins", email="ahankins@rodan2.simssa.ca", password="hahaha"
)
self.test_superuser = User.objects.create_superuser(
- username="super", email="s@s.com", password="hahaha"
+ username="super", email="super@rodan2.simssa.ca", password="hahaha"
)
def setUp_basic_workflow(self):
diff --git a/rodan-main/code/rodan/test/models/test_resource.py b/rodan-main/code/rodan/test/models/test_resource.py
index 314084153..ff5e7f9b6 100644
--- a/rodan-main/code/rodan/test/models/test_resource.py
+++ b/rodan-main/code/rodan/test/models/test_resource.py
@@ -1,6 +1,5 @@
from django.test import TestCase
-from django.contrib.auth.models import User
-from rodan.models import ResourceType, Resource
+from rodan.models import ResourceType, Resource, User
from model_mommy import mommy
from rodan.test.helpers import RodanTestTearDownMixin, RodanTestSetUpMixin
diff --git a/rodan-main/code/rodan/test/models/test_resourcelabel.py b/rodan-main/code/rodan/test/models/test_resourcelabel.py
index bfd3cf264..6ad4cd364 100644
--- a/rodan-main/code/rodan/test/models/test_resourcelabel.py
+++ b/rodan-main/code/rodan/test/models/test_resourcelabel.py
@@ -1,6 +1,5 @@
from django.test import TestCase
-from django.contrib.auth.models import User
-from rodan.models import Resource, ResourceLabel, ResourceType
+from rodan.models import Resource, ResourceLabel, ResourceType, User
from model_mommy import mommy
from rodan.test.helpers import RodanTestTearDownMixin, RodanTestSetUpMixin
diff --git a/rodan-main/code/rodan/test/models/test_userpreference.py b/rodan-main/code/rodan/test/models/test_userpreference.py
index d8ca29136..516686019 100644
--- a/rodan-main/code/rodan/test/models/test_userpreference.py
+++ b/rodan-main/code/rodan/test/models/test_userpreference.py
@@ -1,6 +1,5 @@
from django.test import TestCase
-from django.contrib.auth.models import User
-from rodan.models import UserPreference
+from rodan.models import UserPreference, User
from model_mommy import mommy
from rodan.test.helpers import RodanTestTearDownMixin, RodanTestSetUpMixin
diff --git a/rodan-main/code/rodan/test/models/test_workflow.py b/rodan-main/code/rodan/test/models/test_workflow.py
index eea7f15f7..8d96c795a 100644
--- a/rodan-main/code/rodan/test/models/test_workflow.py
+++ b/rodan-main/code/rodan/test/models/test_workflow.py
@@ -1,6 +1,5 @@
from django.test import TestCase
-from django.contrib.auth.models import User
-from rodan.models import Workflow
+from rodan.models import Workflow, User
# from rodan.models import Project
from model_mommy import mommy
from rodan.test.helpers import RodanTestTearDownMixin, RodanTestSetUpMixin
diff --git a/rodan-main/code/rodan/test/models/test_workflowrun.py b/rodan-main/code/rodan/test/models/test_workflowrun.py
index bf7c17a49..5802e0938 100644
--- a/rodan-main/code/rodan/test/models/test_workflowrun.py
+++ b/rodan-main/code/rodan/test/models/test_workflowrun.py
@@ -1,6 +1,5 @@
from django.test import TestCase
-from django.contrib.auth.models import User
-from rodan.models import WorkflowRun
+from rodan.models import WorkflowRun, User
from model_mommy import mommy
from rodan.test.helpers import RodanTestTearDownMixin, RodanTestSetUpMixin
diff --git a/rodan-main/code/rodan/test/testIndividual_permission.py b/rodan-main/code/rodan/test/testIndividual_permission.py
index 8d019435f..9d5d35e79 100644
--- a/rodan-main/code/rodan/test/testIndividual_permission.py
+++ b/rodan-main/code/rodan/test/testIndividual_permission.py
@@ -3,7 +3,6 @@
"""
import random
-from django.contrib.auth.models import User
from rest_framework.test import APITestCase
from rest_framework import status
from rest_framework.reverse import reverse
@@ -15,7 +14,8 @@
WorkflowRun,
Input,
Output,
- RunJob
+ RunJob,
+ User
)
from rodan.test.helpers import RodanTestSetUpMixin, RodanTestTearDownMixin
@@ -32,16 +32,16 @@ def setUp(self):
self.setUp_user()
self.test_creator = self.test_user
self.test_admin = User.objects.create_user(
- username="test_admin", password="hahaha"
+ username="test_admin", email="test_admin@rodan2.simssa.ca", password="hahaha"
)
self.test_worker = User.objects.create_user(
- username="test_worker", password="hahaha"
+ username="test_worker", email="test_worker@rodan2.simssa.ca", password="hahaha"
)
self.test_worker2 = User.objects.create_user(
- username="test_worker2", password="hahaha"
+ username="test_worker2", email="test_worker2@rodan2.simssa.ca", password="hahaha"
)
self.test_outsider = User.objects.create_user(
- username="test_outsider", password="hahaha"
+ username="test_outsider", email="test_outsider@rodan2.simssa.ca", password="hahaha"
)
def test_all(self):
@@ -936,16 +936,16 @@ def setUp(self):
self.setUp_rodan()
self.setUp_user()
self.test_admin = User.objects.create_user(
- username="test_admin", password="hahaha"
+ username="test_admin", email="test_admin@rodan2.simssa.ca", password="hahaha"
)
self.test_worker = User.objects.create_user(
- username="test_worker", password="hahaha"
+ username="test_worker", email="test_worker@rodan2.simssa.ca", password="hahaha"
)
self.test_worker2 = User.objects.create_user(
- username="test_worker2", password="hahaha"
+ username="test_worker2", email="test_worker2@rodan2.simssa.ca", password="hahaha"
)
self.test_outsider = User.objects.create_user(
- username="test_outsider", password="hahaha"
+ username="test_outsider", email="test_outsider@rodan2.simssa.ca", password="hahaha"
)
def test_construct_workflow(self):
diff --git a/rodan-main/code/rodan/test/views/test_auth.py b/rodan-main/code/rodan/test/views/test_auth.py
index 5f4e228e3..2b1d2754d 100644
--- a/rodan-main/code/rodan/test/views/test_auth.py
+++ b/rodan-main/code/rodan/test/views/test_auth.py
@@ -12,7 +12,7 @@ def setUp(self):
def test_token_auth_pass(self):
token = self.client.post(
"/api/auth/token/",
- {"username": "ahankins", "password": "hahaha"},
+ {"email": "ahankins@rodan2.simssa.ca", "password": "hahaha"},
format="multipart",
)
token_header = "Token {0}".format(token.data["token"])
@@ -26,7 +26,7 @@ def test_token_auth_pass(self):
def test_token_auth_fail(self):
token = self.client.post(
"/api/auth/token/",
- {"username": "ahankins", "password": "wrongg"},
+ {"email": "ahankins@rodan2.simssa.ca", "password": "wrongg"},
format="multipart",
)
self.assertEqual(token.data, {"is_logged_in": False})
diff --git a/rodan-main/code/rodan/views/auth.py b/rodan-main/code/rodan/views/auth.py
index 619969cae..46269d0a9 100644
--- a/rodan-main/code/rodan/views/auth.py
+++ b/rodan-main/code/rodan/views/auth.py
@@ -3,7 +3,6 @@
# login,
# logout
)
-from django.contrib.auth.models import User
from rest_framework import status
from rest_framework.response import Response
from rest_framework import views
@@ -15,6 +14,7 @@
from rest_framework.authtoken.serializers import AuthTokenSerializer
from rodan.serializers.user import UserSerializer
+from rodan.models.user import User
class AuthMeView(generics.RetrieveUpdateAPIView):
@@ -42,12 +42,12 @@ class AuthTokenView(views.APIView):
model = Token
def post(self, request):
- username = request.data.get("username", None)
+ email = request.data.get("email", None)
password = request.data.get("password", None)
- if not username:
+ if not email:
return Response(
- {"detail": "You must supply a username"},
+ {"detail": "You must supply a email"},
status=status.HTTP_401_UNAUTHORIZED,
)
if not password:
@@ -56,7 +56,7 @@ def post(self, request):
status=status.HTTP_401_UNAUTHORIZED,
)
- user = authenticate(username=username, password=password)
+ user = authenticate(email=email, password=password)
if user is not None:
if user.is_active:
@@ -72,7 +72,7 @@ def post(self, request):
{"is_logged_in": False}, status=status.HTTP_403_FORBIDDEN
)
else:
- # user does not exist. Assume a typo in the username or password
+ # user does not exist. Assume a typo in the email or password
# and allow the user to re-authenticate
return Response(
{"is_logged_in": False}, status=status.HTTP_401_UNAUTHORIZED
diff --git a/rodan-main/code/rodan/views/project.py b/rodan-main/code/rodan/views/project.py
index fdac5494b..0dca309f7 100644
--- a/rodan-main/code/rodan/views/project.py
+++ b/rodan-main/code/rodan/views/project.py
@@ -1,8 +1,7 @@
from rest_framework import generics
from rest_framework import permissions, exceptions
from rest_framework.response import Response
-from django.contrib.auth.models import User
-from rodan.models.project import Project
+from rodan.models.project import Project, User
from rodan.serializers.project import ProjectListSerializer, ProjectDetailSerializer
from rodan.permissions import CustomObjectPermissions
from django.db.models import Q
diff --git a/rodan-main/code/rodan/views/user.py b/rodan-main/code/rodan/views/user.py
index 64ad0a123..819fe0c33 100644
--- a/rodan-main/code/rodan/views/user.py
+++ b/rodan-main/code/rodan/views/user.py
@@ -1,5 +1,4 @@
from django.core.exceptions import PermissionDenied
-from django.contrib.auth.models import User
from django.dispatch import receiver
from django.db.models.signals import post_save
@@ -11,6 +10,7 @@
from rodan.permissions import CustomObjectPermissions
from rodan.serializers.user import UserSerializer, UserListSerializer
+from rodan.models.user import User
import django_filters
@@ -54,8 +54,9 @@ def get_queryset(self):
def post(self, request, *args, **kwargs):
userName = request.data.get("username", None)
+ email = request.data.get("email", None)
userPass = request.data.get("password", None)
- user = User.objects.create_user(username=userName, password=userPass)
+ user = User.objects.create_user(username=userName, email=email, password=userPass)
if not user:
return Response(
{"message": "error creating user"}, status=status.HTTP_200_OK
diff --git a/rodan-main/code/rodan/views/userpreference.py b/rodan-main/code/rodan/views/userpreference.py
index bfc52e3ea..1293ee847 100644
--- a/rodan-main/code/rodan/views/userpreference.py
+++ b/rodan-main/code/rodan/views/userpreference.py
@@ -1,5 +1,5 @@
from __future__ import absolute_import
-from rodan.models import UserPreference
+from rodan.models import UserPreference, User
from rodan.serializers.userpreference import (
UserPreferenceListSerializer,
UserPreferenceSerializer,
@@ -7,7 +7,6 @@
from rodan.exceptions import CustomAPIException
from rodan.permissions import CustomObjectPermissions
-from django.contrib.auth.models import User
from django.urls import reverse, Resolver404, resolve
from rest_framework import generics
diff --git a/scripts/local.env b/scripts/local.env
index 350b579cf..50b7acae7 100644
--- a/scripts/local.env
+++ b/scripts/local.env
@@ -3,6 +3,7 @@
###############################################################################
ADMIN_USER=rodan
+ADMIN_EMAIL=admin@rodan2.simssa.ca
ADMIN_PASS=rodan
DJANGO_DEBUG_MODE=False
DJANGO_SECRET_KEY=localdev
diff --git a/scripts/production.sample b/scripts/production.sample
index 4d4638d27..2bd07c666 100644
--- a/scripts/production.sample
+++ b/scripts/production.sample
@@ -3,6 +3,7 @@
###############################################################################
ADMIN_USER=someadmin
+ADMIN_EMAIL=admin@rodan2.simssa.ca
ADMIN_PASS=123456Seven
DJANGO_DEBUG_MODE=False
DJANGO_SECRET_KEY=AVeryLongSecretKeyThatWasGeneratedByOurSpecialScript_DoNotForgetToChangeThis
diff --git a/scripts/staging.sample b/scripts/staging.sample
index ec163bb83..3f8a62eb2 100644
--- a/scripts/staging.sample
+++ b/scripts/staging.sample
@@ -3,6 +3,7 @@
###############################################################################
ADMIN_USER=someadmin
+ADMIN_EMAIL=admin@rodan2.simssa.ca
ADMIN_PASS=123456Seven
DJANGO_DEBUG_MODE=False
DJANGO_SECRET_KEY=AVeryLongSecretKeyThatWasGeneratedByOurSpecialScript_DoNotForgetToChangeThis
diff --git a/scripts/start b/scripts/start
index a062dd59e..003b042fa 100644
--- a/scripts/start
+++ b/scripts/start
@@ -23,10 +23,11 @@ runuser -u root -- yes | MIGRATE="True" python3 manage.py migrate --noinput
cat << EOF | runuser -u root -- python3 manage.py shell
import os
-from django.contrib.auth.models import User
+from django.db.models import Q
+from rodan.models.user import User
print ("Checking if Django super user exists...")
-if not User.objects.filter(username=os.getenv('ADMIN_USER')).exists():
- User.objects.create_superuser(os.getenv('ADMIN_USER'), '', os.getenv('ADMIN_PASS'))
+if not User.objects.filter(Q(username=os.getenv('ADMIN_USER')) | Q(email=os.getenv('ADMIN_EMAIL'))).exists():
+ User.objects.create_superuser(os.getenv('ADMIN_USER'), os.getenv('ADMIN_EMAIL'), os.getenv('ADMIN_PASS'))
print ("Created new user.")
EOF