mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 02:18:08 +08:00
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>
This commit is contained in:
@ -8,37 +8,44 @@ from flask_restx import reqparse
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from core.file.constants import DEFAULT_SERVICE_API_USER_ID
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from libs.login import _get_user
|
from libs.login import _get_user
|
||||||
from models.account import Account, Tenant
|
from models.account import Tenant
|
||||||
from models.model import EndUser
|
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:
|
try:
|
||||||
with Session(db.engine) as session:
|
with Session(db.engine) as session:
|
||||||
if not user_id:
|
if not user_id:
|
||||||
user_id = "DEFAULT-USER"
|
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)
|
||||||
|
|
||||||
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")
|
|
||||||
except Exception:
|
except Exception:
|
||||||
raise ValueError("user not found")
|
raise ValueError("user not found")
|
||||||
|
|
||||||
@ -63,7 +70,7 @@ def get_user_tenant(view: Optional[Callable] = None):
|
|||||||
raise ValueError("tenant_id is required")
|
raise ValueError("tenant_id is required")
|
||||||
|
|
||||||
if not user_id:
|
if not user_id:
|
||||||
user_id = "DEFAULT-USER"
|
user_id = DEFAULT_SERVICE_API_USER_ID
|
||||||
|
|
||||||
del kwargs["tenant_id"]
|
del kwargs["tenant_id"]
|
||||||
del kwargs["user_id"]
|
del kwargs["user_id"]
|
||||||
|
|||||||
@ -13,6 +13,7 @@ from sqlalchemy import select, update
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from werkzeug.exceptions import Forbidden, NotFound, Unauthorized
|
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_database import db
|
||||||
from extensions.ext_redis import redis_client
|
from extensions.ext_redis import redis_client
|
||||||
from libs.datetime_utils import naive_utc_now
|
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.
|
Create or update session terminal based on user ID.
|
||||||
"""
|
"""
|
||||||
if not 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:
|
with Session(db.engine, expire_on_commit=False) as session:
|
||||||
end_user = (
|
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,
|
tenant_id=app_model.tenant_id,
|
||||||
app_id=app_model.id,
|
app_id=app_model.id,
|
||||||
type="service_api",
|
type="service_api",
|
||||||
is_anonymous=user_id == "DEFAULT-USER",
|
is_anonymous=user_id == DEFAULT_SERVICE_API_USER_ID,
|
||||||
session_id=user_id,
|
session_id=user_id,
|
||||||
)
|
)
|
||||||
session.add(end_user)
|
session.add(end_user)
|
||||||
|
|||||||
@ -9,3 +9,7 @@ FILE_MODEL_IDENTITY = "__dify__file__"
|
|||||||
|
|
||||||
def maybe_file_object(o: Any) -> bool:
|
def maybe_file_object(o: Any) -> bool:
|
||||||
return isinstance(o, dict) and o.get("dify_model_identity") == FILE_MODEL_IDENTITY
|
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"
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import os
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from configs import dify_config
|
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:
|
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"
|
url = f"{base_url}/files/upload/for-plugin"
|
||||||
|
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
user_id = "DEFAULT-USER"
|
user_id = DEFAULT_SERVICE_API_USER_ID
|
||||||
|
|
||||||
timestamp = str(int(time.time()))
|
timestamp = str(int(time.time()))
|
||||||
nonce = os.urandom(16).hex()
|
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
|
*, filename: str, mimetype: str, tenant_id: str, user_id: str | None, timestamp: str, nonce: str, sign: str
|
||||||
) -> bool:
|
) -> bool:
|
||||||
if user_id is None:
|
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}"
|
data_to_sign = f"upload|{filename}|{mimetype}|{tenant_id}|{user_id}|{timestamp}|{nonce}"
|
||||||
secret_key = dify_config.SECRET_KEY.encode()
|
secret_key = dify_config.SECRET_KEY.encode()
|
||||||
|
|||||||
Reference in New Issue
Block a user