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 2019/06/20 15:21:05 UTC
[airavata-django-portal] 01/06: AIRAVATA-3047 Separate service to
load users with unverified emails
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit cab1814f2c5da1938c06e753aba6727fcd0f2bc0
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Sat Jun 15 16:44:00 2019 -0400
AIRAVATA-3047 Separate service to load users with unverified emails
---
... => IdentityServiceUserManagementContainer.vue} | 19 +-
.../UnverifiedEmailUserManagementContainer.vue | 93 +++++++++
.../src/components/users/UserDetailsContainer.vue | 16 +-
.../components/users/UserManagementContainer.vue | 207 ++-------------------
.../static/django_airavata_admin/src/router.js | 12 +-
django_airavata/apps/api/serializers.py | 19 +-
.../api/static/django_airavata_api/js/index.js | 7 +-
.../{ManagedUserProfile.js => IAMUserProfile.js} | 2 +-
...serProfile.js => UnverifiedEmailUserProfile.js} | 11 +-
.../django_airavata_api/js/service_config.js | 16 +-
django_airavata/apps/api/urls.py | 6 +-
django_airavata/apps/api/views.py | 80 ++++++--
12 files changed, 249 insertions(+), 239 deletions(-)
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserManagementContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/IdentityServiceUserManagementContainer.vue
similarity index 91%
copy from django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserManagementContainer.vue
copy to django_airavata/apps/admin/static/django_airavata_admin/src/components/users/IdentityServiceUserManagementContainer.vue
index 92e5c25..dba6213 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserManagementContainer.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/IdentityServiceUserManagementContainer.vue
@@ -2,11 +2,6 @@
<div>
<div class="row">
<div class="col">
- <h1 class="h4 mb-4">Manage Users</h1>
- </div>
- </div>
- <div class="row">
- <div class="col">
<div class="card">
<div class="card-body">
<b-input-group>
@@ -57,7 +52,7 @@
slot-scope="data"
>
<user-details-container
- :managed-user-profile="data.item"
+ :iam-user-profile="data.item"
:editable-groups="editableGroups"
@groups-updated="groupsUpdated"
/>
@@ -96,7 +91,7 @@ export default {
UserDetailsContainer
},
created() {
- services.ManagedUserProfileService.list({ limit: 10 }).then(
+ services.IAMUserProfileService.list({ limit: 10 }).then(
users => (this.usersPaginator = users)
);
services.GroupService.list({ limit: -1 }).then(
@@ -166,10 +161,10 @@ export default {
previous() {
this.usersPaginator.previous();
},
- groupsUpdated(managedUserProfile) {
- services.ManagedUserProfileService.update({
- lookup: managedUserProfile.userId,
- data: managedUserProfile
+ groupsUpdated(user) {
+ services.IAMUserProfileService.update({
+ lookup: user.userId,
+ data: user
}).finally(() => {
this.reloadUserProfiles();
});
@@ -182,7 +177,7 @@ export default {
if (this.search) {
params["search"] = this.search;
}
- services.ManagedUserProfileService.list(params).then(
+ services.IAMUserProfileService.list(params).then(
users => (this.usersPaginator = users)
);
},
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UnverifiedEmailUserManagementContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UnverifiedEmailUserManagementContainer.vue
new file mode 100644
index 0000000..5cb7edd
--- /dev/null
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UnverifiedEmailUserManagementContainer.vue
@@ -0,0 +1,93 @@
+<template>
+ <div>
+ <div class="row">
+ <div class="col">
+ <div class="card">
+ <div class="card-body">
+ <b-table
+ hover
+ :fields="fields"
+ :items="items"
+ >
+ <template
+ slot="creationTime"
+ slot-scope="data">
+ <human-date :date="data.value"/>
+ </template>
+ </b-table>
+ <pager
+ v-bind:paginator="usersPaginator"
+ v-on:next="next"
+ v-on:previous="previous"
+ ></pager>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+<script>
+import { components } from "django-airavata-common-ui";
+import { services } from "django-airavata-api";
+export default {
+ name: "unverified-email-user-management-container",
+ data() {
+ return {
+ usersPaginator: null,
+ };
+ },
+ components: {
+ pager: components.Pager,
+ 'human-date': components.HumanDate,
+ },
+ created() {
+ services.UnverifiedEmailUserProfileService.list({ limit: 10 }).then(
+ users => (this.usersPaginator = users)
+ );
+ },
+ computed: {
+ fields() {
+ return [
+ {
+ label: "First Name",
+ key: "firstName"
+ },
+ {
+ label: "Last Name",
+ key: "lastName"
+ },
+ {
+ label: "Username",
+ key: "userId"
+ },
+ {
+ label: "Email",
+ key: "email"
+ },
+ {
+ label: "Email Verified",
+ key: "emailVerified"
+ },
+ {
+ label: "Created",
+ key: "creationTime"
+ },
+ ];
+ },
+ items() {
+ return this.usersPaginator
+ ? this.usersPaginator.results
+ : [];
+ },
+ },
+ methods: {
+ next() {
+ this.usersPaginator.next();
+ },
+ previous() {
+ this.usersPaginator.previous();
+ },
+ }
+};
+</script>
+
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserDetailsContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserDetailsContainer.vue
index 33f96c5..18ce57f 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserDetailsContainer.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserDetailsContainer.vue
@@ -1,8 +1,8 @@
<template>
<user-group-membership-editor
- v-model="localManagedUserProfile.groups"
+ v-model="localIAMUserProfile.groups"
:editable-groups="editableGroups"
- :airavata-internal-user-id="managedUserProfile.airavataInternalUserId"
+ :airavata-internal-user-id="iamUserProfile.airavataInternalUserId"
@input="groupsUpdated"
/>
</template>
@@ -13,8 +13,8 @@ import UserGroupMembershipEditor from "./UserGroupMembershipEditor";
export default {
name: "user-details-container",
props: {
- managedUserProfile: {
- type: models.ManagedUserProfile,
+ iamUserProfile: {
+ type: models.IAMUserProfile,
required: true
},
editableGroups: {
@@ -27,17 +27,17 @@ export default {
},
data() {
return {
- localManagedUserProfile: this.managedUserProfile.clone()
+ localIAMUserProfile: this.iamUserProfile.clone()
};
},
watch: {
- managedUserProfile(newValue) {
- this.localManagedUserProfile = newValue.clone();
+ iamUserProfile(newValue) {
+ this.localIAMUserProfile = newValue.clone();
}
},
methods: {
groupsUpdated() {
- this.$emit("groups-updated", this.localManagedUserProfile);
+ this.$emit("groups-updated", this.localIAMUserProfile);
}
}
};
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserManagementContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserManagementContainer.vue
index 92e5c25..be47876 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserManagementContainer.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/UserManagementContainer.vue
@@ -1,205 +1,38 @@
<template>
<div>
<div class="row">
- <div class="col">
+ <div class="col-auto mr-auto">
<h1 class="h4 mb-4">Manage Users</h1>
</div>
- </div>
- <div class="row">
- <div class="col">
- <div class="card">
- <div class="card-body">
- <b-input-group>
- <b-form-input
- v-model="search"
- placeholder="Search by name, email or username"
- @keydown.native.enter="searchUsers"
- />
- <b-input-group-append>
- <b-button @click="resetSearch">Reset</b-button>
- <b-button
- variant="primary"
- @click="searchUsers"
- >Search</b-button>
- </b-input-group-append>
- </b-input-group>
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col">
- <div class="card">
- <div class="card-body">
- <b-table
- hover
- :fields="fields"
- :items="items"
- >
- <template
- slot="creationTime"
- slot-scope="data">
- <human-date :date="data.value"/>
- </template>
- <template
- slot="action"
- slot-scope="data"
- >
- <b-button
- v-if="data.item.airavataUserProfileExists"
- @click="toggleDetails(data)"
- >
- Edit Groups
- </b-button>
- </template>
- <template
- slot="row-details"
- slot-scope="data"
- >
- <user-details-container
- :managed-user-profile="data.item"
- :editable-groups="editableGroups"
- @groups-updated="groupsUpdated"
- />
- </template>
- </b-table>
- <pager
- v-bind:paginator="usersPaginator"
- v-on:next="next"
- v-on:previous="previous"
- ></pager>
- </div>
- </div>
+ <div class="col-auto">
+ <b-dropdown :text="menuText">
+ <b-dropdown-item
+ :to="{ name: 'identity-service-users'}"
+ :exact="true"
+ >Identity Service</b-dropdown-item>
+ <b-dropdown-item
+ :to="{ name: 'unverified-email-users'}"
+ :exact="true"
+ >Unverified Emails</b-dropdown-item>
+ </b-dropdown>
</div>
</div>
+ <router-view></router-view>
</div>
</template>
<script>
-import { services } from "django-airavata-api";
-import { components } from "django-airavata-common-ui";
-import UserDetailsContainer from "./UserDetailsContainer.vue";
-
export default {
name: "user-management-container",
- data() {
- return {
- usersPaginator: null,
- allGroups: null,
- showingDetails: {},
- search: null
- };
- },
- components: {
- pager: components.Pager,
- 'human-date': components.HumanDate,
- UserDetailsContainer
- },
- created() {
- services.ManagedUserProfileService.list({ limit: 10 }).then(
- users => (this.usersPaginator = users)
- );
- services.GroupService.list({ limit: -1 }).then(
- groups => (this.allGroups = groups)
- );
- },
computed: {
- fields() {
- return [
- {
- label: "First Name",
- key: "firstName"
- },
- {
- label: "Last Name",
- key: "lastName"
- },
- {
- label: "Username",
- key: "userId"
- },
- {
- label: "Email",
- key: "email"
- },
- {
- label: "Enabled",
- key: "enabled"
- },
- {
- label: "Email Verified",
- key: "emailVerified"
- },
- {
- label: "Created",
- key: "creationTime"
- },
- {
- label: "Action",
- key: "action"
- }
- ];
- },
- items() {
- return this.usersPaginator
- ? this.usersPaginator.results.map(u => {
- const user = u.clone();
- user._showDetails =
- this.showingDetails[u.airavataInternalUserId] || false;
- return user;
- })
- : [];
- },
- editableGroups() {
- return this.allGroups
- ? this.allGroups.filter(g => g.isAdmin || g.isOwner)
- : [];
- },
- currentOffset() {
- return this.usersPaginator ? this.usersPaginator.offset : 0;
- }
- },
- methods: {
- next() {
- this.usersPaginator.next();
- },
- previous() {
- this.usersPaginator.previous();
- },
- groupsUpdated(managedUserProfile) {
- services.ManagedUserProfileService.update({
- lookup: managedUserProfile.userId,
- data: managedUserProfile
- }).finally(() => {
- this.reloadUserProfiles();
- });
- },
- reloadUserProfiles() {
- const params = {
- limit: 10,
- offset: this.currentOffset
- };
- if (this.search) {
- params["search"] = this.search;
+ menuText() {
+ if (this.$route.name === "identity-service-users") {
+ return "Identity Service";
+ } else if (this.$route.name === "unverified-email-users") {
+ return "Unverified Emails";
+ } else {
+ return "Menu";
}
- services.ManagedUserProfileService.list(params).then(
- users => (this.usersPaginator = users)
- );
- },
- toggleDetails(row) {
- row.toggleDetails();
- this.showingDetails[row.item.airavataInternalUserId] = !this
- .showingDetails[row.item.airavataInternalUserId];
- },
- searchUsers() {
- // Reset paginator when starting a search
- this.usersPaginator = null;
- this.reloadUserProfiles();
- },
- resetSearch() {
- this.usersPaginator = null;
- this.search = null;
- this.reloadUserProfiles();
}
}
};
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/router.js b/django_airavata/apps/admin/static/django_airavata_admin/src/router.js
index b4070d4..8cf1357 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/router.js
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/router.js
@@ -10,6 +10,8 @@ import ExperimentStatisticsContainer from "./components/statistics/ExperimentSta
import CredentialStoreDashboard from "./components/dashboards/CredentialStoreDashboard";
import GatewayResourceProfileEditorContainer from "./components/gatewayprofile/GatewayResourceProfileEditorContainer.vue";
import GroupComputeResourcePreference from "./components/admin/group_resource_preferences/GroupComputeResourcePreference";
+import IdentityServiceUserManagementContainer from "./components/users/IdentityServiceUserManagementContainer.vue";
+import UnverifiedEmailUserManagementContainer from "./components/users/UnverifiedEmailUserManagementContainer.vue";
import UserManagementContainer from "./components/users/UserManagementContainer.vue";
import VueRouter from "vue-router";
@@ -122,7 +124,15 @@ const routes = [
{
path: "/users",
component: UserManagementContainer,
- name: "users"
+ name: "users",
+ children: [
+ { path: "", component: IdentityServiceUserManagementContainer, name: "identity-service-users" },
+ {
+ path: "unverified-email",
+ component: UnverifiedEmailUserManagementContainer,
+ name: "unverified-email-users"
+ }
+ ]
},
{
path: "/experiment-statistics",
diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py
index a33287d..94a9f2b 100644
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@ -828,7 +828,7 @@ class WorkspacePreferencesSerializer(serializers.ModelSerializer):
exclude = ('username',)
-class ManagedUserProfile(serializers.Serializer):
+class IAMUserProfile(serializers.Serializer):
airavataInternalUserId = serializers.CharField()
userId = serializers.CharField()
gatewayId = serializers.CharField()
@@ -841,7 +841,7 @@ class ManagedUserProfile(serializers.Serializer):
creationTime = UTCPosixTimestampDateTimeField()
groups = GroupSerializer(many=True)
url = FullyEncodedHyperlinkedIdentityField(
- view_name='django_airavata_api:managed-user-profile-detail',
+ view_name='django_airavata_api:iam-user-profile-detail',
lookup_field='userId',
lookup_url_kwarg='user_id')
@@ -863,3 +863,18 @@ class ExperimentStatisticsSerializer(
cancelledExperiments = ExperimentSummarySerializer(many=True)
createdExperiments = ExperimentSummarySerializer(many=True)
runningExperiments = ExperimentSummarySerializer(many=True)
+
+
+class UnverifiedEmailUserProfile(serializers.Serializer):
+ userId = serializers.CharField()
+ gatewayId = serializers.CharField()
+ email = serializers.CharField()
+ firstName = serializers.CharField()
+ lastName = serializers.CharField()
+ enabled = serializers.BooleanField()
+ emailVerified = serializers.BooleanField()
+ creationTime = UTCPosixTimestampDateTimeField()
+ url = FullyEncodedHyperlinkedIdentityField(
+ view_name='django_airavata_api:unverified-email-user-profile-detail',
+ lookup_field='userId',
+ lookup_url_kwarg='user_id')
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/index.js b/django_airavata/apps/api/static/django_airavata_api/js/index.js
index a43fecf..9edc7d9 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/index.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/index.js
@@ -21,6 +21,7 @@ import Group from "./models/Group";
import GroupComputeResourcePreference from "./models/GroupComputeResourcePreference";
import GroupPermission from "./models/GroupPermission";
import GroupResourceProfile from "./models/GroupResourceProfile";
+import IAMUserProfile from "./models/IAMUserProfile";
import InputDataObjectType from "./models/InputDataObjectType";
import JobState from "./models/JobState";
import ManagedUserProfile from "./models/ManagedUserProfile";
@@ -77,6 +78,7 @@ const models = {
GroupComputeResourcePreference,
GroupPermission,
GroupResourceProfile,
+ IAMUserProfile,
InputDataObjectType,
JobState,
ManagedUserProfile,
@@ -113,7 +115,7 @@ const services = {
GroupResourceProfileService: ServiceFactory.service("GroupResourceProfiles"),
GroupService: ServiceFactory.service("Groups"),
LocaJobSubmissionService,
- ManagedUserProfileService: ServiceFactory.service("ManagedUserProfiles"),
+ IAMUserProfileService: ServiceFactory.service("IAMUserProfiles"),
ParserService: ServiceFactory.service("Parsers"),
ProjectService: ServiceFactory.service("Projects"),
SCPDataMovementService,
@@ -124,6 +126,9 @@ const services = {
StorageResourceService: ServiceFactory.service("StorageResources"),
UnicoreDataMovementService,
UnicoreJobSubmissionService,
+ UnverifiedEmailUserProfileService: ServiceFactory.service(
+ "UnverifiedEmailUsers"
+ ),
UserProfileService,
UserStoragePathService: ServiceFactory.service("UserStoragePaths"),
WorkspacePreferencesService: ServiceFactory.service("WorkspacePreferences")
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/ManagedUserProfile.js b/django_airavata/apps/api/static/django_airavata_api/js/models/IAMUserProfile.js
similarity index 87%
copy from django_airavata/apps/api/static/django_airavata_api/js/models/ManagedUserProfile.js
copy to django_airavata/apps/api/static/django_airavata_api/js/models/IAMUserProfile.js
index 3c87783..2b2e6f5 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/models/ManagedUserProfile.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/IAMUserProfile.js
@@ -23,7 +23,7 @@ const FIELDS = [
}
];
-export default class ManagedUserProfile extends BaseModel {
+export default class IAMUserProfile extends BaseModel {
constructor(data = {}) {
super(FIELDS, data);
}
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/ManagedUserProfile.js b/django_airavata/apps/api/static/django_airavata_api/js/models/UnverifiedEmailUserProfile.js
similarity index 53%
rename from django_airavata/apps/api/static/django_airavata_api/js/models/ManagedUserProfile.js
rename to django_airavata/apps/api/static/django_airavata_api/js/models/UnverifiedEmailUserProfile.js
index 3c87783..1b1b59b 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/models/ManagedUserProfile.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/UnverifiedEmailUserProfile.js
@@ -1,9 +1,6 @@
import BaseModel from "./BaseModel";
-import Group from "./Group";
const FIELDS = [
- "userModelVersion",
- "airavataInternalUserId",
"userId",
"gatewayId",
"email",
@@ -11,19 +8,13 @@ const FIELDS = [
"lastName",
"enabled",
"emailVerified",
- "airavataUserProfileExists",
{
name: "creationTime",
type: 'date',
},
- {
- name: "groups",
- type: Group,
- list: true
- }
];
-export default class ManagedUserProfile extends BaseModel {
+export default class UnverifiedEmailUserProfile extends BaseModel {
constructor(data = {}) {
super(FIELDS, 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 ef94c66..ed76e06 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
@@ -13,12 +13,13 @@ import FullExperiment from "./models/FullExperiment";
import GatewayResourceProfile from "./models/GatewayResourceProfile";
import Group from "./models/Group";
import GroupResourceProfile from "./models/GroupResourceProfile";
-import ManagedUserProfile from "./models/ManagedUserProfile";
+import IAMUserProfile from "./models/IAMUserProfile";
import Parser from "./models/Parser";
import Project from "./models/Project";
import SharedEntity from "./models/SharedEntity";
import StoragePreference from "./models/StoragePreference";
import StorageResourceDescription from "./models/StorageResourceDescription";
+import UnverifiedEmailUserProfile from "./models/UnverifiedEmailUserProfile";
import UserProfile from "./models/UserProfile";
import UserStoragePath from "./models/UserStoragePath";
import WorkspacePreferences from "./models/WorkspacePreferences";
@@ -239,12 +240,12 @@ export default {
queryParams: ["limit", "offset"],
modelClass: Group
},
- ManagedUserProfiles: {
- url: "/api/managed-user-profiles",
+ IAMUserProfiles: {
+ url: "/api/iam-user-profiles",
viewSet: true,
pagination: true,
queryParams: ["limit", "offset", "search"],
- modelClass: ManagedUserProfile
+ modelClass: IAMUserProfile
},
Parsers: {
url: "/api/parsers",
@@ -297,6 +298,13 @@ export default {
},
modelClass: StorageResourceDescription
},
+ UnverifiedEmailUsers: {
+ url: "/api/unverified-email-users",
+ viewSet: true,
+ pagination: true,
+ queryParams: ["limit", "offset"],
+ modelClass: UnverifiedEmailUserProfile
+ },
UserProfiles: {
url: "/api/user-profiles",
viewSet: ["list"],
diff --git a/django_airavata/apps/api/urls.py b/django_airavata/apps/api/urls.py
index 267da92..18d66ea 100644
--- a/django_airavata/apps/api/urls.py
+++ b/django_airavata/apps/api/urls.py
@@ -41,8 +41,10 @@ router.register(r'storage-preferences',
views.StoragePreferenceViewSet,
base_name='storage-preference')
router.register(r'parsers', views.ParserViewSet, base_name='parser')
-router.register(r'managed-user-profiles', views.ManagedUserViewSet,
- base_name='managed-user-profile')
+router.register(r'iam-user-profiles', views.IAMUserViewSet,
+ base_name='iam-user-profile')
+router.register(r'unverified-email-users', views.UnverifiedEmailUserViewSet,
+ base_name='unverified-email-user-profile')
app_name = 'django_airavata_api'
urlpatterns = [
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index e13bdd6..135f112 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -40,6 +40,7 @@ from django_airavata.apps.api.view_utils import (
GenericAPIBackedViewSet
)
from django_airavata.apps.auth import iam_admin_client
+from django_airavata.apps.auth.models import EmailVerification
from . import (
data_products_helper,
@@ -1384,12 +1385,12 @@ class WorkspacePreferencesView(APIView):
return Response(serializer.data)
-class ManagedUserViewSet(mixins.CreateModelMixin,
- mixins.RetrieveModelMixin,
- mixins.UpdateModelMixin,
- mixins.ListModelMixin,
- GenericAPIBackedViewSet):
- serializer_class = serializers.ManagedUserProfile
+class IAMUserViewSet(mixins.CreateModelMixin,
+ mixins.RetrieveModelMixin,
+ mixins.UpdateModelMixin,
+ mixins.ListModelMixin,
+ GenericAPIBackedViewSet):
+ serializer_class = serializers.IAMUserProfile
pagination_class = APIResultPagination
lookup_field = 'user_id'
@@ -1398,11 +1399,11 @@ class ManagedUserViewSet(mixins.CreateModelMixin,
convert_user_profile = self._convert_user_profile
- class ManagedUsersResultIterator(APIResultIterator):
+ class IAMUsersResultIterator(APIResultIterator):
def get_results(self, limit=-1, offset=0):
return map(convert_user_profile,
iam_admin_client.get_users(offset, limit, search))
- return ManagedUsersResultIterator()
+ return IAMUsersResultIterator()
def get_instance(self, lookup_value):
return self._convert_user_profile(
@@ -1435,9 +1436,9 @@ class ManagedUserViewSet(mixins.CreateModelMixin,
'email': user_profile.emails[0],
'firstName': user_profile.firstName,
'lastName': user_profile.lastName,
- # TODO: fix this to distinguish between enabled and emailVerified
- 'enabled': user_profile.State == Status.CONFIRMED,
- 'emailVerified': user_profile.State == Status.CONFIRMED,
+ 'enabled': user_profile.State == Status.ACTIVE,
+ 'emailVerified': (user_profile.State == Status.CONFIRMED or
+ user_profile.State == Status.ACTIVE),
'airavataUserProfileExists': airavata_user_profile_exists,
'creationTime': user_profile.creationTime,
'groups': groups
@@ -1469,3 +1470,60 @@ class ExperimentStatisticsView(APIView):
serializer = self.serializer_class(
statistics, context={'request': request})
return Response(serializer.data)
+
+
+class UnverifiedEmailUserViewSet(mixins.ListModelMixin,
+ mixins.RetrieveModelMixin,
+ GenericAPIBackedViewSet):
+ serializer_class = serializers.UnverifiedEmailUserProfile
+ pagination_class = APIResultPagination
+ lookup_field = 'user_id'
+
+ def get_list(self):
+ get_users = self._get_unverified_email_user_profiles
+
+ class UnverifiedEmailUsersResultIterator(APIResultIterator):
+ def get_results(self, limit=-1, offset=0):
+ return get_users(limit, offset)
+ return UnverifiedEmailUsersResultIterator()
+
+ def get_instance(self, lookup_value):
+ users = self._get_unverified_email_user_profiles(
+ limit=1, username=lookup_value)
+ if len(users) == 0:
+ raise Http404("No unverified email record found for user {}"
+ .format(lookup_value))
+ else:
+ return users[0]
+
+ def _get_unverified_email_user_profiles(
+ self, limit=-1, offset=0, username=None):
+ unverified_emails = EmailVerification.objects.filter(
+ verified=False).order_by('username').values('username').distinct()
+ if username is not None:
+ unverified_emails = unverified_emails.filter(username=username)
+ if limit > 0:
+ unverified_emails = unverified_emails[offset:offset+limit]
+ results = []
+ for unverified_email in unverified_emails:
+ username = unverified_email['username']
+ user_profile = iam_admin_client.get_user(username)
+ if (user_profile.State == Status.CONFIRMED or
+ user_profile.State == Status.ACTIVE):
+ # TODO: test this
+ EmailVerification.objects.filter(
+ username=username).update(
+ verified=True)
+ continue
+ results.append({
+ 'userId': user_profile.userId,
+ 'gatewayId': user_profile.gatewayId,
+ 'email': user_profile.emails[0],
+ 'firstName': user_profile.firstName,
+ 'lastName': user_profile.lastName,
+ 'enabled': user_profile.State == Status.ACTIVE,
+ 'emailVerified': (user_profile.State == Status.CONFIRMED or
+ user_profile.State == Status.ACTIVE),
+ 'creationTime': user_profile.creationTime,
+ })
+ return results