Implement user-group relationships for cognito-idp
This commit is contained in:
parent
04fdd5617a
commit
ffa7560d02
@ -827,9 +827,9 @@
|
|||||||
- [ ] unlink_identity
|
- [ ] unlink_identity
|
||||||
- [ ] update_identity_pool
|
- [ ] update_identity_pool
|
||||||
|
|
||||||
## cognito-idp - 0% implemented
|
## cognito-idp - 34% implemented
|
||||||
- [ ] add_custom_attributes
|
- [ ] add_custom_attributes
|
||||||
- [ ] admin_add_user_to_group
|
- [X] admin_add_user_to_group
|
||||||
- [ ] admin_confirm_sign_up
|
- [ ] admin_confirm_sign_up
|
||||||
- [X] admin_create_user
|
- [X] admin_create_user
|
||||||
- [X] admin_delete_user
|
- [X] admin_delete_user
|
||||||
@ -843,9 +843,9 @@
|
|||||||
- [X] admin_initiate_auth
|
- [X] admin_initiate_auth
|
||||||
- [ ] admin_link_provider_for_user
|
- [ ] admin_link_provider_for_user
|
||||||
- [ ] admin_list_devices
|
- [ ] admin_list_devices
|
||||||
- [ ] admin_list_groups_for_user
|
- [X] admin_list_groups_for_user
|
||||||
- [ ] admin_list_user_auth_events
|
- [ ] admin_list_user_auth_events
|
||||||
- [ ] admin_remove_user_from_group
|
- [X] admin_remove_user_from_group
|
||||||
- [ ] admin_reset_user_password
|
- [ ] admin_reset_user_password
|
||||||
- [ ] admin_respond_to_auth_challenge
|
- [ ] admin_respond_to_auth_challenge
|
||||||
- [ ] admin_set_user_mfa_preference
|
- [ ] admin_set_user_mfa_preference
|
||||||
@ -902,7 +902,7 @@
|
|||||||
- [X] list_user_pool_clients
|
- [X] list_user_pool_clients
|
||||||
- [X] list_user_pools
|
- [X] list_user_pools
|
||||||
- [X] list_users
|
- [X] list_users
|
||||||
- [ ] list_users_in_group
|
- [X] list_users_in_group
|
||||||
- [ ] resend_confirmation_code
|
- [ ] resend_confirmation_code
|
||||||
- [X] respond_to_auth_challenge
|
- [X] respond_to_auth_challenge
|
||||||
- [ ] set_risk_configuration
|
- [ ] set_risk_configuration
|
||||||
|
@ -196,6 +196,10 @@ class CognitoIdpGroup(BaseModel):
|
|||||||
self.last_modified_date = datetime.datetime.now()
|
self.last_modified_date = datetime.datetime.now()
|
||||||
self.creation_date = self.last_modified_date
|
self.creation_date = self.last_modified_date
|
||||||
|
|
||||||
|
# Users who are members of this group.
|
||||||
|
# Note that these links are bidirectional.
|
||||||
|
self.users = set()
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
return {
|
return {
|
||||||
"GroupName": self.group_name,
|
"GroupName": self.group_name,
|
||||||
@ -221,6 +225,10 @@ class CognitoIdpUser(BaseModel):
|
|||||||
self.create_date = datetime.datetime.utcnow()
|
self.create_date = datetime.datetime.utcnow()
|
||||||
self.last_modified_date = datetime.datetime.utcnow()
|
self.last_modified_date = datetime.datetime.utcnow()
|
||||||
|
|
||||||
|
# Groups this user is a member of.
|
||||||
|
# Note that these links are bidirectional.
|
||||||
|
self.groups = set()
|
||||||
|
|
||||||
def _base_json(self):
|
def _base_json(self):
|
||||||
return {
|
return {
|
||||||
"UserPoolId": self.user_pool_id,
|
"UserPoolId": self.user_pool_id,
|
||||||
@ -428,8 +436,34 @@ class CognitoIdpBackend(BaseBackend):
|
|||||||
if group_name not in user_pool.groups:
|
if group_name not in user_pool.groups:
|
||||||
raise ResourceNotFoundError(group_name)
|
raise ResourceNotFoundError(group_name)
|
||||||
|
|
||||||
|
group = user_pool.groups[group_name]
|
||||||
|
for user in group.users:
|
||||||
|
user.groups.remove(group)
|
||||||
|
|
||||||
del user_pool.groups[group_name]
|
del user_pool.groups[group_name]
|
||||||
|
|
||||||
|
def admin_add_user_to_group(self, user_pool_id, group_name, username):
|
||||||
|
group = self.get_group(user_pool_id, group_name)
|
||||||
|
user = self.admin_get_user(user_pool_id, username)
|
||||||
|
|
||||||
|
group.users.add(user)
|
||||||
|
user.groups.add(group)
|
||||||
|
|
||||||
|
def list_users_in_group(self, user_pool_id, group_name):
|
||||||
|
group = self.get_group(user_pool_id, group_name)
|
||||||
|
return list(group.users)
|
||||||
|
|
||||||
|
def admin_list_groups_for_user(self, user_pool_id, username):
|
||||||
|
user = self.admin_get_user(user_pool_id, username)
|
||||||
|
return list(user.groups)
|
||||||
|
|
||||||
|
def admin_remove_user_from_group(self, user_pool_id, group_name, username):
|
||||||
|
group = self.get_group(user_pool_id, group_name)
|
||||||
|
user = self.admin_get_user(user_pool_id, username)
|
||||||
|
|
||||||
|
group.users.discard(user)
|
||||||
|
user.groups.discard(group)
|
||||||
|
|
||||||
# User
|
# User
|
||||||
def admin_create_user(self, user_pool_id, username, temporary_password, attributes):
|
def admin_create_user(self, user_pool_id, username, temporary_password, attributes):
|
||||||
user_pool = self.user_pools.get(user_pool_id)
|
user_pool = self.user_pools.get(user_pool_id)
|
||||||
@ -465,6 +499,10 @@ class CognitoIdpBackend(BaseBackend):
|
|||||||
if username not in user_pool.users:
|
if username not in user_pool.users:
|
||||||
raise ResourceNotFoundError(username)
|
raise ResourceNotFoundError(username)
|
||||||
|
|
||||||
|
user = user_pool.users[username]
|
||||||
|
for group in user.groups:
|
||||||
|
group.users.remove(user)
|
||||||
|
|
||||||
del user_pool.users[username]
|
del user_pool.users[username]
|
||||||
|
|
||||||
def _log_user_in(self, user_pool, client, username):
|
def _log_user_in(self, user_pool, client, username):
|
||||||
|
@ -170,6 +170,48 @@ class CognitoIdpResponse(BaseResponse):
|
|||||||
cognitoidp_backends[self.region].delete_group(user_pool_id, group_name)
|
cognitoidp_backends[self.region].delete_group(user_pool_id, group_name)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def admin_add_user_to_group(self):
|
||||||
|
user_pool_id = self._get_param("UserPoolId")
|
||||||
|
username = self._get_param("Username")
|
||||||
|
group_name = self._get_param("GroupName")
|
||||||
|
|
||||||
|
cognitoidp_backends[self.region].admin_add_user_to_group(
|
||||||
|
user_pool_id,
|
||||||
|
group_name,
|
||||||
|
username,
|
||||||
|
)
|
||||||
|
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def list_users_in_group(self):
|
||||||
|
user_pool_id = self._get_param("UserPoolId")
|
||||||
|
group_name = self._get_param("GroupName")
|
||||||
|
users = cognitoidp_backends[self.region].list_users_in_group(user_pool_id, group_name)
|
||||||
|
return json.dumps({
|
||||||
|
"Users": [user.to_json(extended=True) for user in users],
|
||||||
|
})
|
||||||
|
|
||||||
|
def admin_list_groups_for_user(self):
|
||||||
|
username = self._get_param("Username")
|
||||||
|
user_pool_id = self._get_param("UserPoolId")
|
||||||
|
groups = cognitoidp_backends[self.region].admin_list_groups_for_user(user_pool_id, username)
|
||||||
|
return json.dumps({
|
||||||
|
"Groups": [group.to_json() for group in groups],
|
||||||
|
})
|
||||||
|
|
||||||
|
def admin_remove_user_from_group(self):
|
||||||
|
user_pool_id = self._get_param("UserPoolId")
|
||||||
|
username = self._get_param("Username")
|
||||||
|
group_name = self._get_param("GroupName")
|
||||||
|
|
||||||
|
cognitoidp_backends[self.region].admin_remove_user_from_group(
|
||||||
|
user_pool_id,
|
||||||
|
group_name,
|
||||||
|
username,
|
||||||
|
)
|
||||||
|
|
||||||
|
return ""
|
||||||
|
|
||||||
# User
|
# User
|
||||||
def admin_create_user(self):
|
def admin_create_user(self):
|
||||||
user_pool_id = self._get_param("UserPoolId")
|
user_pool_id = self._get_param("UserPoolId")
|
||||||
|
@ -408,13 +408,164 @@ def test_delete_group():
|
|||||||
group_name = str(uuid.uuid4())
|
group_name = str(uuid.uuid4())
|
||||||
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
conn.delete_group(GroupName=group_name, UserPoolId=user_pool_id)
|
result = conn.delete_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
list(result.keys()).should.equal(["ResponseMetadata"]) # No response expected
|
||||||
|
|
||||||
with assert_raises(ClientError) as cm:
|
with assert_raises(ClientError) as cm:
|
||||||
conn.get_group(GroupName=group_name, UserPoolId=user_pool_id)
|
conn.get_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
cm.exception.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
cm.exception.response['Error']['Code'].should.equal('ResourceNotFoundException')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cognitoidp
|
||||||
|
def test_admin_add_user_to_group():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
|
||||||
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
|
group_name = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
username = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
|
||||||
|
result = conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
list(result.keys()).should.equal(["ResponseMetadata"]) # No response expected
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cognitoidp
|
||||||
|
def test_admin_add_user_to_group_again_is_noop():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
|
||||||
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
|
group_name = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
username = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cognitoidp
|
||||||
|
def test_list_users_in_group():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
|
||||||
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
|
group_name = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
username = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
|
||||||
|
result = conn.list_users_in_group(UserPoolId=user_pool_id, GroupName=group_name)
|
||||||
|
|
||||||
|
result["Users"].should.have.length_of(1)
|
||||||
|
result["Users"][0]["Username"].should.equal(username)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cognitoidp
|
||||||
|
def test_list_users_in_group_ignores_deleted_user():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
|
||||||
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
|
group_name = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
username = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
username2 = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username2)
|
||||||
|
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username2, GroupName=group_name)
|
||||||
|
conn.admin_delete_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
|
||||||
|
result = conn.list_users_in_group(UserPoolId=user_pool_id, GroupName=group_name)
|
||||||
|
|
||||||
|
result["Users"].should.have.length_of(1)
|
||||||
|
result["Users"][0]["Username"].should.equal(username2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cognitoidp
|
||||||
|
def test_admin_list_groups_for_user():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
|
||||||
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
|
group_name = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
username = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
|
||||||
|
result = conn.admin_list_groups_for_user(Username=username, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
result["Groups"].should.have.length_of(1)
|
||||||
|
result["Groups"][0]["GroupName"].should.equal(group_name)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cognitoidp
|
||||||
|
def test_admin_list_groups_for_user_ignores_deleted_group():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
|
||||||
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
|
group_name = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
group_name2 = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name2, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
username = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name2)
|
||||||
|
conn.delete_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
result = conn.admin_list_groups_for_user(Username=username, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
result["Groups"].should.have.length_of(1)
|
||||||
|
result["Groups"][0]["GroupName"].should.equal(group_name2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cognitoidp
|
||||||
|
def test_admin_remove_user_from_group():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
|
||||||
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
|
group_name = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
username = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
|
||||||
|
result = conn.admin_remove_user_from_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
list(result.keys()).should.equal(["ResponseMetadata"]) # No response expected
|
||||||
|
conn.list_users_in_group(UserPoolId=user_pool_id, GroupName=group_name) \
|
||||||
|
["Users"].should.have.length_of(0)
|
||||||
|
conn.admin_list_groups_for_user(Username=username, UserPoolId=user_pool_id) \
|
||||||
|
["Groups"].should.have.length_of(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cognitoidp
|
||||||
|
def test_admin_remove_user_from_group_again_is_noop():
|
||||||
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
|
||||||
|
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
|
||||||
|
group_name = str(uuid.uuid4())
|
||||||
|
conn.create_group(GroupName=group_name, UserPoolId=user_pool_id)
|
||||||
|
|
||||||
|
username = str(uuid.uuid4())
|
||||||
|
conn.admin_create_user(UserPoolId=user_pool_id, Username=username)
|
||||||
|
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
conn.admin_add_user_to_group(UserPoolId=user_pool_id, Username=username, GroupName=group_name)
|
||||||
|
|
||||||
|
|
||||||
@mock_cognitoidp
|
@mock_cognitoidp
|
||||||
def test_admin_create_user():
|
def test_admin_create_user():
|
||||||
conn = boto3.client("cognito-idp", "us-west-2")
|
conn = boto3.client("cognito-idp", "us-west-2")
|
||||||
|
Loading…
Reference in New Issue
Block a user