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/10/11 20:47:36 UTC

[airavata-django-portal] 01/01: AIRAVATA-3468 Separately check if username is invalid

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

commit 8aec6381bf8d18fa727c1254a24a417f190516a4
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Mon Oct 11 16:46:54 2021 -0400

    AIRAVATA-3468 Separately check if username is invalid
---
 .../static/django_airavata_api/js/models/User.js   |  1 +
 django_airavata/apps/auth/models.py                |  3 +-
 django_airavata/apps/auth/serializers.py           |  7 +++-
 .../js/components/UserProfileEditor.vue            | 38 +++++++++-------------
 .../js/containers/UserProfileContainer.vue         | 12 +++++--
 5 files changed, 34 insertions(+), 27 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 648721a..e414444 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
@@ -8,6 +8,7 @@ const FIELDS = [
   "email",
   "pending_email_change",
   "complete",
+  "username_valid"
 ];
 
 export default class User extends BaseModel {
diff --git a/django_airavata/apps/auth/models.py b/django_airavata/apps/auth/models.py
index a7480ff..92ea9ea 100644
--- a/django_airavata/apps/auth/models.py
+++ b/django_airavata/apps/auth/models.py
@@ -1,10 +1,10 @@
 import uuid
 
 from django.conf import settings
+from django.core.exceptions import ValidationError
 from django.db import models
 
 from . import forms
-from django.core.exceptions import ValidationError
 
 VERIFY_EMAIL_TEMPLATE = 1
 NEW_USER_EMAIL_TEMPLATE = 2
@@ -75,6 +75,7 @@ class UserProfile(models.Model):
             validates = True
         except ValidationError:
             validates = False
+        # TODO: should be valid if matching an old email address too
         return (validates or (self.is_email_valid and self.user.email == self.user.username))
 
     @property
diff --git a/django_airavata/apps/auth/serializers.py b/django_airavata/apps/auth/serializers.py
index 29e2ef9..2eac92a 100644
--- a/django_airavata/apps/auth/serializers.py
+++ b/django_airavata/apps/auth/serializers.py
@@ -24,10 +24,12 @@ class UserSerializer(serializers.ModelSerializer):
 
     pending_email_change = serializers.SerializerMethodField()
     complete = serializers.SerializerMethodField()
+    username_valid = serializers.SerializerMethodField()
 
     class Meta:
         model = get_user_model()
-        fields = ['id', 'username', 'first_name', 'last_name', 'email', 'pending_email_change', 'complete']
+        fields = ['id', 'username', 'first_name', 'last_name', 'email',
+                  'pending_email_change', 'complete', 'username_valid']
 
     def get_pending_email_change(self, instance):
         request = self.context['request']
@@ -41,6 +43,9 @@ class UserSerializer(serializers.ModelSerializer):
     def get_complete(self, instance):
         return instance.user_profile.is_complete
 
+    def get_username_valid(self, instance):
+        return instance.user_profile.is_username_valid
+
     @atomic
     def update(self, instance, validated_data):
         request = self.context['request']
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 a59050b..39447d1 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
@@ -1,32 +1,24 @@
 <template>
   <b-card>
-    <b-form-group label="Username">
-      <b-form-input
-        v-model="$v.user.username.$model"
-        :disabled="true"
-        :state="validateState($v.user.username)"
-      />
-      <b-form-invalid-feedback v-if="!$v.user.username.emailOrMatchesRegex">
-        Username can only contain lowercase letters, numbers, underscores and
-        hyphens OR it can be the same as the email address. Only an
-        administrator can update your username to a valid value.
-      </b-form-invalid-feedback>
+    <!-- TODO: add help text that only administrators can change a user's username -->
+    <b-form-group label="Username" :disabled="true">
+      <b-form-input v-model="user.username" />
     </b-form-group>
-    <b-form-group label="First Name">
+    <b-form-group label="First Name" :disabled="disabled">
       <b-form-input
         v-model="$v.user.first_name.$model"
         @keydown.native.enter="save"
         :state="validateState($v.user.first_name)"
       />
     </b-form-group>
-    <b-form-group label="Last Name">
+    <b-form-group label="Last Name" :disabled="disabled">
       <b-form-input
         v-model="$v.user.last_name.$model"
         @keydown.native.enter="save"
         :state="validateState($v.user.last_name)"
       />
     </b-form-group>
-    <b-form-group label="Email">
+    <b-form-group label="Email" :disabled="disabled">
       <b-form-input
         v-model="$v.user.email.$model"
         @keydown.native.enter="save"
@@ -45,7 +37,7 @@
         ></b-alert
       >
     </b-form-group>
-    <b-button variant="primary" @click="save" :disabled="$v.$invalid"
+    <b-button variant="primary" @click="save" :disabled="$v.$invalid || disabled"
       >Save</b-button
     >
   </b-card>
@@ -55,7 +47,7 @@
 import { models } from "django-airavata-api";
 import { errors } from "django-airavata-common-ui";
 import { validationMixin } from "vuelidate";
-import { email, helpers, or, required, sameAs } from "vuelidate/lib/validators";
+import { email, required } from "vuelidate/lib/validators";
 
 export default {
   name: "user-profile-editor",
@@ -65,9 +57,15 @@ export default {
       type: models.User,
       required: true,
     },
+    disabled: {
+      type: Boolean,
+      default: false,
+    },
   },
   created() {
-    this.$v.user.$touch();
+    if (!this.disabled) {
+      this.$v.user.$touch();
+    }
   },
   data() {
     return {
@@ -75,14 +73,8 @@ export default {
     };
   },
   validations() {
-    const usernameRegex = helpers.regex("username", /^[a-z0-9_-]+$/);
-    const emailOrMatchesRegex = or(usernameRegex, sameAs("email"));
     return {
       user: {
-        username: {
-          required,
-          emailOrMatchesRegex,
-        },
         first_name: {
           required,
         },
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 3a37faa..03f7b3f 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
@@ -1,16 +1,24 @@
 <template>
   <div>
     <h1 class="h4 mb-4">User Profile Editor</h1>
-    <b-alert :show="user && !user.complete"
+    <b-alert v-if="user && !user.username_valid" show variant="danger">
+      Unfortunately the username on your profile is invalid, which prevents
+      creating or updating your user profile. The administrators have been
+      notified and will be able to update your user account with a valid
+      username. Someone will notify you once your username has been updated to a
+      valid value.
+    </b-alert>
+    <b-alert v-else-if="user && !user.complete" show>
       >Please complete your user profile before continuing.</b-alert
     >
     <user-profile-editor
       v-if="user"
       v-model="user"
+      :disabled="!user.username_valid"
       @save="onSave"
       @resend-email-verification="resendEmailVerification"
     />
-    <b-link class="text-muted small" href="/workspace/dashboard"
+    <b-link v-if="user && user.complete" class="text-muted small" href="/workspace/dashboard"
       >Return to Dashboard</b-link
     >
   </div>