Add functionalities for SAML Providers

This commit is contained in:
Joe Engel 2018-11-19 15:47:21 -08:00 committed by Joseph Engel
parent ed861ecae1
commit 57fa11136b
4 changed files with 178 additions and 5 deletions

View File

@ -2225,7 +2225,7 @@
- [X] create_policy - [X] create_policy
- [X] create_policy_version - [X] create_policy_version
- [X] create_role - [X] create_role
- [ ] create_saml_provider - [X] create_saml_provider
- [ ] create_service_linked_role - [ ] create_service_linked_role
- [ ] create_service_specific_credential - [ ] create_service_specific_credential
- [X] create_user - [X] create_user
@ -2243,7 +2243,7 @@
- [X] delete_policy_version - [X] delete_policy_version
- [X] delete_role - [X] delete_role
- [X] delete_role_policy - [X] delete_role_policy
- [ ] delete_saml_provider - [X] delete_saml_provider
- [X] delete_server_certificate - [X] delete_server_certificate
- [ ] delete_service_linked_role - [ ] delete_service_linked_role
- [ ] delete_service_specific_credential - [ ] delete_service_specific_credential
@ -2273,7 +2273,7 @@
- [X] get_policy_version - [X] get_policy_version
- [X] get_role - [X] get_role
- [X] get_role_policy - [X] get_role_policy
- [ ] get_saml_provider - [X] get_saml_provider
- [X] get_server_certificate - [X] get_server_certificate
- [ ] get_service_linked_role_deletion_status - [ ] get_service_linked_role_deletion_status
- [ ] get_ssh_public_key - [ ] get_ssh_public_key
@ -2296,7 +2296,7 @@
- [X] list_policy_versions - [X] list_policy_versions
- [X] list_role_policies - [X] list_role_policies
- [ ] list_roles - [ ] list_roles
- [ ] list_saml_providers - [X] list_saml_providers
- [ ] list_server_certificates - [ ] list_server_certificates
- [ ] list_service_specific_credentials - [ ] list_service_specific_credentials
- [ ] list_signing_certificates - [ ] list_signing_certificates
@ -2323,7 +2323,7 @@
- [ ] update_open_id_connect_provider_thumbprint - [ ] update_open_id_connect_provider_thumbprint
- [ ] update_role - [ ] update_role
- [ ] update_role_description - [ ] update_role_description
- [ ] update_saml_provider - [X] update_saml_provider
- [ ] update_server_certificate - [ ] update_server_certificate
- [ ] update_service_specific_credential - [ ] update_service_specific_credential
- [ ] update_signing_certificate - [ ] update_signing_certificate

View File

@ -50,6 +50,16 @@ class Policy(BaseModel):
self.update_datetime = datetime.now(pytz.utc) self.update_datetime = datetime.now(pytz.utc)
class SAMLProvider(BaseModel):
def __init__(self, name, saml_metadata_document=None):
self.name = name
self.saml_metadata_document = saml_metadata_document
@property
def arn(self):
return "arn:aws:iam::{0}:saml-provider/{1}".format(ACCOUNT_ID, self.name)
class PolicyVersion(object): class PolicyVersion(object):
def __init__(self, def __init__(self,
@ -427,6 +437,7 @@ class IAMBackend(BaseBackend):
self.credential_report = None self.credential_report = None
self.managed_policies = self._init_managed_policies() self.managed_policies = self._init_managed_policies()
self.account_aliases = [] self.account_aliases = []
self.saml_providers = {}
super(IAMBackend, self).__init__() super(IAMBackend, self).__init__()
def _init_managed_policies(self): def _init_managed_policies(self):
@ -937,5 +948,33 @@ class IAMBackend(BaseBackend):
'managed_policies': returned_policies 'managed_policies': returned_policies
} }
def create_saml_provider(self, name, saml_metadata_document):
saml_provider = SAMLProvider(name, saml_metadata_document)
self.saml_providers[name] = saml_provider
return saml_provider
def update_saml_provider(self, saml_provider_arn, saml_metadata_document):
saml_provider = self.get_saml_provider(saml_provider_arn)
saml_provider.saml_metadata_document = saml_metadata_document
return saml_provider
def delete_saml_provider(self, saml_provider_arn):
try:
for saml_provider in list(self.list_saml_providers()):
if saml_provider.arn == saml_provider_arn:
del self.saml_providers[saml_provider.name]
except KeyError:
raise IAMNotFoundException(
"SAMLProvider {0} not found".format(saml_provider_arn))
def list_saml_providers(self):
return self.saml_providers.values()
def get_saml_provider(self, saml_provider_arn):
for saml_provider in self.list_saml_providers():
if saml_provider.arn == saml_provider_arn:
return saml_provider
raise IAMNotFoundException("SamlProvider {0} not found".format(saml_provider_arn))
iam_backend = IAMBackend() iam_backend = IAMBackend()

