Merge "Adding options to user cli"
This commit is contained in:
		@@ -19,6 +19,12 @@ Create new user
 | 
			
		||||
        [--password-prompt]
 | 
			
		||||
        [--email <email-address>]
 | 
			
		||||
        [--description <description>]
 | 
			
		||||
        [--multi-factor-auth-rule <rule>]
 | 
			
		||||
        [--ignore-lockout-failure-attempts| --no-ignore-lockout-failure-attempts]
 | 
			
		||||
        [--ignore-password-expiry| --no-ignore-password-expiry]
 | 
			
		||||
        [--ignore-change-password-upon-first-use| --no-ignore-change-password-upon-first-use]
 | 
			
		||||
        [--enable-lock-password| --disable-lock-password]
 | 
			
		||||
        [--enable-multi-factor-auth| --disable-multi-factor-auth]
 | 
			
		||||
        [--enable | --disable]
 | 
			
		||||
        [--or-show]
 | 
			
		||||
        <user-name>
 | 
			
		||||
@@ -56,6 +62,63 @@ Create new user
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 3
 | 
			
		||||
 | 
			
		||||
.. option:: --ignore-lockout-failure-attempts
 | 
			
		||||
 | 
			
		||||
    Opt into ignoring the number of times a user has authenticated and
 | 
			
		||||
    locking out the user as a result
 | 
			
		||||
 | 
			
		||||
.. option:: --no-ignore-lockout-failure-attempts
 | 
			
		||||
 | 
			
		||||
    Opt out of ignoring the number of times a user has authenticated
 | 
			
		||||
    and locking out the user as a result
 | 
			
		||||
 | 
			
		||||
.. option:: --ignore-change-password-upon-first-use
 | 
			
		||||
 | 
			
		||||
    Control if a user should be forced to change their password immediately
 | 
			
		||||
    after they log into keystone for the first time. Opt into ignoring
 | 
			
		||||
    the user to change their password during first time login in keystone.
 | 
			
		||||
 | 
			
		||||
.. option:: --no-ignore-change-password-upon-first-use
 | 
			
		||||
 | 
			
		||||
    Control if a user should be forced to change their password immediately
 | 
			
		||||
    after they log into keystone for the first time. Opt out of ignoring
 | 
			
		||||
    the user to change their password during first time login in keystone.
 | 
			
		||||
 | 
			
		||||
.. option:: --ignore-password-expiry
 | 
			
		||||
 | 
			
		||||
    Opt into allowing user to continue using passwords that may be
 | 
			
		||||
    expired
 | 
			
		||||
 | 
			
		||||
.. option:: --no-ignore-password-expiry
 | 
			
		||||
 | 
			
		||||
    Opt out of allowing user to continue using passwords that may be
 | 
			
		||||
    expired
 | 
			
		||||
 | 
			
		||||
.. option:: --enable-lock-password
 | 
			
		||||
 | 
			
		||||
    Disables the ability for a user to change its password through
 | 
			
		||||
    self-service APIs
 | 
			
		||||
 | 
			
		||||
.. option:: --disable-lock-password
 | 
			
		||||
 | 
			
		||||
    Enables the ability for a user to change its password through
 | 
			
		||||
    self-service APIs
 | 
			
		||||
 | 
			
		||||
.. option:: --enable-multi-factor-auth
 | 
			
		||||
 | 
			
		||||
    Enables the MFA (Multi Factor Auth)
 | 
			
		||||
 | 
			
		||||
.. option:: --disable-multi-factor-auth
 | 
			
		||||
 | 
			
		||||
    Disables the MFA (Multi Factor Auth)
 | 
			
		||||
 | 
			
		||||
.. option:: --multi-factor-auth-rule <rule>
 | 
			
		||||
 | 
			
		||||
    Set multi-factor auth rules. For example, to set a rule requiring the
 | 
			
		||||
    "password" and "totp" auth methods to be provided,
 | 
			
		||||
    use: "--multi-factor-auth-rule password,totp".
 | 
			
		||||
    May be provided multiple times to set different rule combinations.
 | 
			
		||||
 | 
			
		||||
