You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2021/05/27 21:26:34 UTC
[airavata-django-portal] branch
AIRAVATA-3319-handle-missing-name-and-email-attributes-from-cilo updated:
AIRAVATA-3455 Add success notification when email changes
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch AIRAVATA-3319-handle-missing-name-and-email-attributes-from-cilo
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
The following commit(s) were added to refs/heads/AIRAVATA-3319-handle-missing-name-and-email-attributes-from-cilo by this push:
new 0c44921 AIRAVATA-3455 Add success notification when email changes
0c44921 is described below
commit 0c44921fb2e6dbbb7033895d043f67cf202bec01
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Thu May 27 16:48:24 2021 -0400
AIRAVATA-3455 Add success notification when email changes
---
.../static/django_airavata_api/js/models/User.js | 2 +-
.../django_airavata_api/js/service_config.js | 8 ++++
django_airavata/apps/auth/serializers.py | 8 ++--
.../js/components/UserProfileEditor.vue | 5 +++
.../js/containers/UserProfileContainer.vue | 31 ++++++++++++++--
django_airavata/apps/auth/urls.py | 2 -
django_airavata/apps/auth/views.py | 43 +++++++---------------
7 files changed, 59 insertions(+), 40 deletions(-)
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/User.js b/django_airavata/apps/api/static/django_airavata_api/js/models/User.js
index 1790a57..53cbf79 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/models/User.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/User.js
@@ -1,6 +1,6 @@
import BaseModel from "./BaseModel";
-const FIELDS = ["id", "username", "first_name", "last_name", "email"];
+const FIELDS = ["id", "username", "first_name", "last_name", "email", "pending_email_change"];
export default class User extends BaseModel {
constructor(data = {}) {
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/service_config.js b/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
index fb2392b..4d5d39b 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
@@ -382,6 +382,14 @@ export default {
url: "/auth/users/<lookup>/resend_email_verification/",
requestType: "post",
},
+ verifyEmailChange: {
+ url: "/auth/users/<lookup>/verify_email_change/",
+ requestType: "post",
+ bodyParams: {
+ name: "data",
+ },
+ modelClass: User,
+ },
},
modelClass: User,
},
diff --git a/django_airavata/apps/auth/serializers.py b/django_airavata/apps/auth/serializers.py
index d5134bb..f12854e 100644
--- a/django_airavata/apps/auth/serializers.py
+++ b/django_airavata/apps/auth/serializers.py
@@ -1,4 +1,5 @@
import logging
+from urllib.parse import urlencode
from django.conf import settings
from django.contrib.auth import get_user_model
@@ -60,10 +61,9 @@ class UserSerializer(serializers.ModelSerializer):
def _send_email_verification_link(self, request, pending_email_change):
- verification_uri = request.build_absolute_uri(
- reverse(
- 'django_airavata_auth:verify_email_change', kwargs={
- 'code': pending_email_change.verification_code}))
+ verification_uri = (
+ request.build_absolute_uri(reverse('django_airavata_auth:user_profile')) +
+ '?' + urlencode({"code": pending_email_change.verification_code}))
logger.debug(
"verification_uri={}".format(verification_uri))
diff --git a/django_airavata/apps/auth/static/django_airavata_auth/js/components/UserProfileEditor.vue b/django_airavata/apps/auth/static/django_airavata_auth/js/components/UserProfileEditor.vue
index c80a6d1..9ccd0fe 100644
--- a/django_airavata/apps/auth/static/django_airavata_auth/js/components/UserProfileEditor.vue
+++ b/django_airavata/apps/auth/static/django_airavata_auth/js/components/UserProfileEditor.vue
@@ -46,6 +46,11 @@ export default {
return JSON.parse(JSON.stringify(this.value));
},
},
+ watch: {
+ value() {
+ this.user = this.cloneValue();
+ }
+ }
};
</script>
diff --git a/django_airavata/apps/auth/static/django_airavata_auth/js/containers/UserProfileContainer.vue b/django_airavata/apps/auth/static/django_airavata_auth/js/containers/UserProfileContainer.vue
index e34e269..389b965 100644
--- a/django_airavata/apps/auth/static/django_airavata_auth/js/containers/UserProfileContainer.vue
+++ b/django_airavata/apps/auth/static/django_airavata_auth/js/containers/UserProfileContainer.vue
@@ -19,9 +19,16 @@ export default {
components: { UserProfileEditor },
name: "user-profile-container",
created() {
- services.UserService.current().then((user) => {
- this.user = user;
- });
+ services.UserService.current()
+ .then((user) => {
+ this.user = user;
+ })
+ .then(() => {
+ const queryParams = new URLSearchParams(window.location.search);
+ if (queryParams.has("code")) {
+ this.verifyEmailChange(queryParams.get("code"));
+ }
+ });
},
data() {
return {
@@ -50,6 +57,24 @@ export default {
);
});
},
+ verifyEmailChange(code) {
+ services.UserService.verifyEmailChange({
+ lookup: this.user.id,
+ data: { code: code },
+ }).then((user) => {
+ // User now updated with email change
+ this.user = user;
+ notifications.NotificationList.add(
+ new notifications.Notification({
+ type: "SUCCESS",
+ message: "Email address verified and updated",
+ duration: 5,
+ })
+ );
+ // Update URL, removing the code from the query string
+ window.history.replaceState({}, '', '/auth/user-profile/');
+ });
+ },
},
};
</script>
diff --git a/django_airavata/apps/auth/urls.py b/django_airavata/apps/auth/urls.py
index d8de4a2..887ed74 100644
--- a/django_airavata/apps/auth/urls.py
+++ b/django_airavata/apps/auth/urls.py
@@ -33,6 +33,4 @@ urlpatterns = [
url(r'^refreshed-token-desktop$', views.refreshed_token_desktop,
name="refreshed_token_desktop"),
url(r'^user-profile/', views.user_profile, name="user_profile"),
- url(r'^verify-email-change/(?P<code>[\w-]+)/$', views.verify_email_change,
- name="verify_email_change"),
]
diff --git a/django_airavata/apps/auth/views.py b/django_airavata/apps/auth/views.py
index 5261b07..dfa9c22 100644
--- a/django_airavata/apps/auth/views.py
+++ b/django_airavata/apps/auth/views.py
@@ -18,6 +18,7 @@ from django.views.decorators.debug import sensitive_variables
from requests_oauthlib import OAuth2Session
from rest_framework import permissions, viewsets
from rest_framework.decorators import action
+from rest_framework.response import Response
from django_airavata.apps.auth import serializers
@@ -553,41 +554,23 @@ class UserViewSet(viewsets.ModelViewSet):
serializer._send_email_verification_link(request, pending_email_change)
return JsonResponse({})
+ @action(methods=['post'], detail=True)
+ @atomic
+ def verify_email_change(self, request, pk=None):
+ user = self.get_object()
+ code = request.data['code']
-@login_required
-@atomic
-def verify_email_change(request, code):
- try:
- pending_email_change = models.PendingEmailChange.objects.get(user=request.user, verification_code=code)
+ pending_email_change = models.PendingEmailChange.objects.get(user=user, verification_code=code)
pending_email_change.verified = True
pending_email_change.save()
- request.user.email = pending_email_change.email_address
- request.user.save()
+ user.email = pending_email_change.email_address
+ user.save()
+ user.refresh_from_db()
user_profile_client = request.profile_service['user_profile']
airavata_user_profile = user_profile_client.getUserProfileById(
- request.authz_token, request.user.username, settings.GATEWAY_ID)
+ request.authz_token, user.username, settings.GATEWAY_ID)
airavata_user_profile.emails = [pending_email_change.email_address]
user_profile_client.updateUserProfile(request.authz_token, airavata_user_profile)
-
- # TODO: add success message
- return redirect(reverse('django_airavata_auth:user_profile'))
- except ObjectDoesNotExist:
- # if doesn't exist, give user a form where they can enter their
- # username to resend verification code
- logger.exception("PendingEmailChange object doesn't exist for "
- "code {}".format(code))
- # TODO: add error message
- # messages.error(
- # request,
- # "Email verification failed. Please enter your username and we "
- # "will send you another email verification link.")
- return redirect(reverse('django_airavata_auth:user_profile'))
- except Exception:
- logger.exception("Email change verification processing failed!")
- # TODO: add error message
- # messages.error(
- # request,
- # "Email verification failed. Please try clicking the email "
- # "verification link again later.")
- return redirect(reverse('django_airavata_auth:user_profile'))
+ serializer = self.get_serializer(user)
+ return Response(serializer.data)