# encoding: utf-8
"""
OOS IAM Python API Example
"""
import json
import traceback
import oos
import ooscore.exceptions as exceptions
from ooscore.client import Config
from ooscore.exceptions import OnlySupportAPIVersionError, OnlySupportV4SignatureError
from ooscore.exceptions import ServiceNameError
from ooscore.compat import urlencode

ACCESS_KEY = 'your_accessKey'
SECRET_KEY = 'your_secretKey'
IAM_ENDPOINT = 'your_domain'
REGION_NAME = "cn"
SERVICE_NAME = "sts"
SIGNATURE_VERSION = 's3v4'  # Algorithm version used for calculating signatures, only support v4 version:'s3v4'
API_VERSION = "2010-05-08"
IAM_USER_NAME = "your_userName"
IAM_GROUP_NAME = "your_GroupName"
POLICY_ARN = "arn:ctyun:iam::{0}:policy/{1}".format("your_accountId", "your_policyName")  # The resource name of policy
SERIAL_NUMBER = "{0}{1}:mfa/{2}". \
    format("arn:ctyun:iam::", "your_accountId", "your_virtualMFADeviceName")

# Preprocessing, setting up access to IAM services
if IAM_ENDPOINT.lower().find("http") < 0 and IAM_ENDPOINT.lower().find("https") < 0:
    IAM_ENDPOINT = "https://" + IAM_ENDPOINT
try:
    if SIGNATURE_VERSION != "s3v4":
        raise OnlySupportV4SignatureError(endpoint_url=IAM_ENDPOINT)
    if API_VERSION != "2010-05-08":
        raise OnlySupportAPIVersionError("2010-05-08")
    if SERVICE_NAME != "sts":
        raise ServiceNameError('sts')
    config = Config(endpoint_url=IAM_ENDPOINT, region_name=REGION_NAME,
                    signature_version=SIGNATURE_VERSION, api_version=API_VERSION,
                    s3={'payload_signing_enabled': True})
    iam_client = oos.client(SERVICE_NAME, api_version=API_VERSION,
                            endpoint_url=IAM_ENDPOINT,
                            access_key_id=ACCESS_KEY, secret_access_key=SECRET_KEY,
                            config=config, verify=True)
except Exception as ex:
    print(traceback.format_exc())
    print(ex)
    exit(-1)


def pretty_print(res):
    """
    Print the return body to the console
    """
    print(json.dumps(res, sort_keys=True, indent=4, default=str, ensure_ascii=False))


def encode_params(data):
    """
    Encode the dict or sequence of two element tuples as a URL query
    """
    result = []
    for k, vs in data.items():
        result.append((k, vs))
    return urlencode(result, doseq=True)


def handle_error(fn):
    """
    Exception handling
    """

    def inner():
        try:
            fn()
        except exceptions.ClientError as e:
            resource = ""
            if hasattr(e.response['Error'], 'Resource'):
                resource = e.response['Error']['Resource']
            print('\n Response code: {0}\n Error message: {1}\n Resource: {2}\n request id: {3}'.format
                  (e.response['Error']['Code'],
                   e.response['Error']['Message'],
                   resource,
                   e.response['ResponseMetadata']['RequestId']
                   ))

    return inner


# Users Management API 1 CreateUser
@handle_error
def create_user_example():
    """
    This operation is used to create a new IAM user
    """
    data = {
        # Specify the operation as CreateUser
        "Action": "CreateUser",
        # Create a user name for the IAM user, which must be unique in the account
        "UserName": IAM_USER_NAME,
        # List of tags attached to newly created IAM user. Tags include tag keys and values
        "Tags.member.1.Key": "Key1",
        "Tags.member.1.Value": "Value1"
    }
    body = encode_params(data)
    response = iam_client.create_user(
        Body=body
    )
    pretty_print(response)


# Users Management API 2 GetUser
@handle_error
def get_user_example():
    """
    This operation is used to obtain IAM user information
    """
    data = {
        # Specify the operation as GetUser
        "Action": "GetUser",
        # Username to be queried
        "UserName": IAM_USER_NAME
    }
    body = encode_params(data)
    response = iam_client.get_user(
        Body=body
    )
    pretty_print(response)


