Merge pull request #881 from smarlowucf/master
Add mfa device endpoints to iam backend.
This commit is contained in:
commit
42f6487c88
@ -11,6 +11,19 @@ from .utils import random_access_key, random_alphanumeric, random_resource_id, r
|
||||
ACCOUNT_ID = 123456789012
|
||||
|
||||
|
||||
class MFADevice(object):
|
||||
"""MFA Device class."""
|
||||
|
||||
def __init__(self,
|
||||
serial_number,
|
||||
authentication_code_1,
|
||||
authentication_code_2):
|
||||
self.enable_date = datetime.now(pytz.utc)
|
||||
self.serial_number = serial_number
|
||||
self.authentication_code_1 = authentication_code_1
|
||||
self.authentication_code_2 = authentication_code_2
|
||||
|
||||
|
||||
class Policy(BaseModel):
|
||||
|
||||
is_attachable = False
|
||||
@ -226,6 +239,7 @@ class User(BaseModel):
|
||||
datetime.utcnow(),
|
||||
"%Y-%m-%d-%H-%M-%S"
|
||||
)
|
||||
self.mfa_devices = {}
|
||||
self.policies = {}
|
||||
self.access_keys = []
|
||||
self.password = None
|
||||
@ -251,6 +265,9 @@ class User(BaseModel):
|
||||
def put_policy(self, policy_name, policy_json):
|
||||
self.policies[policy_name] = policy_json
|
||||
|
||||
def deactivate_mfa_device(self, serial_number):
|
||||
self.mfa_devices.pop(serial_number)
|
||||
|
||||
def delete_policy(self, policy_name):
|
||||
if policy_name not in self.policies:
|
||||
raise IAMNotFoundException(
|
||||
@ -263,6 +280,16 @@ class User(BaseModel):
|
||||
self.access_keys.append(access_key)
|
||||
return access_key
|
||||
|
||||
def enable_mfa_device(self,
|
||||
serial_number,
|
||||
authentication_code_1,
|
||||
authentication_code_2):
|
||||
self.mfa_devices[serial_number] = MFADevice(
|
||||
serial_number,
|
||||
authentication_code_1,
|
||||
authentication_code_2
|
||||
)
|
||||
|
||||
def get_all_access_keys(self):
|
||||
return self.access_keys
|
||||
|
||||
@ -724,6 +751,39 @@ class IAMBackend(BaseBackend):
|
||||
user = self.get_user(user_name)
|
||||
user.delete_access_key(access_key_id)
|
||||
|
||||
def enable_mfa_device(self,
|
||||
user_name,
|
||||
serial_number,
|
||||
authentication_code_1,
|
||||
authentication_code_2):
|
||||
"""Enable MFA Device for user."""
|
||||
user = self.get_user(user_name)
|
||||
if serial_number in user.mfa_devices:
|
||||
raise IAMConflictException(
|
||||
"EntityAlreadyExists",
|
||||
"Device {0} already exists".format(serial_number)
|
||||
)
|
||||
|
||||
user.enable_mfa_device(
|
||||
serial_number,
|
||||
authentication_code_1,
|
||||
authentication_code_2
|
||||
)
|
||||
|
||||
def deactivate_mfa_device(self, user_name, serial_number):
|
||||
"""Deactivate and detach MFA Device from user if device exists."""
|
||||
user = self.get_user(user_name)
|
||||
if serial_number not in user.mfa_devices:
|
||||
raise IAMNotFoundException(
|
||||
"Device {0} not found".format(serial_number)
|
||||
)
|
||||
|
||||
user.deactivate_mfa_device(serial_number)
|
||||
|
||||
def list_mfa_devices(self, user_name):
|
||||
user = self.get_user(user_name)
|
||||
return user.mfa_devices.values()
|
||||
|
||||
def delete_user(self, user_name):
|
||||
try:
|
||||
del self.users[user_name]
|
||||
|
@ -326,6 +326,35 @@ class IamResponse(BaseResponse):
|
||||
template = self.response_template(GENERIC_EMPTY_TEMPLATE)
|
||||
return template.render(name='DeleteAccessKey')
|
||||
|
||||
def deactivate_mfa_device(self):
|
||||
user_name = self._get_param('UserName')
|
||||
serial_number = self._get_param('SerialNumber')
|
||||
|
||||
iam_backend.deactivate_mfa_device(user_name, serial_number)
|
||||
template = self.response_template(GENERIC_EMPTY_TEMPLATE)
|
||||
return template.render(name='DeactivateMFADevice')
|
||||
|
||||
def enable_mfa_device(self):
|
||||
user_name = self._get_param('UserName')
|
||||
serial_number = self._get_param('SerialNumber')
|
||||
authentication_code_1 = self._get_param('AuthenticationCode1')
|
||||
authentication_code_2 = self._get_param('AuthenticationCode2')
|
||||
|
||||
iam_backend.enable_mfa_device(
|
||||
user_name,
|
||||
serial_number,
|
||||
authentication_code_1,
|
||||
authentication_code_2
|
||||
)
|
||||
template = self.response_template(GENERIC_EMPTY_TEMPLATE)
|
||||
return template.render(name='EnableMFADevice')
|
||||
|
||||
def list_mfa_devices(self):
|
||||
user_name = self._get_param('UserName')
|
||||
devices = iam_backend.list_mfa_devices(user_name)
|
||||
template = self.response_template(LIST_MFA_DEVICES_TEMPLATE)
|
||||
return template.render(user_name=user_name, devices=devices)
|
||||
|
||||
def delete_user(self):
|
||||
user_name = self._get_param('UserName')
|
||||
iam_backend.delete_user(user_name)
|
||||
@ -922,3 +951,20 @@ LIST_INSTANCE_PROFILES_FOR_ROLE_TEMPLATE = """<ListInstanceProfilesForRoleRespon
|
||||
<RequestId>6a8c3992-99f4-11e1-a4c3-27EXAMPLE804</RequestId>
|
||||
</ResponseMetadata>
|
||||
</ListInstanceProfilesForRoleResponse>"""
|
||||
|
||||
LIST_MFA_DEVICES_TEMPLATE = """<ListMFADevicesResponse>
|
||||
<ListMFADevicesResult>
|
||||
<MFADevices>
|
||||
{% for device in devices %}
|
||||
<member>
|
||||
<UserName>{{ user_name }}</UserName>
|
||||
<SerialNumber>{{ device.serial_number }}</SerialNumber>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</MFADevices>
|
||||
<IsTruncated>false</IsTruncated>
|
||||
</ListMFADevicesResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
|
||||
</ResponseMetadata>
|
||||
</ListMFADevicesResponse>"""
|
||||
|
@ -292,6 +292,29 @@ def test_delete_access_key():
|
||||
conn.delete_access_key(access_key_id, 'my-user')
|
||||
|
||||
|
||||
@mock_iam()
|
||||
def test_mfa_devices():
|
||||
# Test enable device
|
||||
conn = boto3.client('iam', region_name='us-east-1')
|
||||
conn.create_user(UserName='my-user')
|
||||
conn.enable_mfa_device(
|
||||
UserName='my-user',
|
||||
SerialNumber='123456789',
|
||||
AuthenticationCode1='234567',
|
||||
AuthenticationCode2='987654'
|
||||
)
|
||||
|
||||
# Test list mfa devices
|
||||
response = conn.list_mfa_devices(UserName='my-user')
|
||||
device = response['MFADevices'][0]
|
||||
device['SerialNumber'].should.equal('123456789')
|
||||
|
||||
# Test deactivate mfa device
|
||||
conn.deactivate_mfa_device(UserName='my-user', SerialNumber='123456789')
|
||||
response = conn.list_mfa_devices(UserName='my-user')
|
||||
len(response['MFADevices']).should.equal(0)
|
||||
|
||||
|
||||
@mock_iam_deprecated()
|
||||
def test_delete_user():
|
||||
conn = boto.connect_iam()
|
||||
|
Loading…
Reference in New Issue
Block a user