Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit de74bf3

Browse files
Merge branch 'main' into codecov/unit-tests
2 parents 24b3429 + 142a003 commit de74bf3

File tree

8 files changed

+136
-29
lines changed

8 files changed

+136
-29
lines changed

api/public/v2/tests/test_test_results_view.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ def test_list(self):
5353
"outcome": self.test_instances[0].outcome,
5454
"branch": self.test_instances[0].branch,
5555
"repoid": self.test_instances[0].repoid,
56-
"failure_rate": self.test_instances[0].test.failure_rate,
57-
"commits_where_fail": self.test_instances[
58-
0
59-
].test.commits_where_fail,
6056
},
6157
{
6258
"id": self.test_instances[1].id,
@@ -68,10 +64,6 @@ def test_list(self):
6864
"outcome": self.test_instances[1].outcome,
6965
"branch": self.test_instances[1].branch,
7066
"repoid": self.test_instances[1].repoid,
71-
"failure_rate": self.test_instances[1].test.failure_rate,
72-
"commits_where_fail": self.test_instances[
73-
1
74-
].test.commits_where_fail,
7567
},
7668
],
7769
"total_pages": 1,
@@ -103,10 +95,6 @@ def test_list_filters(self):
10395
"outcome": self.test_instances[0].outcome,
10496
"branch": self.test_instances[0].branch,
10597
"repoid": self.test_instances[0].repoid,
106-
"failure_rate": self.test_instances[0].test.failure_rate,
107-
"commits_where_fail": self.test_instances[
108-
0
109-
].test.commits_where_fail,
11098
},
11199
],
112100
"total_pages": 1,
@@ -137,8 +125,6 @@ def test_retrieve(self, get_repo_permissions):
137125
"outcome": self.test_instances[0].outcome,
138126
"branch": self.test_instances[0].branch,
139127
"repoid": self.test_instances[0].repoid,
140-
"failure_rate": self.test_instances[0].test.failure_rate,
141-
"commits_where_fail": self.test_instances[0].test.commits_where_fail,
142128
}
143129

144130
@patch("api.shared.permissions.RepositoryArtifactPermissions.has_permission")
@@ -240,6 +226,4 @@ def test_result_with_valid_super_token(
240226
"outcome": self.test_instances[0].outcome,
241227
"branch": self.test_instances[0].branch,
242228
"repoid": self.test_instances[0].repoid,
243-
"failure_rate": self.test_instances[0].test.failure_rate,
244-
"commits_where_fail": self.test_instances[0].test.commits_where_fail,
245229
}

codecov/settings_base.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,19 @@
350350
)
351351
CORS_ALLOWED_ORIGINS: list[str] = []
352352

353-
GRAPHQL_PLAYGROUND = True
353+
GRAPHQL_PLAYGROUND = get_settings_module() in [
354+
SettingsModule.DEV.value,
355+
SettingsModule.STAGING.value,
356+
SettingsModule.TESTING.value,
357+
]
354358

355359
UPLOAD_THROTTLING_ENABLED = get_config(
356360
"setup", "upload_throttling_enabled", default=True
357361
)
358362

363+
HIDE_ALL_CODECOV_TOKENS = get_config("setup", "hide_all_codecov_tokens", default=False)
364+
365+
359366
SENTRY_JWT_SHARED_SECRET = get_config(
360367
"sentry", "jwt_shared_secret", default=None
361368
) or get_config("setup", "sentry", "jwt_shared_secret", default=None)

graphql_api/tests/test_owner.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
UnauthorizedGuestAccess,
2828
)
2929
from codecov_auth.models import GithubAppInstallation, OwnerProfile
30+
from graphql_api.types.repository.repository import TOKEN_UNAVAILABLE
3031
from plan.constants import PlanName, TrialStatus
3132
from reports.tests.factories import CommitReportFactory, UploadFactory
3233

@@ -426,6 +427,28 @@ def test_get_org_upload_token(self, mocker):
426427
data = self.gql_request(query, owner=self.owner)
427428
assert data["owner"]["orgUploadToken"] == "upload_token"
428429

430+
@override_settings(HIDE_ALL_CODECOV_TOKENS=True)
431+
def test_get_org_upload_token_hide_tokens_setting_owner_not_admin(self):
432+
random_owner = OwnerFactory()
433+
query = """{
434+
owner(username: "%s") {
435+
orgUploadToken
436+
}
437+
}
438+
""" % (self.owner.username)
439+
random_owner.organizations = [self.owner.ownerid]
440+
random_owner.save()
441+
data = self.gql_request(query, owner=random_owner)
442+
assert data["owner"]["orgUploadToken"] == TOKEN_UNAVAILABLE
443+
444+
@patch("codecov_auth.commands.owner.owner.OwnerCommands.get_org_upload_token")
445+
@override_settings(HIDE_ALL_CODECOV_TOKENS=True)
446+
def test_get_org_upload_token_hide_tokens_setting_owner_is_admin(self, mocker):
447+
mocker.return_value = "upload_token"
448+
query = query_repositories % (self.owner.username, "", "")
449+
data = self.gql_request(query, owner=self.owner)
450+
assert data["owner"]["orgUploadToken"] == "upload_token"
451+
429452
# Applies for old users that didn't get their owner profiles created w/ their owner
430453
def test_when_owner_profile_doesnt_exist(self):
431454
owner = OwnerFactory(username="no-profile-user")