.. option:: --enable
 | 
			
		||||
 | 
			
		||||
    Enable user (default)
 | 
			
		||||
@@ -146,6 +209,12 @@ Set user properties
 | 
			
		||||
        [--password-prompt]
 | 
			
		||||
        [--email <email-address>]
 | 
			
		||||
        [--description <description>]
 | 
			
		||||
        [--multi-factor-auth-rule <rule>]
 | 
			
		||||
        [--ignore-lockout-failure-attempts| --no-ignore-lockout-failure-attempts]
 | 
			
		||||
        [--ignore-password-expiry| --no-ignore-password-expiry]
 | 
			
		||||
        [--ignore-change-password-upon-first-use| --no-ignore-change-password-upon-first-use]
 | 
			
		||||
        [--enable-lock-password| --disable-lock-password]
 | 
			
		||||
        [--enable-multi-factor-auth| --disable-multi-factor-auth]
 | 
			
		||||
        [--enable|--disable]
 | 
			
		||||
        <user>
 | 
			
		||||
 | 
			
		||||
@@ -187,6 +256,63 @@ Set user properties
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 3
 | 
			
		||||
 | 
			
		||||
.. option:: --ignore-lockout-failure-attempts
 | 
			
		||||
 | 
			
		||||
    Opt into ignoring the number of times a user has authenticated and
 | 
			
		||||
    locking out the user as a result
 | 
			
		||||
 | 
			
		||||
.. option:: --no-ignore-lockout-failure-attempts
 | 
			
		||||
 | 
			
		||||
    Opt out of ignoring the number of times a user has authenticated
 | 
			
		||||
    and locking out the user as a result
 | 
			
		||||
 | 
			
		||||
.. option:: --ignore-change-password-upon-first-use
 | 
			
		||||
 | 
			
		||||
    Control if a user should be forced to change their password immediately
 | 
			
		||||
    after they log into keystone for the first time. Opt into ignoring
 | 
			
		||||
    the user to change their password during first time login in keystone.
 | 
			
		||||
 | 
			
		||||
.. option:: --no-ignore-change-password-upon-first-use
 | 
			
		||||
 | 
			
		||||
    Control if a user should be forced to change their password immediately
 | 
			
		||||
    after they log into keystone for the first time. Opt out of ignoring
 | 
			
		||||
    the user to change their password during first time login in keystone.
 | 
			
		||||
 | 
			
		||||
.. option:: --ignore-password-expiry
 | 
			
		||||
 | 
			
		||||
    Opt into allowing user to continue using passwords that may be
 | 
			
		||||
    expired
 | 
			
		||||
 | 
			
		||||
.. option:: --no-ignore-password-expiry
 | 
			
		||||
 | 
			
		||||
    Opt out of allowing user to continue using passwords that may be
 | 
			
		||||
    expired
 | 
			
		||||
 | 
			
		||||
.. option:: --enable-lock-password
 | 
			
		||||
 | 
			
		||||
    Disables the ability for a user to change its password through
 | 
			
		||||
    self-service APIs
 | 
			
		||||
 | 
			
		||||
.. option:: --disable-lock-password
 | 
			
		||||
 | 
			
		||||
    Enables the ability for a user to change its password through
 | 
			
		||||
    self-service APIs
 | 
			
		||||
 | 
			
		||||
.. option:: --enable-multi-factor-auth
 | 
			
		||||
 | 
			
		||||
    Enables the MFA (Multi Factor Auth)
 | 
			
		||||
 | 
			
		||||
.. option:: --disable-multi-factor-auth
 | 
			
		||||
 | 
			
		||||
    Disables the MFA (Multi Factor Auth)
 | 
			
		||||
 | 
			
		||||
.. option:: --multi-factor-auth-rule <rule>
 | 
			
		||||
 | 
			
		||||
    Set multi-factor auth rules. For example, to set a rule requiring the
 | 
			
		||||
    "password" and "totp" auth methods to be provided,
 | 
			
		||||
    use: "--multi-factor-auth-rule password,totp".
 | 
			
		||||
    May be provided multiple times to set different rule combinations.
 | 
			
		||||
 | 
			
		||||
