Stable cognito user pool (#5194)
This commit is contained in:
parent
6d1ed57945
commit
9640ec20d1
@ -145,3 +145,10 @@ cognito-idp
|
|||||||
|
|
||||||
- [ ] verify_user_attribute
|
- [ ] 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.
|
||||||
|
@ -24,6 +24,7 @@ from .exceptions import (
|
|||||||
from .utils import (
|
from .utils import (
|
||||||
create_id,
|
create_id,
|
||||||
check_secret_hash,
|
check_secret_hash,
|
||||||
|
generate_id,
|
||||||
validate_username_format,
|
validate_username_format,
|
||||||
flatten_attrs,
|
flatten_attrs,
|
||||||
expand_attrs,
|
expand_attrs,
|
||||||
@ -31,6 +32,7 @@ from .utils import (
|
|||||||
)
|
)
|
||||||
from moto.utilities.paginator import paginate
|
from moto.utilities.paginator import paginate
|
||||||
from moto.utilities.utils import md5_hash
|
from moto.utilities.utils import md5_hash
|
||||||
|
from ..settings import get_cognito_idp_user_pool_id_strategy
|
||||||
|
|
||||||
|
|
||||||
class UserStatus(str, enum.Enum):
|
class UserStatus(str, enum.Enum):
|
||||||
@ -366,12 +368,20 @@ DEFAULT_USER_POOL_CONFIG = {
|
|||||||
|
|
||||||
|
|
||||||
class CognitoIdpUserPool(BaseModel):
|
class CognitoIdpUserPool(BaseModel):
|
||||||
|
|
||||||
|
MAX_ID_LENGTH = 56
|
||||||
|
|
||||||
def __init__(self, region, name, extended_config):
|
def __init__(self, region, name, extended_config):
|
||||||
self.region = region
|
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.arn = "arn:aws:cognito-idp:{}:{}:userpool/{}".format(
|
||||||
self.region, get_account_id(), self.id
|
self.region, get_account_id(), self.id
|
||||||
)
|
)
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.status = None
|
self.status = None
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import hashlib
|
|||||||
import hmac
|
import hmac
|
||||||
import base64
|
import base64
|
||||||
import re
|
import re
|
||||||
|
import uuid
|
||||||
|
|
||||||
FORMATS = {
|
FORMATS = {
|
||||||
"email": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
|
"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):
|
def expand_attrs(attrs):
|
||||||
return [{"Name": k, "Value": v} for k, v in attrs.items()]
|
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()
|
||||||
|
@ -125,3 +125,7 @@ def get_docker_host():
|
|||||||
)
|
)
|
||||||
print(f"{type(e)}::{e}")
|
print(f"{type(e)}::{e}")
|
||||||
return "http://host.docker.internal"
|
return "http://host.docker.internal"
|
||||||
|
|
||||||
|
|
||||||
|
def get_cognito_idp_user_pool_id_strategy():
|
||||||
|
return os.environ.get("MOTO_COGNITO_IDP_USER_POOL_ID_STRATEGY")
|
||||||
|
@ -5,6 +5,7 @@ import os
|
|||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
import mock
|
||||||
import moto.cognitoidp.models
|
import moto.cognitoidp.models
|
||||||
import requests
|
import requests
|
||||||
import hmac
|
import hmac
|
||||||
@ -506,6 +507,74 @@ def test_add_custom_attributes_existing_attribute():
|
|||||||
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
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
|
@mock_cognitoidp
|
||||||
def test_list_user_pools():
|
def test_list_user_pools():
|
||||||
conn = boto3.client("cognito-idp", "us-west-2")
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user