mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
101 lines
2.6 KiB
Python
101 lines
2.6 KiB
Python
import time
|
|
import warnings
|
|
|
|
import requests
|
|
|
|
from openhands.server.github_utils import (
|
|
GITHUB_CLIENT_ID,
|
|
GITHUB_CLIENT_SECRET,
|
|
authenticate_github_user,
|
|
)
|
|
|
|
with warnings.catch_warnings():
|
|
warnings.simplefilter('ignore')
|
|
|
|
from fastapi import (
|
|
APIRouter,
|
|
Request,
|
|
status,
|
|
)
|
|
from fastapi.responses import JSONResponse
|
|
from pydantic import BaseModel
|
|
|
|
from openhands.core.logger import openhands_logger as logger
|
|
from openhands.server.auth import sign_token
|
|
from openhands.server.shared import config
|
|
|
|
app = APIRouter(prefix='/api')
|
|
|
|
|
|
class AuthCode(BaseModel):
|
|
code: str
|
|
|
|
|
|
@app.post('/github/callback')
|
|
def github_callback(auth_code: AuthCode):
|
|
# Prepare data for the token exchange request
|
|
data = {
|
|
'client_id': GITHUB_CLIENT_ID,
|
|
'client_secret': GITHUB_CLIENT_SECRET,
|
|
'code': auth_code.code,
|
|
}
|
|
|
|
logger.debug('Exchanging code for GitHub token')
|
|
|
|
headers = {'Accept': 'application/json'}
|
|
response = requests.post(
|
|
'https://github.com/login/oauth/access_token', data=data, headers=headers
|
|
)
|
|
|
|
if response.status_code != 200:
|
|
logger.error(f'Failed to exchange code for token: {response.text}')
|
|
return JSONResponse(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
content={'error': 'Failed to exchange code for token'},
|
|
)
|
|
|
|
token_response = response.json()
|
|
|
|
if 'access_token' not in token_response:
|
|
return JSONResponse(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
content={'error': 'No access token in response'},
|
|
)
|
|
|
|
return JSONResponse(
|
|
status_code=status.HTTP_200_OK,
|
|
content={'access_token': token_response['access_token']},
|
|
)
|
|
|
|
|
|
@app.post('/authenticate')
|
|
async def authenticate(request: Request):
|
|
token = request.headers.get('X-GitHub-Token')
|
|
if not await authenticate_github_user(token):
|
|
return JSONResponse(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
content={'error': 'Not authorized via GitHub waitlist'},
|
|
)
|
|
|
|
# Create a signed JWT token with 1-hour expiration
|
|
cookie_data = {
|
|
'github_token': token,
|
|
'exp': int(time.time()) + 3600, # 1 hour expiration
|
|
}
|
|
signed_token = sign_token(cookie_data, config.jwt_secret)
|
|
|
|
response = JSONResponse(
|
|
status_code=status.HTTP_200_OK, content={'message': 'User authenticated'}
|
|
)
|
|
|
|
# Set secure cookie with signed token
|
|
response.set_cookie(
|
|
key='github_auth',
|
|
value=signed_token,
|
|
max_age=3600, # 1 hour in seconds
|
|
httponly=True,
|
|
secure=True,
|
|
samesite='strict',
|
|
)
|
|
return response
|