# Users Management API 3 ListUsers
@handle_error
def list_users_example():
    """
    This operation is used to list IAM users
    If no IAM user is created in the account, an empty list will be returned
    """
    data = {
        # Specify the operation as ListUsers
        "Action": "ListUsers",
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": 1000,
        # Username to be queried for fuzzy matching search
        "UserName": IAM_USER_NAME,
        # Perform fuzzy matching search by specified AccessKeyId
        # "AccessKeyId": "your_AccessKeyId"
        # Page identification
        # "Marker": "your_Marker",
    }
    body = encode_params(data)
    response = iam_client.list_users(
        Body=body
    )
    pretty_print(response)


# Users Management API 4 DeleteUser
@handle_error
def delete_user_example():
    """
    This operation is used to delete the specified IAM user
    """
    data = {
        # Specify the operation as DeleteUser
        "Action": "DeleteUser",
        # IAM user's username to be deleted
        "UserName": IAM_USER_NAME
    }
    body = encode_params(data)
    response = iam_client.delete_user(
        Body=body
    )
    pretty_print(response)


# Users Management API 5 TagUser
@handle_error
def tag_user_example():
    """
    This operation is used to add tags for IAM users
    You can add one or more tags at the same time, and an IAM user can add up to 10 tags
    If Tags.member.Key already exists, its value will be overwritten by the newly added value
    """
    data = {
        # Specify the operation as TagUser
        "Action": "TagUser",
        # IAM username
        "UserName": IAM_USER_NAME,
        # User tag key/value
        "Tags.member.1.Key": "Key1",
        "Tags.member.1.Value": "Value1",
        "Tags.member.2.Key": "Key2",
        "Tags.member.2.Value": "Value2",
        "Tags.member.3.Key": "Key3",
        "Tags.member.3.Value": "Value3",
    }
    body = encode_params(data)
    response = iam_client.tag_user(
        Body=body
    )
    pretty_print(response)


# Users Management API 6 UntagUser
@handle_error
def untag_user_example():
    """
    This operation is used to delete user's specified tag
    """
    data = {
        # Specify the operation as UntagUser
        "Action": "UntagUser",
        # IAM username
        "UserName": IAM_USER_NAME,
        # User tag key
        "TagKeys.member.1": "Key1",
        "TagKeys.member.2": "Key2",

    }
    body = encode_params(data)
    response = iam_client.untag_user(
        Body=body
    )
    pretty_print(response)


# Users Management API 7 ListUserTags
@handle_error
def list_user_tags_example():
    """
    This operation is used to list the tags of the specified IAM user
    """
    data = {
        # Specify the operation as ListUserTags
        "Action": "ListUserTags",
        # Username to be queried
        "UserName": IAM_USER_NAME,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": 1000
    }
    body = encode_params(data)
    response = iam_client.list_user_tags(
        Body=body
    )
    pretty_print(response)


# Users Management API 8 ListGroupsForUser
@handle_error
def list_groups_for_user_example():
    """
    This operation is used to list the IAM user groups to which the specified IAM user belongs
    """
    data = {
        # Specify the operation as ListGroupsForUser
        "Action": "ListGroupsForUser",
        # IAM username
        "UserName": IAM_USER_NAME,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": 1000
    }
    body = encode_params(data)
    response = iam_client.list_groups_for_user(
        Body=body
    )
    pretty_print(response)


# Users Management API 9 CreateAccessKey
@handle_error
def create_access_key_example():
    """
    This operation is used to create a new Access Key for the specified IAM user
    """
    data = {
        # Specify the operation as CreateAccessKey
        "Action": "CreateAccessKey",
        # IAM username
        "UserName": IAM_USER_NAME
    }
    body = encode_params(data)
    response = iam_client.create_access_key(
        Body=body
    )
    pretty_print(response)


# Users Management API 10 ListAccessKeys
@handle_error
def list_access_keys_example():
    """
    This operation is used to return the AK details of the specified IAM user
    """
    data = {
        # Specify the operation as ListAccessKeys
        'Action': 'ListAccessKeys',
        # IAM username
        "UserName": IAM_USER_NAME,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": 100
    }
    body = encode_params(data)
    response = iam_client.list_access_keys(
        Body=body
    )
    pretty_print(response)


# Users Management API 11 GetAccessKeyLastUsed
@handle_error
def get_access_key_last_used_example():
    """
    This operation is used to query the last time the specified key was used and the service name
    """
    data = {
        # Specify the operation as GetAccessKeyLastUsed
        "Action": "GetAccessKeyLastUsed",
        # Request version
        "Version": API_VERSION,
        # Access key ID
        "AccessKeyId": ACCESS_KEY
    }
    response = iam_client.get_access_key_last_used(Body=encode_params(data))
    pretty_print(response)


