mirror of
https://github.com/langgenius/dify.git
synced 2026-04-28 20:17:29 +08:00
fix: exchange public token
This commit is contained in:
parent
3c3261b42e
commit
bc8f741859
@ -1,18 +1,19 @@
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import UTC, datetime, timedelta
|
from datetime import UTC, datetime, timedelta
|
||||||
|
|
||||||
from flask import request
|
|
||||||
from flask_restful import Resource
|
|
||||||
from werkzeug.exceptions import NotFound, Unauthorized
|
|
||||||
|
|
||||||
from configs import dify_config
|
from configs import dify_config
|
||||||
from controllers.web import api
|
from controllers.web import api
|
||||||
from controllers.web.error import WebAppAuthRequiredError
|
from controllers.web.error import WebAppAuthRequiredError
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
|
from flask import request
|
||||||
|
from flask_restful import Resource
|
||||||
from libs.passport import PassportService
|
from libs.passport import PassportService
|
||||||
from models.model import App, EndUser, Site
|
from models.model import App, EndUser, Site
|
||||||
from services.enterprise.enterprise_service import EnterpriseService
|
from services.enterprise.enterprise_service import EnterpriseService
|
||||||
from services.feature_service import FeatureService
|
from services.feature_service import FeatureService
|
||||||
|
from werkzeug.exceptions import NotFound, Unauthorized
|
||||||
|
|
||||||
|
from api.services.webapp_auth_service import WebAppAuthService, WebAppAuthType
|
||||||
|
|
||||||
|
|
||||||
class PassportResource(Resource):
|
class PassportResource(Resource):
|
||||||
@ -116,7 +117,9 @@ def exchange_token_for_existing_web_user(app_code: str, enterprise_user_decoded:
|
|||||||
user_id = enterprise_user_decoded.get("user_id")
|
user_id = enterprise_user_decoded.get("user_id")
|
||||||
end_user_id = enterprise_user_decoded.get("end_user_id")
|
end_user_id = enterprise_user_decoded.get("end_user_id")
|
||||||
session_id = enterprise_user_decoded.get("session_id")
|
session_id = enterprise_user_decoded.get("session_id")
|
||||||
auth_type = enterprise_user_decoded.get("auth_type")
|
user_auth_type = enterprise_user_decoded.get("auth_type")
|
||||||
|
if not user_auth_type:
|
||||||
|
raise Unauthorized("Missing auth_type in the token.")
|
||||||
|
|
||||||
site = db.session.query(Site).filter(Site.code == app_code, Site.status == "normal").first()
|
site = db.session.query(Site).filter(Site.code == app_code, Site.status == "normal").first()
|
||||||
if not site:
|
if not site:
|
||||||
@ -126,13 +129,15 @@ def exchange_token_for_existing_web_user(app_code: str, enterprise_user_decoded:
|
|||||||
if not app_model or app_model.status != "normal" or not app_model.enable_site:
|
if not app_model or app_model.status != "normal" or not app_model.enable_site:
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
|
|
||||||
if not auth_type:
|
app_auth_type = WebAppAuthService.get_app_auth_type(app_code=app_code)
|
||||||
raise Unauthorized("Missing auth_type in the token.")
|
|
||||||
settings = EnterpriseService.WebAppAuth.get_app_access_mode_by_code(app_code=app_code)
|
if app_auth_type == WebAppAuthType.PUBLIC:
|
||||||
if settings.access_mode == "sso_verified" and auth_type != "external":
|
return _exchange_for_public_app_token(app_model, site)
|
||||||
|
elif app_auth_type == WebAppAuthType.EXTERNAL and user_auth_type != "external":
|
||||||
raise WebAppAuthRequiredError("Please login as external user.")
|
raise WebAppAuthRequiredError("Please login as external user.")
|
||||||
elif settings.access_mode in ["private", "private_all"] and auth_type == "external":
|
elif app_auth_type == WebAppAuthType.INTERNAL and user_auth_type != "internal":
|
||||||
raise WebAppAuthRequiredError("Please login as internal user.")
|
raise WebAppAuthRequiredError("Please login as internal user.")
|
||||||
|
|
||||||
end_user = None
|
end_user = None
|
||||||
if end_user_id:
|
if end_user_id:
|
||||||
end_user = db.session.query(EndUser).filter(EndUser.id == end_user_id).first()
|
end_user = db.session.query(EndUser).filter(EndUser.id == end_user_id).first()
|
||||||
@ -158,7 +163,6 @@ def exchange_token_for_existing_web_user(app_code: str, enterprise_user_decoded:
|
|||||||
)
|
)
|
||||||
db.session.add(end_user)
|
db.session.add(end_user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
exp_dt = datetime.now(UTC) + timedelta(hours=dify_config.ACCESS_TOKEN_EXPIRE_MINUTES * 24)
|
exp_dt = datetime.now(UTC) + timedelta(hours=dify_config.ACCESS_TOKEN_EXPIRE_MINUTES * 24)
|
||||||
exp = int(exp_dt.timestamp())
|
exp = int(exp_dt.timestamp())
|
||||||
payload = {
|
payload = {
|
||||||
@ -168,7 +172,7 @@ def exchange_token_for_existing_web_user(app_code: str, enterprise_user_decoded:
|
|||||||
"app_code": site.code,
|
"app_code": site.code,
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
"end_user_id": end_user.id,
|
"end_user_id": end_user.id,
|
||||||
"auth_type": auth_type,
|
"auth_type": user_auth_type,
|
||||||
"granted_at": int(datetime.now(UTC).timestamp()),
|
"granted_at": int(datetime.now(UTC).timestamp()),
|
||||||
"token_source": "webapp",
|
"token_source": "webapp",
|
||||||
"exp": exp,
|
"exp": exp,
|
||||||
@ -179,6 +183,33 @@ def exchange_token_for_existing_web_user(app_code: str, enterprise_user_decoded:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _exchange_for_public_app_token(app_model, site):
|
||||||
|
end_user = EndUser(
|
||||||
|
tenant_id=app_model.tenant_id,
|
||||||
|
app_id=app_model.id,
|
||||||
|
type="browser",
|
||||||
|
is_anonymous=True,
|
||||||
|
session_id=generate_session_id(),
|
||||||
|
)
|
||||||
|
|
||||||
|
db.session.add(end_user)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"iss": site.app_id,
|
||||||
|
"sub": "Web API Passport",
|
||||||
|
"app_id": site.app_id,
|
||||||
|
"app_code": site.code,
|
||||||
|
"end_user_id": end_user.id,
|
||||||
|
}
|
||||||
|
|
||||||
|
tk = PassportService().issue(payload)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"access_token": tk,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def generate_session_id():
|
def generate_session_id():
|
||||||
"""
|
"""
|
||||||
Generate a unique session ID.
|
Generate a unique session ID.
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import enum
|
||||||
import random
|
import random
|
||||||
from datetime import UTC, datetime, timedelta
|
from datetime import UTC, datetime, timedelta
|
||||||
from typing import Any, Optional, cast
|
from typing import Any, Optional, cast
|
||||||
@ -17,6 +18,14 @@ from services.errors.account import AccountLoginError, AccountNotFoundError, Acc
|
|||||||
from tasks.mail_email_code_login import send_email_code_login_mail_task
|
from tasks.mail_email_code_login import send_email_code_login_mail_task
|
||||||
|
|
||||||
|
|
||||||
|
class WebAppAuthType(enum.StrEnum):
|
||||||
|
"""Enum for web app authentication types."""
|
||||||
|
|
||||||
|
PUBLIC = "public"
|
||||||
|
INTERNAL = "internal"
|
||||||
|
EXTERNAL = "external"
|
||||||
|
|
||||||
|
|
||||||
class WebAppAuthService:
|
class WebAppAuthService:
|
||||||
"""Service for web app authentication."""
|
"""Service for web app authentication."""
|
||||||
|
|
||||||
@ -145,3 +154,25 @@ class WebAppAuthService:
|
|||||||
if webapp_settings and webapp_settings.access_mode in modes_requiring_permission_check:
|
if webapp_settings and webapp_settings.access_mode in modes_requiring_permission_check:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_app_auth_type(cls, app_code: str | None = None, access_mode: str | None = None) -> WebAppAuthType:
|
||||||
|
"""
|
||||||
|
Get the authentication type for the app based on its access mode.
|
||||||
|
"""
|
||||||
|
if not app_code and not access_mode:
|
||||||
|
raise ValueError("Either app_code or access_mode must be provided.")
|
||||||
|
|
||||||
|
if access_mode:
|
||||||
|
if access_mode == "public":
|
||||||
|
return WebAppAuthType.PUBLIC
|
||||||
|
elif access_mode in ["private", "private_all"]:
|
||||||
|
return WebAppAuthType.INTERNAL
|
||||||
|
elif access_mode == "sso_verified":
|
||||||
|
return WebAppAuthType.EXTERNAL
|
||||||
|
|
||||||
|
if app_code:
|
||||||
|
webapp_settings = EnterpriseService.WebAppAuth.get_app_access_mode_by_code(app_code)
|
||||||
|
return cls.get_app_auth_type(access_mode=webapp_settings.access_mode)
|
||||||
|
|
||||||
|
raise ValueError("Could not determine app authentication type.")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user