Merge pull request #1958 from Joeskyyy/master

Add functionalities for SAML Providers
This commit is contained in:
Steve Pulec 2018-12-28 20:58:01 -05:00 committed by GitHub
commit e647eeb5a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 181 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

@ -54,6 +54,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,
@ -444,6 +454,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):
@ -996,5 +1007,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)
def upload_signing_certificate(self): def upload_signing_certificate(self):
user_name = self._get_param('UserName') user_name = self._get_param('UserName')
cert_body = self._get_param('CertificateBody') cert_body = self._get_param('CertificateBody')
@ -1518,6 +1554,58 @@ GET_ACCOUNT_AUTHORIZATION_DETAILS_TEMPLATE = """<GetAccountAuthorizationDetailsR
</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>"""
=======
UPLOAD_SIGNING_CERTIFICATE_TEMPLATE = """<UploadSigningCertificateResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/"> UPLOAD_SIGNING_CERTIFICATE_TEMPLATE = """<UploadSigningCertificateResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<UploadSigningCertificateResult> <UploadSigningCertificateResult>

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
@ -851,6 +853,53 @@ def test_signing_certs():
with assert_raises(ClientError): with assert_raises(ClientError):
client.delete_signing_certificate(UserName='notauser', CertificateId=cert_id) client.delete_signing_certificate(UserName='notauser', CertificateId=cert_id)
@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)
with assert_raises(ClientError) as ce: with assert_raises(ClientError) as ce:
client.delete_signing_certificate(UserName='testing', CertificateId=cert_id) client.delete_signing_certificate(UserName='testing', CertificateId=cert_id)