Skip to content

Commit f92b323

Browse files
authored
Merge pull request #1130 from GitGuardian/salomevoltz/handle-api-unknown-scope
Handle unknow scopes in ggshield
2 parents b91c894 + 2066024 commit f92b323

File tree

5 files changed

+85
-9
lines changed

5 files changed

+85
-9
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
For top level release notes, leave all the headers commented out.
6+
-->
7+
8+
<!--
9+
### Removed
10+
11+
- A bullet item for the Removed category.
12+
13+
-->
14+
<!--
15+
### Added
16+
17+
- A bullet item for the Added category.
18+
19+
-->
20+
<!--
21+
### Changed
22+
23+
- A bullet item for the Changed category.
24+
25+
-->
26+
<!--
27+
### Deprecated
28+
29+
- A bullet item for the Deprecated category.
30+
31+
-->
32+
33+
### Fixed
34+
35+
- Fixed crash when API returns scopes not yet recognized by py-gitguardian.
36+
37+
<!--
38+
### Security
39+
40+
- A bullet item for the Security category.
41+
42+
-->

ggshield/core/client.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import os
23
from typing import Optional
34

@@ -19,6 +20,9 @@
1920
from .ui.client_callbacks import ClientCallbacks
2021

2122

23+
logger = logging.getLogger(__name__)
24+
25+
2226
def create_client_from_config(config: Config) -> GGClient:
2327
"""
2428
Create a GGClient using parameters from Config.
@@ -131,8 +135,14 @@ def check_client_api_key(client: GGClient, required_scopes: set[TokenScope]) ->
131135
elif isinstance(response, Detail):
132136
raise UnexpectedError(response.detail)
133137

134-
missing_scopes = required_scopes - set(
135-
TokenScope(scope) for scope in response.scopes
136-
)
138+
# Build set of API scopes, ignoring unknown ones for forward compatibility
139+
api_scopes = set()
140+
for scope_str in response.scopes:
141+
try:
142+
api_scopes.add(TokenScope(scope_str))
143+
except ValueError:
144+
logger.debug("Ignoring unknown scope from API: '%s'", scope_str)
145+
146+
missing_scopes = required_scopes - api_scopes
137147
if missing_scopes:
138148
raise MissingScopesError(list(missing_scopes))

pdm.lock

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ dependencies = [
4242
"marshmallow~=3.18.0",
4343
"marshmallow-dataclass~=8.5.8",
4444
"oauthlib~=3.2.1",
45-
"pygitguardian~=1.25.0",
45+
"pygitguardian @ git+https://github.com/GitGuardian/py-gitguardian.git@11aa57914dc9a3fb93db3579ddc4a0eab2fc8af2",
4646
"pyjwt~=2.6.0",
4747
"python-dotenv~=0.21.0",
4848
"pyyaml~=6.0.1",

tests/unit/core/test_client.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,31 @@ def test_check_client_api_key_without_source_uuid_no_token_check():
155155
client_mock.api_tokens.assert_not_called()
156156

157157

158+
def test_check_client_api_key_unknown_scope():
159+
"""
160+
GIVEN a client with valid API key and API returns unknown scopes
161+
WHEN check_client_api_key() is called with required scopes
162+
THEN it ignores unknown scopes and validates only the required ones
163+
"""
164+
client_mock = Mock(spec=GGClient)
165+
client_mock.base_uri = "http://localhost"
166+
client_mock.read_metadata.return_value = None # Success
167+
client_mock.api_tokens.return_value = APITokensResponse.from_dict(
168+
{
169+
"id": "5ddaad0c-5a0c-4674-beb5-1cd198d13360",
170+
"name": "test-name",
171+
"workspace_id": 1,
172+
"type": "personal_access_token",
173+
"status": "active",
174+
"created_at": "2023-01-01T00:00:00Z",
175+
"scopes": [TokenScope.SCAN_CREATE_INCIDENTS.value, "scope:unknown"],
176+
}
177+
)
178+
179+
# Should not raise any exception
180+
check_client_api_key(client_mock, {TokenScope.SCAN_CREATE_INCIDENTS})
181+
182+
158183
def test_retrieve_client_invalid_api_url():
159184
"""
160185
GIVEN a GITGUARDIAN_API_URL missing its https scheme

0 commit comments

Comments
 (0)