.. option:: --enable
 | 
			
		||||
 | 
			
		||||
    Enable user (default)
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,114 @@ from openstackclient.identity import common
 | 
			
		||||
LOG = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _get_options_for_user(identity_client, parsed_args):
 | 
			
		||||
    options = {}
 | 
			
		||||
    if parsed_args.ignore_lockout_failure_attempts:
 | 
			
		||||
        options['ignore_lockout_failure_attempts'] = True
 | 
			
		||||
    if parsed_args.no_ignore_lockout_failure_attempts:
 | 
			
		||||
        options['ignore_lockout_failure_attempts'] = False
 | 
			
		||||
    if parsed_args.ignore_password_expiry:
 | 
			
		||||
        options['ignore_password_expiry'] = True
 | 
			
		||||
    if parsed_args.no_ignore_password_expiry:
 | 
			
		||||
        options['ignore_password_expiry'] = False
 | 
			
		||||
    if parsed_args.ignore_change_password_upon_first_use:
 | 
			
		||||
        options['ignore_change_password_upon_first_use'] = True
 | 
			
		||||
    if parsed_args.no_ignore_change_password_upon_first_use:
 | 
			
		||||
        options['ignore_change_password_upon_first_use'] = False
 | 
			
		||||
    if parsed_args.enable_lock_password:
 | 
			
		||||
        options['lock_password'] = True
 | 
			
		||||
    if parsed_args.disable_lock_password:
 | 
			
		||||
        options['lock_password'] = False
 | 
			
		||||
    if parsed_args.enable_multi_factor_auth:
 | 
			
		||||
        options['multi_factor_auth_enabled'] = True
 | 
			
		||||
    if parsed_args.disable_multi_factor_auth:
 | 
			
		||||
        options['multi_factor_auth_enabled'] = False
 | 
			
		||||
    if parsed_args.multi_factor_auth_rule:
 | 
			
		||||
        auth_rules = [rule.split(",") for rule in
 | 
			
		||||
                      parsed_args.multi_factor_auth_rule]
 | 
			
		||||
        if auth_rules:
 | 
			
		||||
            options['multi_factor_auth_rules'] = auth_rules
 | 
			
		||||
    return options
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _add_user_options(parser):
 | 
			
		||||
    # Add additional user options
 | 
			
		||||
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--ignore-lockout-failure-attempts',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Opt into ignoring the number of times a user has '
 | 
			
		||||
               'authenticated and locking out the user as a result'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--no-ignore-lockout-failure-attempts',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Opt out of ignoring the number of times a user has '
 | 
			
		||||
               'authenticated and locking out the user as a result'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--ignore-password-expiry',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Opt into allowing user to continue using passwords that '
 | 
			
		||||
               'may be expired'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--no-ignore-password-expiry',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Opt out of allowing user to continue using passwords '
 | 
			
		||||
               'that may be expired'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--ignore-change-password-upon-first-use',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Control if a user should be forced to change their password '
 | 
			
		||||
               'immediately after they log into keystone for the first time. '
 | 
			
		||||
               'Opt into ignoring the user to change their password during '
 | 
			
		||||
               'first time login in keystone'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--no-ignore-change-password-upon-first-use',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Control if a user should be forced to change their password '
 | 
			
		||||
               'immediately after they log into keystone for the first time. '
 | 
			
		||||
               'Opt out of ignoring the user to change their password during '
 | 
			
		||||
               'first time login in keystone'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--enable-lock-password',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Disables the ability for a user to change its password '
 | 
			
		||||
               'through self-service APIs'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--disable-lock-password',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Enables the ability for a user to change its password '
 | 
			
		||||
               'through self-service APIs'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--enable-multi-factor-auth',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Enables the MFA (Multi Factor Auth)'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--disable-multi-factor-auth',
 | 
			
		||||
        action="store_true",
 | 
			
		||||
        help=_('Disables the MFA (Multi Factor Auth)'),
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--multi-factor-auth-rule',
 | 
			
		||||
        metavar='<rule>',
 | 
			
		||||
        action="append",
 | 
			
		||||
        default=[],
 | 
			
		||||
        help=_('Set multi-factor auth rules. For example, to set a rule '
 | 
			
		||||
               'requiring the "password" and "totp" auth methods to be '
 | 
			
		||||
               'provided, use: "--multi-factor-auth-rule password,totp". '
 | 
			
		||||
               'May be provided multiple times to set different rule '
 | 
			
		||||
               'combinations.')
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateUser(command.ShowOne):
 | 
			
		||||
    _description = _("Create new user")
 | 
			
		||||
 | 
			
		||||
@@ -72,6 +180,8 @@ class CreateUser(command.ShowOne):
 | 
			
		||||
            metavar='<description>',
 | 
			
		||||
            help=_('User description'),
 | 
			
		||||
        )
 | 
			
		||||
        _add_user_options(parser)
 | 
			
		||||
 | 
			
		||||
        enable_group = parser.add_mutually_exclusive_group()
 | 
			
		||||
        enable_group.add_argument(
 | 
			
		||||
            '--enable',
 | 
			
		||||
@@ -113,6 +223,7 @@ class CreateUser(command.ShowOne):
 | 
			
		||||
        if not parsed_args.password:
 | 
			
		||||
            LOG.warning(_("No password was supplied, authentication will fail "
 | 
			
		||||
                          "when a user does not have a password."))
 | 
			
		||||
        options = _get_options_for_user(identity_client, parsed_args)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            user = identity_client.users.create(
 | 
			
		||||
@@ -122,7 +233,8 @@ class CreateUser(command.ShowOne):
 | 
			
		||||
                password=parsed_args.password,
 | 
			
		||||
                email=parsed_args.email,
 | 
			
		||||
                description=parsed_args.description,
 | 
			
		||||
                enabled=enabled
 | 
			
		||||
                enabled=enabled,
 | 
			
		||||
                options=options,
 | 
			
		||||
            )
 | 
			
		||||
        except ks_exc.Conflict:
 | 
			
		||||
            if parsed_args.or_show:
 | 
			
		||||
@@ -333,6 +445,8 @@ class SetUser(command.Command):
 | 
			
		||||
            metavar='<description>',
 | 
			
		||||
            help=_('Set user description'),
 | 
			
		||||
        )
 | 
			
		||||
        _add_user_options(parser)
 | 
			
		||||
 | 
			
		||||
        enable_group = parser.add_mutually_exclusive_group()
 | 
			
		||||
        enable_group.add_argument(
 | 
			
		||||
            '--enable',
 | 
			
		||||
@@ -390,6 +504,10 @@ class SetUser(command.Command):
 | 
			
		||||
        if parsed_args.disable:
 | 
			
		||||
            kwargs['enabled'] = False
 | 
			
		||||
 | 
			
		||||
        options = _get_options_for_user(identity_client, parsed_args)
 | 
			
		||||
        if options:
 | 
			
		||||
            kwargs['options'] = options
 | 
			
		||||
 | 
			
		||||
        identity_client.users.update(user.id, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -108,6 +108,9 @@ MAPPING_RESPONSE_2 = {
 | 
			
		||||
    "rules": MAPPING_RULES_2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mfa_opt1 = 'password,totp'
 | 
			
		||||
mfa_opt2 = 'password'
 | 
			
		||||
 | 
			
		||||
project_id = '8-9-64'
 | 
			
		||||
project_name = 'beatles'
 | 
			
		||||
project_description = 'Fab Four'
 | 
			
		||||
 
 | 
			
		||||
@@ -111,6 +111,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
@@ -150,6 +151,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'password': 'secret',
 | 
			
		||||
        }
 | 
			
		||||
@@ -190,6 +192,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'password': 'abc123',
 | 
			
		||||
        }
 | 
			
		||||
@@ -228,6 +231,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': 'barney@example.com',
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
@@ -265,6 +269,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
@@ -311,6 +316,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
@@ -356,6 +362,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': self.domain.id,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
@@ -392,6 +399,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
@@ -428,6 +436,7 @@ class TestUserCreate(TestUser):
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'options': {},
 | 
			
		||||
            'enabled': False,
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
@@ -438,6 +447,471 @@ class TestUserCreate(TestUser):
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_ignore_lockout_failure_attempts(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--ignore-lockout-failure-attempts',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('ignore_lockout_failure_attempts', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_lockout_failure_attempts': True},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_no_ignore_lockout_failure_attempts(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--no-ignore-lockout-failure-attempts',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('no_ignore_lockout_failure_attempts', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_lockout_failure_attempts': False},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_ignore_password_expiry(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--ignore-password-expiry',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('ignore_password_expiry', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_password_expiry': True},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_no_ignore_password_expiry(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--no-ignore-password-expiry',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('no_ignore_password_expiry', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_password_expiry': False},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_ignore_change_password_upon_first_use(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--ignore-change-password-upon-first-use',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('ignore_change_password_upon_first_use', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_change_password_upon_first_use': True},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_no_ignore_change_password_upon_first_use(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--no-ignore-change-password-upon-first-use',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('no_ignore_change_password_upon_first_use', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_change_password_upon_first_use': False},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_enables_lock_password(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--enable-lock-password',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('enable_lock_password', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'lock_password': True},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_disables_lock_password(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--disable-lock-password',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('disable_lock_password', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'lock_password': False},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_enable_multi_factor_auth(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--enable-multi-factor-auth',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('enable_multi_factor_auth', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'multi_factor_auth_enabled': True},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_disable_multi_factor_auth(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--disable-multi-factor-auth',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('disable_multi_factor_auth', True),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'multi_factor_auth_enabled': False},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_option_with_multi_factor_auth_rule(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--multi-factor-auth-rule', identity_fakes.mfa_opt1,
 | 
			
		||||
            '--multi-factor-auth-rule', identity_fakes.mfa_opt2,
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('multi_factor_auth_rule', [identity_fakes.mfa_opt1,
 | 
			
		||||
                                        identity_fakes.mfa_opt2]),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'multi_factor_auth_rules': [["password", "totp"],
 | 
			
		||||
                                                    ["password"]]},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
    def test_user_create_with_multiple_options(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--ignore-password-expiry',
 | 
			
		||||
            '--disable-multi-factor-auth',
 | 
			
		||||
            '--multi-factor-auth-rule', identity_fakes.mfa_opt1,
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('ignore_password_expiry', True),
 | 
			
		||||
            ('disable_multi_factor_auth', True),
 | 
			
		||||
            ('multi_factor_auth_rule', [identity_fakes.mfa_opt1]),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('name', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        # In base command class ShowOne in cliff, abstract method take_action()
 | 
			
		||||
        # returns a two-part tuple with a tuple of column names and a tuple of
 | 
			
		||||
        # data to be shown.
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': self.user.name,
 | 
			
		||||
            'default_project': None,
 | 
			
		||||
            'description': None,
 | 
			
		||||
            'domain': None,
 | 
			
		||||
            'email': None,
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_password_expiry': True,
 | 
			
		||||
                        'multi_factor_auth_enabled': False,
 | 
			
		||||
                        'multi_factor_auth_rules': [["password", "totp"]]},
 | 
			
		||||
            'password': None,
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.create(name=, domain=, project=, password=, email=,
 | 
			
		||||
        #   description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.create.assert_called_with(
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.columns, columns)
 | 
			
		||||
        self.assertEqual(self.datalist, data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestUserDelete(TestUser):
 | 
			
		||||
 | 
			
		||||
@@ -1007,6 +1481,384 @@ class TestUserSet(TestUser):
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_ignore_lockout_failure_attempts(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--ignore-lockout-failure-attempts',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('ignore_lockout_failure_attempts', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_lockout_failure_attempts': True},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_no_ignore_lockout_failure_attempts(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--no-ignore-lockout-failure-attempts',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('no_ignore_lockout_failure_attempts', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_lockout_failure_attempts': False},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_ignore_password_expiry(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--ignore-password-expiry',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('ignore_password_expiry', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_password_expiry': True},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_no_ignore_password_expiry(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--no-ignore-password-expiry',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('no_ignore_password_expiry', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_password_expiry': False},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_ignore_change_password_upon_first_use(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--ignore-change-password-upon-first-use',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('ignore_change_password_upon_first_use', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_change_password_upon_first_use': True},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_no_ignore_change_password_upon_first_use(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--no-ignore-change-password-upon-first-use',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('no_ignore_change_password_upon_first_use', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_change_password_upon_first_use': False},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_enable_lock_password(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--enable-lock-password',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('enable_lock_password', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'lock_password': True},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_disable_lock_password(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--disable-lock-password',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('disable_lock_password', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'lock_password': False},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_enable_multi_factor_auth(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--enable-multi-factor-auth',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('enable_multi_factor_auth', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'multi_factor_auth_enabled': True},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_disable_multi_factor_auth(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--disable-multi-factor-auth',
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('disable_multi_factor_auth', True),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'multi_factor_auth_enabled': False},
 | 
			
		||||
        }
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_option_multi_factor_auth_rule(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--multi-factor-auth-rule', identity_fakes.mfa_opt1,
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('multi_factor_auth_rule', [identity_fakes.mfa_opt1]),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'multi_factor_auth_rules': [["password", "totp"]]}}
 | 
			
		||||
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
    def test_user_set_with_multiple_options(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--ignore-password-expiry',
 | 
			
		||||
            '--enable-multi-factor-auth',
 | 
			
		||||
            '--multi-factor-auth-rule', identity_fakes.mfa_opt1,
 | 
			
		||||
            self.user.name,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ('name', None),
 | 
			
		||||
            ('password', None),
 | 
			
		||||
            ('email', None),
 | 
			
		||||
            ('ignore_password_expiry', True),
 | 
			
		||||
            ('enable_multi_factor_auth', True),
 | 
			
		||||
            ('multi_factor_auth_rule', [identity_fakes.mfa_opt1]),
 | 
			
		||||
            ('project', None),
 | 
			
		||||
            ('enable', False),
 | 
			
		||||
            ('disable', False),
 | 
			
		||||
            ('user', self.user.name),
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        result = self.cmd.take_action(parsed_args)
 | 
			
		||||
        # Set expected values
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'enabled': True,
 | 
			
		||||
            'options': {'ignore_password_expiry': True,
 | 
			
		||||
                        'multi_factor_auth_enabled': True,
 | 
			
		||||
                        'multi_factor_auth_rules': [["password", "totp"]]}}
 | 
			
		||||
 | 
			
		||||
        # UserManager.update(user, name=, domain=, project=, password=,
 | 
			
		||||
        #     email=, description=, enabled=, default_project=)
 | 
			
		||||
        self.users_mock.update.assert_called_with(
 | 
			
		||||
            self.user.id,
 | 
			
		||||
            **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        self.assertIsNone(result)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestUserSetPassword(TestUser):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
---
 | 
			
		||||
features:
 | 
			
		||||
  - |
 | 
			
		||||
    Added the below mentioned parameters to the user create and set commands.
 | 
			
		||||
 | 
			
		||||
    * --ignore-lockout-failure-attempts
 | 
			
		||||
    * --no-ignore-lockout-failure-attempts
 | 
			
		||||
    * --ignore-password-expiry
 | 
			
		||||
    * --no-ignore-password-expiry
 | 
			
		||||
    * --ignore-change-password-upon-first-use
 | 
			
		||||
    * --no-ignore-change-password-upon-first-use
 | 
			
		||||
    * --enable-lock-password
 | 
			
		||||
    * --disable-lock-password
 | 
			
		||||
    * --enable-multi-factor-auth
 | 
			
		||||
    * --disable-multi-factor-auth
 | 
			
		||||
    * --multi-factor-auth-rule
 | 
			
		||||
 | 
			
		||||
    This will now allow users to set user options via CLI.
 | 
			
		||||
    <https://docs.openstack.org/keystone/latest/admin/resource-options.html#user-options>
 | 
			
		||||
		Reference in New Issue
	
	Block a user