Skip to content

Commit

Permalink
task/DES-2616: Add TAS institution to user profile and update it on l…
Browse files Browse the repository at this point in the history
…ogin (#1130)

* Add TAS institution to user profile and update it on login

* update institution in db when profile update form is submitted

---------

Co-authored-by: Jake Rosenberg <[email protected]>
  • Loading branch information
jarosenb and Jake Rosenberg authored Dec 13, 2023
1 parent 445ce2c commit f7e0cee
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 3 deletions.
2 changes: 1 addition & 1 deletion designsafe/apps/accounts/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ def clean_website(self):

class Meta:
model = DesignSafeProfile
exclude = ['user', 'ethnicity', 'gender', 'update_required']
exclude = ['user', 'ethnicity', 'gender', 'update_required', 'institution']


class UserRegistrationForm(UserProfileForm, ProfessionalProfileForm):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.6 on 2023-11-18 18:22

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("designsafe_accounts", "0019_designsafeprofile_nh_interests_primary"),
]

operations = [
migrations.AddField(
model_name="designsafeprofile",
name="institution",
field=models.CharField(default=None, max_length=256, null=True),
),
]
1 change: 1 addition & 0 deletions designsafe/apps/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class DesignSafeProfile(models.Model):
nh_technical_domains = models.ManyToManyField(DesignSafeProfileNHTechnicalDomains)
professional_level = models.CharField(max_length=256, default=None, null=True)
research_activities = models.ManyToManyField(DesignSafeProfileResearchActivities)
institution = models.CharField(max_length=256, default=None, null=True)
update_required = models.BooleanField(default=True)
last_updated = models.DateTimeField(auto_now=True, null=True)

Expand Down
1 change: 1 addition & 0 deletions designsafe/apps/accounts/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def mock_user_side_effect(username = 'ds_admin', email = '[email protected]'):

# pass test for duplicate email check
mock_tas().get_user.side_effect = mock_user_side_effect
mock_tas().save_user.side_effect = mock_user_side_effect

edit_url = reverse('designsafe_accounts:profile_edit')
self.client.login(username='ds_admin', password='admin/password')
Expand Down
6 changes: 4 additions & 2 deletions designsafe/apps/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def profile_edit(request):

# retain original account source
data['source'] = tas_user['source']
tas.save_user(tas_user['id'], data)
saved_user = tas.save_user(tas_user['id'], data)
messages.success(request, 'Your profile has been updated!')

try:
Expand All @@ -298,6 +298,7 @@ def profile_edit(request):
ds_profile.orcid_id = pro_data['orcid_id']
ds_profile.professional_level = pro_data['professional_level']
ds_profile.nh_interests_primary = pro_data['nh_interests_primary']
ds_profile.institution = saved_user.get('institution', None)

except ObjectDoesNotExist as e:
logger.info('exception e: {} {}'.format(type(e), e ))
Expand All @@ -309,7 +310,8 @@ def profile_edit(request):
website=pro_data['website'],
orcid_id=pro_data['orcid_id'],
professional_level=pro_data['professional_level'],
nh_interests_primary=pro_data['nh_interests_primary']
nh_interests_primary=pro_data['nh_interests_primary'],
institution=saved_user.get('institution', None)
)

ds_profile.update_required = False
Expand Down
5 changes: 5 additions & 0 deletions designsafe/apps/auth/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.dispatch import receiver
from designsafe.apps.accounts.models import DesignSafeProfile, NotificationPreferences
from designsafe.apps.api.agave import get_service_account_client
from designsafe.apps.auth.tasks import update_institution_from_tas
from pytas.http import TASClient
import logging
import re
Expand Down Expand Up @@ -93,8 +94,11 @@ def authenticate(self, request, username=None, password=None, **kwargs):
)
try:
profile = DesignSafeProfile.objects.get(user=user)
profile.institution = tas_user.get('institution', None)
profile.save()
except DesignSafeProfile.DoesNotExist:
profile = DesignSafeProfile(user=user)
profile.institution = tas_user.get('institution', None)
profile.save()

try:
Expand Down Expand Up @@ -155,6 +159,7 @@ def authenticate(self, *args, **kwargs):
except DesignSafeProfile.DoesNotExist:
profile = DesignSafeProfile(user=user)
profile.save()
update_institution_from_tas.apply_async(args=[username], queue='api')

try:
prefs = NotificationPreferences.objects.get(user=user)
Expand Down
13 changes: 13 additions & 0 deletions designsafe/apps/auth/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from designsafe.apps.api.tasks import agave_indexer
from designsafe.apps.api.notifications.models import Notification
from celery import shared_task
from django.contrib.auth import get_user_model
from pytas.http import TASClient

from requests import HTTPError
from django.contrib.auth import get_user_model
Expand Down Expand Up @@ -101,3 +103,14 @@ def clear_old_notifications(self):
"""Delete notifications older than 30 days to prevent them cluttering the db."""
time_cutoff = datetime.now() - timedelta(days=30)
Notification.objects.filter(datetime__lte=time_cutoff).delete()


@shared_task(bind=True, max_retries=3)
def update_institution_from_tas(self, username):
user_model = get_user_model().objects.get(username=username)
try:
tas_model = TASClient().get_user(username=username)
except Exception as exc:
raise self.retry(exc=exc)
user_model.profile.institution = tas_model.get('institution', None)
user_model.profile.save()

0 comments on commit f7e0cee

Please sign in to comment.