Skip to content

Commit

Permalink
Handle AuthenticationErrors in OpenIDConnectPlugin (#15623)
Browse files Browse the repository at this point in the history
  • Loading branch information
IKarbowiak committed Mar 19, 2024
1 parent 370dd17 commit 0857fba
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 8 deletions.
20 changes: 12 additions & 8 deletions saleor/plugins/openid_connect/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +292,18 @@ def external_obtain_access_tokens(
}
)

parsed_id_token = get_parsed_id_token(
token_data, self.config.json_web_key_set_url
)

user, user_created, user_updated = get_or_create_user_from_payload(
parsed_id_token,
self.config.authorization_url,
)
try:
parsed_id_token = get_parsed_id_token(
token_data, self.config.json_web_key_set_url
)
user, user_created, user_updated = get_or_create_user_from_payload(
parsed_id_token,
self.config.authorization_url,
)
except AuthenticationError as e:
raise ValidationError(
{"code": ValidationError(str(e), code=PluginErrorCode.INVALID.value)}
)

user_permissions = []
is_staff_user_email = self.is_staff_user_email(user)
Expand Down
91 changes: 91 additions & 0 deletions saleor/plugins/openid_connect/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from ....graphql.account.mutations.authentication.utils import _get_new_csrf_token
from ...base_plugin import ExternalAccessTokens
from ...models import PluginConfiguration
from ..exceptions import AuthenticationError
from ..utils import (
create_jwt_refresh_token,
create_jwt_token,
Expand Down Expand Up @@ -818,6 +819,96 @@ def test_external_obtain_access_tokens_fetch_token_raises_error(
)


def test_external_obtain_access_tokens_get_parsed_id_token_raises_error(
openid_plugin, monkeypatch, rf, id_token, id_payload
):
# given
mocked_jwt_validator = MagicMock()
mocked_jwt_validator.__getitem__.side_effect = id_payload.__getitem__
mocked_jwt_validator.get.side_effect = id_payload.get

monkeypatch.setattr(
"saleor.plugins.openid_connect.utils.get_decoded_token",
Mock(return_value=mocked_jwt_validator),
)
plugin = openid_plugin(use_oauth_scope_permissions=True)

oauth_payload = {
"access_token": "FeHkE_QbuU3cYy1a1eQUrCE5jRcUnBK3",
"refresh_token": "refresh",
"id_token": id_token,
"scope": "openid profile email offline_access",
"expires_in": 86400,
"token_type": "Bearer",
"expires_at": 1600851112,
}
mocked_fetch_token = Mock(return_value=oauth_payload)
monkeypatch.setattr(
"saleor.plugins.openid_connect.client.OAuth2Client.fetch_token",
mocked_fetch_token,
)

monkeypatch.setattr(
"saleor.plugins.openid_connect.plugin.get_parsed_id_token",
Mock(side_effect=AuthenticationError()),
)

redirect_uri = "http://localhost:3000/used-logged-in"
state = signing.dumps({"redirectUri": redirect_uri})
code = "oauth-code"

# when & then
with pytest.raises(ValidationError):
plugin.external_obtain_access_tokens(
{"state": state, "code": code}, rf.request(), previous_value=None
)


def test_external_obtain_access_tokens_get_or_create_user_from_payload_raises_error(
openid_plugin, monkeypatch, rf, id_token, id_payload
):
# given
mocked_jwt_validator = MagicMock()
mocked_jwt_validator.__getitem__.side_effect = id_payload.__getitem__
mocked_jwt_validator.get.side_effect = id_payload.get

monkeypatch.setattr(
"saleor.plugins.openid_connect.utils.get_decoded_token",
Mock(return_value=mocked_jwt_validator),
)
plugin = openid_plugin(use_oauth_scope_permissions=True)

oauth_payload = {
"access_token": "FeHkE_QbuU3cYy1a1eQUrCE5jRcUnBK3",
"refresh_token": "refresh",
"id_token": id_token,
"scope": "openid profile email offline_access",
"expires_in": 86400,
"token_type": "Bearer",
"expires_at": 1600851112,
}
mocked_fetch_token = Mock(return_value=oauth_payload)
monkeypatch.setattr(
"saleor.plugins.openid_connect.client.OAuth2Client.fetch_token",
mocked_fetch_token,
)

monkeypatch.setattr(
"saleor.plugins.openid_connect.plugin.get_or_create_user_from_payload",
Mock(side_effect=AuthenticationError()),
)

redirect_uri = "http://localhost:3000/used-logged-in"
state = signing.dumps({"redirectUri": redirect_uri})
code = "oauth-code"

# when & then
with pytest.raises(ValidationError):
plugin.external_obtain_access_tokens(
{"state": state, "code": code}, rf.request(), previous_value=None
)


test_url = "http://saleor.io/"


Expand Down

0 comments on commit 0857fba

Please sign in to comment.