Skip to content

Commit

Permalink
add X-Tokenless header when uploading from fork (#335)
Browse files Browse the repository at this point in the history
Public forks will accept tokenless uploads.
Currently we were just sending an empty header (no Authorization).
These changes add a header `X-Tokenless: fork_slug` so we know
easily that the request is from a fork, and which fork it's from.

I also have a tendency to compulsively add typehints to complex
types.
  • Loading branch information
giovanni-guidini authored Dec 5, 2023
1 parent b304bf0 commit 96c0578
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 13 deletions.
6 changes: 4 additions & 2 deletions codecov_cli/helpers/git.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import logging
import re
from enum import Enum
from typing import Optional
from urllib.parse import urlparse

from codecov_cli.helpers.encoder import decode_slug
from codecov_cli.helpers.git_services import PullDict
from codecov_cli.helpers.git_services.github import Github

slug_regex = re.compile(r"[^/\s]+\/[^/\s]+$")
Expand Down Expand Up @@ -92,15 +94,15 @@ def parse_git_service(remote_repo_url: str):
return None


def is_fork_pr(pull_dict):
def is_fork_pr(pull_dict: PullDict) -> bool:
"""
takes in dict: pull_dict
returns true if PR is made in a fork context, false if not.
"""
return pull_dict and pull_dict["head"]["slug"] != pull_dict["base"]["slug"]


def get_pull(service, slug, pr_num):
def get_pull(service, slug, pr_num) -> Optional[PullDict]:
"""
takes in str git service e.g. github, gitlab etc., slug in the owner/repo format, and the pull request number
returns the pull request info gotten from the git service provider if successful, None if not
Expand Down
14 changes: 14 additions & 0 deletions codecov_cli/helpers/git_services/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from typing import TypedDict


class CommitInfo(TypedDict):
sha: str
label: str
ref: str
slug: str


class PullDict(TypedDict):
url: str
head: CommitInfo
base: CommitInfo
4 changes: 3 additions & 1 deletion codecov_cli/helpers/git_services/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import requests

from codecov_cli.helpers.git_services import PullDict


class Github:
api_url = "https://api.github.com"
api_version = "2022-11-28"

def get_pull_request(self, slug, pr_number):
def get_pull_request(self, slug, pr_number) -> PullDict:
pull_url = f"/repos/{slug}/pulls/{pr_number}"
url = self.api_url + pull_url
headers = {"X-GitHub-Api-Version": self.api_version}
Expand Down
2 changes: 1 addition & 1 deletion codecov_cli/services/commit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def send_commit_data(
decoded_slug = decode_slug(slug)
pull_dict = get_pull(service, decoded_slug, pr) if not token else None
if is_fork_pr(pull_dict):
headers = {}
headers = {"X-Tokenless": pull_dict["head"]["slug"]}
branch = pull_dict["head"]["slug"] + ":" + branch
logger.info("The PR is happening in a forked repo. Using tokenless upload.")
else:
Expand Down
7 changes: 4 additions & 3 deletions codecov_cli/services/report/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ def send_create_report_request(
pull_dict = (
get_pull(service, decoded_slug, pull_request_number) if not token else None
)
headers = (
{} if not token and is_fork_pr(pull_dict) else get_token_header_or_fail(token)
)
if is_fork_pr(pull_dict):
headers = {"X-Tokenless": pull_dict["head"]["slug"]}
else:
headers = get_token_header_or_fail(token)
upload_url = enterprise_url or CODECOV_API_URL
url = f"{upload_url}/upload/{service}/{encoded_slug}/commits/{commit_sha}/reports"
return send_post_request(url=url, headers=headers, data=data)
Expand Down
10 changes: 5 additions & 5 deletions codecov_cli/services/upload/upload_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ def send_upload_data(
pull_dict = (
get_pull(git_service, slug, pull_request_number) if not token else None
)
headers = (
{}
if not token and is_fork_pr(pull_dict)
else get_token_header_or_fail(token)
)

if is_fork_pr(pull_dict):
headers = {"X-Tokenless": pull_dict["head"]["slug"]}
else:
headers = get_token_header_or_fail(token)
encoded_slug = encode_slug(slug)
upload_url = enterprise_url or CODECOV_API_URL
url = f"{upload_url}/upload/{git_service}/{encoded_slug}/commits/{commit_sha}/reports/{report_code}/uploads"
Expand Down
2 changes: 1 addition & 1 deletion tests/services/commit/test_commit_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,5 +195,5 @@ def mock_request(*args, headers={}, **kwargs):
"pullid": "1",
"branch": "user_forked_repo/codecov-cli:branch",
},
headers={},
headers={"X-Tokenless": "user_forked_repo/codecov-cli"},
)

0 comments on commit 96c0578

Please sign in to comment.