mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
import asyncio
|
|
|
|
from pydantic import SecretStr
|
|
from sqlalchemy import select
|
|
|
|
from openhands.core.logger import openhands_logger as logger
|
|
from openhands.integrations.service_types import ProviderType
|
|
from openhands.server.types import AppMode
|
|
|
|
|
|
async def _user_has_gitlab_provider(user_id: str) -> bool:
|
|
"""Check if the user has authenticated with GitLab.
|
|
|
|
Args:
|
|
user_id: The Keycloak user ID
|
|
|
|
Returns:
|
|
True if the user has a GitLab provider token, False otherwise
|
|
"""
|
|
# Lazy import to avoid circular dependency issues at module load time
|
|
from storage.auth_tokens import AuthTokens
|
|
from storage.database import a_session_maker
|
|
|
|
async with a_session_maker() as session:
|
|
result = await session.execute(
|
|
select(AuthTokens).where(
|
|
AuthTokens.keycloak_user_id == user_id,
|
|
AuthTokens.identity_provider == ProviderType.GITLAB.value,
|
|
)
|
|
)
|
|
return result.scalars().first() is not None
|
|
|
|
|
|
def schedule_gitlab_repo_sync(
|
|
user_id: str, keycloak_access_token: SecretStr | None = None
|
|
) -> None:
|
|
"""Schedule a background sync of GitLab repositories and webhook tracking.
|
|
|
|
Because the outer call is already a background task, we instruct the service
|
|
to store repository data synchronously (store_in_background=False) to avoid
|
|
nested background tasks while still keeping the overall operation async.
|
|
|
|
The sync is only performed if the user has authenticated with GitLab.
|
|
"""
|
|
|
|
async def _run():
|
|
try:
|
|
# Check if the user has a GitLab provider token before syncing
|
|
if not await _user_has_gitlab_provider(user_id):
|
|
logger.debug(
|
|
'gitlab_repo_sync_skipped: user has no GitLab provider',
|
|
extra={'user_id': user_id},
|
|
)
|
|
return
|
|
|
|
# Lazy import to avoid circular dependency:
|
|
# middleware -> gitlab_sync -> integrations.gitlab.gitlab_service
|
|
# -> openhands.integrations.gitlab.gitlab_service -> get_impl
|
|
# -> integrations.gitlab.gitlab_service (circular)
|
|
from integrations.gitlab.gitlab_service import SaaSGitLabService
|
|
|
|
service = SaaSGitLabService(
|
|
external_auth_id=user_id, external_auth_token=keycloak_access_token
|
|
)
|
|
await service.get_all_repositories(
|
|
'pushed', AppMode.SAAS, store_in_background=False
|
|
)
|
|
except Exception:
|
|
logger.warning('gitlab_repo_sync_failed', exc_info=True)
|
|
|
|
asyncio.create_task(_run())
|