diff --git a/api/app/settings/common.py b/api/app/settings/common.py index cefe46ca4edb..17e4b586ab61 100644 --- a/api/app/settings/common.py +++ b/api/app/settings/common.py @@ -21,6 +21,7 @@ import pytz import requests from corsheaders.defaults import default_headers +from django.core.exceptions import ImproperlyConfigured from django.core.management.utils import get_random_secret_key from environs import Env @@ -1082,5 +1083,11 @@ LDAP_SYNC_USER_USERNAME = env.str("LDAP_SYNC_USER_USERNAME", None) LDAP_SYNC_USER_PASSWORD = env.str("LDAP_SYNC_USER_PASSWORD", None) +SEGMENT_CONDITION_VALUE_LIMIT = env.int("SEGMENT_CONDITION_VALUE_LIMIT", default=1000) +if not 0 <= SEGMENT_CONDITION_VALUE_LIMIT < 2000000: + raise ImproperlyConfigured( + "SEGMENT_CONDITION_VALUE_LIMIT must be between 0 and 2,000,000 (2MB)." + ) + WEBHOOK_BACKOFF_BASE = env.int("WEBHOOK_BACKOFF_BASE", default=2) WEBHOOK_BACKOFF_RETRIES = env.int("WEBHOOK_BACKOFF_RETRIES", default=3) diff --git a/api/segments/migrations/0004_auto_20190523_1325.py b/api/segments/migrations/0004_auto_20190523_1325.py index f9b16664806d..5c339b58aaa3 100644 --- a/api/segments/migrations/0004_auto_20190523_1325.py +++ b/api/segments/migrations/0004_auto_20190523_1325.py @@ -2,6 +2,7 @@ # Generated by Django 1.11.20 on 2019-05-23 13:25 from __future__ import unicode_literals +from django.conf import settings from django.db import migrations, models import django.db.models.deletion @@ -19,7 +20,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('operator', models.CharField(choices=[('EQUAL', 'Exactly Equal'), ('GREATER_THAN', 'Greater than'), ('LESS_THAN', 'Less than')], max_length=500)), ('property', models.CharField(max_length=1000)), - ('value', models.CharField(max_length=1000)), + ('value', models.CharField(max_length=settings.SEGMENT_CONDITION_VALUE_LIMIT)), ], ), migrations.CreateModel( diff --git a/api/segments/migrations/0013_add_is_set_and_is_not_set_operators.py b/api/segments/migrations/0013_add_is_set_and_is_not_set_operators.py index cbe5543e24fd..dc63f4320185 100644 --- a/api/segments/migrations/0013_add_is_set_and_is_not_set_operators.py +++ b/api/segments/migrations/0013_add_is_set_and_is_not_set_operators.py @@ -1,12 +1,12 @@ # Generated by Django 3.2.15 on 2022-10-04 16:21 +from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('segments', '0012_alter_condition_operator'), + ("segments", "0012_alter_condition_operator"), ] operations = [ @@ -18,6 +18,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='condition', name='value', - field=models.CharField(blank=True, max_length=1000, null=True), + field=models.CharField(blank=True, max_length=settings.SEGMENT_CONDITION_VALUE_LIMIT, null=True), ), ] diff --git a/api/segments/migrations/0019_add_audit_to_condition.py b/api/segments/migrations/0019_add_audit_to_condition.py index fc3c82a68aa2..b780fdddaf4b 100644 --- a/api/segments/migrations/0019_add_audit_to_condition.py +++ b/api/segments/migrations/0019_add_audit_to_condition.py @@ -35,7 +35,7 @@ class Migration(migrations.Migration): ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), ('operator', models.CharField(choices=[('EQUAL', 'Exactly Matches'), ('GREATER_THAN', 'Greater than'), ('LESS_THAN', 'Less than'), ('CONTAINS', 'Contains'), ('GREATER_THAN_INCLUSIVE', 'Greater than or equal to'), ('LESS_THAN_INCLUSIVE', 'Less than or equal to'), ('NOT_CONTAINS', 'Does not contain'), ('NOT_EQUAL', 'Does not match'), ('REGEX', 'Matches regex'), ('PERCENTAGE_SPLIT', 'Percentage split'), ('MODULO', 'Modulo Operation'), ('IS_SET', 'Is set'), ('IS_NOT_SET', 'Is not set'), ('IN', 'In')], max_length=500)), ('property', models.CharField(blank=True, max_length=1000, null=True)), - ('value', models.CharField(blank=True, max_length=1000, null=True)), + ('value', models.CharField(blank=True, max_length=settings.SEGMENT_CONDITION_VALUE_LIMIT, null=True)), ('description', models.TextField(blank=True, null=True)), ('created_with_segment', models.BooleanField(default=False, help_text='Field to denote whether a condition was created along with segment or added after creation.')), ('history_id', models.AutoField(primary_key=True, serialize=False)), diff --git a/api/segments/models.py b/api/segments/models.py index 21eeb0d6de69..c34735c1c5de 100644 --- a/api/segments/models.py +++ b/api/segments/models.py @@ -7,6 +7,7 @@ SoftDeleteExportableModel, abstract_base_auditable_model_factory, ) +from django.conf import settings from django.core.exceptions import ValidationError from django.db import models from flag_engine.segments import constants @@ -151,7 +152,9 @@ class Condition( operator = models.CharField(choices=CONDITION_TYPES, max_length=500) property = models.CharField(blank=True, null=True, max_length=1000) - value = models.CharField(max_length=1000, blank=True, null=True) + value = models.CharField( + max_length=settings.SEGMENT_CONDITION_VALUE_LIMIT, blank=True, null=True + ) description = models.TextField(blank=True, null=True) created_with_segment = models.BooleanField( diff --git a/docs/docs/deployment/hosting/locally-api.md b/docs/docs/deployment/hosting/locally-api.md index 9f77d13611a3..b029425dac38 100644 --- a/docs/docs/deployment/hosting/locally-api.md +++ b/docs/docs/deployment/hosting/locally-api.md @@ -246,6 +246,11 @@ the below variables will be ignored. ignored. - `DISABLE_FLAGSMITH_UI`: Disable the Flagsmith UI which can be rendered by the API containers in a single container environment. Use `True` to disable, defaults to `False`. +- `SEGMENT_CONDITION_VALUE_LIMIT`: Configure the size of the segment condition value in bytes. Default is 1000. + Minimum 0. Maximum 2000000 (2MB). Note that this environment variable changes the length of the column in the database + and hence should not be modified for already running instances of flagsmith. It should only be used for new + installations, and should not be modified. WARNING: setting this to a higher limit may prevent imports to our SaaS + platform if required in the future. #### Security Environment Variables