# Users Management API 12 UpdateAccessKey
@handle_error
def update_access_key_example():
    """
    This operation is used to update the status of the specified access key (AK)
    from Active to Inactive, or from Inactive to Active
    """
    data = {
        # Specify the operation as UpdateAccessKey
        "Action": "UpdateAccessKey",
        # The access key ID that needs to be updated
        "AccessKeyId": ACCESS_KEY,
        # The status of the access key, values: Active/Inactive
        "Status": "Active"
    }
    body = encode_params(data)
    response = iam_client.update_access_key(
        Body=body
    )
    pretty_print(response)


# Users Management API 13 DeleteAccessKey
@handle_error
def delete_access_key_example():
    """
    This operation is used to delete the AccessKey associated with the specified IAM user
    """
    data = {
        # Specify the operation as DeleteAccessKey
        "Action": "DeleteAccessKey",
        # Specify the username for deleting the key
        "UserName": IAM_USER_NAME,
        # The access key ID that needs to be deleted
        "AccessKeyId": "your_accessKeyId"
    }
    body = encode_params(data)
    response = iam_client.delete_access_key(
        Body=body
    )
    pretty_print(response)


# Users Management API 14 GetSessionToken
@handle_error
def get_session_token_example():
    """
    OOS provides users with temporary authorized access. This operation is used to obtain the temporary access key
    By default, the root user and sub-user have the permission to call this API.
    If an IAM policy is configured that prevent sub-users from calling this API, this policy does not take effect
    """
    data = {
        # Specify the operation as GetSessionToken
        "Action": "GetSessionToken",
        # Request version
        "Version": API_VERSION,
        # The validity period of the token, values: [900, 129600], in seconds
        "DurationSeconds": "1800"
    }
    body = encode_params(data)
    response = iam_client.get_session_token(
        Body=body
    )
    pretty_print(response)
    print(response['GetSessionTokenResult']['Credentials']['SessionToken'])
    print(response['GetSessionTokenResult']['Credentials']['AccessKeyId'])
    print(response['GetSessionTokenResult']['Credentials']['SecretAccessKey'])


# Users Management API 15 CreateLoginProfile
@handle_error
def create_login_profile_example():
    """
    This operation is used to create a login password for the console for the specified IAM user
    """
    data = {
        # Specify the operation as CreateLoginProfile
        "Action": "CreateLoginProfile",
        # The username for which a login password needs to be created
        "UserName": IAM_USER_NAME,
        # Specify the password for the user to log in to the console
        "Password": "your_password",
        # Whether the IAM user needs to reset the password after logging in to the console with the initial password
        "PasswordResetRequired": False
    }
    body = encode_params(data)
    response = iam_client.create_login_profile(
        Body=body
    )
    pretty_print(response)


# Users Management API 16 GetLoginProfile
@handle_error
def get_login_profile_example():
    """
    This operation is used to obtain the time when the IAM user console login password was created
    and whether the user needs to change the password after logging in for the first time
    """
    data = {
        # Specify the operation as GetLoginProfile
        "Action": "GetLoginProfile",
        # The IAM username to be queried
        "UserName": IAM_USER_NAME
    }
    body = encode_params(data)
    response = iam_client.get_login_profile(
        Body=body
    )
    pretty_print(response)


# Users Management API 17 UpdateLoginProfile
@handle_error
def update_login_profile_example():
    """
    This operation is used to change the login password of the specified IAM user console
    """
    data = {
        # Specify the operation as UpdateLoginProfile
        "Action": "UpdateLoginProfile",
        # The IAM username that requires changing console login password
        "UserName": IAM_USER_NAME,
        # Specify the password for the user to log in to the console
        "Password": "your_password",
        # Whether the IAM user needs to reset the password after logging in to the console with the initial password
        "PasswordResetRequired": False
    }
    body = encode_params(data)
    response = iam_client.update_login_profile(
        Body=body
    )
    pretty_print(response)


