Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions apps/api/plane/api/serializers/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
import random
from rest_framework import serializers


# Python imports
import re

# Module imports
from plane.db.models import Project, ProjectIdentifier, WorkspaceMember, State, Estimate

Expand Down Expand Up @@ -97,6 +101,15 @@ class Meta:
]

def validate(self, data):
project_name = data.get("name", None)
project_identifier = data.get("identifier", None)

if project_name is not None and re.match(Project.FORBIDDEN_IDENTIFIER_CHARS_PATTERN, project_name):
raise serializers.ValidationError("Project name cannot contain special characters.")

if project_identifier is not None and re.match(Project.FORBIDDEN_IDENTIFIER_CHARS_PATTERN, project_identifier):
raise serializers.ValidationError("Project identifier cannot contain special characters.")

if data.get("project_lead", None) is not None:
# Check if the project lead is a member of the workspace
if not WorkspaceMember.objects.filter(
Expand Down Expand Up @@ -156,6 +169,15 @@ class Meta(ProjectCreateSerializer.Meta):
read_only_fields = ProjectCreateSerializer.Meta.read_only_fields

def update(self, instance, validated_data):
project_name = validated_data.get("name", None)
project_identifier = validated_data.get("identifier", None)

if project_name is not None and re.match(Project.FORBIDDEN_IDENTIFIER_CHARS_PATTERN, project_name):
raise serializers.ValidationError("Project name cannot contain special characters.")

if project_identifier is not None and re.match(Project.FORBIDDEN_IDENTIFIER_CHARS_PATTERN, project_identifier):
raise serializers.ValidationError("Project identifier cannot contain special characters.")

"""Update a project"""
if (
validated_data.get("default_state", None) is not None
Expand Down Expand Up @@ -206,6 +228,15 @@ class Meta:
]

def validate(self, data):
project_name = data.get("name", None)
project_identifier = data.get("identifier", None)

if project_name is not None and re.match(Project.FORBIDDEN_IDENTIFIER_CHARS_PATTERN, project_name):
raise serializers.ValidationError("Project name cannot contain special characters.")

if project_identifier is not None and re.match(Project.FORBIDDEN_IDENTIFIER_CHARS_PATTERN, project_identifier):
raise serializers.ValidationError("Project identifier cannot contain special characters.")

# Check project lead should be a member of the workspace
if (
data.get("project_lead", None) is not None
Expand Down
9 changes: 9 additions & 0 deletions apps/api/plane/app/serializers/project.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Third party imports
from rest_framework import serializers

# Python imports
import re

# Module imports
from .base import BaseSerializer, DynamicBaseSerializer
from django.db.models import Max
Expand Down Expand Up @@ -33,6 +36,9 @@ def validate_name(self, name):
project_id = self.instance.id if self.instance else None
workspace_id = self.context["workspace_id"]

if re.match(Project.FORBIDDEN_IDENTIFIER_CHARS_PATTERN, name):
raise serializers.ValidationError(detail="PROJECT_NAME_CANNOT_CONTAIN_SPECIAL_CHARACTERS")

project = Project.objects.filter(name=name, workspace_id=workspace_id)

if project_id:
Expand All @@ -49,6 +55,9 @@ def validate_identifier(self, identifier):
project_id = self.instance.id if self.instance else None
workspace_id = self.context["workspace_id"]

if re.match(Project.FORBIDDEN_IDENTIFIER_CHARS_PATTERN, identifier):
raise serializers.ValidationError(detail="PROJECT_IDENTIFIER_CANNOT_CONTAIN_SPECIAL_CHARACTERS")

project = Project.objects.filter(identifier=identifier, workspace_id=workspace_id)

if project_id:
Expand Down
2 changes: 2 additions & 0 deletions apps/api/plane/db/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ def __str__(self):
"""Return name of the project"""
return f"{self.name} <{self.workspace.name}>"

FORBIDDEN_IDENTIFIER_CHARS_PATTERN = r"^.*[&+,:;$^}{*=?@#|'<>.()%!-].*$"

class Meta:
unique_together = [
["identifier", "workspace", "deleted_at"],
Expand Down
Loading