ozellik: google oauth, gmail-drive araclari ve admin durum kartlarini ekle
This commit is contained in:
@@ -1,12 +1,27 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.admin.services import AdminService
|
||||
from app.config import get_settings as get_app_settings
|
||||
from app.db import SecretORM, get_session
|
||||
from app.google.auth import GoogleAuthError, GoogleAuthManager
|
||||
from app.llm.ollama_client import OllamaClient
|
||||
from app.models import AutomationRecord, MemoryRecord, OllamaStatus, RuntimeSettings, TelegramStatus, UserProfileRecord, UserRecord
|
||||
from app.models import (
|
||||
AnythingLLMStatus,
|
||||
AutomationRecord,
|
||||
GoogleIntegrationStatus,
|
||||
MemoryRecord,
|
||||
OllamaStatus,
|
||||
RuntimeSettings,
|
||||
TelegramStatus,
|
||||
UserProfileRecord,
|
||||
UserRecord,
|
||||
)
|
||||
from app.tools.second_brain import SecondBrainTool
|
||||
|
||||
router = APIRouter(prefix="/admin", tags=["admin"])
|
||||
|
||||
@@ -16,10 +31,29 @@ class SecretPayload(BaseModel):
|
||||
value: str
|
||||
|
||||
|
||||
class GoogleClientPayload(BaseModel):
|
||||
client_id: str
|
||||
client_secret: str
|
||||
|
||||
|
||||
def get_admin_service(session: Session = Depends(get_session)) -> AdminService:
|
||||
return AdminService(session)
|
||||
|
||||
|
||||
def get_google_auth_manager() -> GoogleAuthManager:
|
||||
return GoogleAuthManager(get_app_settings(), Path(__file__).resolve().parents[2])
|
||||
|
||||
|
||||
def sync_google_client_file(service: AdminService, manager: GoogleAuthManager) -> None:
|
||||
settings = get_app_settings()
|
||||
client_id_record = service.session.get(SecretORM, "google_client_id")
|
||||
client_secret_record = service.session.get(SecretORM, "google_client_secret")
|
||||
client_id = (client_id_record.value if client_id_record else settings.google_client_id).strip()
|
||||
client_secret = (client_secret_record.value if client_secret_record else settings.google_client_secret).strip()
|
||||
if client_id and client_secret:
|
||||
manager.write_client_secrets_file(client_id, client_secret)
|
||||
|
||||
|
||||
@router.get("/dashboard")
|
||||
def get_dashboard(service: AdminService = Depends(get_admin_service)):
|
||||
return service.dashboard()
|
||||
@@ -77,6 +111,18 @@ def post_secret(payload: SecretPayload, service: AdminService = Depends(get_admi
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@router.post("/integrations/google/client")
|
||||
def post_google_client(
|
||||
payload: GoogleClientPayload,
|
||||
service: AdminService = Depends(get_admin_service),
|
||||
manager: GoogleAuthManager = Depends(get_google_auth_manager),
|
||||
):
|
||||
service.save_secret("google_client_id", payload.client_id.strip())
|
||||
service.save_secret("google_client_secret", payload.client_secret.strip())
|
||||
sync_google_client_file(service, manager)
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@router.get("/integrations/llm", response_model=OllamaStatus)
|
||||
@router.get("/integrations/ollama", response_model=OllamaStatus)
|
||||
async def get_llm_status(service: AdminService = Depends(get_admin_service)):
|
||||
@@ -94,3 +140,116 @@ async def get_llm_status(service: AdminService = Depends(get_admin_service)):
|
||||
@router.get("/integrations/telegram", response_model=TelegramStatus)
|
||||
def get_telegram_status(service: AdminService = Depends(get_admin_service)):
|
||||
return service.telegram_status()
|
||||
|
||||
|
||||
@router.get("/integrations/anythingllm", response_model=AnythingLLMStatus)
|
||||
async def get_anythingllm_status(service: AdminService = Depends(get_admin_service)):
|
||||
runtime = service.get_runtime_settings()
|
||||
settings = get_app_settings()
|
||||
secret = service.session.get(SecretORM, "anythingllm_api_key")
|
||||
tool = SecondBrainTool(
|
||||
base_url=runtime.anythingllm_base_url,
|
||||
workspace_slug=runtime.anythingllm_workspace_slug,
|
||||
api_key=secret.value if secret else settings.anythingllm_api_key,
|
||||
)
|
||||
status = await tool.status()
|
||||
return AnythingLLMStatus(
|
||||
reachable=bool(status.get("reachable")),
|
||||
workspace_found=bool(status.get("workspace_found")),
|
||||
base_url=runtime.anythingllm_base_url,
|
||||
workspace_slug=runtime.anythingllm_workspace_slug,
|
||||
message=str(status.get("message", "")),
|
||||
)
|
||||
|
||||
|
||||
@router.get("/integrations/google", response_model=GoogleIntegrationStatus)
|
||||
def get_google_status(
|
||||
request: Request,
|
||||
service: AdminService = Depends(get_admin_service),
|
||||
manager: GoogleAuthManager = Depends(get_google_auth_manager),
|
||||
):
|
||||
sync_google_client_file(service, manager)
|
||||
client_configured, connected, message = manager.oauth_status()
|
||||
connect_url = str(request.url_for("google_oauth_connect"))
|
||||
return GoogleIntegrationStatus(
|
||||
client_configured=client_configured,
|
||||
connected=connected,
|
||||
connect_url=connect_url,
|
||||
message=message,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/integrations/google/connect", name="google_oauth_connect")
|
||||
def google_oauth_connect(
|
||||
request: Request,
|
||||
service: AdminService = Depends(get_admin_service),
|
||||
manager: GoogleAuthManager = Depends(get_google_auth_manager),
|
||||
):
|
||||
redirect_uri = str(request.url_for("google_oauth_callback"))
|
||||
try:
|
||||
sync_google_client_file(service, manager)
|
||||
authorization_url = manager.begin_web_oauth(redirect_uri)
|
||||
except GoogleAuthError as exc:
|
||||
return HTMLResponse(
|
||||
(
|
||||
"<html><body style='font-family: sans-serif; padding: 24px;'>"
|
||||
f"<h2>Google connect failed</h2><p>{exc}</p>"
|
||||
"<p>Add your client_secret.json file, then try the connect button again.</p>"
|
||||
"</body></html>"
|
||||
),
|
||||
status_code=400,
|
||||
)
|
||||
return RedirectResponse(url=authorization_url)
|
||||
|
||||
|
||||
@router.get("/integrations/google/callback", response_class=HTMLResponse, name="google_oauth_callback")
|
||||
def google_oauth_callback(
|
||||
request: Request,
|
||||
state: str | None = None,
|
||||
error: str | None = None,
|
||||
manager: GoogleAuthManager = Depends(get_google_auth_manager),
|
||||
):
|
||||
if error:
|
||||
return HTMLResponse(
|
||||
(
|
||||
"<html><body style='font-family: sans-serif; padding: 24px;'>"
|
||||
f"<h2>Google connect failed</h2><p>{error}</p>"
|
||||
"<p>You can close this tab and try again from the WiseClaw admin panel.</p>"
|
||||
"</body></html>"
|
||||
),
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
if not state:
|
||||
return HTMLResponse(
|
||||
(
|
||||
"<html><body style='font-family: sans-serif; padding: 24px;'>"
|
||||
"<h2>Google connect failed</h2><p>Missing OAuth state.</p>"
|
||||
"<p>You can close this tab and try again from the WiseClaw admin panel.</p>"
|
||||
"</body></html>"
|
||||
),
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
try:
|
||||
manager.complete_web_oauth(str(request.url_for("google_oauth_callback")), state, str(request.url))
|
||||
except Exception as exc:
|
||||
return HTMLResponse(
|
||||
(
|
||||
"<html><body style='font-family: sans-serif; padding: 24px;'>"
|
||||
f"<h2>Google connect failed</h2><p>{exc}</p>"
|
||||
"<p>You can close this tab and try again from the WiseClaw admin panel.</p>"
|
||||
"</body></html>"
|
||||
),
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
return HTMLResponse(
|
||||
(
|
||||
"<html><body style='font-family: sans-serif; padding: 24px;'>"
|
||||
"<h2>Google account connected</h2>"
|
||||
"<p>WiseClaw can now use your Gmail and Google Drive tools.</p>"
|
||||
"<p>You can close this tab and refresh the admin panel.</p>"
|
||||
"</body></html>"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -169,7 +169,11 @@ class AdminService:
|
||||
|
||||
def get_secret_mask(self, key: str) -> str:
|
||||
record = self.session.get(SecretORM, key)
|
||||
value = record.value if record else ""
|
||||
if record is not None:
|
||||
value = record.value
|
||||
else:
|
||||
settings = get_settings()
|
||||
value = str(getattr(settings, key, "") or "")
|
||||
if len(value) < 4:
|
||||
return ""
|
||||
return f"{value[:2]}***{value[-2:]}"
|
||||
|
||||
Reference in New Issue
Block a user