# Users Management API 18 DeleteLoginProfile
@handle_error
def delete_login_profile_example():
    """
    This operation is used to delete the login password of the specified IAM user console
    After doing this, the specified user will not be able to perform OOS service via the console
    """
    data = {
        # Specify the operation as DeleteLoginProfile
        "Action": "DeleteLoginProfile",
        # Specify the IAM username that requires deleting console login password
        "UserName": IAM_USER_NAME
    }
    body = encode_params(data)
    response = iam_client.delete_login_profile(
        Body=body
    )
    pretty_print(response)


# Users Management API 19 ChangePassword
@handle_error
def change_password_example():
    """
    This operation is used to modify the console login password of IAM user
    """
    data = {
        # Specify the operation as ChangePassword
        "Action": "ChangePassword",
        # Specify a new password for logging in to the console
        "NewPassword": "your_newPassword",
        # Current console login password
        "OldPassword": "your_oldPassword"
    }
    body = encode_params(data)
    response = iam_client.change_password(
        Body=body
    )
    pretty_print(response)


# Users Management API 20 CreateVirtualMFADevice
@handle_error
def create_virtual_mfa_device_example():
    """
    This operation is used to create a virtual MFA device
    After creating a virtual MFA, you can use EnableMFADevice to enable the virtual MFA device
    and associate it with the specified IAM user
    """
    data = {
        # Specify the operation as CreateVirtualMFADevice
        "Action": "CreateVirtualMFADevice",
        # Name of the virtual MFA device
        "VirtualMFADeviceName": "your_virtualMFADeviceName"
    }
    body = encode_params(data)
    response = iam_client.create_virtual_mfa_device(
        Body=body
    )
    pretty_print(response)


# Users Management API 21 EnableMFADevice
@handle_error
def enable_mfa_device_example():
    """
    This operation is used to enable the specified virtual MFA device and associate it with the specified IAM user
    """
    data = {
        # Specify the operation as EnableMFADevice
        "Action": "EnableMFADevice",
        # Specify the IAM username associated with the virtual MFA
        "UserName": IAM_USER_NAME,
        # The verification code issued by the virtual MFA device is a six digit verification code
        "AuthenticationCode1": "your_code1",
        # The next six digit verification code next to AuthenticationCode1 issued by the virtual MFA device
        "AuthenticationCode2": "your_code2",
        # The serial number that uniquely identifies the MFA device.
        "SerialNumber": SERIAL_NUMBER
    }
    body = encode_params(data)
    response = iam_client.enable_mfa_device(
        Body=body
    )
    pretty_print(response)


# Users Management API 22 ListVirtualMFADevices
@handle_error
def list_virtual_mfa_devices_example():
    """
    This operation is used to list the virtual MFA devices defined in the OOS account by assignment status
    If no assignment status is specified, the operation returns a list of all virtual MFA devices
    """
    data = {
        # Specify the operation as ListVirtualMFADevices
        "Action": "ListVirtualMFADevices",
        # Specify the virtual MFA device status that needs to be listed, values: Assigned/Unassigned/Any
        "AssignmentStatus": "Any",
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": "100"
    }
    body = encode_params(data)
    response = iam_client.list_virtual_mfa_devices(
        Body=body
    )
    pretty_print(response)


# Users Management API 23 ListMFADevices
@handle_error
def list_mfa_devices_example():
    """
    This operation is used to list the virtual MFA devices of the IAM users
    """
    data = {
        # Specify the operation as ListMFADevices
        "Action": "ListMFADevices",
        # Specify the IAM username
        "UserName": IAM_USER_NAME,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": "100"
    }
    body = encode_params(data)
    response = iam_client.list_mfa_devices(
        Body=body
    )
    pretty_print(response)


# Users Management API 24 DeactivateMFADevice
@handle_error
def deactivate_mfa_device_example():
    """
    This operation is used to terminate the use of the specified MFA device and disassociate it from the user
    """
    data = {
        # Specify the operation as DeactivateMFADevice
        "Action": "DeactivateMFADevice",
        # Specify the IAM username that is disassociated from the virtual MFA
        "UserName": IAM_USER_NAME,
        # The serial number that uniquely identifies the MFA device.
        "SerialNumber": SERIAL_NUMBER
    }
    body = encode_params(data)
    response = iam_client.deactivate_mfa_device(
        Body=body
    )
    pretty_print(response)


