Skip to content

Commit d36be97

Browse files
authored
Merge pull request #5 from Flagsmith/fix/ensure_segments_match
fix: Ensure owning segment matches to parent segment from rule or condition
2 parents ccb6c06 + 21e3fa8 commit d36be97

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

common/segments/serializers.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def _update_or_create_segment_rules(
199199
continue
200200

201201
self._update_or_create_conditions(
202-
conditions, child_rule, is_create=is_create
202+
conditions, child_rule, is_create=is_create, segment=segment
203203
)
204204

205205
self._update_or_create_segment_rules(
@@ -238,6 +238,13 @@ def _update_or_create_segment_rule(
238238
) -> Optional[models.Model]:
239239
SegmentRule = apps.get_model("segments", "SegmentRule")
240240
rule_id = rule_data.pop("id", None)
241+
if rule_id is not None:
242+
segment_rule = SegmentRule.objects.get(id=rule_id)
243+
matching_segment = segment or rule.get_segment()
244+
245+
if segment_rule.get_segment() != matching_segment:
246+
raise ValidationError({"segment": "Mismatched segment is not allowed"})
247+
241248
if rule_data.get("delete"):
242249
SegmentRule.objects.filter(id=rule_id).delete()
243250
return
@@ -249,16 +256,31 @@ def _update_or_create_segment_rule(
249256

250257
@staticmethod
251258
def _update_or_create_conditions(
252-
conditions_data: dict, rule: models.Model, is_create: bool = False
259+
conditions_data: dict[str, Any],
260+
rule: models.Model,
261+
segment: models.Model | None = None,
262+
is_create: bool = False,
253263
) -> None:
254264
Condition = apps.get_model("segments", "Condition")
255-
for condition in conditions_data:
256-
condition_id = condition.pop("id", None)
257-
if condition.get("delete"):
265+
for condition_data in conditions_data:
266+
condition_id = condition_data.pop("id", None)
267+
if condition_id is not None:
268+
condition = Condition.objects.get(id=condition_id)
269+
matching_segment = segment or rule.get_segment()
270+
if condition._get_segment() != matching_segment:
271+
raise ValidationError(
272+
{"segment": "Mismatched segment is not allowed"}
273+
)
274+
275+
if condition_data.get("delete"):
258276
Condition.objects.filter(id=condition_id).delete()
259277
continue
260278

261279
Condition.objects.update_or_create(
262280
id=condition_id,
263-
defaults={**condition, "created_with_segment": is_create, "rule": rule},
281+
defaults={
282+
**condition_data,
283+
"created_with_segment": is_create,
284+
"rule": rule,
285+
},
264286
)

0 commit comments

Comments
 (0)