fix(api): allow account avatars across workspaces (#40055)

Co-authored-by: aiden <zhouyuchi@kurogames.com>
This commit is contained in:
Aiden
2026-08-06 03:33:23 +00:00
committed by GitHub
co-authored by aiden
parent 8170a2a5f3
commit 6add64a44d
2 changed files with 13 additions and 18 deletions
+1 -6
View File
@@ -43,7 +43,6 @@ from controllers.console.wraps import (
enterprise_license_required,
only_edition_cloud,
setup_required,
with_current_tenant_id,
with_current_user,
)
from enums.deployment_edition import DeploymentEdition
@@ -333,8 +332,7 @@ class AccountAvatarApi(Resource):
@login_required
@account_initialization_required
@with_current_user
@with_current_tenant_id
def get(self, current_tenant_id: str, current_user: Account):
def get(self, current_user: Account):
args = AccountAvatarQuery.model_validate(request.args.to_dict(flat=True))
avatar = args.avatar
@@ -345,9 +343,6 @@ class AccountAvatarApi(Resource):
if upload_file is None:
raise NotFound("Avatar file not found")
if upload_file.tenant_id != current_tenant_id:
raise NotFound("Avatar file not found")
if upload_file.created_by_role != CreatorUserRole.ACCOUNT or upload_file.created_by != current_user.id:
raise NotFound("Avatar file not found")
@@ -216,7 +216,7 @@ class TestAccountAvatarApiGet:
return_value="https://signed/example",
) as sign_mock,
):
result = method(api, tenant_id, user)
result = method(api, user)
assert result == {"avatar_url": "https://signed/example"}
sign_mock.assert_called_once_with(upload_file_id=file_id)
@@ -252,11 +252,11 @@ class TestAccountAvatarApiGet:
patch("controllers.console.workspace.account.db.session", sqlite_session),
patch(
"controllers.console.workspace.account.file_helpers.get_signed_file_url",
return_value="https://signed/leak",
return_value="https://signed/example",
) as sign_mock,
):
with pytest.raises(NotFound):
method(api, tenant_id, user)
method(api, user)
sign_mock.assert_not_called()
@@ -265,12 +265,13 @@ class TestAccountAvatarApiGet:
[(Account, Tenant, TenantAccountJoin, UploadFile)],
indirect=True,
)
def test_get_avatar_not_found_when_upload_belongs_to_other_tenant(self, app: Flask, sqlite_session: Session):
def test_get_avatar_signed_url_when_upload_owned_by_current_account_in_other_tenant(
self, app: Flask, sqlite_session: Session
):
api = AccountAvatarApi()
method = inspect.unwrap(api.get)
user, tenant = persist_account_with_tenant(sqlite_session, "acc-owner")
tenant_id = tenant.id
user, _ = persist_account_with_tenant(sqlite_session, "acc-owner")
file_id = "550e8400-e29b-41d4-a716-446655440002"
other_tenant = Tenant(name="tenant-other")
@@ -285,20 +286,19 @@ class TestAccountAvatarApiGet:
patch("controllers.console.workspace.account.db.session", sqlite_session),
patch(
"controllers.console.workspace.account.file_helpers.get_signed_file_url",
return_value="https://signed/leak",
return_value="https://signed/example",
) as sign_mock,
):
with pytest.raises(NotFound):
method(api, tenant_id, user)
result = method(api, user)
sign_mock.assert_not_called()
assert result == {"avatar_url": "https://signed/example"}
sign_mock.assert_called_once_with(upload_file_id=file_id)
def test_get_avatar_https_pass_through_without_signing(self, app: Flask):
api = AccountAvatarApi()
method = inspect.unwrap(api.get)
user = make_account("acc-owner")
tenant_id = "tenant-1"
external = "https://cdn.example/avatar.png"
with (
@@ -308,7 +308,7 @@ class TestAccountAvatarApiGet:
return_value="https://signed/should-not-use",
) as sign_mock,
):
result = method(api, tenant_id, user)
result = method(api, user)
assert result == {"avatar_url": external}
sign_mock.assert_not_called()