# Users Management API 25 DeleteVirtualMFADevice
@handle_error
def delete_virtual_mfa_device_example():
    """
    This operation is used to delete the specified virtual MFA device
    """
    data = {
        # Specify the operation as DeleteVirtualMFADevice
        "Action": "DeleteVirtualMFADevice",
        # The serial number that uniquely identifies the MFA device.
        "SerialNumber": SERIAL_NUMBER
    }
    body = encode_params(data)
    response = iam_client.delete_virtual_mfa_device(
        Body=body
    )
    pretty_print(response)


# User Group Management API 1 CreateGroup
@handle_error
def create_group_example():
    """
    This operation is used to create a new IAM user group
    """
    data = {
        # Specify the operation as CreateGroup
        "Action": "CreateGroup",
        # IAM user group name, which must be unique in the account
        "GroupName": IAM_GROUP_NAME
    }
    body = encode_params(data)
    response = iam_client.create_group(
        Body=body
    )
    pretty_print(response)
    print("HTTPStatusCode:" + str(response['ResponseMetadata']['HTTPStatusCode']))
    print("GroupName:" + response['CreateGroupResult']['Group']['GroupName'])


# User Group Management API 2 GetGroup
@handle_error
def get_group_example():
    """
    This operation is used to obtain the specified IAM user group and the list of IAM users in the group
    """
    data = {
        # Specify the operation as GetGroup
        "Action": "GetGroup",
        # IAM user group name
        "GroupName": IAM_GROUP_NAME,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": "1000"
    }
    body = encode_params(data)
    response = iam_client.get_group(
        Body=body
    )
    pretty_print(response)


# User Group Management API 3 AddUserToGroup
@handle_error
def add_user_to_group_example():
    """
    This operation is used to add the specified IAM user to the specified IAM user group,
    and only one user can be added to the specified user group at a time
    """
    data = {
        # Specify the operation as AddUserToGroup
        "Action": "AddUserToGroup",
        # IAM username
        "UserName": IAM_USER_NAME,
        # Specify the IAM user group name
        "GroupName": IAM_GROUP_NAME
    }
    body = encode_params(data)
    response = iam_client.add_user_to_group(
        Body=body
    )
    pretty_print(response)


# User Group Management API 4 RemoveUserFromGroup
@handle_error
def remove_user_from_group_example():
    """
    This operation is used to remove the specified user from the specified user group
    """
    data = {
        # Specify the operation as RemoveUserFromGroup
        "Action": "RemoveUserFromGroup",
        # IAM user group name
        "GroupName": IAM_GROUP_NAME,
        # The IAM username to be deleted
        "UserName": IAM_USER_NAME
    }
    body = encode_params(data)
    response = iam_client.remove_user_from_group(
        Body=body
    )
    pretty_print(response)


# User Group Management API 5 ListGroup
@handle_error
def list_group_example():
    """
    This operation is used to list all IAM user groups
    """
    data = {
        # Specify the operation as ListGroups
        "Action": "ListGroups",
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": 1000,
        # Specify the IAM user group name and perform user group fuzzy matching query in this operation
        "GroupName": IAM_GROUP_NAME
    }
    body = encode_params(data)
    response = iam_client.list_groups(
        Body=body
    )
    pretty_print(response)


