mirror of
https://github.com/langgenius/dify.git
synced 2026-04-15 18:06:36 +08:00
fix(api): validate workflow mentions against tenant members
This commit is contained in:
parent
3288f5e100
commit
977af3399e
@ -28,8 +28,10 @@ class WorkflowCommentService:
|
||||
raise ValueError("Comment content cannot exceed 1000 characters")
|
||||
|
||||
@staticmethod
|
||||
def _filter_valid_mentioned_user_ids(mentioned_user_ids: Sequence[str]) -> list[str]:
|
||||
"""Return deduplicated UUID user IDs in the order provided."""
|
||||
def _filter_valid_mentioned_user_ids(
|
||||
mentioned_user_ids: Sequence[str], *, session: Session, tenant_id: str
|
||||
) -> list[str]:
|
||||
"""Return deduplicated UUID user IDs that belong to the tenant, preserving input order."""
|
||||
unique_user_ids: list[str] = []
|
||||
seen: set[str] = set()
|
||||
for user_id in mentioned_user_ids:
|
||||
@ -41,7 +43,20 @@ class WorkflowCommentService:
|
||||
continue
|
||||
seen.add(user_id)
|
||||
unique_user_ids.append(user_id)
|
||||
return unique_user_ids
|
||||
if not unique_user_ids:
|
||||
return []
|
||||
|
||||
tenant_member_ids = {
|
||||
str(account_id)
|
||||
for account_id in session.scalars(
|
||||
select(TenantAccountJoin.account_id).where(
|
||||
TenantAccountJoin.tenant_id == tenant_id,
|
||||
TenantAccountJoin.account_id.in_(unique_user_ids),
|
||||
)
|
||||
).all()
|
||||
}
|
||||
|
||||
return [user_id for user_id in unique_user_ids if user_id in tenant_member_ids]
|
||||
|
||||
@staticmethod
|
||||
def _format_comment_excerpt(content: str, max_length: int = 200) -> str:
|
||||
@ -220,7 +235,11 @@ class WorkflowCommentService:
|
||||
session.flush() # Get the comment ID for mentions
|
||||
|
||||
# Create mentions if specified
|
||||
mentioned_user_ids = WorkflowCommentService._filter_valid_mentioned_user_ids(mentioned_user_ids or [])
|
||||
mentioned_user_ids = WorkflowCommentService._filter_valid_mentioned_user_ids(
|
||||
mentioned_user_ids or [],
|
||||
session=session,
|
||||
tenant_id=tenant_id,
|
||||
)
|
||||
for user_id in mentioned_user_ids:
|
||||
mention = WorkflowCommentMention(
|
||||
comment_id=comment.id,
|
||||
@ -293,7 +312,11 @@ class WorkflowCommentService:
|
||||
session.delete(mention)
|
||||
|
||||
# Add new mentions
|
||||
mentioned_user_ids = WorkflowCommentService._filter_valid_mentioned_user_ids(mentioned_user_ids or [])
|
||||
mentioned_user_ids = WorkflowCommentService._filter_valid_mentioned_user_ids(
|
||||
mentioned_user_ids or [],
|
||||
session=session,
|
||||
tenant_id=tenant_id,
|
||||
)
|
||||
new_mentioned_user_ids = [
|
||||
user_id for user_id in mentioned_user_ids if user_id not in existing_mentioned_user_ids
|
||||
]
|
||||
@ -380,7 +403,11 @@ class WorkflowCommentService:
|
||||
session.flush() # Get the reply ID for mentions
|
||||
|
||||
# Create mentions if specified
|
||||
mentioned_user_ids = WorkflowCommentService._filter_valid_mentioned_user_ids(mentioned_user_ids or [])
|
||||
mentioned_user_ids = WorkflowCommentService._filter_valid_mentioned_user_ids(
|
||||
mentioned_user_ids or [],
|
||||
session=session,
|
||||
tenant_id=comment.tenant_id,
|
||||
)
|
||||
for user_id in mentioned_user_ids:
|
||||
# Create mention linking to specific reply
|
||||
mention = WorkflowCommentMention(comment_id=comment_id, reply_id=reply.id, mentioned_user_id=user_id)
|
||||
@ -425,7 +452,15 @@ class WorkflowCommentService:
|
||||
session.delete(mention)
|
||||
|
||||
# Add mentions
|
||||
mentioned_user_ids = WorkflowCommentService._filter_valid_mentioned_user_ids(mentioned_user_ids or [])
|
||||
raw_mentioned_user_ids = mentioned_user_ids or []
|
||||
comment = session.get(WorkflowComment, reply.comment_id)
|
||||
mentioned_user_ids = []
|
||||
if comment:
|
||||
mentioned_user_ids = WorkflowCommentService._filter_valid_mentioned_user_ids(
|
||||
raw_mentioned_user_ids,
|
||||
session=session,
|
||||
tenant_id=comment.tenant_id,
|
||||
)
|
||||
new_mentioned_user_ids = [
|
||||
user_id for user_id in mentioned_user_ids if user_id not in existing_mentioned_user_ids
|
||||
]
|
||||
@ -436,7 +471,6 @@ class WorkflowCommentService:
|
||||
session.add(mention)
|
||||
|
||||
mention_email_payloads: list[dict[str, str]] = []
|
||||
comment = session.get(WorkflowComment, reply.comment_id)
|
||||
if comment:
|
||||
mention_email_payloads = WorkflowCommentService._build_mention_email_payloads(
|
||||
session=session,
|
||||
|
||||
@ -39,20 +39,28 @@ class TestWorkflowCommentService:
|
||||
with pytest.raises(ValueError):
|
||||
WorkflowCommentService._validate_content("a" * 1001)
|
||||
|
||||
def test_filter_valid_mentioned_user_ids_deduplicates_and_preserves_order(self) -> None:
|
||||
def test_filter_valid_mentioned_user_ids_filters_by_tenant_and_preserves_order(self, mock_session: Mock) -> None:
|
||||
tenant_member_1 = "123e4567-e89b-12d3-a456-426614174000"
|
||||
tenant_member_2 = "123e4567-e89b-12d3-a456-426614174002"
|
||||
non_tenant_member = "123e4567-e89b-12d3-a456-426614174001"
|
||||
mock_session.scalars.return_value = _mock_scalars([tenant_member_1, tenant_member_2])
|
||||
|
||||
result = WorkflowCommentService._filter_valid_mentioned_user_ids(
|
||||
[
|
||||
"123e4567-e89b-12d3-a456-426614174000",
|
||||
tenant_member_1,
|
||||
"",
|
||||
123, # type: ignore[list-item]
|
||||
"123e4567-e89b-12d3-a456-426614174000",
|
||||
"123e4567-e89b-12d3-a456-426614174001",
|
||||
]
|
||||
tenant_member_1,
|
||||
non_tenant_member,
|
||||
tenant_member_2,
|
||||
],
|
||||
session=mock_session,
|
||||
tenant_id="tenant-1",
|
||||
)
|
||||
|
||||
assert result == [
|
||||
"123e4567-e89b-12d3-a456-426614174000",
|
||||
"123e4567-e89b-12d3-a456-426614174001",
|
||||
tenant_member_1,
|
||||
tenant_member_2,
|
||||
]
|
||||
|
||||
def test_format_comment_excerpt_handles_short_and_long_limits(self) -> None:
|
||||
@ -140,7 +148,7 @@ class TestWorkflowCommentService:
|
||||
with (
|
||||
patch.object(service_module, "WorkflowComment", return_value=comment),
|
||||
patch.object(service_module, "WorkflowCommentMention", return_value=Mock()),
|
||||
patch.object(service_module, "uuid_value", side_effect=[True, False]),
|
||||
patch.object(WorkflowCommentService, "_filter_valid_mentioned_user_ids", return_value=["user-2"]),
|
||||
):
|
||||
result = WorkflowCommentService.create_comment(
|
||||
tenant_id="tenant-1",
|
||||
@ -192,7 +200,7 @@ class TestWorkflowCommentService:
|
||||
existing_mentions = [Mock(), Mock()]
|
||||
mock_session.scalars.return_value = _mock_scalars(existing_mentions)
|
||||
|
||||
with patch.object(service_module, "uuid_value", side_effect=[True, False]):
|
||||
with patch.object(WorkflowCommentService, "_filter_valid_mentioned_user_ids", return_value=["user-2"]):
|
||||
result = WorkflowCommentService.update_comment(
|
||||
tenant_id="tenant-1",
|
||||
app_id="app-1",
|
||||
@ -218,7 +226,11 @@ class TestWorkflowCommentService:
|
||||
mock_session.scalars.return_value = _mock_scalars([existing_mention])
|
||||
|
||||
with (
|
||||
patch.object(service_module, "uuid_value", side_effect=[True, True]),
|
||||
patch.object(
|
||||
WorkflowCommentService,
|
||||
"_filter_valid_mentioned_user_ids",
|
||||
return_value=["user-2", "user-3"],
|
||||
),
|
||||
patch.object(
|
||||
WorkflowCommentService,
|
||||
"_build_mention_email_payloads",
|
||||
@ -369,7 +381,7 @@ class TestWorkflowCommentService:
|
||||
with (
|
||||
patch.object(service_module, "WorkflowCommentReply", return_value=reply),
|
||||
patch.object(service_module, "WorkflowCommentMention", return_value=Mock()),
|
||||
patch.object(service_module, "uuid_value", side_effect=[True, False]),
|
||||
patch.object(WorkflowCommentService, "_filter_valid_mentioned_user_ids", return_value=["user-2"]),
|
||||
):
|
||||
result = WorkflowCommentService.create_reply(
|
||||
comment_id="comment-1",
|
||||
@ -405,7 +417,7 @@ class TestWorkflowCommentService:
|
||||
mock_session.get.return_value = reply
|
||||
mock_session.scalars.return_value = _mock_scalars([Mock()])
|
||||
|
||||
with patch.object(service_module, "uuid_value", side_effect=[True, False]):
|
||||
with patch.object(WorkflowCommentService, "_filter_valid_mentioned_user_ids", return_value=["user-2"]):
|
||||
result = WorkflowCommentService.update_reply(
|
||||
reply_id="reply-1",
|
||||
user_id="owner",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user