[WEB - 1408] dev: add logo prop and accounts migration (#4558)

* dev: add logo prop and accounts migration

* dev: add default values for id_token

* dev: update is_active as read only field

* dev: delete all sessions when deactivating account

* dev: add issue description binary

* dev: add logo props for team
This commit is contained in:
Nikhil 2024-05-23 18:08:35 +05:30 committed by GitHub
parent 6a3c4eb512
commit b57432818d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 85 additions and 4 deletions

View File

@ -33,6 +33,7 @@ class UserSerializer(BaseSerializer):
"is_bot", "is_bot",
"is_password_autoset", "is_password_autoset",
"is_email_verified", "is_email_verified",
"is_active",
] ]
extra_kwargs = {"password": {"write_only": True}} extra_kwargs = {"password": {"write_only": True}}

View File

@ -1,3 +1,6 @@
# Python imports
# import uuid
# Django imports # Django imports
from django.db.models import Case, Count, IntegerField, Q, When from django.db.models import Case, Count, IntegerField, Q, When
from django.contrib.auth import logout from django.contrib.auth import logout
@ -26,6 +29,7 @@ from plane.db.models import (
User, User,
WorkspaceMember, WorkspaceMember,
WorkspaceMemberInvite, WorkspaceMemberInvite,
Session,
) )
from plane.license.models import Instance, InstanceAdmin from plane.license.models import Instance, InstanceAdmin
from plane.utils.cache import cache_response, invalidate_cache from plane.utils.cache import cache_response, invalidate_cache
@ -160,12 +164,13 @@ class UserEndpoint(BaseViewSet):
email=user.email, email=user.email,
).delete() ).delete()
# Deactivate the user # Delete all sessions
user.is_active = False Session.objects.filter(user_id=request.user.id).delete()
# Profile updates # Profile updates
profile = Profile.objects.get(user=user) profile = Profile.objects.get(user=user)
# Reset onboarding
profile.last_workspace_id = None profile.last_workspace_id = None
profile.is_tour_completed = False profile.is_tour_completed = False
profile.is_onboarded = False profile.is_onboarded = False
@ -177,7 +182,12 @@ class UserEndpoint(BaseViewSet):
} }
profile.save() profile.save()
# User log out # Reset password
# user.is_password_autoset = True
# user.set_password(uuid.uuid4().hex)
# Deactivate the user
user.is_active = False
user.last_logout_ip = user_ip(request=request) user.last_logout_ip = user_ip(request=request)
user.last_logout_time = timezone.now() user.last_logout_time = timezone.now()
user.save() user.save()

View File

@ -85,5 +85,6 @@ class OauthAdapter(Adapter):
"refresh_token_expired_at" "refresh_token_expired_at"
), ),
"last_connected_at": timezone.now(), "last_connected_at": timezone.now(),
"id_token": self.token_data.get("id_token", ""),
}, },
) )

View File

@ -100,6 +100,7 @@ class GitHubOAuthProvider(OauthAdapter):
if token_response.get("refresh_token_expired_at") if token_response.get("refresh_token_expired_at")
else None else None
), ),
"id_token": token_response.get("id_token", ""),
} }
) )

View File

@ -98,6 +98,7 @@ class GoogleOAuthProvider(OauthAdapter):
if token_response.get("refresh_token_expired_at") if token_response.get("refresh_token_expired_at")
else None else None
), ),
"id_token": token_response.get("id_token", ""),
} }
) )

View File

@ -0,0 +1,58 @@
# Generated by Django 4.2.11 on 2024-05-22 15:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("db", "0065_auto_20240415_0937"),
]
operations = [
migrations.AddField(
model_name="account",
name="id_token",
field=models.TextField(blank=True),
),
migrations.AddField(
model_name="cycle",
name="logo_props",
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="module",
name="logo_props",
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="issueview",
name="logo_props",
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="inbox",
name="logo_props",
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="dashboard",
name="logo_props",
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="widget",
name="logo_props",
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name="issue",
name="description_binary",
field=models.BinaryField(null=True),
),
migrations.AddField(
model_name="team",
name="logo_props",
field=models.JSONField(default=dict),
),
]

View File

@ -70,6 +70,7 @@ class Cycle(ProjectBaseModel):
external_id = models.CharField(max_length=255, blank=True, null=True) external_id = models.CharField(max_length=255, blank=True, null=True)
progress_snapshot = models.JSONField(default=dict) progress_snapshot = models.JSONField(default=dict)
archived_at = models.DateTimeField(null=True) archived_at = models.DateTimeField(null=True)
logo_props = models.JSONField(default=dict)
class Meta: class Meta:
verbose_name = "Cycle" verbose_name = "Cycle"

