-
Notifications
You must be signed in to change notification settings - Fork 150
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(with-incident-details): Ensure the token has the correct scope 'i…
…ncident:read'
- Loading branch information
1 parent
b82d7ca
commit b3c6e1d
Showing
5 changed files
with
183 additions
and
3 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
....voltz_scrt_4913_ggshield_with_incident_details_does_not_tell_about_required.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<!-- | ||
A new scriv changelog fragment. | ||
Uncomment the section that is right (remove the HTML comment wrapper). | ||
--> | ||
|
||
<!-- | ||
### Removed | ||
- A bullet item for the Removed category. | ||
--> | ||
<!-- | ||
### Added | ||
- A bullet item for the Added category. | ||
--> | ||
<!-- | ||
### Changed | ||
- A bullet item for the Changed category. | ||
--> | ||
<!-- | ||
### Deprecated | ||
- A bullet item for the Deprecated category. | ||
--> | ||
|
||
### Fixed | ||
|
||
- When `ggshield secret scan` is called with `--with-incident-details` and the token does not have the required scopes, the command fails and an error message is printed. | ||
|
||
<!-- | ||
### Security | ||
- A bullet item for the Security category. | ||
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
from unittest.mock import Mock | ||
|
||
import click | ||
import pytest | ||
from pygitguardian import GGClient | ||
from pygitguardian.models import ApiTokensResponse, Detail | ||
|
||
from ggshield.cmd.secret.scan.secret_scan_common_options import ( | ||
_with_incident_details_callback, | ||
) | ||
from ggshield.cmd.utils.context_obj import ContextObj | ||
from ggshield.core.config.config import Config | ||
from ggshield.core.errors import APIKeyCheckError, MissingScopeError, UnexpectedError | ||
|
||
|
||
API_TOKENS_RESPONSE_SCAN_SCOPES = { | ||
"id": "5ddaad0c-5a0c-4674-beb5-1cd198d13360", | ||
"name": "myTokenName", | ||
"workspace_id": 42, | ||
"type": "personal_access_token", | ||
"status": "revoked", | ||
"created_at": "2023-05-20T12:40:55.662949Z", | ||
"last_used_at": "2023-05-24T12:40:55.662949Z", | ||
"expire_at": None, | ||
"revoked_at": "2023-05-27T12:40:55.662949Z", | ||
"member_id": 22015, | ||
"creator_id": 22015, | ||
"scopes": ["scan"], | ||
} | ||
|
||
API_TOKENS_RESPONSE_INCIDENT_READ_SCOPES = { | ||
"id": "5ddaad0c-5a0c-4674-beb5-1cd198d13360", | ||
"name": "myTokenName", | ||
"workspace_id": 42, | ||
"type": "personal_access_token", | ||
"status": "revoked", | ||
"created_at": "2023-05-20T12:40:55.662949Z", | ||
"last_used_at": "2023-05-24T12:40:55.662949Z", | ||
"expire_at": None, | ||
"revoked_at": "2023-05-27T12:40:55.662949Z", | ||
"member_id": 22015, | ||
"creator_id": 22015, | ||
"scopes": ["scan", "incidents:read"], | ||
} | ||
|
||
|
||
@pytest.fixture | ||
def mock_context(): | ||
"""Fixture for creating the mock context and config.""" | ||
config = Config() | ||
ctx_obj = ContextObj() | ||
ctx_obj.config = config | ||
return click.Context(click.Command(""), obj=ctx_obj) | ||
|
||
|
||
@pytest.mark.parametrize("with_incident_details", [True, False]) | ||
def test_with_incident_details_callback( | ||
mock_context, monkeypatch, with_incident_details | ||
): | ||
monkeypatch.setattr( | ||
GGClient, | ||
"api_tokens", | ||
Mock( | ||
return_value=ApiTokensResponse.from_dict( | ||
API_TOKENS_RESPONSE_INCIDENT_READ_SCOPES | ||
) | ||
), | ||
) | ||
|
||
assert ( | ||
_with_incident_details_callback(mock_context, Mock(), with_incident_details) | ||
is with_incident_details | ||
) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"api_response, expected_error", | ||
[ | ||
( | ||
Detail(status_code=401, detail="Unauthorized"), | ||
pytest.raises(APIKeyCheckError, match="Invalid API key."), | ||
), | ||
( | ||
Detail(detail="Unexpected response"), | ||
pytest.raises(UnexpectedError, match="Unexpected response"), | ||
), | ||
( | ||
ApiTokensResponse.from_dict(API_TOKENS_RESPONSE_SCAN_SCOPES), | ||
pytest.raises( | ||
MissingScopeError, | ||
match="Token is missing the scope: 'incidents:read' to retrieve incident details.", | ||
), | ||
), | ||
], | ||
) | ||
def test_with_incident_details_callback_error( | ||
mock_context, monkeypatch, api_response, expected_error | ||
): | ||
monkeypatch.setattr(GGClient, "api_tokens", Mock(return_value=api_response)) | ||
|
||
with expected_error: | ||
_with_incident_details_callback(mock_context, Mock(), True) |