Skip to content

Commit

Permalink
Merge pull request #689 from basedosdados/feat/change-user-gcp-email
Browse files Browse the repository at this point in the history
Feat/change user gcp email
  • Loading branch information
jhonylucas74 authored Sep 30, 2024
2 parents 5c7c264 + 559610d commit 45e3af1
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 14 deletions.
20 changes: 20 additions & 0 deletions backend/apps/account/migrations/0018_account_gcp_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 4.2.16 on 2024-09-29 22:44

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("account", "0017_account_available_for_research_and_more"),
]

operations = [
migrations.AddField(
model_name="account",
name="gcp_email",
field=models.EmailField(
blank=True, max_length=254, null=True, verbose_name="GCP email"
),
),
]
1 change: 1 addition & 0 deletions backend/apps/account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ class Account(BaseModel, AbstractBaseUser, PermissionsMixin):
uuid = models.UUIDField(primary_key=False, default=uuid4)

email = models.EmailField("Email", unique=True)
gcp_email = models.EmailField("GCP email", null=True, blank=True) # Google Cloud Platform email
username = models.CharField("Username", max_length=40, blank=True, null=True, unique=True)

first_name = models.CharField("Nome", max_length=40, blank=True)
Expand Down
2 changes: 1 addition & 1 deletion backend/apps/account/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def create_subscription(user: Account):
customer.subscriber = user
customer.save()
# Add user to Google Group
add_user(user.email)
add_user(user.gcp_email or user.email)


@receiver(post_save, sender=Account)
Expand Down
63 changes: 60 additions & 3 deletions backend/apps/account_payment/graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from stripe import SetupIntent

from backend.apps.account.models import Account, Subscription
from backend.apps.account_payment.webhooks import add_user, remove_user
from backend.apps.account_payment.webhooks import add_user, is_email_in_group, remove_user
from backend.custom.environment import get_backend_url
from backend.custom.graphql_base import CountableConnection, PlainTextNode

Expand Down Expand Up @@ -384,7 +384,7 @@ def mutate(cls, root, info, account_id, subscription_id):

subscription = Subscription.objects.get(id=subscription_id)
assert admin.id == subscription.admin.id
add_user(account.email)
add_user(account.gcp_email or account.email)
subscription.subscribers.add(account)
return cls(ok=True)
except Exception as e:
Expand All @@ -410,14 +410,69 @@ def mutate(cls, root, info, account_id, subscription_id):
account = Account.objects.get(id=account_id)
subscription = Subscription.objects.get(id=subscription_id)
assert admin.id == subscription.admin.id
remove_user(account.email)
remove_user(account.gcp_email or account.email)
subscription.subscribers.remove(account)
return cls(ok=True)
except Exception as e:
logger.error(e)
return cls(errors=[str(e)])


class ChangeUserGCPEmail(Mutation):
"""Change user GCP email"""

ok = Boolean()
errors = List(String)

class Arguments:
email = String(required=True)

@classmethod
@login_required
def mutate(cls, root, info, email):
try:
user = info.context.user
old_email = user.gcp_email or user.email

if old_email == email:
return cls(ok=True)

user.gcp_email = email
user.save()

if is_email_in_group(old_email):
remove_user(old_email)

subscription = user.pro_subscription()
if subscription and not is_email_in_group(email):
add_user(email)

return cls(ok=True)
except Exception as e:
logger.error(e)
return cls(errors=[str(e)])


# Query to check based on a email if the user is in a group
class IsEmailInGoogleGroup(Mutation):
"""Check if user is in group"""

ok = Boolean()
errors = List(String)

class Arguments:
email = String(required=True)

@classmethod
@login_required
def mutate(cls, root, info, email):
try:
return cls(ok=is_email_in_group(email))
except Exception as e:
logger.error(e)
return cls(errors=[str(e)])