View File

@ -31,6 +31,7 @@ class Dashboard(BaseModel):
verbose_name="Dashboard Type", verbose_name="Dashboard Type",
default="home", default="home",
) )
logo_props = models.JSONField(default=dict)
def __str__(self): def __str__(self):
"""Return name of the dashboard""" """Return name of the dashboard"""
@ -53,6 +54,7 @@ class Widget(TimeAuditModel):
) )
key = models.CharField(max_length=255) key = models.CharField(max_length=255)
filters = models.JSONField(default=dict) filters = models.JSONField(default=dict)
logo_props = models.JSONField(default=dict)
def __str__(self): def __str__(self):
"""Return name of the widget""" """Return name of the widget"""

View File

@ -12,6 +12,7 @@ class Inbox(ProjectBaseModel):
) )
is_default = models.BooleanField(default=False) is_default = models.BooleanField(default=False)
view_props = models.JSONField(default=dict) view_props = models.JSONField(default=dict)
logo_props = models.JSONField(default=dict)
def __str__(self): def __str__(self):
"""Return name of the Inbox""" """Return name of the Inbox"""

View File

@ -128,6 +128,7 @@ class Issue(ProjectBaseModel):
description = models.JSONField(blank=True, default=dict) description = models.JSONField(blank=True, default=dict)
description_html = models.TextField(blank=True, default="<p></p>") description_html = models.TextField(blank=True, default="<p></p>")
description_stripped = models.TextField(blank=True, null=True) description_stripped = models.TextField(blank=True, null=True)
description_binary = models.BinaryField(null=True)
priority = models.CharField( priority = models.CharField(
max_length=30, max_length=30,
choices=PRIORITY_CHOICES, choices=PRIORITY_CHOICES,

View File

@ -93,6 +93,7 @@ class Module(ProjectBaseModel):
external_source = models.CharField(max_length=255, null=True, blank=True) external_source = models.CharField(max_length=255, null=True, blank=True)
external_id = models.CharField(max_length=255, blank=True, null=True) external_id = models.CharField(max_length=255, blank=True, null=True)
archived_at = models.DateTimeField(null=True) archived_at = models.DateTimeField(null=True)
logo_props = models.JSONField(default=dict)
class Meta: class Meta:
unique_together = ["name", "project"] unique_together = ["name", "project"]

View File

@ -189,6 +189,7 @@ class Account(TimeAuditModel):
refresh_token = models.TextField(null=True, blank=True) refresh_token = models.TextField(null=True, blank=True)
refresh_token_expired_at = models.DateTimeField(null=True) refresh_token_expired_at = models.DateTimeField(null=True)
last_connected_at = models.DateTimeField(default=timezone.now) last_connected_at = models.DateTimeField(default=timezone.now)
id_token = models.TextField(blank=True)
metadata = models.JSONField(default=dict) metadata = models.JSONField(default=dict)
class Meta: class Meta:

View File

@ -52,6 +52,7 @@ def get_default_display_properties():
} }
# DEPRECATED TODO: - Remove in next release
class GlobalView(BaseModel): class GlobalView(BaseModel):
workspace = models.ForeignKey( workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="global_views" "db.Workspace", on_delete=models.CASCADE, related_name="global_views"
@ -87,7 +88,6 @@ class GlobalView(BaseModel):
return f"{self.name} <{self.workspace.name}>" return f"{self.name} <{self.workspace.name}>"
# DEPRECATED TODO: - Remove in next release
class IssueView(WorkspaceBaseModel): class IssueView(WorkspaceBaseModel):
name = models.CharField(max_length=255, verbose_name="View Name") name = models.CharField(max_length=255, verbose_name="View Name")
description = models.TextField(verbose_name="View Description", blank=True) description = models.TextField(verbose_name="View Description", blank=True)
@ -101,6 +101,7 @@ class IssueView(WorkspaceBaseModel):
default=1, choices=((0, "Private"), (1, "Public")) default=1, choices=((0, "Private"), (1, "Public"))
) )
sort_order = models.FloatField(default=65535) sort_order = models.FloatField(default=65535)
logo_props = models.JSONField(default=dict)
class Meta: class Meta:
verbose_name = "Issue View" verbose_name = "Issue View"

View File

@ -244,6 +244,7 @@ class Team(BaseModel):
workspace = models.ForeignKey( workspace = models.ForeignKey(
Workspace, on_delete=models.CASCADE, related_name="workspace_team" Workspace, on_delete=models.CASCADE, related_name="workspace_team"
) )
logo_props = models.JSONField(default=dict)
def __str__(self): def __str__(self):
"""Return name of the team""" """Return name of the team"""