# User Group Management API 6 DeleteGroup
@handle_error
def delete_group_example():
    """
    This operation is used to delete the specified IAM user group
    """
    data = {
        # Specify the operation as DeleteGroup
        "Action": "DeleteGroup",
        # IAM user group name
        "GroupName": IAM_GROUP_NAME
    }
    body = encode_params(data)
    response = iam_client.delete_group(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 1 CreatePolicy
@handle_error
def create_policy_example():
    """
    This operation is used to create a policy for the account
    If the policy name already exists, create a new policy with the same name,
    and the newly created policy will overwrite the existing policy with the same name
    """
    policy_document = '''{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Action": "*",
        "Resource": "*"
        }]
    }'''

    data = {
        # Specify the operation as CreatePolicy
        "Action": "CreatePolicy",
        # Policy name, which must be unique
        "PolicyName": "your_policyName",
        # Policy Description
        "Description": "The first policy",
        # Policy content described in JSON language
        "PolicyDocument": policy_document
    }
    body = encode_params(data)
    response = iam_client.create_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 2 GetPolicy
@handle_error
def get_policy_example():
    """
    This operation is used to obtain policy related information
    """
    data = {
        # Specify the operation as GetPolicy
        "Action": "GetPolicy",
        # Resource name of the permission policy
        "PolicyArn": POLICY_ARN
    }
    body = encode_params(data)
    response = iam_client.get_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 3 ListPolicies
@handle_error
def list_policies_example():
    """
    This operation is used to list all policies under the account
    """
    data = {
        # Specify the operation as ListPolicies
        "Action": "ListPolicies",
        # A policy that identifies whether to display only the associated IAM users or IAM user groups
        "OnlyAttached": True,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": "10",
        # Permission policy name, which can be used for fuzzy matching query
        "PolicyName": "your_PolicyName"
    }
    body = encode_params(data)
    response = iam_client.list_policies(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 4 ListEntitiesForPolicy
@handle_error
def list_entities_for_policy_example():
    """
    This operation is used to list all IAM users or IAM user groups attached to the specified policy
    """
    data = {
        # Specify the operation as ListEntitiesForPolicy
        "Action": "ListEntitiesForPolicy",
        # Resource name of the permission policy
        "PolicyArn": POLICY_ARN,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": "10",
        # Specify the entity type to filter
        # "EntityFilter": "User"
    }
    body = encode_params(data)
    response = iam_client.list_entities_for_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 5 DeletePolicy
@handle_error
def delete_policy_example():
    """
    This operation is used to delete the specified policy
    """
    data = {
        # Specify the operation as DeletePolicy
        "Action": "DeletePolicy",
        # Resource name of the permission policy
        "PolicyArn": POLICY_ARN
    }
    body = encode_params(data)
    response = iam_client.delete_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 6 AttachUserPolicy
@handle_error
def attach_user_policy_example():
    """
    This operation is used to associate the specified policy with the specified IAM user
    """
    data = {
        # Specify the operation as AttachUserPolicy
        "Action": "AttachUserPolicy",
        # IAM username
        "UserName": IAM_USER_NAME,
        # Resource name of the permission policy
        "PolicyArn": POLICY_ARN
    }
    body = encode_params(data)
    response = iam_client.attach_user_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 7 ListAttachedUserPolicies
@handle_error
def list_attached_user_policies_example():
    """
    This operation is used to list the policies associated with the specified user
    """
    data = {
        # Specify the operation as ListAttachedUserPolicies
        "Action": "ListAttachedUserPolicies",
        # IAM username
        "UserName": IAM_USER_NAME,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": "10"
    }
    body = encode_params(data)
    response = iam_client.list_attached_user_policies(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 8 DetachUserPolicy
@handle_error
def detach_user_policy_example():
    """
    This operation is used to disassociate the specified policy from the specified user
    """
    data = {
        # Specify the operation as DetachUserPolicy
        "Action": "DetachUserPolicy",
        # IAM username
        "UserName": IAM_USER_NAME,
        # Resource name of the permission policy
        "PolicyArn": POLICY_ARN
    }
    body = encode_params(data)
    response = iam_client.detach_user_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 9 AttachGroupPolicy
@handle_error
def attach_group_policy_example():
    """
    This operation is used to Group associate the specified policy with the specified IAM user group
    """
    data = {
        # Specify the operation as AttachGroupPolicy
        "Action": "AttachGroupPolicy",
        # IAM user group name
        "GroupName": IAM_GROUP_NAME,
        # Resource name of the permission policy
        "PolicyArn": POLICY_ARN
    }
    body = encode_params(data)
    response = iam_client.attach_group_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 10 ListAttachedGroupPolicies
@handle_error
def list_attached_group_policies_example():
    """
    This operation is used to list the policies associated with the specified IAM user group
    """
    data = {
        # Specify the operation as ListAttachedGroupPolicies
        "Action": "ListAttachedGroupPolicies",
        # IAM user group name
        "GroupName": IAM_GROUP_NAME,
        # Set the maximum number of returned responses, value: 1~1000
        "MaxItems": "10"
    }
    body = encode_params(data)
    response = iam_client.list_attached_group_policies(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 11 DetachGroupPolicy
@handle_error
def detach_group_policy_example():
    """
    This operation is used to disassociate the specified IAM user group from the specified policy
    """
    data = {
        # Specify the operation as DetachGroupPolicy
        "Action": "DetachGroupPolicy",
        # IAM user group name
        "GroupName": IAM_GROUP_NAME,
        # Resource name of the permission policy
        "PolicyArn": POLICY_ARN
    }
    body = encode_params(data)
    response = iam_client.detach_group_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 12 UpdateAccountPasswordPolicy
@handle_error
def update_account_password_policy_example():
    """
    This operation is used to update the password rule settings of the account
    """
    data = {
        # Specify the operation as UpdateAccountPasswordPolicy
        "Action": "UpdateAccountPasswordPolicy",
        # Whether to allow IAM users to change the password of the console
        "AllowUsersToChangePassword": True,
        # After the console password expires, whether to allow the user to change the password in the console when logging in next time
        "HardExpiry": True,
        # Number of days the IAM user password is valid, value: 0-1095, 0 means never expire
        "MaxPasswordAge": "0",
        # The minimum length of the console login password
        "MinimumPasswordLength": "8",
        # Specify that when an IAM user sets a new login password, it must not be repeated from the previous login password within a certain number of times
        "PasswordReusePrevention": "3",
        # Specify whether the console login password must contain lowercase letters
        "RequireLowercaseCharacters": False,
        # Specify whether the console login password must include numbers
        "RequireNumbers": False,
        # Specify whether the console login password must contain special characters
        "RequireSymbols": True,
        # Specify whether the console login password must contain uppercase letters
        "RequireUppercaseCharacters": False
    }
    body = encode_params(data)
    response = iam_client.update_account_password_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 13 GetAccountPasswordPolicy
@handle_error
def get_account_password_policy_example():
    """
    This operation is used to obtain the password policy for the account
    """
    data = {
        # Specify the operation as GetAccountPasswordPolicy
        "Action": "GetAccountPasswordPolicy",
        # Request version
        "Version": API_VERSION
    }
    body = encode_params(data)
    response = iam_client.get_account_password_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 14 DeleteAccountPasswordPolicy
@handle_error
def delete_account_password_policy_example():
    """
    This operation is used to restore the password rules of the account to the default password rules
    """
    data = {
        # Specify the operation as DeleteAccountPasswordPolicy
        "Action": "DeleteAccountPasswordPolicy",
        # Request version
        "Version": API_VERSION
    }
    body = encode_params(data)
    response = iam_client.delete_account_password_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 15 UpdateAccountLoginSecurityPolicy
@handle_error
def update_account_login_security_policy_example():
    """
    This operation is used to update IAM user login security policy settings
    """
    data = {
        # Specify the operation as UpdateAccountLoginSecurityPolicy
        "Action": "UpdateAccountLoginSecurityPolicy",
        # Request version
        "Version": API_VERSION,
        # Limited time of login failures
        "PeriodWithLoginFailures": "15",
        # The number of consecutive login failures allowed for the IAM user within a limited time
        "LoginFailedTimes": "5",
        # The time when IAM user is locked
        "LockoutDuration": "20",
        # Whether to allow IAM user to log in to multiple clients at the same time
        "AllowSingleUsersSimultaneousLogin": False,
        # After the IAM user logs in to the console, the duration of the session is saved when no operation is performed
        "SessionDuration": "10",
    }
    body = encode_params(data)
    response = iam_client.update_account_login_security_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 16 GetAccountLoginSecurityPolicy
@handle_error
def get_account_login_security_policy_example():
    """
    This operation is used to obtain the IAM user login security policy
    """
    data = {
        # Specify the operation as GetAccountLoginSecurityPolicy
        "Action": "GetAccountLoginSecurityPolicy",
        # Request version
        "Version": API_VERSION
    }
    body = encode_params(data)
    response = iam_client.get_account_login_security_policy(
        Body=body
    )
    pretty_print(response)


# IAM Policy API 17 DeleteAccountLoginSecurityPolicy
@handle_error
def delete_account_login_security_policy_example():
    """
    This operation is used to restore IAM user login security policy to the default value
    """
    data = {
        # Specify the operation as DeleteAccountLoginSecurityPolicy
        "Action": "DeleteAccountLoginSecurityPolicy",
        # Request version
        "Version": API_VERSION
    }
    body = encode_params(data)
    response = iam_client.delete_account_login_security_policy(
        Body=body
    )
    pretty_print(response)


# Service Quantity Query API GetAccountSummary
@handle_error
def get_account_summary_example():
    """
    This operation is used to obtain the number of entities and service limitations in the account
    """
    data = {
        # Specify the operation as GetAccountSummary
        "Action": "GetAccountSummary",
        # Request version
        "Version": API_VERSION
    }
    body = encode_params(data)
    response = iam_client.get_account_summary(
        Body=body
    )
    pretty_print(response)


if __name__ == '__main__':
    try:
        # Users Management API 1 CreateUser
        # create_user_example()

        # Users Management API 2 GetUser
        # get_user_example()

        # Users Management API 3 ListUsers
        list_users_example()

        # Users Management API 4 DeleteUser
        # delete_user_example()

        # Users Management API 5 TagUser
        # tag_user_example()

        # Users Management API 6 UntagUser
        # untag_user_example()

        # Users Management API 7 ListUserTags
        # list_user_tags_example()

        # Users Management API 8 ListGroupsForUser
        # list_groups_for_user_example()

        # Users Management API 9 CreateAccessKey
        # create_access_key_example()

        # Users Management API 10 ListAccessKeys
        # list_access_keys_example()

        # Users Management API 11 GetAccessKeyLastUsed
        # get_access_key_last_used_example()

        # Users Management API 12 UpdateAccessKey
        # update_access_key_example()

        # Users Management API 13 DeleteAccessKey
        # delete_access_key_example()

        # Users Management API 14 GetSessionToken
        # get_session_token_example()

        # Users Management API 15 CreateLoginProfile
        # create_login_profile_example()

        # Users Management API 16 GetLoginProfile
        # get_login_profile_example()

        # Users Management API 17 UpdateLoginProfile
        # update_login_profile_example()

        # Users Management API 18 DeleteLoginProfile
        # delete_login_profile_example()

        # Users Management API 19 ChangePassword
        # change_password_example()

        # Users Management API 20 CreateVirtualMFADevice
        # create_virtual_mfa_device_example()

        # Users Management API 21 EnableMFADevice
        # enable_mfa_device_example()

        # Users Management API 22 ListVirtualMFADevices
        # list_virtual_mfa_devices_example()

        # Users Management API 23 ListMFADevices
        # list_mfa_devices_example()

        # Users Management API 24 DeactivateMFADevice
        # deactivate_mfa_device_example()

        # Users Management API 25 DeleteVirtualMFADevice
        # delete_virtual_mfa_device_example()

        # User Group Management API 1 CreateGroup
        # create_group_example()

        # User Group Management API 2 GetGroup
        # get_group_example()

        # User Group Management API 3 AddUserToGroup
        # add_user_to_group_example()

        # User Group Management API 4 RemoveUserFromGroup
        # remove_user_from_group_example()

        # User Group Management API 5 ListGroups
        # list_group_example()

        # User Group Management API 6 DeleteGroup
        # delete_group_example()

        # IAM Policy API 1 CreatePolicy
        # create_policy_example()

        # IAM Policy API 2 GetPolicy
        # get_policy_example()

        # IAM Policy API 3 ListPolicies
        # list_policies_example()

        # IAM Policy API 4 ListEntitiesForPolicy
        # list_entities_for_policy_example()

        # IAM Policy API 5 DeletePolicy
        # delete_policy_example()

        # IAM Policy API 6 AttachUserPolicy
        # attach_user_policy_example()

        # IAM Policy API 7 ListAttachedUserPolicies
        # list_attached_user_policies_example()

        # IAM Policy API 8 DetachUserPolicy
        # detach_user_policy_example()

        # IAM Policy API 9 AttachGroupPolicy
        # attach_group_policy_example()

        # IAM Policy API 10 ListAttachedGroupPolicies
        # list_attached_group_policies_example()

        # IAM Policy API 11 DetachGroupPolicy
        # detach_group_policy_example()

        # IAM Policy API 12 UpdateAccountPasswordPolicy
        # update_account_password_policy_example()

        # IAM Policy API 13 GetAccountPasswordPolicy
        # get_account_password_policy_example()

        # IAM Policy API 14 DeleteAccountPasswordPolicy
        # delete_account_password_policy_example()

        # IAM Policy API 15 UpdateAccountLoginSecurityPolicy
        # update_account_login_security_policy_example()

        # IAM Policy API 16 GetAccountLoginSecurityPolicy
        # get_account_login_security_policy_example()

        # IAM Policy API 17 DeleteAccountLoginSecurityPolicy
        # delete_account_login_security_policy_example()

        # Service Quantity Query API GetAccountSummary
        # get_account_summary_example()

    except Exception as ex:
        print(traceback.format_exc())
        print(ex)
