Skip to content

Commit

Permalink
redo the whole thing, condense into one class that both views share
Browse files Browse the repository at this point in the history
  • Loading branch information
nora-codecov committed Oct 12, 2024
1 parent b70b7c9 commit f2f587d
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 411 deletions.
95 changes: 32 additions & 63 deletions codecov_auth/authentication/repo_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.http import HttpRequest
from django.utils import timezone
from jwt import PyJWTError
from rest_framework import authentication, exceptions
from rest_framework import authentication, exceptions, serializers
from rest_framework.exceptions import NotAuthenticated
from rest_framework.views import exception_handler
from shared.django_apps.codecov_auth.models import Owner
Expand All @@ -24,7 +24,6 @@
from core.models import Commit, Repository
from upload.helpers import get_global_tokens, get_repo_with_github_actions_oidc_token
from upload.views.helpers import (
get_repository_and_owner_from_slug_and_commit,
get_repository_and_owner_from_string,
get_repository_from_string,
)
Expand Down Expand Up @@ -406,84 +405,54 @@ def authenticate(
)


class TestResultsUploadTokenRequiredAuthenticationCheck(
UploadTokenRequiredAuthenticationCheck
):
"""
Repository and Owner are not in the path for this endpoint, have to get them another way,
then use the same authenticate() as parent class.
"""

def _get_info_from_request_data(
self, request: HttpRequest
) -> tuple[Repository | None, Owner | None]:
from upload.views.test_results import UploadSerializer # circular imports

try:
body = json.loads(str(request.body, "utf8"))
except json.JSONDecodeError:
return None, None # continue to next auth class

serializer = UploadSerializer(data=body)
if not serializer.is_valid():
return None, None # continue to next auth class

# these fields are required=True
slug = serializer.validated_data["slug"]
commitid = serializer.validated_data["commit"]

return get_repository_and_owner_from_slug_and_commit(
slug=slug, commitid=commitid
)

def get_repository_and_owner(
self, request: HttpRequest
) -> tuple[Repository | None, Owner | None]:
return self._get_info_from_request_data(request)
class UploadTokenRequiredGetFromBodySerializer(serializers.Serializer):
slug = serializers.CharField(required=True)
service = serializers.CharField(required=False) # git_service from TA
git_service = serializers.CharField(required=False) # git_service from BA


class BundleAnalysisUploadTokenRequiredAuthenticationCheck(
class UploadTokenRequiredGetFromBodyAuthenticationCheck(
UploadTokenRequiredAuthenticationCheck
):
"""
Repository and Owner are not in the path for this endpoint, have to get them another way,
Get Repository and Owner from request body instead of path,
then use the same authenticate() as parent class.
"""

def _get_info_from_request_data(
def _get_git(self, validated_data):
"""
BA sends this in as git_service, TA sends this in as service.
Use this function so this Check class can be used by both views.
"""
git_service = validated_data.get("git_service")
if not git_service:
git_service = validated_data.get("service")
return git_service

def _get_info_from_request_body(
self, request: HttpRequest
) -> tuple[Repository | None, Owner | None]:
from upload.views.bundle_analysis import UploadSerializer # circular imports

try:
body = json.loads(str(request.body, "utf8"))
except json.JSONDecodeError:
return None, None # continue to next auth class

serializer = UploadSerializer(data=body)
if not serializer.is_valid():
return None, None # continue to next auth class
serializer = UploadTokenRequiredGetFromBodySerializer(data=body)

# these fields are required=True
slug = serializer.validated_data["slug"]
commitid = serializer.validated_data["commit"]
if serializer.is_valid():
git_service = self._get_git(validated_data=serializer.validated_data)
service_enum = Service(git_service)
return get_repository_and_owner_from_string(
service=service_enum,
repo_identifier=serializer.validated_data["slug"],
)

# this field is required=False but is much better for getting repository and owner
service = serializer.validated_data.get("git_service")
if service:
try:
service_enum = Service(service)
except ValueError:
return None, None
return get_repository_and_owner_from_string(
service=service_enum, repo_identifier=slug
)
except (json.JSONDecodeError, ValueError):
# exceptions raised by json.loads() and Service()
# catch rather than raise to continue to next auth class
pass

return get_repository_and_owner_from_slug_and_commit(
slug=slug, commitid=commitid
)
return None, None # continue to next auth class

def get_repository_and_owner(
self, request: HttpRequest
) -> tuple[Repository | None, Owner | None]:
return self._get_info_from_request_data(request)
return self._get_info_from_request_body(request)
Loading

0 comments on commit f2f587d

Please sign in to comment.