View File

@ -552,6 +552,42 @@ class IamResponse(BaseResponse):
roles=account_details['roles'] roles=account_details['roles']
) )
def create_saml_provider(self):
saml_provider_name = self._get_param('Name')
saml_metadata_document = self._get_param('SAMLMetadataDocument')
saml_provider = iam_backend.create_saml_provider(saml_provider_name, saml_metadata_document)
template = self.response_template(CREATE_SAML_PROVIDER_TEMPLATE)
return template.render(saml_provider=saml_provider)
def update_saml_provider(self):
saml_provider_arn = self._get_param('SAMLProviderArn')
saml_metadata_document = self._get_param('SAMLMetadataDocument')
saml_provider = iam_backend.update_saml_provider(saml_provider_arn, saml_metadata_document)
template = self.response_template(UPDATE_SAML_PROVIDER_TEMPLATE)
return template.render(saml_provider=saml_provider)
def delete_saml_provider(self):
saml_provider_arn = self._get_param('SAMLProviderArn')
iam_backend.delete_saml_provider(saml_provider_arn)
template = self.response_template(DELETE_SAML_PROVIDER_TEMPLATE)
return template.render()
def list_saml_providers(self):
saml_providers = iam_backend.list_saml_providers()
template = self.response_template(LIST_SAML_PROVIDERS_TEMPLATE)
return template.render(saml_providers=saml_providers)
def get_saml_provider(self):
saml_provider_arn = self._get_param('SAMLProviderArn')
saml_provider = iam_backend.get_saml_provider(saml_provider_arn)
template = self.response_template(GET_SAML_PROVIDER_TEMPLATE)
return template.render(saml_provider=saml_provider)
ATTACH_ROLE_POLICY_TEMPLATE = """<AttachRolePolicyResponse> ATTACH_ROLE_POLICY_TEMPLATE = """<AttachRolePolicyResponse>
<ResponseMetadata> <ResponseMetadata>
@ -1485,3 +1521,55 @@ GET_ACCOUNT_AUTHORIZATION_DETAILS_TEMPLATE = """<GetAccountAuthorizationDetailsR
<RequestId>92e79ae7-7399-11e4-8c85-4b53eEXAMPLE</RequestId> <RequestId>92e79ae7-7399-11e4-8c85-4b53eEXAMPLE</RequestId>
</ResponseMetadata> </ResponseMetadata>
</GetAccountAuthorizationDetailsResponse>""" </GetAccountAuthorizationDetailsResponse>"""
CREATE_SAML_PROVIDER_TEMPLATE = """<CreateSAMLProviderResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<CreateSAMLProviderResult>
<SAMLProviderArn>{{ saml_provider.arn }}</SAMLProviderArn>
</CreateSAMLProviderResult>
<ResponseMetadata>
<RequestId>29f47818-99f5-11e1-a4c3-27EXAMPLE804</RequestId>
</ResponseMetadata>
</CreateSAMLProviderResponse>"""
LIST_SAML_PROVIDERS_TEMPLATE = """<ListSAMLProvidersResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<ListSAMLProvidersResult>
<SAMLProviderList>
{% for saml_provider in saml_providers %}
<member>
<Arn>{{ saml_provider.arn }}</Arn>
<ValidUntil>2032-05-09T16:27:11Z</ValidUntil>
<CreateDate>2012-05-09T16:27:03Z</CreateDate>
</member>
{% endfor %}
</SAMLProviderList>
</ListSAMLProvidersResult>
<ResponseMetadata>
<RequestId>fd74fa8d-99f3-11e1-a4c3-27EXAMPLE804</RequestId>
</ResponseMetadata>
</ListSAMLProvidersResponse>"""
GET_SAML_PROVIDER_TEMPLATE = """<GetSAMLProviderResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<GetSAMLProviderResult>
<CreateDate>2012-05-09T16:27:11Z</CreateDate>
<ValidUntil>2015-12-31T21:59:59Z</ValidUntil>
<SAMLMetadataDocument>{{ saml_provider.saml_metadata_document }}</SAMLMetadataDocument>
</GetSAMLProviderResult>
<ResponseMetadata>
<RequestId>29f47818-99f5-11e1-a4c3-27EXAMPLE804</RequestId>
</ResponseMetadata>
</GetSAMLProviderResponse>"""
DELETE_SAML_PROVIDER_TEMPLATE = """<DeleteSAMLProviderResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<ResponseMetadata>
<RequestId>c749ee7f-99ef-11e1-a4c3-27EXAMPLE804</RequestId>
</ResponseMetadata>
</DeleteSAMLProviderResponse>"""
UPDATE_SAML_PROVIDER_TEMPLATE = """<UpdateSAMLProviderResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<UpdateSAMLProviderResult>
<SAMLProviderArn>{{ saml_provider.arn }}</SAMLProviderArn>
</UpdateSAMLProviderResult>
<ResponseMetadata>
<RequestId>29f47818-99f5-11e1-a4c3-27EXAMPLE804</RequestId>
</ResponseMetadata>
</UpdateSAMLProviderResponse>"""

View File

@ -3,7 +3,9 @@ import base64
import boto import boto
import boto3 import boto3
import os
import sure # noqa import sure # noqa
import sys
from boto.exception import BotoServerError from boto.exception import BotoServerError
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_iam, mock_iam_deprecated from moto import mock_iam, mock_iam_deprecated
@ -756,5 +758,49 @@ def test_get_account_authorization_details():
len(result['GroupDetailList']) == 1 len(result['GroupDetailList']) == 1
len(result['Policies']) > 1 len(result['Policies']) > 1
@mock_iam()
def test_create_saml_provider():
conn = boto3.client('iam', region_name='us-east-1')
response = conn.create_saml_provider(
Name="TestSAMLProvider",
SAMLMetadataDocument='a' * 1024
)
response['SAMLProviderArn'].should.equal("arn:aws:iam::123456789012:saml-provider/TestSAMLProvider")
@mock_iam()
def test_get_saml_provider():
conn = boto3.client('iam', region_name='us-east-1')
saml_provider_create = conn.create_saml_provider(
Name="TestSAMLProvider",
SAMLMetadataDocument='a' * 1024
)
response = conn.get_saml_provider(
SAMLProviderArn=saml_provider_create['SAMLProviderArn']
)
response['SAMLMetadataDocument'].should.equal('a' * 1024)
@mock_iam()
def test_list_saml_providers():
conn = boto3.client('iam', region_name='us-east-1')
conn.create_saml_provider(
Name="TestSAMLProvider",
SAMLMetadataDocument='a' * 1024
)
response = conn.list_saml_providers()
response['SAMLProviderList'][0]['Arn'].should.equal("arn:aws:iam::123456789012:saml-provider/TestSAMLProvider")
@mock_iam()
def test_delete_saml_provider():
conn = boto3.client('iam', region_name='us-east-1')
saml_provider_create = conn.create_saml_provider(
Name="TestSAMLProvider",
SAMLMetadataDocument='a' * 1024
)
response = conn.list_saml_providers()
print(response)
len(response['SAMLProviderList']).should.equal(1)
conn.delete_saml_provider(
SAMLProviderArn=saml_provider_create['SAMLProviderArn']
)
response = conn.list_saml_providers()
len(response['SAMLProviderList']).should.equal(0)