sso-admin: add PermissionSet actions (#5208)

This commit is contained in:
Feng He 2022-06-10 03:37:30 +10:00 committed by GitHub
parent d4355a93f8
commit 47fe052c6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 411 additions and 5 deletions

View File

@ -5662,15 +5662,15 @@
- [ ] attach_managed_policy_to_permission_set
- [X] create_account_assignment
- [ ] create_instance_access_control_attribute_configuration
- [ ] create_permission_set
- [X] create_permission_set
- [X] delete_account_assignment
- [ ] delete_inline_policy_from_permission_set
- [ ] delete_instance_access_control_attribute_configuration
- [ ] delete_permission_set
- [X] delete_permission_set
- [ ] describe_account_assignment_creation_status
- [ ] describe_account_assignment_deletion_status
- [ ] describe_instance_access_control_attribute_configuration
- [ ] describe_permission_set
- [X] describe_permission_set
- [ ] describe_permission_set_provisioning_status
- [ ] detach_managed_policy_from_permission_set
- [ ] get_inline_policy_for_permission_set
@ -5681,7 +5681,7 @@
- [ ] list_instances
- [ ] list_managed_policies_in_permission_set
- [ ] list_permission_set_provisioning_status
- [ ] list_permission_sets
- [X] list_permission_sets
- [ ] list_permission_sets_provisioned_to_account
- [ ] list_tags_for_resource
- [ ] provision_permission_set
@ -5689,7 +5689,7 @@
- [ ] tag_resource
- [ ] untag_resource
- [ ] update_instance_access_control_attribute_configuration
- [ ] update_permission_set
- [X] update_permission_set
</details>
## stepfunctions

View File

@ -3,6 +3,9 @@ from .exceptions import ResourceNotFound
from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict, unix_time
from uuid import uuid4
import random
from moto.utilities.paginator import paginate
from .utils import PAGINATION_MODEL
class AccountAssignment(BaseModel):
@ -37,12 +40,54 @@ class AccountAssignment(BaseModel):
return summary
class PermissionSet(BaseModel):
def __init__(
self,
name,
description,
instance_arn,
session_duration,
relay_state,
tags,
):
self.name = name
self.description = description
self.instance_arn = instance_arn
self.permission_set_arn = PermissionSet.generate_id(instance_arn)
self.session_duration = session_duration
self.relay_state = relay_state
self.tags = tags
self.created_date = unix_time()
def to_json(self, include_creation_date=False):
summary = {
"Name": self.name,
"Description": self.description,
"PermissionSetArn": self.permission_set_arn,
"SessionDuration": self.session_duration,
"RelayState": self.relay_state,
}
if include_creation_date:
summary["CreatedDate"] = self.created_date
return summary
@staticmethod
def generate_id(instance_arn):
chars = list(range(10)) + ["a", "b", "c", "d", "e", "f"]
return (
instance_arn
+ "/ps-"
+ "".join(str(random.choice(chars)) for _ in range(16))
)
class SSOAdminBackend(BaseBackend):
"""Implementation of SSOAdmin APIs."""
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self.account_assignments = list()
self.permission_sets = list()
def create_account_assignment(
self,
@ -132,5 +177,89 @@ class SSOAdminBackend(BaseBackend):
)
return account_assignments
def create_permission_set(
self,
name,
description,
instance_arn,
session_duration,
relay_state,
tags,
):
permission_set = PermissionSet(
name,
description,
instance_arn,
session_duration,
relay_state,
tags,
)
self.permission_sets.append(permission_set)
return permission_set.to_json(True)
def update_permission_set(
self,
instance_arn,
permission_set_arn,
description,
session_duration,
relay_state,
):
permission_set = self._find_permission_set(
instance_arn,
permission_set_arn,
)
self.permission_sets.remove(permission_set)
permission_set.description = description
permission_set.session_duration = session_duration
permission_set.relay_state = relay_state
self.permission_sets.append(permission_set)
return permission_set.to_json(True)
def describe_permission_set(
self,
instance_arn,
permission_set_arn,
):
permission_set = self._find_permission_set(
instance_arn,
permission_set_arn,
)
return permission_set.to_json(True)
def delete_permission_set(
self,
instance_arn,
permission_set_arn,
):
permission_set = self._find_permission_set(
instance_arn,
permission_set_arn,
)
self.permission_sets.remove(permission_set)
return permission_set.to_json(include_creation_date=True)
def _find_permission_set(
self,
instance_arn,
permission_set_arn,
):
for permission_set in self.permission_sets:
instance_arn_match = permission_set.instance_arn == instance_arn
permission_set_match = (
permission_set.permission_set_arn == permission_set_arn
)
if instance_arn_match and permission_set_match:
return permission_set
raise ResourceNotFound
@paginate(pagination_model=PAGINATION_MODEL)
def list_permission_sets(self, instance_arn):
permission_sets = []
for permission_set in self.permission_sets:
if permission_set.instance_arn == instance_arn:
permission_sets.append(permission_set)
return permission_sets
ssoadmin_backends = BackendDict(SSOAdminBackend, "sso")

View File

@ -65,3 +65,71 @@ class SSOAdminResponse(BaseResponse):
permission_set_arn=permission_set_arn,
)
return json.dumps({"AccountAssignments": assignments})
def create_permission_set(self):
name = self._get_param("Name")
description = self._get_param("Description")
instance_arn = self._get_param("InstanceArn")
session_duration = self._get_param("SessionDuration", 3600)
relay_state = self._get_param("RelayState")
tags = self._get_param("Tags")
permission_set = self.ssoadmin_backend.create_permission_set(
name=name,
description=description,
instance_arn=instance_arn,
session_duration=session_duration,
relay_state=relay_state,
tags=tags,
)
return json.dumps({"PermissionSet": permission_set})
def delete_permission_set(self):
params = json.loads(self.body)
instance_arn = params.get("InstanceArn")
permission_set_arn = params.get("PermissionSetArn")
self.ssoadmin_backend.delete_permission_set(
instance_arn=instance_arn,
permission_set_arn=permission_set_arn,
)
def update_permission_set(self):
instance_arn = self._get_param("InstanceArn")
permission_set_arn = self._get_param("PermissionSetArn")
description = self._get_param("Description")
session_duration = self._get_param("SessionDuration", 3600)
relay_state = self._get_param("RelayState")
self.ssoadmin_backend.update_permission_set(
instance_arn=instance_arn,
permission_set_arn=permission_set_arn,
description=description,
session_duration=session_duration,
relay_state=relay_state,
)
def describe_permission_set(self):
instance_arn = self._get_param("InstanceArn")
permission_set_arn = self._get_param("PermissionSetArn")
permission_set = self.ssoadmin_backend.describe_permission_set(
instance_arn=instance_arn,
permission_set_arn=permission_set_arn,
)
return json.dumps({"PermissionSet": permission_set})
def list_permission_sets(self):
instance_arn = self._get_param("InstanceArn")
max_results = self._get_int_param("MaxResults")
next_token = self._get_param("NextToken")
permission_sets, next_token = self.ssoadmin_backend.list_permission_sets(
instance_arn=instance_arn, max_results=max_results, next_token=next_token
)
permission_set_ids = []
for permission_set in permission_sets:
permission_set_ids.append(permission_set.permission_set_arn)
response = {"PermissionSets": permission_set_ids}
if next_token:
response["NextToken"] = next_token
return json.dumps(response)

