Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions backend/alembic/versions/048_authentication_ddl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""048_authentication_ddl

Revision ID: 073bf544b373
Revises: c1b794a961ce
Create Date: 2025-10-30 14:11:29.786938

"""
from alembic import op
import sqlalchemy as sa
import sqlmodel.sql.sqltypes

# revision identifiers, used by Alembic.
revision = '073bf544b373'
down_revision = 'c1b794a961ce'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('sys_authentication',
sa.Column('id', sa.BigInteger(), nullable=False),
sa.Column('name', sa.String(255), nullable=False),
sa.Column('type', sa.Integer(), nullable=False),
sa.Column('config', sa.Text(), nullable=True),
sa.Column('enable', sa.Boolean(), nullable=False),
sa.Column('valid', sa.Boolean(), nullable=False),
sa.Column('create_time', sa.BigInteger(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_sys_authentication_id'), 'sys_authentication', ['id'], unique=False)

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_sys_authentication_id'), table_name='sys_authentication')
op.drop_table('sys_authentication')
# ### end Alembic commands ###
42 changes: 42 additions & 0 deletions backend/alembic/versions/049_user_platform_ddl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""049_user_platform_ddl

Revision ID: b58a71ca6ae3
Revises: 073bf544b373
Create Date: 2025-11-04 12:31:56.481582

"""
from alembic import op
import sqlalchemy as sa
import sqlmodel.sql.sqltypes

