Stable cognito user pool (#5194)

This commit is contained in:
Fedorenko Dmitrij 2022-06-13 13:14:22 +03:00 committed by GitHub
parent 6d1ed57945
commit 9640ec20d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 115 additions and 1 deletions

View File

@ -145,3 +145,10 @@ cognito-idp
- [ ] verify_user_attribute
|start-h3| Stable Cognito User Pool Id |end-h3|
In some cases, you need to have reproducible IDs for the user pool.
For example, a single initialization before the start of integration tests.
This behavior can be enabled by passing the environment variable: MOTO_COGNITO_IDP_USER_POOL_ID_STRATEGY=HASH.

View File

@ -24,6 +24,7 @@ from .exceptions import (
from .utils import (
create_id,
check_secret_hash,
generate_id,
validate_username_format,
flatten_attrs,
expand_attrs,
@ -31,6 +32,7 @@ from .utils import (
)
from moto.utilities.paginator import paginate
from moto.utilities.utils import md5_hash
from ..settings import get_cognito_idp_user_pool_id_strategy
class UserStatus(str, enum.Enum):
@ -366,12 +368,20 @@ DEFAULT_USER_POOL_CONFIG = {
class CognitoIdpUserPool(BaseModel):
MAX_ID_LENGTH = 56
def __init__(self, region, name, extended_config):
self.region = region
self.id = "{}_{}".format(self.region, str(uuid.uuid4().hex))
user_pool_id = generate_id(
get_cognito_idp_user_pool_id_strategy(), region, name, extended_config
)
self.id = "{}_{}".format(self.region, user_pool_id)[: self.MAX_ID_LENGTH]
self.arn = "arn:aws:cognito-idp:{}:{}:userpool/{}".format(
self.region, get_account_id(), self.id
)
self.name = name
self.status = None

View File

@ -4,6 +4,7 @@ import hashlib
import hmac
import base64
import re
import uuid
FORMATS = {
"email": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
@ -66,3 +67,26 @@ def flatten_attrs(attrs):
def expand_attrs(attrs):
return [{"Name": k, "Value": v} for k, v in attrs.items()]
ID_HASH_STRATEGY = "HASH"
def generate_id(strategy, *args):
if strategy == ID_HASH_STRATEGY:
return _generate_id_hash(args)
else:
return _generate_id_uuid()
def _generate_id_uuid():
return uuid.uuid4().hex
def _generate_id_hash(args):
hasher = hashlib.sha256()
for arg in args:
hasher.update(str(arg).encode())
return hasher.hexdigest()

View File

@ -125,3 +125,7 @@ def get_docker_host():
)
print(f"{type(e)}::{e}")
return "http://host.docker.internal"
def get_cognito_idp_user_pool_id_strategy():
return os.environ.get("MOTO_COGNITO_IDP_USER_POOL_ID_STRATEGY")

View File

@ -5,6 +5,7 @@ import os
import random
import re
import mock
import moto.cognitoidp.models
import requests
import hmac
@ -506,6 +507,74 @@ def test_add_custom_attributes_existing_attribute():
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
@mock_cognitoidp
def test_create_user_pool_default_id_strategy():
conn = boto3.client("cognito-idp", "us-west-2")
first_pool = conn.create_user_pool(PoolName=str("default-pool"))
second_pool = conn.create_user_pool(PoolName=str("default-pool"))
first_pool["UserPool"]["Id"].should_not.equal(second_pool["UserPool"]["Id"])
@mock_cognitoidp
@mock.patch.dict(os.environ, {"MOTO_COGNITO_IDP_USER_POOL_ID_STRATEGY": "HASH"})
def test_create_user_pool_hash_id_strategy_with_equal_pool_name():
if settings.TEST_SERVER_MODE:
raise SkipTest("Cannot set environemnt variables in ServerMode")
conn = boto3.client("cognito-idp", "us-west-2")
first_pool = conn.create_user_pool(PoolName=str("default-pool"))
second_pool = conn.create_user_pool(PoolName=str("default-pool"))
first_pool["UserPool"]["Id"].should.equal(second_pool["UserPool"]["Id"])
@mock_cognitoidp
@mock.patch.dict(os.environ, {"MOTO_COGNITO_IDP_USER_POOL_ID_STRATEGY": "HASH"})
def test_create_user_pool_hash_id_strategy_with_different_pool_name():
if settings.TEST_SERVER_MODE:
raise SkipTest("Cannot set environemnt variables in ServerMode")
conn = boto3.client("cognito-idp", "us-west-2")
first_pool = conn.create_user_pool(PoolName=str("first-pool"))
second_pool = conn.create_user_pool(PoolName=str("second-pool"))
first_pool["UserPool"]["Id"].should_not.equal(second_pool["UserPool"]["Id"])
@mock_cognitoidp
@mock.patch.dict(os.environ, {"MOTO_COGNITO_IDP_USER_POOL_ID_STRATEGY": "HASH"})
def test_create_user_pool_hash_id_strategy_with_different_attributes():
if settings.TEST_SERVER_MODE:
raise SkipTest("Cannot set environemnt variables in ServerMode")
conn = boto3.client("cognito-idp", "us-west-2")
first_pool = conn.create_user_pool(
PoolName=str("default-pool"),
Schema=[
{
"Name": "first",
"AttributeDataType": "String",
}
],
)
second_pool = conn.create_user_pool(
PoolName=str("default-pool"),
Schema=[
{
"Name": "second",
"AttributeDataType": "String",
}
],
)
first_pool["UserPool"]["Id"].should_not.equal(second_pool["UserPool"]["Id"])
@mock_cognitoidp
def test_list_user_pools():
conn = boto3.client("cognito-idp", "us-west-2")