1# Copyright (c) 2010-2011 Mitch Garnaat http://garnaat.org/
2# Copyright (c) 2010-2011, Eucalyptus Systems, Inc.
3#
4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the
6# "Software"), to deal in the Software without restriction, including
7# without limitation the rights to use, copy, modify, merge, publish, dis-
8# tribute, sublicense, and/or sell copies of the Software, and to permit
9# persons to whom the Software is furnished to do so, subject to the fol-
10# lowing conditions:
11#
12# The above copyright notice and this permission notice shall be included
13# in all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21# IN THE SOFTWARE.
22import boto
23import boto.jsonresponse
24from boto.compat import json, six
25from boto.resultset import ResultSet
26from boto.iam.summarymap import SummaryMap
27from boto.connection import AWSQueryConnection
28
29DEFAULT_POLICY_DOCUMENTS = {
30    'default': {
31        'Statement': [
32            {
33                'Principal': {
34                    'Service': ['ec2.amazonaws.com']
35                },
36                'Effect': 'Allow',
37                'Action': ['sts:AssumeRole']
38            }
39        ]
40    },
41    'amazonaws.com.cn': {
42        'Statement': [
43            {
44                'Principal': {
45                    'Service': ['ec2.amazonaws.com.cn']
46                },
47                'Effect': 'Allow',
48                'Action': ['sts:AssumeRole']
49            }
50        ]
51    },
52}
53# For backward-compatibility, we'll preserve this here.
54ASSUME_ROLE_POLICY_DOCUMENT = json.dumps(DEFAULT_POLICY_DOCUMENTS['default'])
55
56
57class IAMConnection(AWSQueryConnection):
58
59    APIVersion = '2010-05-08'
60
61    def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
62                 is_secure=True, port=None, proxy=None, proxy_port=None,
63                 proxy_user=None, proxy_pass=None, host='iam.amazonaws.com',
64                 debug=0, https_connection_factory=None, path='/',
65                 security_token=None, validate_certs=True, profile_name=None):
66        super(IAMConnection, self).__init__(aws_access_key_id,
67                                            aws_secret_access_key,
68                                            is_secure, port, proxy,
69                                            proxy_port, proxy_user, proxy_pass,
70                                            host, debug, https_connection_factory,
71                                            path, security_token,
72                                            validate_certs=validate_certs,
73                                            profile_name=profile_name)
74
75    def _required_auth_capability(self):
76        return ['hmac-v4']
77
78    def get_response(self, action, params, path='/', parent=None,
79                     verb='POST', list_marker='Set'):
80        """
81        Utility method to handle calls to IAM and parsing of responses.
82        """
83        if not parent:
84            parent = self
85        response = self.make_request(action, params, path, verb)
86        body = response.read()
87        boto.log.debug(body)
88        if response.status == 200:
89            if body:
90                e = boto.jsonresponse.Element(list_marker=list_marker,
91                                              pythonize_name=True)
92                h = boto.jsonresponse.XmlHandler(e, parent)
93                h.parse(body)
94                return e
95            else:
96                # Support empty responses, e.g. deleting a SAML provider
97                # according to the official documentation.
98                return {}
99        else:
100            boto.log.error('%s %s' % (response.status, response.reason))
101            boto.log.error('%s' % body)
102            raise self.ResponseError(response.status, response.reason, body)
103
104    #
105    # Group methods
106    #
107
108    def get_all_groups(self, path_prefix='/', marker=None, max_items=None):
109        """
110        List the groups that have the specified path prefix.
111
112        :type path_prefix: string
113        :param path_prefix: If provided, only groups whose paths match
114            the provided prefix will be returned.
115
116        :type marker: string
117        :param marker: Use this only when paginating results and only
118            in follow-up request after you've received a response
119            where the results are truncated.  Set this to the value of
120            the Marker element in the response you just received.
121
122        :type max_items: int
123        :param max_items: Use this only when paginating results to indicate
124            the maximum number of groups you want in the response.
125        """
126        params = {}
127        if path_prefix:
128            params['PathPrefix'] = path_prefix
129        if marker:
130            params['Marker'] = marker
131        if max_items:
132            params['MaxItems'] = max_items
133        return self.get_response('ListGroups', params,
134                                 list_marker='Groups')
135
136    def get_group(self, group_name, marker=None, max_items=None):
137        """
138        Return a list of users that are in the specified group.
139
140        :type group_name: string
141        :param group_name: The name of the group whose information should
142                           be returned.
143        :type marker: string
144        :param marker: Use this only when paginating results and only
145            in follow-up request after you've received a response
146            where the results are truncated.  Set this to the value of
147            the Marker element in the response you just received.
148
149        :type max_items: int
150        :param max_items: Use this only when paginating results to indicate
151            the maximum number of groups you want in the response.
152        """
153        params = {'GroupName': group_name}
154        if marker:
155            params['Marker'] = marker
156        if max_items:
157            params['MaxItems'] = max_items
158        return self.get_response('GetGroup', params, list_marker='Users')
159
160    def create_group(self, group_name, path='/'):
161        """
162        Create a group.
163
164        :type group_name: string
165        :param group_name: The name of the new group
166
167        :type path: string
168        :param path: The path to the group (Optional).  Defaults to /.
169
170        """
171        params = {'GroupName': group_name,
172                  'Path': path}
173        return self.get_response('CreateGroup', params)
174
175    def delete_group(self, group_name):
176        """
177        Delete a group. The group must not contain any Users or
178        have any attached policies
179
180        :type group_name: string
181        :param group_name: The name of the group to delete.
182
183        """
184        params = {'GroupName': group_name}
185        return self.get_response('DeleteGroup', params)
186
187    def update_group(self, group_name, new_group_name=None, new_path=None):
188        """
189        Updates name and/or path of the specified group.
190
191        :type group_name: string
192        :param group_name: The name of the new group
193
194        :type new_group_name: string
195        :param new_group_name: If provided, the name of the group will be
196            changed to this name.
197
198        :type new_path: string
199        :param new_path: If provided, the path of the group will be
200            changed to this path.
201
202        """
203        params = {'GroupName': group_name}
204        if new_group_name:
205            params['NewGroupName'] = new_group_name
206        if new_path:
207            params['NewPath'] = new_path
208        return self.get_response('UpdateGroup', params)
209
210    def add_user_to_group(self, group_name, user_name):
211        """
212        Add a user to a group
213
214        :type group_name: string
215        :param group_name: The name of the group
216
217        :type user_name: string
218        :param user_name: The to be added to the group.
219
220        """
221        params = {'GroupName': group_name,
222                  'UserName': user_name}
223        return self.get_response('AddUserToGroup', params)
224
225    def remove_user_from_group(self, group_name, user_name):
226        """
227        Remove a user from a group.
228
229        :type group_name: string
230        :param group_name: The name of the group
231
232        :type user_name: string
233        :param user_name: The user to remove from the group.
234
235        """
236        params = {'GroupName': group_name,
237                  'UserName': user_name}
238        return self.get_response('RemoveUserFromGroup', params)
239
240    def put_group_policy(self, group_name, policy_name, policy_json):
241        """
242        Adds or updates the specified policy document for the specified group.
243
244        :type group_name: string
245        :param group_name: The name of the group the policy is associated with.
246
247        :type policy_name: string
248        :param policy_name: The policy document to get.
249
250        :type policy_json: string
251        :param policy_json: The policy document.
252
253        """
254        params = {'GroupName': group_name,
255                  'PolicyName': policy_name,
256                  'PolicyDocument': policy_json}
257        return self.get_response('PutGroupPolicy', params, verb='POST')
258
259    def get_all_group_policies(self, group_name, marker=None, max_items=None):
260        """
261        List the names of the policies associated with the specified group.
262
263        :type group_name: string
264        :param group_name: The name of the group the policy is associated with.
265
266        :type marker: string
267        :param marker: Use this only when paginating results and only
268            in follow-up request after you've received a response
269            where the results are truncated.  Set this to the value of
270            the Marker element in the response you just received.
271
272        :type max_items: int
273        :param max_items: Use this only when paginating results to indicate
274            the maximum number of groups you want in the response.
275        """
276        params = {'GroupName': group_name}
277        if marker:
278            params['Marker'] = marker
279        if max_items:
280            params['MaxItems'] = max_items
281        return self.get_response('ListGroupPolicies', params,
282                                 list_marker='PolicyNames')
283
284    def get_group_policy(self, group_name, policy_name):
285        """
286        Retrieves the specified policy document for the specified group.
287
288        :type group_name: string
289        :param group_name: The name of the group the policy is associated with.
290
291        :type policy_name: string
292        :param policy_name: The policy document to get.
293
294        """
295        params = {'GroupName': group_name,
296                  'PolicyName': policy_name}
297        return self.get_response('GetGroupPolicy', params, verb='POST')
298
299    def delete_group_policy(self, group_name, policy_name):
300        """
301        Deletes the specified policy document for the specified group.
302
303        :type group_name: string
304        :param group_name: The name of the group the policy is associated with.
305
306        :type policy_name: string
307        :param policy_name: The policy document to delete.
308
309        """
310        params = {'GroupName': group_name,
311                  'PolicyName': policy_name}
312        return self.get_response('DeleteGroupPolicy', params, verb='POST')
313
314    def get_all_users(self, path_prefix='/', marker=None, max_items=None):
315        """
316        List the users that have the specified path prefix.
317
318        :type path_prefix: string
319        :param path_prefix: If provided, only users whose paths match
320            the provided prefix will be returned.
321
322        :type marker: string
323        :param marker: Use this only when paginating results and only
324            in follow-up request after you've received a response
325            where the results are truncated.  Set this to the value of
326            the Marker element in the response you just received.
327
328        :type max_items: int
329        :param max_items: Use this only when paginating results to indicate
330            the maximum number of groups you want in the response.
331        """
332        params = {'PathPrefix': path_prefix}
333        if marker:
334            params['Marker'] = marker
335        if max_items:
336            params['MaxItems'] = max_items
337        return self.get_response('ListUsers', params, list_marker='Users')
338
339    #
340    # User methods
341    #
342
343    def create_user(self, user_name, path='/'):
344        """
345        Create a user.
346
347        :type user_name: string
348        :param user_name: The name of the new user
349
350        :type path: string
351        :param path: The path in which the user will be created.
352            Defaults to /.
353
354        """
355        params = {'UserName': user_name,
356                  'Path': path}
357        return self.get_response('CreateUser', params)
358
359    def delete_user(self, user_name):
360        """
361        Delete a user including the user's path, GUID and ARN.
362
363        If the user_name is not specified, the user_name is determined
364        implicitly based on the AWS Access Key ID used to sign the request.
365
366        :type user_name: string
367        :param user_name: The name of the user to delete.
368
369        """
370        params = {'UserName': user_name}
371        return self.get_response('DeleteUser', params)
372
373    def get_user(self, user_name=None):
374        """
375        Retrieve information about the specified user.
376
377        If the user_name is not specified, the user_name is determined
378        implicitly based on the AWS Access Key ID used to sign the request.
379
380        :type user_name: string
381        :param user_name: The name of the user to retrieve.
382            If not specified, defaults to user making request.
383        """
384        params = {}
385        if user_name:
386            params['UserName'] = user_name
387        return self.get_response('GetUser', params)
388
389    def update_user(self, user_name, new_user_name=None, new_path=None):
390        """
391        Updates name and/or path of the specified user.
392
393        :type user_name: string
394        :param user_name: The name of the user
395
396        :type new_user_name: string
397        :param new_user_name: If provided, the username of the user will be
398            changed to this username.
399
400        :type new_path: string
401        :param new_path: If provided, the path of the user will be
402            changed to this path.
403
404        """
405        params = {'UserName': user_name}
406        if new_user_name:
407            params['NewUserName'] = new_user_name
408        if new_path:
409            params['NewPath'] = new_path
410        return self.get_response('UpdateUser', params)
411
412    def get_all_user_policies(self, user_name, marker=None, max_items=None):
413        """
414        List the names of the policies associated with the specified user.
415
416        :type user_name: string
417        :param user_name: The name of the user the policy is associated with.
418
419        :type marker: string
420        :param marker: Use this only when paginating results and only
421            in follow-up request after you've received a response
422            where the results are truncated.  Set this to the value of
423            the Marker element in the response you just received.
424
425        :type max_items: int
426        :param max_items: Use this only when paginating results to indicate
427            the maximum number of groups you want in the response.
428        """
429        params = {'UserName': user_name}
430        if marker:
431            params['Marker'] = marker
432        if max_items:
433            params['MaxItems'] = max_items
434        return self.get_response('ListUserPolicies', params,
435                                 list_marker='PolicyNames')
436
437    def put_user_policy(self, user_name, policy_name, policy_json):
438        """
439        Adds or updates the specified policy document for the specified user.
440
441        :type user_name: string
442        :param user_name: The name of the user the policy is associated with.
443
444        :type policy_name: string
445        :param policy_name: The policy document to get.
446
447        :type policy_json: string
448        :param policy_json: The policy document.
449
450        """
451        params = {'UserName': user_name,
452                  'PolicyName': policy_name,
453                  'PolicyDocument': policy_json}
454        return self.get_response('PutUserPolicy', params, verb='POST')
455
456    def get_user_policy(self, user_name, policy_name):
457        """
458        Retrieves the specified policy document for the specified user.
459
460        :type user_name: string
461        :param user_name: The name of the user the policy is associated with.
462
463        :type policy_name: string
464        :param policy_name: The policy document to get.
465
466        """
467        params = {'UserName': user_name,
468                  'PolicyName': policy_name}
469        return self.get_response('GetUserPolicy', params, verb='POST')
470
471    def delete_user_policy(self, user_name, policy_name):
472        """
473        Deletes the specified policy document for the specified user.
474
475        :type user_name: string
476        :param user_name: The name of the user the policy is associated with.
477
478        :type policy_name: string
479        :param policy_name: The policy document to delete.
480
481        """
482        params = {'UserName': user_name,
483                  'PolicyName': policy_name}
484        return self.get_response('DeleteUserPolicy', params, verb='POST')
485
486    def get_groups_for_user(self, user_name, marker=None, max_items=None):
487        """
488        List the groups that a specified user belongs to.
489
490        :type user_name: string
491        :param user_name: The name of the user to list groups for.
492
493        :type marker: string
494        :param marker: Use this only when paginating results and only
495            in follow-up request after you've received a response
496            where the results are truncated.  Set this to the value of
497            the Marker element in the response you just received.
498
499        :type max_items: int
500        :param max_items: Use this only when paginating results to indicate
501            the maximum number of groups you want in the response.
502        """
503        params = {'UserName': user_name}
504        if marker:
505            params['Marker'] = marker
506        if max_items:
507            params['MaxItems'] = max_items
508        return self.get_response('ListGroupsForUser', params,
509                                 list_marker='Groups')
510
511    #
512    # Access Keys
513    #
514
515    def get_all_access_keys(self, user_name, marker=None, max_items=None):
516        """
517        Get all access keys associated with an account.
518
519        :type user_name: string
520        :param user_name: The username of the user
521
522        :type marker: string
523        :param marker: Use this only when paginating results and only
524            in follow-up request after you've received a response
525            where the results are truncated.  Set this to the value of
526            the Marker element in the response you just received.
527
528        :type max_items: int
529        :param max_items: Use this only when paginating results to indicate
530            the maximum number of groups you want in the response.
531        """
532        params = {'UserName': user_name}
533        if marker:
534            params['Marker'] = marker
535        if max_items:
536            params['MaxItems'] = max_items
537        return self.get_response('ListAccessKeys', params,
538                                 list_marker='AccessKeyMetadata')
539
540    def create_access_key(self, user_name=None):
541        """
542        Create a new AWS Secret Access Key and corresponding AWS Access Key ID
543        for the specified user.  The default status for new keys is Active
544
545        If the user_name is not specified, the user_name is determined
546        implicitly based on the AWS Access Key ID used to sign the request.
547
548        :type user_name: string
549        :param user_name: The username of the user
550
551        """
552        params = {'UserName': user_name}
553        return self.get_response('CreateAccessKey', params)
554
555    def update_access_key(self, access_key_id, status, user_name=None):
556        """
557        Changes the status of the specified access key from Active to Inactive
558        or vice versa.  This action can be used to disable a user's key as
559        part of a key rotation workflow.
560
561        If the user_name is not specified, the user_name is determined
562        implicitly based on the AWS Access Key ID used to sign the request.
563
564        :type access_key_id: string
565        :param access_key_id: The ID of the access key.
566
567        :type status: string
568        :param status: Either Active or Inactive.
569
570        :type user_name: string
571        :param user_name: The username of user (optional).
572
573        """
574        params = {'AccessKeyId': access_key_id,
575                  'Status': status}
576        if user_name:
577            params['UserName'] = user_name
578        return self.get_response('UpdateAccessKey', params)
579
580    def delete_access_key(self, access_key_id, user_name=None):
581        """
582        Delete an access key associated with a user.
583
584        If the user_name is not specified, it is determined implicitly based
585        on the AWS Access Key ID used to sign the request.
586
587        :type access_key_id: string
588        :param access_key_id: The ID of the access key to be deleted.
589
590        :type user_name: string
591        :param user_name: The username of the user
592
593        """
594        params = {'AccessKeyId': access_key_id}
595        if user_name:
596            params['UserName'] = user_name
597        return self.get_response('DeleteAccessKey', params)
598
599    #
600    # Signing Certificates
601    #
602
603    def get_all_signing_certs(self, marker=None, max_items=None,
604                              user_name=None):
605        """
606        Get all signing certificates associated with an account.
607
608        If the user_name is not specified, it is determined implicitly based
609        on the AWS Access Key ID used to sign the request.
610
611        :type marker: string
612        :param marker: Use this only when paginating results and only
613            in follow-up request after you've received a response
614            where the results are truncated.  Set this to the value of
615            the Marker element in the response you just received.
616
617        :type max_items: int
618        :param max_items: Use this only when paginating results to indicate
619            the maximum number of groups you want in the response.
620
621        :type user_name: string
622        :param user_name: The username of the user
623
624        """
625        params = {}
626        if marker:
627            params['Marker'] = marker
628        if max_items:
629            params['MaxItems'] = max_items
630        if user_name:
631            params['UserName'] = user_name
632        return self.get_response('ListSigningCertificates',
633                                 params, list_marker='Certificates')
634
635    def update_signing_cert(self, cert_id, status, user_name=None):
636        """
637        Change the status of the specified signing certificate from
638        Active to Inactive or vice versa.
639
640        If the user_name is not specified, it is determined implicitly based
641        on the AWS Access Key ID used to sign the request.
642
643        :type cert_id: string
644        :param cert_id: The ID of the signing certificate
645
646        :type status: string
647        :param status: Either Active or Inactive.
648
649        :type user_name: string
650        :param user_name: The username of the user
651        """
652        params = {'CertificateId': cert_id,
653                  'Status': status}
654        if user_name:
655            params['UserName'] = user_name
656        return self.get_response('UpdateSigningCertificate', params)
657
658    def upload_signing_cert(self, cert_body, user_name=None):
659        """
660        Uploads an X.509 signing certificate and associates it with
661        the specified user.
662
663        If the user_name is not specified, it is determined implicitly based
664        on the AWS Access Key ID used to sign the request.
665
666        :type cert_body: string
667        :param cert_body: The body of the signing certificate.
668
669        :type user_name: string
670        :param user_name: The username of the user
671
672        """
673        params = {'CertificateBody': cert_body}
674        if user_name:
675            params['UserName'] = user_name
676        return self.get_response('UploadSigningCertificate', params,
677                                 verb='POST')
678
679    def delete_signing_cert(self, cert_id, user_name=None):
680        """
681        Delete a signing certificate associated with a user.
682
683        If the user_name is not specified, it is determined implicitly based
684        on the AWS Access Key ID used to sign the request.
685
686        :type user_name: string
687        :param user_name: The username of the user
688
689        :type cert_id: string
690        :param cert_id: The ID of the certificate.
691
692        """
693        params = {'CertificateId': cert_id}
694        if user_name:
695            params['UserName'] = user_name
696        return self.get_response('DeleteSigningCertificate', params)
697
698    #
699    # Server Certificates
700    #
701
702    def list_server_certs(self, path_prefix='/',
703                          marker=None, max_items=None):
704        """
705        Lists the server certificates that have the specified path prefix.
706        If none exist, the action returns an empty list.
707
708        :type path_prefix: string
709        :param path_prefix: If provided, only certificates whose paths match
710            the provided prefix will be returned.
711
712        :type marker: string
713        :param marker: Use this only when paginating results and only
714            in follow-up request after you've received a response
715            where the results are truncated.  Set this to the value of
716            the Marker element in the response you just received.
717
718        :type max_items: int
719        :param max_items: Use this only when paginating results to indicate
720            the maximum number of groups you want in the response.
721
722        """
723        params = {}
724        if path_prefix:
725            params['PathPrefix'] = path_prefix
726        if marker:
727            params['Marker'] = marker
728        if max_items:
729            params['MaxItems'] = max_items
730        return self.get_response('ListServerCertificates',
731                                 params,
732                                 list_marker='ServerCertificateMetadataList')
733
734    # Preserves backwards compatibility.
735    # TODO: Look into deprecating this eventually?
736    get_all_server_certs = list_server_certs
737
738    def update_server_cert(self, cert_name, new_cert_name=None,
739                           new_path=None):
740        """
741        Updates the name and/or the path of the specified server certificate.
742
743        :type cert_name: string
744        :param cert_name: The name of the server certificate that you want
745            to update.
746
747        :type new_cert_name: string
748        :param new_cert_name: The new name for the server certificate.
749            Include this only if you are updating the
750            server certificate's name.
751
752        :type new_path: string
753        :param new_path: If provided, the path of the certificate will be
754                         changed to this path.
755        """
756        params = {'ServerCertificateName': cert_name}
757        if new_cert_name:
758            params['NewServerCertificateName'] = new_cert_name
759        if new_path:
760            params['NewPath'] = new_path
761        return self.get_response('UpdateServerCertificate', params)
762
763    def upload_server_cert(self, cert_name, cert_body, private_key,
764                           cert_chain=None, path=None):
765        """
766        Uploads a server certificate entity for the AWS Account.
767        The server certificate entity includes a public key certificate,
768        a private key, and an optional certificate chain, which should
769        all be PEM-encoded.
770
771        :type cert_name: string
772        :param cert_name: The name for the server certificate. Do not
773            include the path in this value.
774
775        :type cert_body: string
776        :param cert_body: The contents of the public key certificate
777            in PEM-encoded format.
778
779        :type private_key: string
780        :param private_key: The contents of the private key in
781            PEM-encoded format.
782
783        :type cert_chain: string
784        :param cert_chain: The contents of the certificate chain. This
785            is typically a concatenation of the PEM-encoded
786            public key certificates of the chain.
787
788        :type path: string
789        :param path: The path for the server certificate.
790        """
791        params = {'ServerCertificateName': cert_name,
792                  'CertificateBody': cert_body,
793                  'PrivateKey': private_key}
794        if cert_chain:
795            params['CertificateChain'] = cert_chain
796        if path:
797            params['Path'] = path
798        return self.get_response('UploadServerCertificate', params,
799                                 verb='POST')
800
801    def get_server_certificate(self, cert_name):
802        """
803        Retrieves information about the specified server certificate.
804
805        :type cert_name: string
806        :param cert_name: The name of the server certificate you want
807            to retrieve information about.
808
809        """
810        params = {'ServerCertificateName': cert_name}
811        return self.get_response('GetServerCertificate', params)
812
813    def delete_server_cert(self, cert_name):
814        """
815        Delete the specified server certificate.
816
817        :type cert_name: string
818        :param cert_name: The name of the server certificate you want
819            to delete.
820
821        """
822        params = {'ServerCertificateName': cert_name}
823        return self.get_response('DeleteServerCertificate', params)
824
825    #
826    # MFA Devices
827    #
828
829    def get_all_mfa_devices(self, user_name, marker=None, max_items=None):
830        """
831        Get all MFA devices associated with an account.
832
833        :type user_name: string
834        :param user_name: The username of the user
835
836        :type marker: string
837        :param marker: Use this only when paginating results and only
838            in follow-up request after you've received a response
839            where the results are truncated.  Set this to the value of
840            the Marker element in the response you just received.
841
842        :type max_items: int
843        :param max_items: Use this only when paginating results to indicate
844            the maximum number of groups you want in the response.
845
846        """
847        params = {'UserName': user_name}
848        if marker:
849            params['Marker'] = marker
850        if max_items:
851            params['MaxItems'] = max_items
852        return self.get_response('ListMFADevices',
853                                 params, list_marker='MFADevices')
854
855    def enable_mfa_device(self, user_name, serial_number,
856                          auth_code_1, auth_code_2):
857        """
858        Enables the specified MFA device and associates it with the
859        specified user.
860
861        :type user_name: string
862        :param user_name: The username of the user
863
864        :type serial_number: string
865        :param serial_number: The serial number which uniquely identifies
866            the MFA device.
867
868        :type auth_code_1: string
869        :param auth_code_1: An authentication code emitted by the device.
870
871        :type auth_code_2: string
872        :param auth_code_2: A subsequent authentication code emitted
873            by the device.
874
875        """
876        params = {'UserName': user_name,
877                  'SerialNumber': serial_number,
878                  'AuthenticationCode1': auth_code_1,
879                  'AuthenticationCode2': auth_code_2}
880        return self.get_response('EnableMFADevice', params)
881
882    def deactivate_mfa_device(self, user_name, serial_number):
883        """
884        Deactivates the specified MFA device and removes it from
885        association with the user.
886
887        :type user_name: string
888        :param user_name: The username of the user
889
890        :type serial_number: string
891        :param serial_number: The serial number which uniquely identifies
892            the MFA device.
893
894        """
895        params = {'UserName': user_name,
896                  'SerialNumber': serial_number}
897        return self.get_response('DeactivateMFADevice', params)
898
899    def resync_mfa_device(self, user_name, serial_number,
900                          auth_code_1, auth_code_2):
901        """
902        Syncronizes the specified MFA device with the AWS servers.
903
904        :type user_name: string
905        :param user_name: The username of the user
906
907        :type serial_number: string
908        :param serial_number: The serial number which uniquely identifies
909            the MFA device.
910
911        :type auth_code_1: string
912        :param auth_code_1: An authentication code emitted by the device.
913
914        :type auth_code_2: string
915        :param auth_code_2: A subsequent authentication code emitted
916            by the device.
917
918        """
919        params = {'UserName': user_name,
920                  'SerialNumber': serial_number,
921                  'AuthenticationCode1': auth_code_1,
922                  'AuthenticationCode2': auth_code_2}
923        return self.get_response('ResyncMFADevice', params)
924
925    #
926    # Login Profiles
927    #
928
929    def get_login_profiles(self, user_name):
930        """
931        Retrieves the login profile for the specified user.
932
933        :type user_name: string
934        :param user_name: The username of the user
935
936        """
937        params = {'UserName': user_name}
938        return self.get_response('GetLoginProfile', params)
939
940    def create_login_profile(self, user_name, password):
941        """
942        Creates a login profile for the specified user, give the user the
943        ability to access AWS services and the AWS Management Console.
944
945        :type user_name: string
946        :param user_name: The name of the user
947
948        :type password: string
949        :param password: The new password for the user
950
951        """
952        params = {'UserName': user_name,
953                  'Password': password}
954        return self.get_response('CreateLoginProfile', params)
955
956    def delete_login_profile(self, user_name):
957        """
958        Deletes the login profile associated with the specified user.
959
960        :type user_name: string
961        :param user_name: The name of the user to delete.
962
963        """
964        params = {'UserName': user_name}
965        return self.get_response('DeleteLoginProfile', params)
966
967    def update_login_profile(self, user_name, password):
968        """
969        Resets the password associated with the user's login profile.
970
971        :type user_name: string
972        :param user_name: The name of the user
973
974        :type password: string
975        :param password: The new password for the user
976
977        """
978        params = {'UserName': user_name,
979                  'Password': password}
980        return self.get_response('UpdateLoginProfile', params)
981
982    def create_account_alias(self, alias):
983        """
984        Creates a new alias for the AWS account.
985
986        For more information on account id aliases, please see
987        http://goo.gl/ToB7G
988
989        :type alias: string
990        :param alias: The alias to attach to the account.
991        """
992        params = {'AccountAlias': alias}
993        return self.get_response('CreateAccountAlias', params)
994
995    def delete_account_alias(self, alias):
996        """
997        Deletes an alias for the AWS account.
998
999        For more information on account id aliases, please see
1000        http://goo.gl/ToB7G
1001
1002        :type alias: string
1003        :param alias: The alias to remove from the account.
1004        """
1005        params = {'AccountAlias': alias}
1006        return self.get_response('DeleteAccountAlias', params)
1007
1008    def get_account_alias(self):
1009        """
1010        Get the alias for the current account.
1011
1012        This is referred to in the docs as list_account_aliases,
1013        but it seems you can only have one account alias currently.
1014
1015        For more information on account id aliases, please see
1016        http://goo.gl/ToB7G
1017        """
1018        return self.get_response('ListAccountAliases', {},
1019                                 list_marker='AccountAliases')
1020
1021    def get_signin_url(self, service='ec2'):
1022        """
1023        Get the URL where IAM users can use their login profile to sign in
1024        to this account's console.
1025
1026        :type service: string
1027        :param service: Default service to go to in the console.
1028        """
1029        alias = self.get_account_alias()
1030
1031        if not alias:
1032            raise Exception('No alias associated with this account.  Please use iam.create_account_alias() first.')
1033
1034        resp = alias.get('list_account_aliases_response', {})
1035        result = resp.get('list_account_aliases_result', {})
1036        aliases = result.get('account_aliases', [])
1037
1038        if not len(aliases):
1039            raise Exception('No alias associated with this account.  Please use iam.create_account_alias() first.')
1040
1041        # We'll just use the first one we find.
1042        alias = aliases[0]
1043
1044        if self.host == 'iam.us-gov.amazonaws.com':
1045            return "https://%s.signin.amazonaws-us-gov.com/console/%s" % (
1046                alias,
1047                service
1048            )
1049        elif self.host.endswith('amazonaws.com.cn'):
1050            return "https://%s.signin.amazonaws.cn/console/%s" % (
1051                alias,
1052                service
1053            )
1054        else:
1055            return "https://%s.signin.aws.amazon.com/console/%s" % (
1056                alias,
1057                service
1058            )
1059
1060    def get_account_summary(self):
1061        """
1062        Get the alias for the current account.
1063
1064        This is referred to in the docs as list_account_aliases,
1065        but it seems you can only have one account alias currently.
1066
1067        For more information on account id aliases, please see
1068        http://goo.gl/ToB7G
1069        """
1070        return self.get_object('GetAccountSummary', {}, SummaryMap)
1071
1072    #
1073    # IAM Roles
1074    #
1075
1076    def add_role_to_instance_profile(self, instance_profile_name, role_name):
1077        """
1078        Adds the specified role to the specified instance profile.
1079
1080        :type instance_profile_name: string
1081        :param instance_profile_name: Name of the instance profile to update.
1082
1083        :type role_name: string
1084        :param role_name: Name of the role to add.
1085        """
1086        return self.get_response('AddRoleToInstanceProfile',
1087                                 {'InstanceProfileName': instance_profile_name,
1088                                  'RoleName': role_name})
1089
1090    def create_instance_profile(self, instance_profile_name, path=None):
1091        """
1092        Creates a new instance profile.
1093
1094        :type instance_profile_name: string
1095        :param instance_profile_name: Name of the instance profile to create.
1096
1097        :type path: string
1098        :param path: The path to the instance profile.
1099        """
1100        params = {'InstanceProfileName': instance_profile_name}
1101        if path is not None:
1102            params['Path'] = path
1103        return self.get_response('CreateInstanceProfile', params)
1104
1105    def _build_policy(self, assume_role_policy_document=None):
1106        if assume_role_policy_document is not None:
1107            if isinstance(assume_role_policy_document, six.string_types):
1108                # Historically, they had to pass a string. If it's a string,
1109                # assume the user has already handled it.
1110                return assume_role_policy_document
1111        else:
1112
1113            for tld, policy in DEFAULT_POLICY_DOCUMENTS.items():
1114                if tld is 'default':
1115                    # Skip the default. We'll fall back to it if we don't find
1116                    # anything.
1117                    continue
1118
1119                if self.host and self.host.endswith(tld):
1120                    assume_role_policy_document = policy
1121                    break
1122
1123            if not assume_role_policy_document:
1124                assume_role_policy_document = DEFAULT_POLICY_DOCUMENTS['default']
1125
1126        # Dump the policy (either user-supplied ``dict`` or one of the defaults)
1127        return json.dumps(assume_role_policy_document)
1128
1129    def create_role(self, role_name, assume_role_policy_document=None, path=None):
1130        """
1131        Creates a new role for your AWS account.
1132
1133        The policy grants permission to an EC2 instance to assume the role.
1134        The policy is URL-encoded according to RFC 3986. Currently, only EC2
1135        instances can assume roles.
1136
1137        :type role_name: string
1138        :param role_name: Name of the role to create.
1139
1140        :type assume_role_policy_document: ``string`` or ``dict``
1141        :param assume_role_policy_document: The policy that grants an entity
1142            permission to assume the role.
1143
1144        :type path: string
1145        :param path: The path to the role.
1146        """
1147        params = {
1148            'RoleName': role_name,
1149            'AssumeRolePolicyDocument': self._build_policy(
1150                assume_role_policy_document
1151            ),
1152        }
1153        if path is not None:
1154            params['Path'] = path
1155        return self.get_response('CreateRole', params)
1156
1157    def delete_instance_profile(self, instance_profile_name):
1158        """
1159        Deletes the specified instance profile. The instance profile must not
1160        have an associated role.
1161
1162        :type instance_profile_name: string
1163        :param instance_profile_name: Name of the instance profile to delete.
1164        """
1165        return self.get_response(
1166            'DeleteInstanceProfile',
1167            {'InstanceProfileName': instance_profile_name})
1168
1169    def delete_role(self, role_name):
1170        """
1171        Deletes the specified role. The role must not have any policies
1172        attached.
1173
1174        :type role_name: string
1175        :param role_name: Name of the role to delete.
1176        """
1177        return self.get_response('DeleteRole', {'RoleName': role_name})
1178
1179    def delete_role_policy(self, role_name, policy_name):
1180        """
1181        Deletes the specified policy associated with the specified role.
1182
1183        :type role_name: string
1184        :param role_name: Name of the role associated with the policy.
1185
1186        :type policy_name: string
1187        :param policy_name: Name of the policy to delete.
1188        """
1189        return self.get_response(
1190            'DeleteRolePolicy',
1191            {'RoleName': role_name, 'PolicyName': policy_name})
1192
1193    def get_instance_profile(self, instance_profile_name):
1194        """
1195        Retrieves information about the specified instance profile, including
1196        the instance profile's path, GUID, ARN, and role.
1197
1198        :type instance_profile_name: string
1199        :param instance_profile_name: Name of the instance profile to get
1200            information about.
1201        """
1202        return self.get_response('GetInstanceProfile',
1203                                 {'InstanceProfileName': instance_profile_name})
1204
1205    def get_role(self, role_name):
1206        """
1207        Retrieves information about the specified role, including the role's
1208        path, GUID, ARN, and the policy granting permission to EC2 to assume
1209        the role.
1210
1211        :type role_name: string
1212        :param role_name: Name of the role associated with the policy.
1213        """
1214        return self.get_response('GetRole', {'RoleName': role_name})
1215
1216    def get_role_policy(self, role_name, policy_name):
1217        """
1218        Retrieves the specified policy document for the specified role.
1219
1220        :type role_name: string
1221        :param role_name: Name of the role associated with the policy.
1222
1223        :type policy_name: string
1224        :param policy_name: Name of the policy to get.
1225        """
1226        return self.get_response('GetRolePolicy',
1227                                 {'RoleName': role_name,
1228                                  'PolicyName': policy_name})
1229
1230    def list_instance_profiles(self, path_prefix=None, marker=None,
1231                               max_items=None):
1232        """
1233        Lists the instance profiles that have the specified path prefix. If
1234        there are none, the action returns an empty list.
1235
1236        :type path_prefix: string
1237        :param path_prefix: The path prefix for filtering the results. For
1238            example: /application_abc/component_xyz/, which would get all
1239            instance profiles whose path starts with
1240            /application_abc/component_xyz/.
1241
1242        :type marker: string
1243        :param marker: Use this parameter only when paginating results, and
1244            only in a subsequent request after you've received a response
1245            where the results are truncated. Set it to the value of the
1246            Marker element in the response you just received.
1247
1248        :type max_items: int
1249        :param max_items: Use this parameter only when paginating results to
1250            indicate the maximum number of user names you want in the response.
1251        """
1252        params = {}
1253        if path_prefix is not None:
1254            params['PathPrefix'] = path_prefix
1255        if marker is not None:
1256            params['Marker'] = marker
1257        if max_items is not None:
1258            params['MaxItems'] = max_items
1259
1260        return self.get_response('ListInstanceProfiles', params,
1261                                 list_marker='InstanceProfiles')
1262
1263    def list_instance_profiles_for_role(self, role_name, marker=None,
1264                                        max_items=None):
1265        """
1266        Lists the instance profiles that have the specified associated role. If
1267        there are none, the action returns an empty list.
1268
1269        :type role_name: string
1270        :param role_name: The name of the role to list instance profiles for.
1271
1272        :type marker: string
1273        :param marker: Use this parameter only when paginating results, and
1274            only in a subsequent request after you've received a response
1275            where the results are truncated. Set it to the value of the
1276            Marker element in the response you just received.
1277
1278        :type max_items: int
1279        :param max_items: Use this parameter only when paginating results to
1280            indicate the maximum number of user names you want in the response.
1281        """
1282        params = {'RoleName': role_name}
1283        if marker is not None:
1284            params['Marker'] = marker
1285        if max_items is not None:
1286            params['MaxItems'] = max_items
1287        return self.get_response('ListInstanceProfilesForRole', params,
1288                                 list_marker='InstanceProfiles')
1289
1290    def list_role_policies(self, role_name, marker=None, max_items=None):
1291        """
1292        Lists the names of the policies associated with the specified role. If
1293        there are none, the action returns an empty list.
1294
1295        :type role_name: string
1296        :param role_name: The name of the role to list policies for.
1297
1298        :type marker: string
1299        :param marker: Use this parameter only when paginating results, and
1300            only in a subsequent request after you've received a response
1301            where the results are truncated. Set it to the value of the
1302            marker element in the response you just received.
1303
1304        :type max_items: int
1305        :param max_items: Use this parameter only when paginating results to
1306            indicate the maximum number of user names you want in the response.
1307        """
1308        params = {'RoleName': role_name}
1309        if marker is not None:
1310            params['Marker'] = marker
1311        if max_items is not None:
1312            params['MaxItems'] = max_items
1313        return self.get_response('ListRolePolicies', params,
1314                                 list_marker='PolicyNames')
1315
1316    def list_roles(self, path_prefix=None, marker=None, max_items=None):
1317        """
1318        Lists the roles that have the specified path prefix. If there are none,
1319        the action returns an empty list.
1320
1321        :type path_prefix: string
1322        :param path_prefix: The path prefix for filtering the results.
1323
1324        :type marker: string
1325        :param marker: Use this parameter only when paginating results, and
1326            only in a subsequent request after you've received a response
1327            where the results are truncated. Set it to the value of the
1328            marker element in the response you just received.
1329
1330        :type max_items: int
1331        :param max_items: Use this parameter only when paginating results to
1332            indicate the maximum number of user names you want in the response.
1333        """
1334        params = {}
1335        if path_prefix is not None:
1336            params['PathPrefix'] = path_prefix
1337        if marker is not None:
1338            params['Marker'] = marker
1339        if max_items is not None:
1340            params['MaxItems'] = max_items
1341        return self.get_response('ListRoles', params, list_marker='Roles')
1342
1343    def put_role_policy(self, role_name, policy_name, policy_document):
1344        """
1345        Adds (or updates) a policy document associated with the specified role.
1346
1347        :type role_name: string
1348        :param role_name: Name of the role to associate the policy with.
1349
1350        :type policy_name: string
1351        :param policy_name: Name of the policy document.
1352
1353        :type policy_document: string
1354        :param policy_document: The policy document.
1355        """
1356        return self.get_response('PutRolePolicy',
1357                                 {'RoleName': role_name,
1358                                  'PolicyName': policy_name,
1359                                  'PolicyDocument': policy_document})
1360
1361    def remove_role_from_instance_profile(self, instance_profile_name,
1362                                          role_name):
1363        """
1364        Removes the specified role from the specified instance profile.
1365
1366        :type instance_profile_name: string
1367        :param instance_profile_name: Name of the instance profile to update.
1368
1369        :type role_name: string
1370        :param role_name: Name of the role to remove.
1371        """
1372        return self.get_response('RemoveRoleFromInstanceProfile',
1373                                 {'InstanceProfileName': instance_profile_name,
1374                                  'RoleName': role_name})
1375
1376    def update_assume_role_policy(self, role_name, policy_document):
1377        """
1378        Updates the policy that grants an entity permission to assume a role.
1379        Currently, only an Amazon EC2 instance can assume a role.
1380
1381        :type role_name: string
1382        :param role_name: Name of the role to update.
1383
1384        :type policy_document: string
1385        :param policy_document: The policy that grants an entity permission to
1386            assume the role.
1387        """
1388        return self.get_response('UpdateAssumeRolePolicy',
1389                                 {'RoleName': role_name,
1390                                  'PolicyDocument': policy_document})
1391
1392    def create_saml_provider(self, saml_metadata_document, name):
1393        """
1394        Creates an IAM entity to describe an identity provider (IdP)
1395        that supports SAML 2.0.
1396
1397        The SAML provider that you create with this operation can be
1398        used as a principal in a role's trust policy to establish a
1399        trust relationship between AWS and a SAML identity provider.
1400        You can create an IAM role that supports Web-based single
1401        sign-on (SSO) to the AWS Management Console or one that
1402        supports API access to AWS.
1403
1404        When you create the SAML provider, you upload an a SAML
1405        metadata document that you get from your IdP and that includes
1406        the issuer's name, expiration information, and keys that can
1407        be used to validate the SAML authentication response
1408        (assertions) that are received from the IdP. You must generate
1409        the metadata document using the identity management software
1410        that is used as your organization's IdP.
1411        This operation requires `Signature Version 4`_.
1412        For more information, see `Giving Console Access Using SAML`_
1413        and `Creating Temporary Security Credentials for SAML
1414        Federation`_ in the Using Temporary Credentials guide.
1415
1416        :type saml_metadata_document: string
1417        :param saml_metadata_document: An XML document generated by an identity
1418            provider (IdP) that supports SAML 2.0. The document includes the
1419            issuer's name, expiration information, and keys that can be used to
1420            validate the SAML authentication response (assertions) that are
1421            received from the IdP. You must generate the metadata document
1422            using the identity management software that is used as your
1423            organization's IdP.
1424        For more information, see `Creating Temporary Security Credentials for
1425            SAML Federation`_ in the Using Temporary Security Credentials
1426            guide.
1427
1428        :type name: string
1429        :param name: The name of the provider to create.
1430
1431        """
1432        params = {
1433            'SAMLMetadataDocument': saml_metadata_document,
1434            'Name': name,
1435        }
1436        return self.get_response('CreateSAMLProvider', params)
1437
1438    def list_saml_providers(self):
1439        """
1440        Lists the SAML providers in the account.
1441        This operation requires `Signature Version 4`_.
1442        """
1443        return self.get_response('ListSAMLProviders', {}, list_marker='SAMLProviderList')
1444
1445    def get_saml_provider(self, saml_provider_arn):
1446        """
1447        Returns the SAML provider metadocument that was uploaded when
1448        the provider was created or updated.
1449        This operation requires `Signature Version 4`_.
1450
1451        :type saml_provider_arn: string
1452        :param saml_provider_arn: The Amazon Resource Name (ARN) of the SAML
1453            provider to get information about.
1454
1455        """
1456        params = {'SAMLProviderArn': saml_provider_arn}
1457        return self.get_response('GetSAMLProvider', params)
1458
1459    def update_saml_provider(self, saml_provider_arn, saml_metadata_document):
1460        """
1461        Updates the metadata document for an existing SAML provider.
1462        This operation requires `Signature Version 4`_.
1463
1464        :type saml_provider_arn: string
1465        :param saml_provider_arn: The Amazon Resource Name (ARN) of the SAML
1466            provider to update.
1467
1468        :type saml_metadata_document: string
1469        :param saml_metadata_document: An XML document generated by an identity
1470            provider (IdP) that supports SAML 2.0. The document includes the
1471            issuer's name, expiration information, and keys that can be used to
1472            validate the SAML authentication response (assertions) that are
1473            received from the IdP. You must generate the metadata document
1474            using the identity management software that is used as your
1475            organization's IdP.
1476
1477        """
1478        params = {
1479            'SAMLMetadataDocument': saml_metadata_document,
1480            'SAMLProviderArn': saml_provider_arn,
1481        }
1482        return self.get_response('UpdateSAMLProvider', params)
1483
1484    def delete_saml_provider(self, saml_provider_arn):
1485        """
1486        Deletes a SAML provider.
1487
1488        Deleting the provider does not update any roles that reference
1489        the SAML provider as a principal in their trust policies. Any
1490        attempt to assume a role that references a SAML provider that
1491        has been deleted will fail.
1492        This operation requires `Signature Version 4`_.
1493
1494        :type saml_provider_arn: string
1495        :param saml_provider_arn: The Amazon Resource Name (ARN) of the SAML
1496            provider to delete.
1497
1498        """
1499        params = {'SAMLProviderArn': saml_provider_arn}
1500        return self.get_response('DeleteSAMLProvider', params)
1501
1502    #
1503    # IAM Reports
1504    #
1505
1506    def generate_credential_report(self):
1507        """
1508        Generates a credential report for an account
1509
1510        A new credential report can only be generated every 4 hours. If one
1511        hasn't been generated in the last 4 hours then get_credential_report
1512        will error when called
1513        """
1514        params = {}
1515        return self.get_response('GenerateCredentialReport', params)
1516
1517    def get_credential_report(self):
1518        """
1519        Retrieves a credential report for an account
1520
1521        A report must have been generated in the last 4 hours to succeed.
1522        The report is returned as a base64 encoded blob within the response.
1523        """
1524        params = {}
1525        return self.get_response('GetCredentialReport', params)
1526
1527    def create_virtual_mfa_device(self, path, device_name):
1528        """
1529        Creates a new virtual MFA device for the AWS account.
1530
1531        After creating the virtual MFA, use enable-mfa-device to
1532        attach the MFA device to an IAM user.
1533
1534        :type path: string
1535        :param path: The path for the virtual MFA device.
1536
1537        :type device_name: string
1538        :param device_name: The name of the virtual MFA device.
1539            Used with path to uniquely identify a virtual MFA device.
1540
1541        """
1542        params = {
1543            'Path': path,
1544            'VirtualMFADeviceName': device_name
1545        }
1546        return self.get_response('CreateVirtualMFADevice', params)
1547
1548    #
1549    # IAM password policy
1550    #
1551
1552    def get_account_password_policy(self):
1553        """
1554        Returns the password policy for the AWS account.
1555        """
1556        params = {}
1557        return self.get_response('GetAccountPasswordPolicy', params)
1558
1559    def delete_account_password_policy(self):
1560        """
1561        Delete the password policy currently set for the AWS account.
1562        """
1563        params = {}
1564        return self.get_response('DeleteAccountPasswordPolicy', params)
1565
1566    def update_account_password_policy(self, allow_users_to_change_password=None,
1567                                        hard_expiry=None, max_password_age=None ,
1568                                        minimum_password_length=None ,
1569                                        password_reuse_prevention=None,
1570                                        require_lowercase_characters=None,
1571                                        require_numbers=None, require_symbols=None ,
1572                                        require_uppercase_characters=None):
1573        """
1574        Update the password policy for the AWS account.
1575
1576        Notes: unset parameters will be reset to Amazon default settings!
1577            Most of the password policy settings are enforced the next time your users
1578            change their passwords. When you set minimum length and character type
1579            requirements, they are enforced the next time your users change their
1580            passwords - users are not forced to change their existing passwords, even
1581            if the pre-existing passwords do not adhere to the updated password
1582            policy. When you set a password expiration period, the expiration period
1583            is enforced immediately.
1584
1585        :type allow_users_to_change_password: bool
1586        :param allow_users_to_change_password: Allows all IAM users in your account
1587            to use the AWS Management Console to change their own passwords.
1588
1589        :type hard_expiry: bool
1590        :param hard_expiry: Prevents IAM users from setting a new password after
1591            their password has expired.
1592
1593        :type max_password_age: int
1594        :param max_password_age: The number of days that an IAM user password is valid.
1595
1596        :type minimum_password_length: int
1597        :param minimum_password_length: The minimum number of characters allowed in
1598            an IAM user password.
1599
1600        :type password_reuse_prevention: int
1601        :param password_reuse_prevention: Specifies the number of previous passwords
1602            that IAM users are prevented from reusing.
1603
1604        :type require_lowercase_characters: bool
1605        :param require_lowercase_characters: Specifies whether IAM user passwords
1606            must contain at least one lowercase character from the ISO basic Latin
1607            alphabet (``a`` to ``z``).
1608
1609        :type require_numbers: bool
1610        :param require_numbers: Specifies whether IAM user passwords must contain at
1611            least one numeric character (``0`` to ``9``).
1612
1613        :type require_symbols: bool
1614        :param require_symbols: Specifies whether IAM user passwords must contain at
1615            least one of the following non-alphanumeric characters:
1616            ``! @ # $ % ^ & * ( ) _ + - = [ ] { } | '``
1617
1618        :type require_uppercase_characters: bool
1619        :param require_uppercase_characters: Specifies whether IAM user passwords
1620            must contain at least one uppercase character from the ISO basic Latin
1621            alphabet (``A`` to ``Z``).
1622        """
1623        params = {}
1624        if allow_users_to_change_password is not None and type(allow_users_to_change_password) is bool:
1625            params['AllowUsersToChangePassword'] = str(allow_users_to_change_password).lower()
1626        if hard_expiry is not None and type(allow_users_to_change_password) is bool:
1627            params['HardExpiry'] = str(hard_expiry).lower()
1628        if max_password_age is not None:
1629            params['MaxPasswordAge'] = max_password_age
1630        if minimum_password_length is not None:
1631            params['MinimumPasswordLength'] = minimum_password_length
1632        if password_reuse_prevention is not None:
1633            params['PasswordReusePrevention'] = password_reuse_prevention
1634        if require_lowercase_characters is not None and type(allow_users_to_change_password) is bool:
1635            params['RequireLowercaseCharacters'] = str(require_lowercase_characters).lower()
1636        if require_numbers is not None and type(allow_users_to_change_password) is bool:
1637            params['RequireNumbers'] = str(require_numbers).lower()
1638        if require_symbols is not None and type(allow_users_to_change_password) is bool:
1639            params['RequireSymbols'] = str(require_symbols).lower()
1640        if require_uppercase_characters is not None and type(allow_users_to_change_password) is bool:
1641            params['RequireUppercaseCharacters'] = str(require_uppercase_characters).lower()
1642        return self.get_response('UpdateAccountPasswordPolicy', params)
1643