Skip to content

Commit

Permalink
Merge pull request #1970 from onaio/email-verification-issue
Browse files Browse the repository at this point in the history
Clear cache and refresh user profile on email verification
  • Loading branch information
DavisRayM committed Dec 17, 2020
2 parents 8178796 + c54dc72 commit 853883b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 26 deletions.
51 changes: 32 additions & 19 deletions onadata/apps/api/tests/viewsets/test_user_profile_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from onadata.libs.authentication import DigestAuthentication
from onadata.libs.serializers.user_profile_serializer import \
_get_first_last_names
from onadata.libs.utils.cache_tools import USER_PROFILE_PREFIX, safe_key


def _profile_data():
Expand Down Expand Up @@ -205,24 +204,6 @@ def test_profiles_get(self):
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, self.user_profile_data())

def test_retrieve_user_profile_from_cache(self):
"""
Test that user_profiles are cached on retrieve
"""
view = UserProfileViewSet.as_view({
'get': 'retrieve'
})

# clear cache
cache.delete(safe_key(f'{USER_PROFILE_PREFIX}bob'))

self.assertIsNone(cache.get(safe_key(f'{USER_PROFILE_PREFIX}bob')))

request = self.factory.get('/', **self.extra)
view(request, user='bob')

self.assertIsNotNone(cache.get(f'{USER_PROFILE_PREFIX}bob'))

def test_profiles_get_anon(self):
view = UserProfileViewSet.as_view({
'get': 'retrieve'
Expand Down Expand Up @@ -1208,6 +1189,38 @@ def test_monthly_submissions_with_year_param(self):
self.assertFalse(self.xform.shared)
self.assertEquals(response.data, {'private': count})

@override_settings(ENABLE_EMAIL_VERIFICATION=True)
@patch(
'onadata.apps.api.viewsets.user_profile_viewset.RegistrationProfile')
def test_reads_from_master(self, mock_rp_class):
"""
Test that on failure to retrieve a UserProfile in the first
try a second query is run on the master database
"""
data = _profile_data()
self._create_user_using_profiles_endpoint(data)

view = UserProfileViewSet.as_view({'get': 'verify_email'})
rp = RegistrationProfile.objects.get(
user__username=data.get('username')
)
_data = {'verification_key': rp.activation_key}
mock_rp_class.DoesNotExist = RegistrationProfile.DoesNotExist
mock_rp_class.objects.select_related(
'user', 'user__profile'
).get.side_effect = [RegistrationProfile.DoesNotExist, rp]
request = self.factory.get('/', data=_data)
response = view(request)
self.assertEquals(response.status_code, 200)
self.assertIn('is_email_verified', response.data)
self.assertIn('username', response.data)
self.assertTrue(response.data.get('is_email_verified'))
self.assertEquals(
response.data.get('username'), data.get('username'))
self.assertEqual(
mock_rp_class.objects.select_related(
'user', 'user__profile').get.call_count, 2)

def test_change_password_attempts(self):
view = UserProfileViewSet.as_view(
{'post': 'change_password'})
Expand Down
26 changes: 19 additions & 7 deletions onadata/apps/api/viewsets/user_profile_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from multidb.pinning import use_master

from onadata.apps.api.tasks import send_verification_email
from onadata.apps.api.permissions import UserProfilePermissions
Expand Down Expand Up @@ -100,7 +101,7 @@ def serializer_from_settings():


def set_is_email_verified(profile, is_email_verified):
profile.metadata.update({"is_email_verified": is_email_verified})
profile.metadata.update({'is_email_verified': is_email_verified})
profile.save()


Expand Down Expand Up @@ -214,7 +215,6 @@ def retrieve(self, request, *args, **kwargs):
return Response(cached_user)
response = super(UserProfileViewSet, self)\
.retrieve(request, *args, **kwargs)
cache.set(f'{USER_PROFILE_PREFIX}{username}', response.data)
return response

def create(self, request, *args, **kwargs):
Expand Down Expand Up @@ -337,19 +337,31 @@ def verify_email(self, request, *args, **kwargs):
verification_key = request.query_params.get('verification_key')
response_message = _("Missing or invalid verification key")
if verification_key:
rp = None
try:
rp = RegistrationProfile.objects.get(
activation_key=verification_key)
rp = RegistrationProfile.objects.select_related(
'user', 'user__profile').get(
activation_key=verification_key)
except RegistrationProfile.DoesNotExist:
pass
else:
with use_master:
try:
rp = RegistrationProfile.objects.select_related(
'user', 'user__profile').get(
activation_key=verification_key)
except RegistrationProfile.DoesNotExist:
pass

if rp:
rp.activation_key = verified_key_text
rp.save()

username = rp.user.username
set_is_email_verified(rp.user.profile, True)
# Clear profiles cache
safe_delete(f'{USER_PROFILE_PREFIX}{username}')

response_data = {
'username': rp.user.username,
'username': username,
'is_email_verified': True
}

Expand Down

0 comments on commit 853883b

Please sign in to comment.