graphql_api/tests/test_repository.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
RepositoryTokenFactory,
1212
)
1313

14+
from graphql_api.types.repository.repository import TOKEN_UNAVAILABLE
1415
from services.profiling import CriticalFile
1516

1617
from .helper import GraphQLTestHelper
@@ -73,6 +74,11 @@
7374
"""
7475

7576

77+
def mock_get_config_global_upload_tokens(*args):
78+
if args == ("setup", "hide_all_codecov_tokens"):
79+
return True
80+
81+
7682
class TestFetchRepository(GraphQLTestHelper, TransactionTestCase):
7783
def fetch_repository(self, name, fields=None):
7884
data = self.gql_request(
@@ -683,6 +689,68 @@ def test_fetch_is_github_rate_limited_not_on_gh_service(self):
683689

684690
assert data["me"]["owner"]["repository"]["isGithubRateLimited"] == False
685691

692+
@override_settings(HIDE_ALL_CODECOV_TOKENS=True)
693+
def test_repo_upload_token_not_available_config_setting_owner_not_admin(self):
694+
owner = OwnerFactory(service="gitlab")
695+
696+
repo = RepositoryFactory(
697+
author=owner,
698+
author__service="gitlab",
699+
service_id=12345,
700+
active=True,
701+
)
702+
new_owner = OwnerFactory(service="gitlab", organizations=[owner.ownerid])
703+
new_owner.permission = [repo.repoid]
704+
new_owner.save()
705+
owner.admins = []
706+
707+
query = """
708+
query {
709+
owner(username: "%s") {
710+
repository(name: "%s") {
711+
... on Repository {
712+
uploadToken
713+
}
714+
}
715+
}
716+
}
717+
""" % (
718+
owner.username,
719+
repo.name,
720+
)
721+
722+
data = self.gql_request(
723+
query,
724+
owner=new_owner,
725+
variables={"name": repo.name},
726+
provider="gitlab",
727+
)
728+
729+
assert data["owner"]["repository"]["uploadToken"] == TOKEN_UNAVAILABLE
730+
731+
@override_settings(HIDE_ALL_CODECOV_TOKENS=True)
732+
def test_repo_upload_token_not_available_config_setting_owner_is_admin(self):
733+
owner = OwnerFactory(service="gitlab")
734+
repo = RepositoryFactory(
735+
author=owner,
736+
author__service="gitlab",
737+
service_id=12345,
738+
active=True,
739+
)
740+
owner.admins = [owner.ownerid]
741+
742+
data = self.gql_request(
743+
query_repository
744+
% """
745+
uploadToken
746+
""",
747+
owner=owner,
748+
variables={"name": repo.name},
749+
provider="gitlab",
750+
)
751+
752+
assert data["me"]["owner"]["repository"]["uploadToken"] != TOKEN_UNAVAILABLE
753+
686754
@patch("shared.rate_limits.determine_entity_redis_key")
687755
@patch("shared.rate_limits.determine_if_entity_is_rate_limited")
688756
@patch("logging.Logger.warning")

graphql_api/types/owner/owner.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import stripe
77
import yaml
88
from ariadne import ObjectType
9+
from django.conf import settings
910
from graphql import GraphQLResolveInfo
1011

1112
import services.activation as activation
@@ -37,6 +38,7 @@
3738
)
3839
from graphql_api.types.enums import OrderingDirection, RepositoryOrdering
3940
from graphql_api.types.errors.errors import NotFoundError, OwnerNotActivatedError
41+
from graphql_api.types.repository.repository import TOKEN_UNAVAILABLE
4042
from plan.constants import FREE_PLAN_REPRESENTATIONS, PlanData, PlanName
4143
from plan.service import PlanService
4244
from services.billing import BillingService
@@ -205,7 +207,16 @@ def resolve_hash_ownerid(owner: Owner, info: GraphQLResolveInfo) -> str:
205207
def resolve_org_upload_token(
206208
owner: Owner, info: GraphQLResolveInfo, **kwargs: Any
207209
) -> str:
210+
should_hide_tokens = settings.HIDE_ALL_CODECOV_TOKENS
211+
current_owner = info.context["request"].current_owner
208212
command = info.context["executor"].get_command("owner")
213+
if not current_owner:
214+
is_owner_admin = False
215+
else:
216+
is_owner_admin = current_owner.is_admin(owner)
217+
if should_hide_tokens and not is_owner_admin:
218+
return TOKEN_UNAVAILABLE
219+
209220
return command.get_org_upload_token(owner)
210221

211222

graphql_api/types/repository/repository.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import shared.rate_limits as rate_limits
66
import yaml
77
from ariadne import ObjectType, UnionType
8+
from django.conf import settings
89
from graphql.type.definition import GraphQLResolveInfo
910

1011
from codecov.db import sync_to_async
@@ -24,6 +25,8 @@
2425
from services.profiling import CriticalFile, ProfilingSummary
2526
from services.redis_configuration import get_redis_connection
2627

28+
TOKEN_UNAVAILABLE = "Token Unavailable. Please contact your admin."
29+
2730
log = logging.getLogger(__name__)
2831

2932
repository_bindable = ObjectType("Repository")
@@ -68,6 +71,16 @@ def resolve_commit(repository: Repository, info: GraphQLResolveInfo, id):
6871

6972
@repository_bindable.field("uploadToken")
7073
def resolve_upload_token(repository: Repository, info: GraphQLResolveInfo):
74+
should_hide_tokens = settings.HIDE_ALL_CODECOV_TOKENS
75+
76+
current_owner = info.context["request"].current_owner
77+
if not current_owner:
78+
is_current_user_admin = False
79+
else:
80+
is_current_user_admin = current_owner.is_admin(repository.author)
81+
82+
if should_hide_tokens and not is_current_user_admin:
83+
return TOKEN_UNAVAILABLE
7184
command = info.context["executor"].get_command("repository")
7285
return command.get_upload_token(repository)
7386

requirements.in

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
aiodataloader
2-
ariadne
3-
ariadne_django
2+
ariadne==0.23
3+
ariadne_django==0.3.0
44
celery>=5.3.6
55
cerberus
66
ddtrace
7-
Django>=4.2.15
7+
Django>=4.2.16
88
django-cors-headers
99
django-csp
1010
django-dynamic-fixture
@@ -20,7 +20,7 @@ factory-boy
2020
fakeredis
2121
freezegun
2222
https://github.com/codecov/opentelem-python/archive/refs/tags/v0.0.4a1.tar.gz#egg=codecovopentelem
23-
https://github.com/codecov/shared/archive/4e2792779e3efc65f876ab8ac38ffd244189e34d.tar.gz#egg=shared
23+
https://github.com/codecov/shared/archive/067b2e4ec72cdf1b3213306ea8aaaccbb374aecc.tar.gz#egg=shared
2424
google-cloud-pubsub
2525
gunicorn>=22.0.0
2626
https://github.com/photocrowd/django-cursor-pagination/archive/f560902696b0c8509e4d95c10ba0d62700181d84.tar.gz
@@ -49,6 +49,7 @@ sentry-sdk>=2.13.0
4949
sentry-sdk[celery]
5050
setproctitle
5151
simplejson
52+
starlette==0.40.0
5253
stripe>=9.6.0
5354
urllib3>=1.26.19
5455
vcrpy

requirements.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ anyio==3.6.1
1818
# starlette
1919
appdirs==1.4.4
2020
# via virtualenv
21-
ariadne==0.19.1
21+
ariadne==0.23.0
2222
# via
2323
# -r requirements.in
2424
# ariadne-django
25-
ariadne-django==0.2.0
25+
ariadne-django==0.3.0
2626
# via -r requirements.in
2727
asgiref==3.6.0
2828
# via django
@@ -109,7 +109,7 @@ deprecated==1.2.12
109109
# via opentelemetry-api
110110
distlib==0.3.1
111111
# via virtualenv
112-
django==4.2.15
112+
django==4.2.16
113113
# via
114114
# -r requirements.in
115115
# ariadne-django
@@ -205,8 +205,6 @@ googleapis-common-protos[grpc]==1.59.1
205205
# grpcio-status
206206
graphql-core==3.2.3
207207
# via ariadne
208-
greenlet==3.1.1
209-
# via sqlalchemy
210208
grpc-google-iam-v1==0.12.6
211209
# via google-cloud-pubsub
212210
grpcio==1.62.1
@@ -421,7 +419,7 @@ sentry-sdk[celery]==2.13.0
421419
# shared
422420
setproctitle==1.1.10
423421
# via -r requirements.in
424-
shared @ https://github.com/codecov/shared/archive/4e2792779e3efc65f876ab8ac38ffd244189e34d.tar.gz
422+
shared @ https://github.com/codecov/shared/archive/067b2e4ec72cdf1b3213306ea8aaaccbb374aecc.tar.gz
425423
# via -r requirements.in
426424
simplejson==3.17.2
427425
# via -r requirements.in
@@ -449,8 +447,10 @@ sqlparse==0.5.0
449447
# via
450448
# ddtrace
451449
# django
452-
starlette==0.36.2
453-
# via ariadne
450+
starlette==0.40.0
451+
# via
452+
# -r requirements.in
453+
# ariadne
454454
stripe==9.6.0
455455
# via -r requirements.in
456456
text-unidecode==1.3

0 commit comments

Comments
 (0)