Browse Source

fix: tenant_id was not specific when retrieval end-user in plugin backwards invocation wraps (#25377)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
tags/1.9.0
Yeuoly 1 month ago
parent
commit
720ecea737
No account linked to committer's email address

+ 31
- 24
api/controllers/inner_api/plugin/wraps.py View File

@@ -8,37 +8,44 @@ from flask_restx import reqparse
from pydantic import BaseModel
from sqlalchemy.orm import Session

from core.file.constants import DEFAULT_SERVICE_API_USER_ID
from extensions.ext_database import db
from libs.login import _get_user
from models.account import Account, Tenant
from models.account import Tenant
from models.model import EndUser
from services.account_service import AccountService


def get_user(tenant_id: str, user_id: str | None) -> Account | EndUser:
def get_user(tenant_id: str, user_id: str | None) -> EndUser:
"""
Get current user

NOTE: user_id is not trusted, it could be maliciously set to any value.
As a result, it could only be considered as an end user id.
"""
try:
with Session(db.engine) as session:
if not user_id:
user_id = "DEFAULT-USER"

if user_id == "DEFAULT-USER":
user_model = session.query(EndUser).where(EndUser.session_id == "DEFAULT-USER").first()
if not user_model:
user_model = EndUser(
tenant_id=tenant_id,
type="service_api",
is_anonymous=True if user_id == "DEFAULT-USER" else False,
session_id=user_id,
)
session.add(user_model)
session.commit()
session.refresh(user_model)
else:
user_model = AccountService.load_user(user_id)
if not user_model:
user_model = session.query(EndUser).where(EndUser.id == user_id).first()
if not user_model:
raise ValueError("user not found")
user_id = DEFAULT_SERVICE_API_USER_ID

user_model = (
session.query(EndUser)
.where(
EndUser.session_id == user_id,
EndUser.tenant_id == tenant_id,
)
.first()
)
if not user_model:
user_model = EndUser(
tenant_id=tenant_id,
type="service_api",
is_anonymous=user_id == DEFAULT_SERVICE_API_USER_ID,
session_id=user_id,
)
session.add(user_model)
session.commit()
session.refresh(user_model)

except Exception:
raise ValueError("user not found")

@@ -63,7 +70,7 @@ def get_user_tenant(view: Optional[Callable] = None):
raise ValueError("tenant_id is required")

if not user_id:
user_id = "DEFAULT-USER"
user_id = DEFAULT_SERVICE_API_USER_ID

del kwargs["tenant_id"]
del kwargs["user_id"]

+ 3
- 2
api/controllers/service_api/wraps.py View File

@@ -13,6 +13,7 @@ from sqlalchemy import select, update
from sqlalchemy.orm import Session
from werkzeug.exceptions import Forbidden, NotFound, Unauthorized

from core.file.constants import DEFAULT_SERVICE_API_USER_ID
from extensions.ext_database import db
from extensions.ext_redis import redis_client
from libs.datetime_utils import naive_utc_now
@@ -271,7 +272,7 @@ def create_or_update_end_user_for_user_id(app_model: App, user_id: Optional[str]
Create or update session terminal based on user ID.
"""
if not user_id:
user_id = "DEFAULT-USER"
user_id = DEFAULT_SERVICE_API_USER_ID

with Session(db.engine, expire_on_commit=False) as session:
end_user = (
@@ -290,7 +291,7 @@ def create_or_update_end_user_for_user_id(app_model: App, user_id: Optional[str]
tenant_id=app_model.tenant_id,
app_id=app_model.id,
type="service_api",
is_anonymous=user_id == "DEFAULT-USER",
is_anonymous=user_id == DEFAULT_SERVICE_API_USER_ID,
session_id=user_id,
)
session.add(end_user)

+ 4
- 0
api/core/file/constants.py View File

@@ -9,3 +9,7 @@ FILE_MODEL_IDENTITY = "__dify__file__"

def maybe_file_object(o: Any) -> bool:
return isinstance(o, dict) and o.get("dify_model_identity") == FILE_MODEL_IDENTITY


# The default user ID for service API calls.
DEFAULT_SERVICE_API_USER_ID = "DEFAULT-USER"

+ 3
- 2
api/core/file/helpers.py View File

@@ -5,6 +5,7 @@ import os
import time

from configs import dify_config
from core.file.constants import DEFAULT_SERVICE_API_USER_ID


def get_signed_file_url(upload_file_id: str) -> str:
@@ -26,7 +27,7 @@ def get_signed_file_url_for_plugin(filename: str, mimetype: str, tenant_id: str,
url = f"{base_url}/files/upload/for-plugin"

if user_id is None:
user_id = "DEFAULT-USER"
user_id = DEFAULT_SERVICE_API_USER_ID

timestamp = str(int(time.time()))
nonce = os.urandom(16).hex()
@@ -42,7 +43,7 @@ def verify_plugin_file_signature(
*, filename: str, mimetype: str, tenant_id: str, user_id: str | None, timestamp: str, nonce: str, sign: str
) -> bool:
if user_id is None:
user_id = "DEFAULT-USER"
user_id = DEFAULT_SERVICE_API_USER_ID

data_to_sign = f"upload|{filename}|{mimetype}|{tenant_id}|{user_id}|{timestamp}|{nonce}"
secret_key = dify_config.SECRET_KEY.encode()

Loading…
Cancel
Save