Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy to stage #260

Merged
merged 9 commits into from
Oct 28, 2023
1 change: 1 addition & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
]
THIRD_PARTY_APPS = [
"crispy_forms",
"crispy_bootstrap5",
"allauth",
"allauth.account",
"allauth.socialaccount",
Expand Down
2 changes: 2 additions & 0 deletions primed/primed_anvil/adapters.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from anvil_consortium_manager.adapters.account import BaseAccountAdapter
from django.db.models import Q

from .filters import AccountListFilter
from .tables import AccountTable


class AccountAdapter(BaseAccountAdapter):
"""Custom account adapter for PRIMED."""

list_table_class = AccountTable
list_filterset_class = AccountListFilter

def get_autocomplete_queryset(self, queryset, q):
"""Filter to Accounts where the email or the associated user name matches the query `q`."""
Expand Down
10 changes: 10 additions & 0 deletions primed/primed_anvil/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from anvil_consortium_manager.forms import FilterForm
from anvil_consortium_manager.models import Account
from django_filters import FilterSet


class AccountListFilter(FilterSet):
class Meta:
model = Account
fields = {"email": ["icontains"], "user__name": ["icontains"]}
form = FilterForm
15 changes: 15 additions & 0 deletions primed/primed_anvil/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,21 @@ def test_view_with_two_objects(self):
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 2)

def test_filter_by_name(self):
"""Filtering by name works as expected."""
user = UserFactory.create(name="First Last")
account = AccountFactory.create(user=user)
other_account = AccountFactory.create(verified=True)
self.client.force_login(self.user)
response = self.client.get(
reverse("anvil_consortium_manager:accounts:list"),
{"user__name__icontains": "First"},
)
self.assertIn("table", response.context_data)
self.assertEqual(len(response.context_data["table"].rows), 1)
self.assertIn(account, response.context_data["table"].data)
self.assertNotIn(other_account, response.context_data["table"].data)


class AvailableDataTest(TestCase):
"""Tests for the StudyDetail view."""
Expand Down
6 changes: 1 addition & 5 deletions primed/templates/primed_anvil/study_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ <h3>Workspaces on AnVIL</h3>
Workspaces that have been shared with the Consortium can be identified by a green check box in the "Shared with PRIMED?" column of the tables below.
</p>
<p>
To access a workspace on AnVIL after it has been shared with the consortium, investigators must:
<ol>
<li>link their AnVIL account in this app, and</li>
<li>have approval via the correct PRIMED data access mechanism for data in the workspace.</li>
</ol>
To access a workspace on AnVIL after it has been shared with the consortium, investigators must have linked their AnVIL account in this app, and have approval via the correct PRIMED data access mechanism for data in the workspace.
More information can be found on the <a href="https://primedconsortium.org/members/research/getting-started-with-data">Getting Started with Data page</a>.
</p>

Expand Down
27 changes: 24 additions & 3 deletions primed/users/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,36 @@ class SocialAccountAdapter(DefaultSocialAccountAdapter):
def is_open_for_signup(self, request: HttpRequest, sociallogin: Any):
return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True)

def update_user_name(self, user, extra_data: Dict):
def update_user_info(self, user, extra_data: Dict):
drupal_username = extra_data.get("preferred_username")
drupal_email = extra_data.get("email")
first_name = extra_data.get("first_name")
last_name = extra_data.get("last_name")
full_name = " ".join(part for part in (first_name, last_name) if part)
user_changed = False
if user.name != full_name:
logger.info(
f"[SocialAccountAdatpter:update_user_name] user {user} name updated from {user.name} to {full_name}"
f"[SocialAccountAdatpter:update_user_name] user {user} "
f"name updated from {user.name} to {full_name}"
)
user.name = full_name
user_changed = True
if user.username != drupal_username:
logger.info(
f"[SocialAccountAdatpter:update_user_name] user {user} "
f"username updated from {user.username} to {drupal_username}"
)
user.username = drupal_username
user_changed = True
if user.email != drupal_email:
logger.info(
f"[SocialAccountAdatpter:update_user_name] user {user}"
f" email updated from {user.email} to {drupal_email}"
)
user.email = drupal_email
user_changed = True

if user_changed is True:
user.save()

def update_user_study_sites(self, user, extra_data: Dict):
Expand Down Expand Up @@ -116,6 +137,6 @@ def update_user_data(self, sociallogin: Any):
extra_data = sociallogin.account.extra_data
user = sociallogin.user

self.update_user_name(user, extra_data)
self.update_user_info(user, extra_data)
self.update_user_study_sites(user, extra_data)
self.update_user_groups(user, extra_data)
41 changes: 33 additions & 8 deletions primed/users/tests/test_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,61 @@ def test_drupal_social_login_adapter(self):
User = get_user_model()
user = User()
old_name = "Old Name"
setattr(user, account_settings.USER_MODEL_USERNAME_FIELD, "test")
setattr(user, "name", "Old Name")
setattr(user, account_settings.USER_MODEL_EMAIL_FIELD, "[email protected]")
old_username = "test"
old_email = "[email protected]"
setattr(user, account_settings.USER_MODEL_USERNAME_FIELD, old_username)
setattr(user, "name", old_name)
setattr(user, account_settings.USER_MODEL_EMAIL_FIELD, old_email)

account = SocialAccount(
provider="drupal_oauth_provider",
uid="123",
extra_data=dict(first_name="Old", last_name="Name"),
extra_data=dict(
first_name="Old",
last_name="Name",
email=old_email,
preferred_username=old_username,
),
)
sociallogin = SocialLogin(user=user, account=account)
complete_social_login(request, sociallogin)

user = User.objects.get(**{account_settings.USER_MODEL_USERNAME_FIELD: "test"})
user = User.objects.get(
**{account_settings.USER_MODEL_USERNAME_FIELD: old_username}
)
assert SocialAccount.objects.filter(user=user, uid=account.uid).exists() is True
assert user.name == old_name
assert user.username == old_username
assert user.email == old_email

def test_update_user_name(self):
def test_update_user_info(self):
adapter = SocialAccountAdapter()

User = get_user_model()
user = User()
new_name = "New Name"
new_first_name = "New"
new_last_name = "Name"
new_name = f"{new_first_name} {new_last_name}"
new_email = "[email protected]"
new_username = "newusername"
setattr(user, account_settings.USER_MODEL_USERNAME_FIELD, "test")
setattr(user, "name", "Old Name")
setattr(user, account_settings.USER_MODEL_EMAIL_FIELD, "[email protected]")

user.save()

adapter.update_user_name(user, dict(first_name="New", last_name="Name"))
adapter.update_user_info(
user,
dict(
first_name=new_first_name,
last_name=new_last_name,
email=new_email,
preferred_username=new_username,
),
)
assert user.name == new_name
assert user.email == new_email
assert user.username == new_username

def test_update_user_study_sites_add(self):
adapter = SocialAccountAdapter()
Expand Down
2 changes: 1 addition & 1 deletion requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ django-dbbackup==4.0.1 # https://github.com/jazzband/django-dbbackup
django-extensions==3.2.1 # https://github.com/django-extensions/django-extensions

# anvil_consortium_manager
git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.18
git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.19

# Simple history - model history tracking
django-simple-history==3.1.1
Expand Down