Skip to content

Commit

Permalink
Properly complete token transaction (#329)
Browse files Browse the repository at this point in the history
  • Loading branch information
petebachant authored Feb 4, 2025
1 parent b8e43a7 commit 7ed2b62
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
10 changes: 7 additions & 3 deletions backend/app/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import git
from fastapi import HTTPException
from filelock import FileLock, Timeout
from git.exc import GitCommandError
from sqlmodel import Session

from app import users
Expand Down Expand Up @@ -48,7 +49,7 @@ def get_repo(
shutil.rmtree(repo_dir, ignore_errors=True)
# Clone the repo if it doesn't exist -- it will be in a "repo" dir
if user is not None:
logger.info("Getting access token for Git repo URL")
logger.info(f"Getting {user.email}'s access token for Git repo URL")
access_token = users.get_github_token(session=session, user=user)
git_clone_url = (
f"https://x-access-token:{access_token}@"
Expand All @@ -75,8 +76,8 @@ def get_repo(
repo_dir,
]
)
except subprocess.CalledProcessError as e:
logger.error(f"Failed to clone repo: {e}")
except subprocess.CalledProcessError:
logger.error("Failed to clone repo")
raise HTTPException(404, "Git repo not found")
# Touch a file so we can compute a TTL
subprocess.check_call(["touch", updated_fpath])
Expand Down Expand Up @@ -110,6 +111,9 @@ def get_repo(
subprocess.call(["touch", updated_fpath])
except Timeout:
logger.warning("Git repo lock timed out")
except GitCommandError:
logger.error("Failed to refresh repo")
raise HTTPException(404, "Git repo not found")
if repo is None:
repo = git.Repo(repo_dir)
return repo
Expand Down
27 changes: 18 additions & 9 deletions backend/app/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def get_github_token(session: Session, user: User) -> str:
if (utcnow() + timedelta(minutes=30)) >= token.expires:
# Make sure no other process is trying to refresh the token
# Lock the user token row
logger.info("Refreshing GitHub token")
logger.info(f"Refreshing GitHub token for {user.email}")
resp = requests.post(
"https://github.com/login/oauth/access_token",
json=dict(
Expand All @@ -113,7 +113,6 @@ def get_github_token(session: Session, user: User) -> str:
refresh_token=decrypt_secret(token.refresh_token),
),
)
logger.info("Refreshed GitHub token")
logger.info(f"GitHub token refresh status code: {resp.status_code}")
gh_resp = token_resp_text_to_dict(resp.text)
logger.info(
Expand All @@ -127,17 +126,27 @@ def get_github_token(session: Session, user: User) -> str:
)
logger.error(msg)
if gh_resp["error"] == "bad_refresh_token":
logger.info("Deleting bad GitHub token")
logger.info(f"Bad refresh token for {user.email}")
logger.info(f"Deleting bad GitHub token for {user.email}")
session.delete(token)
session.commit()
logger.info("Bad refresh token")
raise HTTPException(401, "GitHub token refresh failed")
token = save_github_token(
session,
user=user,
github_resp=gh_resp,
# Save the newly refreshed token
now = utcnow()
expires = now + timedelta(seconds=int(gh_resp["expires_in"]))
rt_expires = now + timedelta(
seconds=int(gh_resp["refresh_token_expires_in"])
)
return decrypt_secret(token.access_token)
token.access_token = encrypt_secret(gh_resp["access_token"])
token.refresh_token = encrypt_secret(gh_resp["refresh_token"])
token.expires = expires
token.refresh_token_expires = rt_expires
token.updated = now
user.github_token = token
session.commit()
session.commit()
session.refresh(user.github_token)
return decrypt_secret(user.github_token.access_token)


def save_github_token(
Expand Down

0 comments on commit 7ed2b62

Please sign in to comment.