feat: add project

This commit is contained in:
qixinbo
2026-03-16 16:12:35 +08:00
parent 1354a0cbc6
commit cec5fde098
23 changed files with 990 additions and 179 deletions
+25 -38
View File
@@ -1,57 +1,35 @@
from typing import List, Dict, Any
from typing import List, Dict, Any, Optional
from fastapi import APIRouter, HTTPException, Depends, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from jose import jwt, JWTError
from sqlalchemy.orm import Session
from app.database import get_db
from app.models.datasource import DataSource
from app.schemas.datasource import DataSourceCreate, DataSourceUpdate, DataSource as DataSourceSchema, DataSourceTestRequest
from app.core.security import SECRET_KEY, ALGORITHM
from app.core.security import get_current_user, get_admin_user, CurrentUser
from app.connectors.factory import get_connector_from_config
from pydantic import BaseModel
router = APIRouter()
security = HTTPBearer()
class CurrentUser(BaseModel):
id: int
username: str
is_admin: bool = False
def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> CurrentUser:
unauthorized = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
)
try:
payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])
except JWTError:
raise unauthorized
user_id = payload.get("id")
username = payload.get("sub")
is_admin = bool(payload.get("is_admin", False))
if user_id is None or username is None:
raise unauthorized
return CurrentUser(id=user_id, username=username, is_admin=is_admin)
def get_admin_user(current_user: CurrentUser = Depends(get_current_user)) -> CurrentUser:
if not current_user.is_admin:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Admin permission required")
return current_user
@router.get("/datasources", response_model=List[DataSourceSchema])
def list_datasources(
project_id: Optional[int] = None,
skip: int = 0,
limit: int = 100,
db: Session = Depends(get_db),
current_user: CurrentUser = Depends(get_current_user)
):
# Admin can see all, regular user might only see allowed ones?
# For now, let's assume only admin can manage, but maybe regular users can see them to use?
# The requirement says "Add data source config in Admin User Center", implying management is admin-only.
# But usage in chat should be available to users.
# Let's allow read for all authenticated users for now.
datasources = db.query(DataSource).offset(skip).limit(limit).all()
query = db.query(DataSource)
if project_id:
query = query.filter(DataSource.project_id == project_id)
# If not admin, check if user has access to the project
if not current_user.is_admin and project_id:
from app.models.project import Project
project = db.query(Project).filter(Project.id == project_id).first()
if not project or project.owner_id != current_user.id:
raise HTTPException(status_code=403, detail="Not enough permissions for this project")
datasources = query.offset(skip).limit(limit).all()
# Hide sensitive info for non-admins if necessary, but config usually contains secrets.
# Maybe we should return a sanitized version for regular users?
@@ -75,8 +53,17 @@ def list_datasources(
def create_datasource(
datasource: DataSourceCreate,
db: Session = Depends(get_db),
_: CurrentUser = Depends(get_admin_user)
current_user: CurrentUser = Depends(get_current_user)
):
# Check if project exists and user has access
from app.models.project import Project
project = db.query(Project).filter(Project.id == datasource.project_id).first()
if not project:
raise HTTPException(status_code=404, detail="Project not found")
if not current_user.is_admin and project.owner_id != current_user.id:
raise HTTPException(status_code=403, detail="Not enough permissions for this project")
db_datasource = DataSource(**datasource.dict())
db.add(db_datasource)
db.commit()