Skip to content

Commit

Permalink
PR fixes & linter fix
Browse files Browse the repository at this point in the history
  • Loading branch information
wojcikmat committed Feb 14, 2024
1 parent e1da630 commit 9f46f15
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 100 deletions.
6 changes: 2 additions & 4 deletions packages/backend/apps/demo/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from apps.content import models as content_models
from common.storages import UniqueFilePathGenerator
from common.models import TimestampedMixin

User = get_user_model()

Expand All @@ -24,14 +25,11 @@ def __init__(self, *args, **kwargs):
self.edited_by: Optional[User] = None


class ContentfulDemoItemFavorite(models.Model):
class ContentfulDemoItemFavorite(TimestampedMixin, models.Model):
id = hashid_field.HashidAutoField(primary_key=True)
item = models.ForeignKey(content_models.DemoItem, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

class Meta:
unique_together = [['item', 'user']]

Expand Down
8 changes: 7 additions & 1 deletion packages/backend/apps/multitenancy/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@


class TenantType(models.TextChoices):
SIGN_UP = "sign_up", "Sign Up"
"""
DEFAULT is a tenant type created during user sign up.
It's default tenant for user to ensure that user always have at least one.
ORGANIZATION is a tenant type for tenants created by user manually for purposes of inviting other members.
"""

DEFAULT = "default", "Default"
ORGANIZATION = "organization", "Organization"


Expand Down
13 changes: 7 additions & 6 deletions packages/backend/apps/multitenancy/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@


class TenantManager(models.Manager):
def get_or_create_user_sign_up_tenant(self, user):
def get_or_create_user_default_tenant(self, user):
"""
Description:
Retrieves or creates a tenant for a given user to ensure there is always at least one tenant associated with the user.
Retrieves or creates a default tenant for a given user to ensure that there is always at least one tenant
instance associated with the user.
Parameters:
- user (User): The user for whom the tenant is retrieved or created.
Returns:
Tenant: The associated or newly created tenant instance of SIGN_UP type.
"""
sign_up_tenant = self.filter(creator=user, type=TenantType.SIGN_UP).order_by('created').first()
if sign_up_tenant:
return sign_up_tenant, False
default_tenant = self.filter(creator=user, type=TenantType.DEFAULT).order_by('created_at').first()
if default_tenant:
return default_tenant, False

new_tenant = self.create(creator=user, type=TenantType.SIGN_UP, name=str(user))
new_tenant = self.create(creator=user, type=TenantType.DEFAULT, name=str(user))
new_tenant.members.add(user)

return new_tenant, True
78 changes: 0 additions & 78 deletions packages/backend/apps/multitenancy/migrations/0001_initial.py

This file was deleted.

10 changes: 5 additions & 5 deletions packages/backend/apps/multitenancy/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

from . import constants
from .managers import TenantManager
from common.models import TimestampedMixin


class Tenant(models.Model):
class Tenant(TimestampedMixin, models.Model):
id: str = hashid_field.HashidAutoField(primary_key=True)
creator: settings.AUTH_USER_MODEL = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name: str = models.CharField(max_length=100, unique=True)
slug: str = models.SlugField(max_length=100, unique=True)
type: str = models.CharField(choices=constants.TenantType.choices)
created = models.DateTimeField(auto_now_add=True)
members = models.ManyToManyField(
settings.AUTH_USER_MODEL, through='TenantMembership', related_name='tenants', blank=True
)
Expand All @@ -30,10 +30,10 @@ def save(self, *args, **kwargs):
super().save(*args, **kwargs)


class TenantMembership(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="memberships")
class TenantMembership(TimestampedMixin, models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="tenant_memberships")
role = models.CharField(choices=constants.TenantUserRole.choices, default=constants.TenantUserRole.OWNER)
tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE, related_name="memberships")
tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE, related_name="user_memberships")

class Meta:
unique_together = ('user', 'tenant')
Expand Down
5 changes: 4 additions & 1 deletion packages/backend/apps/multitenancy/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ class TenantFactory(factory.django.DjangoModelFactory):
type = factory.Iterator(constants.TenantType.values)
name = factory.Faker('pystr')
slug = factory.Faker('pystr')
created = factory.Faker('date_time')
created_at = factory.Faker('date_time')
updated_at = factory.Faker('date_time')

class Meta:
model = models.Tenant
Expand All @@ -18,6 +19,8 @@ class Meta:
class TenantMembershipFactory(factory.django.DjangoModelFactory):
user = factory.SubFactory("apps.users.tests.factories.UserFactory")
tenant = factory.SubFactory(TenantFactory)
created_at = factory.Faker('date_time')
updated_at = factory.Faker('date_time')

class Meta:
model = models.TenantMembership
4 changes: 2 additions & 2 deletions packages/backend/apps/users/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class Meta:
@staticmethod
def resolve_role(parent, info):
user = get_user_from_resolver(info)
return parent.memberships.filter(user=user).first().role
return parent.user_memberships.filter(user=user).first().role


@permission_classes(policies.AnyoneFullAccess)
Expand Down Expand Up @@ -180,7 +180,7 @@ def resolve_tenants(parent, info):
user = get_user_from_resolver(info)
tenants = user.tenants.all()
if not len(tenants):
Tenant.objects.get_or_create_user_sign_up_tenant(user)
Tenant.objects.get_or_create_user_default_tenant(user)
return tenants


Expand Down
2 changes: 1 addition & 1 deletion packages/backend/apps/users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def create(self, validated_data):
).send()

# Create user signup tenant
Tenant.objects.get_or_create_user_sign_up_tenant(user)
Tenant.objects.get_or_create_user_default_tenant(user)

return {'id': user.id, 'email': user.email, 'access': str(refresh.access_token), 'refresh': str(refresh)}

Expand Down
2 changes: 1 addition & 1 deletion packages/backend/apps/users/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def sign_up_tenant(self, create: bool, extracted: Optional[List[str]], **kwargs)
if not create:
return

Tenant.objects.get_or_create_user_sign_up_tenant(self)
Tenant.objects.get_or_create_user_default_tenant(self)

@factory.post_generation
def admin(self, create, extracted, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/apps/users/tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def test_response_data(self, graphene_client, user_factory, user_avatar_factory)
assert len(data["tenants"]) > 0
assert data["tenants"][0]["name"] == "[email protected]"
assert data["tenants"][0]["role"] == "owner"
assert data["tenants"][0]["type"] == "sign_up"
assert data["tenants"][0]["type"] == "default"

def test_not_authenticated(self, graphene_client):
executed = graphene_client.query(
Expand Down
9 changes: 9 additions & 0 deletions packages/backend/common/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.db import models
from django.core.files.base import ContentFile
from io import BytesIO
from common.graphql import exceptions as graphql_exceptions
Expand Down Expand Up @@ -31,3 +32,11 @@ def save(self, *args, **kwargs):
if self.original:
self.make_thumbnail()
super().save(*args, **kwargs)


class TimestampedMixin(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

class Meta:
abstract = True

0 comments on commit 9f46f15

Please sign in to comment.