From 5e494531eb93b52a2d1be98fcc25531509146eaa Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Fri, 3 Jun 2022 23:03:54 +0400 Subject: [PATCH] Add CloudUsersView --- .../models/cloud_organization_connector.py | 2 +- .../oss_installation/models/cloud_users.py | 2 +- engine/apps/oss_installation/urls.py | 3 +- .../apps/oss_installation/views/__init__.py | 1 + .../oss_installation/views/cloud_users.py | 53 +++++++++++++++++++ engine/apps/twilioapp/models/sms_message.py | 2 +- 6 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 engine/apps/oss_installation/views/cloud_users.py diff --git a/engine/apps/oss_installation/models/cloud_organization_connector.py b/engine/apps/oss_installation/models/cloud_organization_connector.py index 36316457..a142ddcb 100644 --- a/engine/apps/oss_installation/models/cloud_organization_connector.py +++ b/engine/apps/oss_installation/models/cloud_organization_connector.py @@ -102,7 +102,7 @@ class CloudOrganizationConnector(models.Model): i.email = cloud_users_identities_to_update[i.cloud_id]["email"] i.phone_number_verified = cloud_users_identities_to_update[i.cloud_id]["is_phone_number_verified"] - # TODO: Grafana Twilio: check if data validation needed. + # TODO: Grafana CN: check if data validation needed. CloudUserIdentity.objects.bulk_create(cloud_users_identities_to_create, batch_size=1000) CloudUserIdentity.objects.bulk_update( existing_cloud_identities, ["email", "phone_number_verified"], batch_size=1000 diff --git a/engine/apps/oss_installation/models/cloud_users.py b/engine/apps/oss_installation/models/cloud_users.py index cbef16c0..5eb87f91 100644 --- a/engine/apps/oss_installation/models/cloud_users.py +++ b/engine/apps/oss_installation/models/cloud_users.py @@ -10,5 +10,5 @@ class CloudUserIdentity(models.Model): ) class Meta: - # TODO: Grafana Twilio: Check if this constraint needed + # TODO: Grafana CN: Check if this constraint needed unique_together = ("cloud_id", "organization") diff --git a/engine/apps/oss_installation/urls.py b/engine/apps/oss_installation/urls.py index 956ffe74..cfa876e2 100644 --- a/engine/apps/oss_installation/urls.py +++ b/engine/apps/oss_installation/urls.py @@ -1,7 +1,8 @@ from common.api_helpers.optional_slash_router import optional_slash_path -from .views import CloudHeartbeatStatusView +from .views import CloudHeartbeatStatusView, CloudUsersView urlpatterns = [ optional_slash_path("cloud_heartbeat_status", CloudHeartbeatStatusView.as_view(), name="cloud_heartbeat_status"), + optional_slash_path("cloud_users", CloudUsersView.as_view(), name="cloud_users"), ] diff --git a/engine/apps/oss_installation/views/__init__.py b/engine/apps/oss_installation/views/__init__.py index 0716482b..98caf343 100644 --- a/engine/apps/oss_installation/views/__init__.py +++ b/engine/apps/oss_installation/views/__init__.py @@ -1 +1,2 @@ from .cloud_heartbeat_status import CloudHeartbeatStatusView # noqa: F401 +from .cloud_users import CloudUsersView # noqa: F401 diff --git a/engine/apps/oss_installation/views/cloud_users.py b/engine/apps/oss_installation/views/cloud_users.py new file mode 100644 index 00000000..a1f93343 --- /dev/null +++ b/engine/apps/oss_installation/views/cloud_users.py @@ -0,0 +1,53 @@ +from urllib.parse import urljoin + +from rest_framework.permissions import IsAuthenticated +from rest_framework.views import APIView + +from apps.auth_token.auth import PluginAuthentication +from apps.oss_installation.models import CloudOrganizationConnector, CloudUserIdentity +from apps.user_management.models import User +from common.api_helpers.paginators import HundredPageSizePaginator + + +class CloudUsersView(HundredPageSizePaginator, APIView): + authentication_classes = (PluginAuthentication,) + # TODO: Grafana CN - permissions, ratelimit + permission_classes = (IsAuthenticated,) + + def get(self, request): + queryset = User.objects.filter(organization=self.request.user.organization) + + if self.request.user.current_team is not None: + queryset = queryset.filter(teams=self.request.user.current_team).distinct() + + results = self.paginate_queryset(queryset, request, view=self) + + emails = list(queryset.values_list("email", flat=True)) + cloud_identities = list( + CloudUserIdentity.objects.filter(organization=self.request.user.organization, email__in=emails) + ) + cloud_identities = {cloud_identity.email: cloud_identity for cloud_identity in cloud_identities} + + response = [] + + connector = CloudOrganizationConnector.objects.first() + + for user in results: + cloud_identity = cloud_identities.get(user.email, None) + link = None + status = 0 + if cloud_identity: + status = 1 + is_phone_verified = cloud_identity.phone_number_verified + if is_phone_verified: + status = 2 + link = urljoin( + connector.cloud_url, f"a/grafana-oncall-app/?page=users&p=1&id={cloud_identity.cloud_id}" + ) + + # TODO: Grafana CN - decide if emails is needed. If yes - don't forget to check that they mustn't be shown to users + response.append( + {"id": user.public_primary_key, "username": user.username, "cloud_sync_status": status, "link": link} + ) + + return self.get_paginated_response(response) diff --git a/engine/apps/twilioapp/models/sms_message.py b/engine/apps/twilioapp/models/sms_message.py index 433419e5..c18dd7e8 100644 --- a/engine/apps/twilioapp/models/sms_message.py +++ b/engine/apps/twilioapp/models/sms_message.py @@ -41,7 +41,7 @@ class SMSMessageManager(models.Manager): sms_message = sms_message_qs.first() if sms_message.grafana_cloud_notification: - # If sms was sent via grafana twilio it is don't needed to create logs on it's delivery status. + # If sms was sent via grafana cloud notifications don't create logs on its delivery status. return log_record = None