9
moto/ssoadmin/utils.py Normal file
View File

@ -0,0 +1,9 @@
PAGINATION_MODEL = {
"list_permission_sets": {
"input_token": "next_token",
"limit_key": "max_results",
"limit_default": 100,
"result_key": "PermissionSets",
"unique_attribute": "permission_set_arn",
},
}

View File

@ -188,3 +188,203 @@ def test_list_account_assignments():
}
]
)
@mock_ssoadmin
def test_create_permission_set():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
resp = client.create_permission_set(
Name="test",
Description="Test permission set",
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
SessionDuration="PT1H",
RelayState="https://console.aws.amazon.com/ec2",
)
resp.should.have.key("PermissionSet")
permissionSet = resp["PermissionSet"]
permissionSet.should.have.key("Name").equals("test")
permissionSet.should.have.key("PermissionSetArn")
permissionSet.should.have.key("Description")
permissionSet.should.have.key("CreatedDate")
permissionSet.should.have.key("SessionDuration")
permissionSet.should.have.key("RelayState")
@mock_ssoadmin
def test_update_permission_set():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
resp = client.create_permission_set(
Name="test",
Description="Test permission set",
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
SessionDuration="PT1H",
)
permissionSet = resp["PermissionSet"]
resp = client.update_permission_set(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
PermissionSetArn=permissionSet["PermissionSetArn"],
Description="New description",
SessionDuration="PT2H",
RelayState="https://console.aws.amazon.com/s3",
)
resp = client.describe_permission_set(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
PermissionSetArn=permissionSet["PermissionSetArn"],
)
resp.should.have.key("PermissionSet")
permissionSet = resp["PermissionSet"]
permissionSet.should.have.key("Name").equals("test")
permissionSet.should.have.key("Description").equals("New description")
permissionSet.should.have.key("CreatedDate")
permissionSet.should.have.key("SessionDuration").equals("PT2H")
permissionSet.should.have.key("RelayState").equals(
"https://console.aws.amazon.com/s3"
)
@mock_ssoadmin
def test_update_permission_set_unknown():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
with pytest.raises(ClientError) as exc:
client.update_permission_set(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
PermissionSetArn="arn:aws:sso:::permissionSet/ins-eeeeffffgggghhhh/ps-hhhhkkkkppppoooo",
Description="New description",
SessionDuration="PT2H",
RelayState="https://console.aws.amazon.com/s3",
)
err = exc.value.response["Error"]
err["Code"].should.equal("ResourceNotFound")
@mock_ssoadmin
def test_describe_permission_set():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
resp = client.create_permission_set(
Name="test",
Description="Test permission set",
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
SessionDuration="PT1H",
)
permissionSet = resp["PermissionSet"]
resp = client.describe_permission_set(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
PermissionSetArn=permissionSet["PermissionSetArn"],
)
resp.should.have.key("PermissionSet")
permissionSet = resp["PermissionSet"]
permissionSet.should.have.key("Name").equals("test")
permissionSet.should.have.key("PermissionSetArn")
permissionSet.should.have.key("Description")
permissionSet.should.have.key("CreatedDate")
permissionSet.should.have.key("SessionDuration")
@mock_ssoadmin
def test_describe_permission_set_unknown():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
with pytest.raises(ClientError) as exc:
client.describe_permission_set(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
PermissionSetArn="arn:aws:sso:::permissionSet/ins-eeeeffffgggghhhh/ps-hhhhkkkkppppoooo",
)
err = exc.value.response["Error"]
err["Code"].should.equal("ResourceNotFound")
@mock_ssoadmin
def test_delete_permission_set():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
resp = client.create_permission_set(
Name="test",
Description="Test permission set",
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
SessionDuration="PT1H",
)
permissionSet = resp["PermissionSet"]
resp = client.delete_permission_set(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
PermissionSetArn=permissionSet["PermissionSetArn"],
)
with pytest.raises(ClientError) as exc:
client.describe_permission_set(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
PermissionSetArn=permissionSet["PermissionSetArn"],
)
err = exc.value.response["Error"]
err["Code"].should.equal("ResourceNotFound")
@mock_ssoadmin
def test_delete_permission_set_unknown():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
with pytest.raises(ClientError) as exc:
client.delete_permission_set(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
PermissionSetArn="arn:aws:sso:::permissionSet/ins-eeeeffffgggghhhh/ps-hhhhkkkkppppoooo",
)
err = exc.value.response["Error"]
err["Code"].should.equal("ResourceNotFound")
@mock_ssoadmin
def test_list_permission_sets():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
response = client.list_permission_sets(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
)
response.should.have.key("PermissionSets")
permissionSets = response["PermissionSets"]
len(permissionSets).should.equal(0)
for i in range(5):
client.create_permission_set(
Name="test" + str(i),
Description="Test permission set " + str(i),
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
SessionDuration="PT1H",
)
response = client.list_permission_sets(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
)
response.should.have.key("PermissionSets")
permissionSets = response["PermissionSets"]
len(permissionSets).should.equal(5)
@mock_ssoadmin
def test_list_permission_sets_pagination():
client = boto3.client("sso-admin", region_name="ap-southeast-1")
response = client.list_permission_sets(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
)
response.should.have.key("PermissionSets")
permissionSets = response["PermissionSets"]
len(permissionSets).should.equal(0)
for i in range(25):
client.create_permission_set(
Name="test" + str(i),
Description="Test permission set " + str(i),
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
SessionDuration="PT1H",
)
response = client.list_permission_sets(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd",
)
response.should.have.key("PermissionSets")
response.should_not.have.key("NextToken")
paginator = client.get_paginator("list_permission_sets")
page_iterator = paginator.paginate(
InstanceArn="arn:aws:sso:::instance/ins-aaaabbbbccccdddd", MaxResults=5
)
for page in page_iterator:
len(page["PermissionSets"]).should.be.lower_than_or_equal_to(5)