Implemented identitystore describe_group (#7015)
This commit is contained in:
parent
d244885dbf
commit
84329158ce
@ -14,6 +14,14 @@ from .exceptions import (
|
|||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
|
||||||
|
class Group(NamedTuple):
|
||||||
|
GroupId: str
|
||||||
|
DisplayName: str
|
||||||
|
ExternalIds: List[Optional[Dict[str, str]]]
|
||||||
|
Description: str
|
||||||
|
IdentityStoreId: str
|
||||||
|
|
||||||
|
|
||||||
class Name(NamedTuple):
|
class Name(NamedTuple):
|
||||||
Formatted: Optional[str]
|
Formatted: Optional[str]
|
||||||
FamilyName: Optional[str]
|
FamilyName: Optional[str]
|
||||||
@ -56,7 +64,7 @@ class User(NamedTuple):
|
|||||||
|
|
||||||
class IdentityStoreData:
|
class IdentityStoreData:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.groups: Dict[str, Dict[str, str]] = {}
|
self.groups: Dict[str, Group] = {}
|
||||||
self.users: Dict[str, User] = {}
|
self.users: Dict[str, User] = {}
|
||||||
self.group_memberships: Dict[str, Any] = {}
|
self.group_memberships: Dict[str, Any] = {}
|
||||||
|
|
||||||
@ -95,9 +103,7 @@ class IdentityStoreBackend(BaseBackend):
|
|||||||
identity_store = self.__get_identity_store(identity_store_id)
|
identity_store = self.__get_identity_store(identity_store_id)
|
||||||
|
|
||||||
matching = [
|
matching = [
|
||||||
g
|
g for g in identity_store.groups.values() if g.DisplayName == display_name
|
||||||
for g in identity_store.groups.values()
|
|
||||||
if g["DisplayName"] == display_name
|
|
||||||
]
|
]
|
||||||
if len(matching) > 0:
|
if len(matching) > 0:
|
||||||
raise ConflictException(
|
raise ConflictException(
|
||||||
@ -106,13 +112,14 @@ class IdentityStoreBackend(BaseBackend):
|
|||||||
)
|
)
|
||||||
|
|
||||||
group_id = str(mock_random.uuid4())
|
group_id = str(mock_random.uuid4())
|
||||||
group_dict = {
|
group = Group(
|
||||||
"GroupId": group_id,
|
group_id,
|
||||||
"IdentityStoreId": identity_store_id,
|
display_name,
|
||||||
"DisplayName": display_name,
|
[],
|
||||||
"Description": description,
|
description,
|
||||||
}
|
identity_store_id,
|
||||||
identity_store.groups[group_id] = group_dict
|
)
|
||||||
|
identity_store.groups[group_id] = group
|
||||||
return group_id, identity_store_id
|
return group_id, identity_store_id
|
||||||
|
|
||||||
def get_group_id(
|
def get_group_id(
|
||||||
@ -127,10 +134,10 @@ class IdentityStoreBackend(BaseBackend):
|
|||||||
):
|
):
|
||||||
for g in identity_store.groups.values():
|
for g in identity_store.groups.values():
|
||||||
if (
|
if (
|
||||||
g["DisplayName"]
|
g.DisplayName
|
||||||
== alternate_identifier["UniqueAttribute"]["AttributeValue"]
|
== alternate_identifier["UniqueAttribute"]["AttributeValue"]
|
||||||
):
|
):
|
||||||
return g["GroupId"], identity_store_id
|
return g.GroupId, identity_store_id
|
||||||
elif "ExternalId" in alternate_identifier:
|
elif "ExternalId" in alternate_identifier:
|
||||||
warnings.warn("ExternalId has not been implemented.")
|
warnings.warn("ExternalId has not been implemented.")
|
||||||
|
|
||||||
@ -138,6 +145,23 @@ class IdentityStoreBackend(BaseBackend):
|
|||||||
message="GROUP not found.", resource_type="GROUP"
|
message="GROUP not found.", resource_type="GROUP"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def describe_group(self, identity_store_id: str, group_id: str) -> Group:
|
||||||
|
identity_store = self.__get_identity_store(identity_store_id)
|
||||||
|
if group_id in identity_store.groups:
|
||||||
|
g = identity_store.groups[group_id]
|
||||||
|
# External Ids are not implemented
|
||||||
|
external_ids: List[Any] = []
|
||||||
|
return Group(
|
||||||
|
g.GroupId,
|
||||||
|
g.DisplayName,
|
||||||
|
external_ids,
|
||||||
|
g.Description,
|
||||||
|
identity_store_id,
|
||||||
|
)
|
||||||
|
raise ResourceNotFoundException(
|
||||||
|
message="GROUP not found.", resource_type="GROUP"
|
||||||
|
)
|
||||||
|
|
||||||
def delete_group(self, identity_store_id: str, group_id: str) -> None:
|
def delete_group(self, identity_store_id: str, group_id: str) -> None:
|
||||||
identity_store = self.__get_identity_store(identity_store_id)
|
identity_store = self.__get_identity_store(identity_store_id)
|
||||||
if group_id in identity_store.groups:
|
if group_id in identity_store.groups:
|
||||||
@ -240,19 +264,19 @@ class IdentityStoreBackend(BaseBackend):
|
|||||||
@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
|
@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
|
||||||
def list_groups(
|
def list_groups(
|
||||||
self, identity_store_id: str, filters: List[Dict[str, str]]
|
self, identity_store_id: str, filters: List[Dict[str, str]]
|
||||||
) -> List[Dict[str, str]]:
|
) -> List[Dict[str, Any]]:
|
||||||
identity_store = self.__get_identity_store(identity_store_id)
|
identity_store = self.__get_identity_store(identity_store_id)
|
||||||
|
|
||||||
if filters:
|
if filters:
|
||||||
if filters[0].get("AttributePath") == "DisplayName":
|
if filters[0].get("AttributePath") == "DisplayName":
|
||||||
displayname = filters[0].get("AttributeValue")
|
displayname = filters[0].get("AttributeValue")
|
||||||
return [
|
return [
|
||||||
m
|
m._asdict()
|
||||||
for m in identity_store.groups.values()
|
for m in identity_store.groups.values()
|
||||||
if m["DisplayName"] == displayname
|
if m.DisplayName == displayname
|
||||||
]
|
]
|
||||||
|
|
||||||
return [m for m in identity_store.groups.values()]
|
return [m._asdict() for m in identity_store.groups.values()]
|
||||||
|
|
||||||
@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
|
@paginate(pagination_model=PAGINATION_MODEL) # type: ignore
|
||||||
def list_users(
|
def list_users(
|
||||||
|
@ -150,6 +150,29 @@ class IdentityStoreResponse(BaseResponse):
|
|||||||
|
|
||||||
return json.dumps(dict(Groups=groups, NextToken=next_token))
|
return json.dumps(dict(Groups=groups, NextToken=next_token))
|
||||||
|
|
||||||
|
def describe_group(self) -> str:
|
||||||
|
identity_store_id = self._get_param("IdentityStoreId")
|
||||||
|
group_id = self._get_param("GroupId")
|
||||||
|
(
|
||||||
|
group_id,
|
||||||
|
display_name,
|
||||||
|
external_ids,
|
||||||
|
description,
|
||||||
|
identity_store_id,
|
||||||
|
) = self.identitystore_backend.describe_group(
|
||||||
|
identity_store_id=identity_store_id,
|
||||||
|
group_id=group_id,
|
||||||
|
)
|
||||||
|
return json.dumps(
|
||||||
|
dict(
|
||||||
|
GroupId=group_id,
|
||||||
|
DisplayName=display_name,
|
||||||
|
ExternalIds=external_ids,
|
||||||
|
Description=description,
|
||||||
|
IdentityStoreId=identity_store_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def list_users(self) -> str:
|
def list_users(self) -> str:
|
||||||
identity_store_id = self._get_param("IdentityStoreId")
|
identity_store_id = self._get_param("IdentityStoreId")
|
||||||
max_results = self._get_param("MaxResults")
|
max_results = self._get_param("MaxResults")
|
||||||
|
@ -432,6 +432,7 @@ def test_list_groups():
|
|||||||
{
|
{
|
||||||
"GroupId": group_id,
|
"GroupId": group_id,
|
||||||
"DisplayName": display_name,
|
"DisplayName": display_name,
|
||||||
|
"ExternalIds": [],
|
||||||
"Description": description,
|
"Description": description,
|
||||||
"IdentityStoreId": identity_store_id,
|
"IdentityStoreId": identity_store_id,
|
||||||
}
|
}
|
||||||
@ -476,6 +477,7 @@ def test_list_groups_filter():
|
|||||||
expected_group = {
|
expected_group = {
|
||||||
"GroupId": group_id,
|
"GroupId": group_id,
|
||||||
"DisplayName": display_name,
|
"DisplayName": display_name,
|
||||||
|
"ExternalIds": [],
|
||||||
"Description": description,
|
"Description": description,
|
||||||
"IdentityStoreId": identity_store_id,
|
"IdentityStoreId": identity_store_id,
|
||||||
}
|
}
|
||||||
@ -733,6 +735,40 @@ def test_delete_user_doesnt_exist():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_identitystore
|
||||||
|
def test_create_describe_group() -> None:
|
||||||
|
client = boto3.client("identitystore", region_name="us-east-2")
|
||||||
|
identity_store_id = get_identity_store_id()
|
||||||
|
group_name, group_descriprion, group_id = __create_test_group(
|
||||||
|
client, identity_store_id
|
||||||
|
)
|
||||||
|
|
||||||
|
client_response = client.describe_group(
|
||||||
|
IdentityStoreId=identity_store_id, GroupId=group_id
|
||||||
|
)
|
||||||
|
assert client_response["GroupId"] == group_id
|
||||||
|
assert client_response["DisplayName"] == group_name
|
||||||
|
assert client_response["Description"] == group_descriprion
|
||||||
|
assert client_response["IdentityStoreId"] == identity_store_id
|
||||||
|
|
||||||
|
|
||||||
|
@mock_identitystore
|
||||||
|
def test_describe_group_doesnt_exist() -> None:
|
||||||
|
client = boto3.client("identitystore", region_name="us-east-2")
|
||||||
|
identity_store_id = get_identity_store_id()
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.describe_group(IdentityStoreId=identity_store_id, GroupId=str(uuid4()))
|
||||||
|
|
||||||
|
err = exc.value
|
||||||
|
assert err.response["Error"]["Code"] == "ResourceNotFoundException"
|
||||||
|
assert err.response["Error"]["Message"] == "GROUP not found."
|
||||||
|
assert err.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
||||||
|
assert err.response["ResourceType"] == "GROUP"
|
||||||
|
assert err.response["Message"] == "GROUP not found."
|
||||||
|
assert "RequestId" in err.response
|
||||||
|
|
||||||
|
|
||||||
def __create_test_group(client, store_id: str):
|
def __create_test_group(client, store_id: str):
|
||||||
rand = "".join(random.choices(string.ascii_lowercase, k=8))
|
rand = "".join(random.choices(string.ascii_lowercase, k=8))
|
||||||
group_name = f"test_group_{rand}"
|
group_name = f"test_group_{rand}"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user