Merge pull request #2501 from edekadigital/add-iam-virtual-mfa-device
Add iam virtual mfa device
This commit is contained in:
commit
a5d4a68922
5 changed files with 448 additions and 7 deletions
|
|
@ -753,6 +753,263 @@ def test_mfa_devices():
|
|||
len(response['MFADevices']).should.equal(0)
|
||||
|
||||
|
||||
@mock_iam
|
||||
def test_create_virtual_mfa_device():
|
||||
client = boto3.client('iam', region_name='us-east-1')
|
||||
response = client.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName='test-device'
|
||||
)
|
||||
device = response['VirtualMFADevice']
|
||||
|
||||
device['SerialNumber'].should.equal('arn:aws:iam::123456789012:mfa/test-device')
|
||||
device['Base32StringSeed'].decode('ascii').should.match('[A-Z234567]')
|
||||
device['QRCodePNG'].should_not.be.empty
|
||||
|
||||
response = client.create_virtual_mfa_device(
|
||||
Path='/',
|
||||
VirtualMFADeviceName='test-device-2'
|
||||
)
|
||||
device = response['VirtualMFADevice']
|
||||
|
||||
device['SerialNumber'].should.equal('arn:aws:iam::123456789012:mfa/test-device-2')
|
||||
device['Base32StringSeed'].decode('ascii').should.match('[A-Z234567]')
|
||||
device['QRCodePNG'].should_not.be.empty
|
||||
|
||||
response = client.create_virtual_mfa_device(
|
||||
Path='/test/',
|
||||
VirtualMFADeviceName='test-device'
|
||||
)
|
||||
device = response['VirtualMFADevice']
|
||||
|
||||
device['SerialNumber'].should.equal('arn:aws:iam::123456789012:mfa/test/test-device')
|
||||
device['Base32StringSeed'].decode('ascii').should.match('[A-Z234567]')
|
||||
device['QRCodePNG'].should_not.be.empty
|
||||
|
||||
|
||||
@mock_iam
|
||||
def test_create_virtual_mfa_device_errors():
|
||||
client = boto3.client('iam', region_name='us-east-1')
|
||||
client.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName='test-device'
|
||||
)
|
||||
|
||||
client.create_virtual_mfa_device.when.called_with(
|
||||
VirtualMFADeviceName='test-device'
|
||||
).should.throw(
|
||||
ClientError,
|
||||
'MFADevice entity at the same path and name already exists.'
|
||||
)
|
||||
|
||||
client.create_virtual_mfa_device.when.called_with(
|
||||
Path='test',
|
||||
VirtualMFADeviceName='test-device'
|
||||
).should.throw(
|
||||
ClientError,
|
||||
'The specified value for path is invalid. '
|
||||
'It must begin and end with / and contain only alphanumeric characters and/or / characters.'
|
||||
)
|
||||
|
||||
client.create_virtual_mfa_device.when.called_with(
|
||||
Path='/test//test/',
|
||||
VirtualMFADeviceName='test-device'
|
||||
).should.throw(
|
||||
ClientError,
|
||||
'The specified value for path is invalid. '
|
||||
'It must begin and end with / and contain only alphanumeric characters and/or / characters.'
|
||||
)
|
||||
|
||||
too_long_path = '/{}/'.format('b' * 511)
|
||||
client.create_virtual_mfa_device.when.called_with(
|
||||
Path=too_long_path,
|
||||
VirtualMFADeviceName='test-device'
|
||||
).should.throw(
|
||||
ClientError,
|
||||
'1 validation error detected: '
|
||||
'Value "{}" at "path" failed to satisfy constraint: '
|
||||
'Member must have length less than or equal to 512'
|
||||
)
|
||||
|
||||
|
||||
@mock_iam
|
||||
def test_delete_virtual_mfa_device():
|
||||
client = boto3.client('iam', region_name='us-east-1')
|
||||
response = client.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName='test-device'
|
||||
)
|
||||
serial_number = response['VirtualMFADevice']['SerialNumber']
|
||||
|
||||
client.delete_virtual_mfa_device(
|
||||
SerialNumber=serial_number
|
||||
)
|
||||
|
||||
response = client.list_virtual_mfa_devices()
|
||||
|
||||
response['VirtualMFADevices'].should.have.length_of(0)
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
|
||||
@mock_iam
|
||||
def test_delete_virtual_mfa_device_errors():
|
||||
client = boto3.client('iam', region_name='us-east-1')
|
||||
|
||||
serial_number = 'arn:aws:iam::123456789012:mfa/not-existing'
|
||||
client.delete_virtual_mfa_device.when.called_with(
|
||||
SerialNumber=serial_number
|
||||
).should.throw(
|
||||
ClientError,
|
||||
'VirtualMFADevice with serial number {0} doesn\'t exist.'.format(serial_number)
|
||||
)
|
||||
|
||||
|
||||
@mock_iam
|
||||
def test_list_virtual_mfa_devices():
|
||||
client = boto3.client('iam', region_name='us-east-1')
|
||||
response = client.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName='test-device'
|
||||
)
|
||||
serial_number_1 = response['VirtualMFADevice']['SerialNumber']
|
||||
|
||||
response = client.create_virtual_mfa_device(
|
||||
Path='/test/',
|
||||
VirtualMFADeviceName='test-device'
|
||||
)
|
||||
serial_number_2 = response['VirtualMFADevice']['SerialNumber']
|
||||
|
||||
response = client.list_virtual_mfa_devices()
|
||||
|
||||
response['VirtualMFADevices'].should.equal([
|
||||
{
|
||||
'SerialNumber': serial_number_1
|
||||
},
|
||||
{
|
||||
'SerialNumber': serial_number_2
|
||||
}
|
||||
])
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
response = client.list_virtual_mfa_devices(
|
||||
AssignmentStatus='Assigned'
|
||||
)
|
||||
|
||||
response['VirtualMFADevices'].should.have.length_of(0)
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
response = client.list_virtual_mfa_devices(
|
||||
AssignmentStatus='Unassigned'
|
||||
)
|
||||
|
||||
response['VirtualMFADevices'].should.equal([
|
||||
{
|
||||
'SerialNumber': serial_number_1
|
||||
},
|
||||
{
|
||||
'SerialNumber': serial_number_2
|
||||
}
|
||||
])
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
response = client.list_virtual_mfa_devices(
|
||||
AssignmentStatus='Any',
|
||||
MaxItems=1
|
||||
)
|
||||
|
||||
response['VirtualMFADevices'].should.equal([
|
||||
{
|
||||
'SerialNumber': serial_number_1
|
||||
}
|
||||
])
|
||||
response['IsTruncated'].should.be.ok
|
||||
response['Marker'].should.equal('1')
|
||||
|
||||
response = client.list_virtual_mfa_devices(
|
||||
AssignmentStatus='Any',
|
||||
Marker=response['Marker']
|
||||
)
|
||||
|
||||
response['VirtualMFADevices'].should.equal([
|
||||
{
|
||||
'SerialNumber': serial_number_2
|
||||
}
|
||||
])
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
|
||||
@mock_iam
|
||||
def test_list_virtual_mfa_devices_errors():
|
||||
client = boto3.client('iam', region_name='us-east-1')
|
||||
client.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName='test-device'
|
||||
)
|
||||
|
||||
client.list_virtual_mfa_devices.when.called_with(
|
||||
Marker='100'
|
||||
).should.throw(
|
||||
ClientError,
|
||||
'Invalid Marker.'
|
||||
)
|
||||
|
||||
|
||||
@mock_iam
|
||||
def test_enable_virtual_mfa_device():
|
||||
client = boto3.client('iam', region_name='us-east-1')
|
||||
response = client.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName='test-device'
|
||||
)
|
||||
serial_number = response['VirtualMFADevice']['SerialNumber']
|
||||
|
||||
client.create_user(UserName='test-user')
|
||||
client.enable_mfa_device(
|
||||
UserName='test-user',
|
||||
SerialNumber=serial_number,
|
||||
AuthenticationCode1='234567',
|
||||
AuthenticationCode2='987654'
|
||||
)
|
||||
|
||||
response = client.list_virtual_mfa_devices(
|
||||
AssignmentStatus='Unassigned'
|
||||
)
|
||||
|
||||
response['VirtualMFADevices'].should.have.length_of(0)
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
response = client.list_virtual_mfa_devices(
|
||||
AssignmentStatus='Assigned'
|
||||
)
|
||||
|
||||
device = response['VirtualMFADevices'][0]
|
||||
device['SerialNumber'].should.equal(serial_number)
|
||||
device['User']['Path'].should.equal('/')
|
||||
device['User']['UserName'].should.equal('test-user')
|
||||
device['User']['UserId'].should_not.be.empty
|
||||
device['User']['Arn'].should.equal('arn:aws:iam::123456789012:user/test-user')
|
||||
device['User']['CreateDate'].should.be.a(datetime)
|
||||
device['EnableDate'].should.be.a(datetime)
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
client.deactivate_mfa_device(
|
||||
UserName='test-user',
|
||||
SerialNumber=serial_number
|
||||
)
|
||||
|
||||
response = client.list_virtual_mfa_devices(
|
||||
AssignmentStatus='Assigned'
|
||||
)
|
||||
|
||||
response['VirtualMFADevices'].should.have.length_of(0)
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
response = client.list_virtual_mfa_devices(
|
||||
AssignmentStatus = 'Unassigned'
|
||||
)
|
||||
|
||||
response['VirtualMFADevices'].should.equal([
|
||||
{
|
||||
'SerialNumber': serial_number
|
||||
}
|
||||
])
|
||||
response['IsTruncated'].should_not.be.ok
|
||||
|
||||
|
||||
@mock_iam_deprecated()
|
||||
def test_delete_user_deprecated():
|
||||
conn = boto.connect_iam()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue