github.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import os
  2. import httpx
  3. from openhands.core.logger import openhands_logger as logger
  4. GITHUB_CLIENT_ID = os.getenv('GITHUB_CLIENT_ID', '').strip()
  5. GITHUB_CLIENT_SECRET = os.getenv('GITHUB_CLIENT_SECRET', '').strip()
  6. GITHUB_USER_LIST = None
  7. def load_github_user_list():
  8. global GITHUB_USER_LIST
  9. waitlist = os.getenv('GITHUB_USER_LIST_FILE')
  10. if waitlist:
  11. with open(waitlist, 'r') as f:
  12. GITHUB_USER_LIST = [line.strip() for line in f if line.strip()]
  13. load_github_user_list()
  14. async def authenticate_github_user(auth_token) -> bool:
  15. logger.info('Checking GitHub token')
  16. if not GITHUB_USER_LIST:
  17. return True
  18. if not auth_token:
  19. logger.warning('No GitHub token provided')
  20. return False
  21. login, error = await get_github_user(auth_token)
  22. if error:
  23. logger.warning(f'Invalid GitHub token: {error}')
  24. return False
  25. if login not in GITHUB_USER_LIST:
  26. logger.warning(f'GitHub user {login} not in allow list')
  27. return False
  28. logger.info(f'GitHub user {login} authenticated')
  29. return True
  30. async def get_github_user(token: str) -> tuple[str | None, str | None]:
  31. """Get GitHub user info from token.
  32. Args:
  33. token: GitHub access token
  34. Returns:
  35. Tuple of (login, error_message)
  36. If successful, error_message is None
  37. If failed, login is None and error_message contains the error
  38. """
  39. headers = {
  40. 'Accept': 'application/vnd.github+json',
  41. 'Authorization': f'Bearer {token}',
  42. 'X-GitHub-Api-Version': '2022-11-28',
  43. }
  44. try:
  45. async with httpx.AsyncClient() as client:
  46. response = await client.get('https://api.github.com/user', headers=headers)
  47. if response.status_code == 200:
  48. user_data = response.json()
  49. return user_data.get('login'), None
  50. else:
  51. return (
  52. None,
  53. f'GitHub API error: {response.status_code} - {response.text}',
  54. )
  55. except Exception as e:
  56. return None, f'Error connecting to GitHub: {str(e)}'