# revision identifiers, used by Alembic.
revision = 'b58a71ca6ae3'
down_revision = '073bf544b373'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('sys_user_platform',
sa.Column('uid', sa.BigInteger(), nullable=False),
sa.Column('origin', sa.Integer(), server_default='0', nullable=False),
sa.Column('platform_uid', sa.String(255), nullable=False),
sa.Column('id', sa.BigInteger(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_sys_user_platform_id'), 'sys_user_platform', ['id'], unique=False)

op.add_column('sys_user', sa.Column('origin', sa.Integer(), server_default='0', nullable=False))

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###

op.drop_column('sys_user', 'origin')

op.drop_index(op.f('ix_sys_user_platform_id'), table_name='sys_user_platform')
op.drop_table('sys_user_platform')
# ### end Alembic commands ###
12 changes: 10 additions & 2 deletions backend/apps/system/api/login.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Annotated
from fastapi import APIRouter, Depends, HTTPException
from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi.security import OAuth2PasswordRequestForm
from apps.system.schemas.logout_schema import LogoutSchema
from apps.system.schemas.system_schema import BaseUserDTO
from common.core.deps import SessionDep, Trans
from common.utils.crypto import sqlbot_decrypt
Expand All @@ -9,6 +10,7 @@
from datetime import timedelta
from common.core.config import settings
from common.core.schemas import Token
from sqlbot_xpack.authentication.manage import logout as xpack_logout
router = APIRouter(tags=["login"], prefix="/login")

@router.post("/access-token")
Expand All @@ -30,4 +32,10 @@ async def local_login(
user_dict = user.to_dict()
return Token(access_token=create_access_token(
user_dict, expires_delta=access_token_expires
))
))

@router.post("/logout")
async def logout(session: SessionDep, request: Request, dto: LogoutSchema):
if dto.origin != 0:
return await xpack_logout(session, request, dto)
return None
14 changes: 13 additions & 1 deletion backend/apps/system/models/system_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,16 @@ class AssistantBaseModel(SQLModel):

class AssistantModel(SnowflakeBase, AssistantBaseModel, table=True):
__tablename__ = "sys_assistant"



class AuthenticationBaseModel(SQLModel):
name: str = Field(max_length=255, nullable=False)
type: int = Field(nullable=False, default=0)
config: Optional[str] = Field(sa_type = Text(), nullable=True)


class AuthenticationModel(SnowflakeBase, AuthenticationBaseModel, table=True):
__tablename__ = "sys_authentication"
create_time: Optional[int] = Field(default=0, sa_type=BigInteger())
enable: bool = Field(default=False, nullable=False)
valid: bool = Field(default=False, nullable=False)
11 changes: 11 additions & 0 deletions backend/apps/system/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,20 @@ class BaseUserPO(SQLModel):
password: str = Field(default_factory=default_md5_pwd, max_length=255)
email: str = Field(max_length=255)
status: int = Field(default=0, nullable=False)
origin: int = Field(nullable=False, default=0)
create_time: int = Field(default_factory=get_timestamp, sa_type=BigInteger(), nullable=False)
language: str = Field(max_length=255, default="zh-CN")

class UserModel(SnowflakeBase, BaseUserPO, table=True):
__tablename__ = "sys_user"


class UserPlatformBase(SQLModel):
uid: int = Field(nullable=False, sa_type=BigInteger())
origin: int = Field(nullable=False, default=0)
platform_uid: str = Field(max_length=255, nullable=False)

class UserPlatformModel(SnowflakeBase, UserPlatformBase, table=True):
__tablename__ = "sys_user_platform"


4 changes: 3 additions & 1 deletion backend/apps/system/schemas/auth.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

from typing import Optional
from pydantic import BaseModel
from enum import Enum

Expand All @@ -16,4 +17,5 @@ class CacheName(Enum):
ASSISTANT_INFO = "assistant:info"
ASSISTANT_DS = "assistant:ds"
def __str__(self):
return self.value
return self.value

9 changes: 9 additions & 0 deletions backend/apps/system/schemas/logout_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from typing import Optional
from pydantic import BaseModel


class LogoutSchema(BaseModel):
token: Optional[str] = None
flag: Optional[str] = 'default'
origin: Optional[int] = 0
data: Optional[str] = None
3 changes: 2 additions & 1 deletion backend/apps/system/schemas/system_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class UserCreator(BaseUser):
name: str = Field(min_length=1, max_length=100, description="用户名")
email: str = Field(min_length=1, max_length=100, description="用户邮箱")
status: int = 1
origin: Optional[int] = 0
oid_list: Optional[list[int]] = None

""" @field_validator("email")
Expand All @@ -70,7 +71,7 @@ class UserGrid(UserEditor):
create_time: int
language: str = "zh-CN"
# space_name: Optional[str] = None
origin: str = ''
# origin: str = ''


class PwdEditor(BaseModel):
Expand Down
31 changes: 31 additions & 0 deletions backend/common/utils/http_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import Tuple
import requests
from urllib.parse import urlparse
from requests.exceptions import RequestException, Timeout

def verify_url(url: str, timeout: int = 5) -> Tuple[bool, str]:
try:
parsed = urlparse(url)
if not all([parsed.scheme, parsed.netloc]):
return False, "无效的 URL 格式"

if parsed.scheme not in ['http', 'https']:
return False, "URL 必须以 http 或 https 开头"

response = requests.get(
url,
timeout=timeout,
verify=False # 忽略 SSL 证书验证
)

if response.status_code < 400:
return True, "URL 可达"
else:
return False, f"服务器返回错误状态码: {response.status_code}"

except Timeout:
return False, f"连接超时 (>{timeout}秒)"
except RequestException as e:
return False, f"连接失败: {str(e)}"
except Exception as e:
return False, f"验证过程发生错误: {str(e)}"
5 changes: 4 additions & 1 deletion backend/common/utils/whitelist.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
"/system/assistant/info/*",
"/system/assistant/app/*",
"/system/assistant/picture/*",
"/datasource/uploadExcel"
"/datasource/uploadExcel",
"/system/authentication/platform/status",
"/system/authentication/login/*",
"/system/authentication/sso/*",
]

class WhitelistChecker:
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/api/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ export const AuthApi = {
},
})
},
logout: () => request.post('/auth/logout'),
logout: (data: any) => request.post('/login/logout', data),
info: () => request.get('/user/info'),
}
16 changes: 16 additions & 0 deletions frontend/src/assets/svg/logo_cas.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions frontend/src/assets/svg/logo_dingtalk.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions frontend/src/assets/svg/logo_lark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions frontend/src/assets/svg/logo_ldap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading