CognitoIDP: Allow public actions even if IAM auth is enabled (#7331)
This commit is contained in:
parent
ad63e3966b
commit
588b50f5c1
@ -143,6 +143,14 @@ class _TemplateEnvironmentMixin(object):
|
|||||||
class ActionAuthenticatorMixin(object):
|
class ActionAuthenticatorMixin(object):
|
||||||
request_count: ClassVar[int] = 0
|
request_count: ClassVar[int] = 0
|
||||||
|
|
||||||
|
PUBLIC_OPERATIONS = [
|
||||||
|
"AWSCognitoIdentityProviderService.ConfirmSignUp",
|
||||||
|
"AWSCognitoIdentityProviderService.GetUser",
|
||||||
|
"AWSCognitoIdentityProviderService.ForgotPassword",
|
||||||
|
"AWSCognitoIdentityProviderService.InitiateAuth",
|
||||||
|
"AWSCognitoIdentityProviderService.SignUp",
|
||||||
|
]
|
||||||
|
|
||||||
def _authenticate_and_authorize_action(
|
def _authenticate_and_authorize_action(
|
||||||
self, iam_request_cls: type, resource: str = "*"
|
self, iam_request_cls: type, resource: str = "*"
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -150,6 +158,11 @@ class ActionAuthenticatorMixin(object):
|
|||||||
ActionAuthenticatorMixin.request_count
|
ActionAuthenticatorMixin.request_count
|
||||||
>= settings.INITIAL_NO_AUTH_ACTION_COUNT
|
>= settings.INITIAL_NO_AUTH_ACTION_COUNT
|
||||||
):
|
):
|
||||||
|
if (
|
||||||
|
self.headers.get("X-Amz-Target") # type: ignore[attr-defined]
|
||||||
|
in ActionAuthenticatorMixin.PUBLIC_OPERATIONS
|
||||||
|
):
|
||||||
|
return
|
||||||
parsed_url = urlparse(self.uri) # type: ignore[attr-defined]
|
parsed_url = urlparse(self.uri) # type: ignore[attr-defined]
|
||||||
path = parsed_url.path
|
path = parsed_url.path
|
||||||
if parsed_url.query:
|
if parsed_url.query:
|
||||||
|
@ -19,6 +19,7 @@ import moto.cognitoidp.models
|
|||||||
from moto import mock_aws, settings
|
from moto import mock_aws, settings
|
||||||
from moto.cognitoidp.utils import create_id
|
from moto.cognitoidp.utils import create_id
|
||||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
||||||
|
from moto.core import set_initial_no_auth_action_count
|
||||||
|
|
||||||
|
|
||||||
@mock_aws
|
@mock_aws
|
||||||
@ -2357,6 +2358,7 @@ def test_get_user():
|
|||||||
|
|
||||||
|
|
||||||
@mock_aws
|
@mock_aws
|
||||||
|
@set_initial_no_auth_action_count(0)
|
||||||
def test_get_user_unknown_accesstoken():
|
def test_get_user_unknown_accesstoken():
|
||||||
conn = boto3.client("cognito-idp", "us-west-2")
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
with pytest.raises(ClientError) as ex:
|
with pytest.raises(ClientError) as ex:
|
||||||
@ -3047,6 +3049,7 @@ def test_change_password__using_custom_user_agent_header():
|
|||||||
|
|
||||||
|
|
||||||
@mock_aws
|
@mock_aws
|
||||||
|
@set_initial_no_auth_action_count(2)
|
||||||
def test_forgot_password():
|
def test_forgot_password():
|
||||||
conn = boto3.client("cognito-idp", "us-west-2")
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
@ -3913,15 +3916,22 @@ def test_confirm_sign_up():
|
|||||||
client_id = conn.create_user_pool_client(
|
client_id = conn.create_user_pool_client(
|
||||||
UserPoolId=user_pool_id, ClientName=str(uuid.uuid4()), GenerateSecret=True
|
UserPoolId=user_pool_id, ClientName=str(uuid.uuid4()), GenerateSecret=True
|
||||||
)["UserPoolClient"]["ClientId"]
|
)["UserPoolClient"]["ClientId"]
|
||||||
|
_signup_and_confirm(client_id, conn, password, username)
|
||||||
|
|
||||||
|
result = conn.admin_get_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
assert result["UserStatus"] == "CONFIRMED"
|
||||||
|
|
||||||
|
|
||||||
|
@set_initial_no_auth_action_count(0)
|
||||||
|
def _signup_and_confirm(client_id, conn, password, username):
|
||||||
|
# Also verify Authentication works for these actions
|
||||||
|
# There are no IAM policies, but they should be public - accessible by anyone
|
||||||
conn.sign_up(ClientId=client_id, Username=username, Password=password)
|
conn.sign_up(ClientId=client_id, Username=username, Password=password)
|
||||||
|
|
||||||
conn.confirm_sign_up(
|
conn.confirm_sign_up(
|
||||||
ClientId=client_id, Username=username, ConfirmationCode="123456"
|
ClientId=client_id, Username=username, ConfirmationCode="123456"
|
||||||
)
|
)
|
||||||
|
|
||||||
result = conn.admin_get_user(UserPoolId=user_pool_id, Username=username)
|
|
||||||
assert result["UserStatus"] == "CONFIRMED"
|
|
||||||
|
|
||||||
|
|
||||||
@mock_aws
|
@mock_aws
|
||||||
def test_confirm_sign_up_with_username_attributes():
|
def test_confirm_sign_up_with_username_attributes():
|
||||||
@ -4857,6 +4867,21 @@ def test_login_denied_if_account_disabled():
|
|||||||
assert ex.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
assert ex.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
||||||
|
|
||||||
|
|
||||||
|
@mock_aws
|
||||||
|
# Also validate that we don't need IAM policies, as this operation should be publicly accessible
|
||||||
|
@set_initial_no_auth_action_count(0)
|
||||||
|
def test_initiate_auth_with_invalid_user_pool():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
conn.initiate_auth(
|
||||||
|
ClientId="unknown",
|
||||||
|
AuthFlow="USER_PASSWORD_AUTH",
|
||||||
|
AuthParameters={"USERNAME": "user", "PASSWORD": "pass"},
|
||||||
|
)
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
assert err["Code"] == "ResourceNotFoundException"
|
||||||
|
|
||||||
|
|
||||||
# Test will retrieve public key from cognito.amazonaws.com/.well-known/jwks.json,
|
# Test will retrieve public key from cognito.amazonaws.com/.well-known/jwks.json,
|
||||||
# which isnt mocked in ServerMode
|
# which isnt mocked in ServerMode
|
||||||
if not settings.TEST_SERVER_MODE:
|
if not settings.TEST_SERVER_MODE:
|
||||||
|
Loading…
Reference in New Issue
Block a user