def get_stripe_promo(promotion_code):
"""
Helper function to retrieve a Stripe Promotion Code by its code.
Expand All @@ -443,6 +498,7 @@ def get_stripe_promo(promotion_code):
class Query(ObjectType):
stripe_price = PlainTextNode.Field(StripePriceNode)
all_stripe_price = DjangoFilterConnectionField(StripePriceNode)
is_email_in_google_group = IsEmailInGoogleGroup.Field()


class Mutation(ObjectType):
Expand All @@ -453,6 +509,7 @@ class Mutation(ObjectType):
create_stripe_customer_subscription = StripeSubscriptionCustomerCreateMutation.Field()
update_stripe_customer_subscription = StripeSubscriptionCustomerDeleteMutation.Field()
validate_stripe_coupon = StripeCouponValidationMutation.Field()
change_user_gcp_email = ChangeUserGCPEmail.Field()


# Reference
Expand Down
68 changes: 58 additions & 10 deletions backend/apps/account_payment/webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from stripe import Customer as StripeCustomer
from stripe import Subscription as StripeSubscription

from backend.apps.account.models import Subscription
from backend.apps.account.models import Account, Subscription
from backend.custom.client import send_discord_message as send
from backend.custom.environment import get_backend_url

Expand Down Expand Up @@ -110,6 +110,31 @@ def list_user(group_key: str = None):
raise e


def is_email_in_group(email: str, group_key: str = None) -> bool:
"""Check if a user is in a Google group."""
if not group_key:
group_key = settings.GOOGLE_DIRECTORY_GROUP_KEY
if "+" in email and email.index("+") < email.index("@"):
email = email.split("+")[0] + "@" + email.split("@")[1]

try:
service = get_service()
service.members().get(
groupKey=group_key,
memberKey=email,
).execute()
return True
except HttpError as e:
if e.resp.status == 404:
return False
else:
logger.error(f"Erro ao verificar o usuário {email} no grupo {group_key}: {e}")
raise e
except Exception as e:
logger.error(f"Erro inesperado ao verificar o usuário {email}: {e}")
raise e


@webhooks.handler("customer.updated")
def update_customer(event: Event, **kwargs):
"""Propagate customer email update if exists"""
Expand All @@ -123,21 +148,29 @@ def update_customer(event: Event, **kwargs):
def handle_subscription(event: Event):
"""Handle subscription status"""
subscription = get_subscription(event)
account = Account.objects.filter(email=event.customer.email).first()

if event.data["object"]["status"] in ["trialing", "active"]:
if subscription:
logger.info(f"Adicionando a inscrição do cliente {event.customer.email}")
subscription.is_active = True
subscription.save()

# Add user to google group if subscription exists or not
add_user(event.customer.email)
if account:
add_user(account.gcp_email or account.email)
else:
add_user(event.customer.email)
else:
if subscription:
logger.info(f"Removendo a inscrição do cliente {event.customer.email}")
subscription.is_active = False
subscription.save()
# Remove user from google group if subscription exists or not
remove_user(event.customer.email)
if account:
remove_user(account.gcp_email or account.email)
else:
remove_user(event.customer.email)


@webhooks.handler("customer.subscription.updated")
Expand All @@ -159,39 +192,54 @@ def unsubscribe(event: Event, **kwargs):
logger.info(f"Removendo a inscrição do cliente {event.customer.email}")
subscription.is_active = False
subscription.save()

account = Account.objects.filter(email=event.customer.email).first()
# Remove user from google group if subscription exists or not
try:
remove_user(event.customer.email)
if account:
remove_user(account.gcp_email or account.email)
else:
remove_user(event.customer.email)
except Exception as e:
logger.error(e)


@webhooks.handler("customer.subscription.paused")
def pause_subscription(event: Event, **kwargs):
"""Pause customer subscription"""
account = Account.objects.filter(email=event.customer.email).first()

if subscription := get_subscription(event):
logger.info(f"Pausando a inscrição do cliente {event.customer.email}")
subscription.is_active = False
subscription.save()

try:
try:
if account:
remove_user(account.gcp_email or account.email)
else:
remove_user(event.customer.email)
except Exception as e:
logger.error(e)
except Exception as e:
logger.error(e)


@webhooks.handler("customer.subscription.resumed")
def resume_subscription(event: Event, **kwargs):
"""Resume customer subscription"""
account = Account.objects.filter(email=event.customer.email).first()

if subscription := get_subscription(event):
logger.info(f"Resumindo a inscrição do cliente {event.customer.email}")
subscription.is_active = True
subscription.save()

try:
try:
if account:
add_user(account.gcp_email or account.email)
else:
add_user(event.customer.email)
except Exception as e:
logger.error(e)
except Exception as e:
logger.error(e)


@webhooks.handler("setup_intent.succeeded")
Expand Down

0 comments on commit 45e3af1

Please sign in to comment.