Handle GitHub OAuth callback for account linking
(
request: Request,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
github_service: GitHubService = Depends(get_github_service),
oauth_client=Depends(get_github_oauth_client),
)
| 206 | |
| 207 | @router.get("/authorize/callback", name="github_authorize_callback") |
| 208 | async def github_authorize_callback( |
| 209 | request: Request, |
| 210 | current_user: User = Depends(get_current_user), |
| 211 | db: AsyncSession = Depends(get_db), |
| 212 | github_service: GitHubService = Depends(get_github_service), |
| 213 | oauth_client=Depends(get_github_oauth_client), |
| 214 | ): |
| 215 | """Handle GitHub OAuth callback for account linking""" |
| 216 | |
| 217 | redirect_url = safe_redirect( |
| 218 | request, |
| 219 | next_value=request.session.pop("redirect_after_github", "/"), |
| 220 | referer=None, |
| 221 | ) |
| 222 | |
| 223 | if not oauth_client.github: |
| 224 | flash(request, _("GitHub OAuth not configured."), "error") |
| 225 | return RedirectResponse(redirect_url, status_code=303) |
| 226 | |
| 227 | try: |
| 228 | token = await oauth_client.github.authorize_access_token(request) |
| 229 | response = await oauth_client.github.get("user", token=token) |
| 230 | github_user = response.json() |
| 231 | |
| 232 | existing_user = await get_user_by_provider(db, "github", str(github_user["id"])) |
| 233 | if existing_user and existing_user.id != current_user.id: |
| 234 | flash( |
| 235 | request, |
| 236 | _("This GitHub account is already linked to another user"), |
| 237 | "error", |
| 238 | ) |
| 239 | return RedirectResponse(redirect_url, status_code=303) |
| 240 | |
| 241 | result = await db.execute( |
| 242 | select(UserIdentity).where( |
| 243 | UserIdentity.user_id == current_user.id, |
| 244 | UserIdentity.provider == "github", |
| 245 | ) |
| 246 | ) |
| 247 | github_identity = result.scalar_one_or_none() |
| 248 | |
| 249 | if github_identity: |
| 250 | github_identity.access_token = token["access_token"] |
| 251 | github_identity.provider_metadata = { |
| 252 | "login": github_user["login"], |
| 253 | "name": github_user.get("name"), |
| 254 | } |
| 255 | else: |
| 256 | github_identity = UserIdentity( |
| 257 | user_id=current_user.id, |
| 258 | provider="github", |
| 259 | provider_user_id=str(github_user["id"]), |
| 260 | access_token=token["access_token"], |
| 261 | provider_metadata={ |
| 262 | "login": github_user["login"], |
| 263 | "name": github_user.get("name"), |
| 264 | }, |
| 265 | ) |
nothing calls this directly
no test coverage detected