Add user-stage command

This patch replaces 'stageuser-add --from-delete' with new command
user-stage.

Original way always required  to specify first and last name, and
overall combination of options was hard to manage. The new command
requires only login of deleted user (user-del --preserve).

https://fedorahosted.org/freeipa/ticket/5041

Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
Martin Basti 2015-08-17 20:11:21 +02:00
parent d8b9125895
commit fb98e77104
4 changed files with 70 additions and 39 deletions

10
API.txt
View File

@ -4211,7 +4211,7 @@ option: Str('displayname', attribute=True, autofill=True, cli_name='displayname'
option: Str('employeenumber', attribute=True, cli_name='employeenumber', multivalue=False, required=False)
option: Str('employeetype', attribute=True, cli_name='employeetype', multivalue=False, required=False)
option: Str('facsimiletelephonenumber', attribute=True, cli_name='fax', multivalue=True, required=False)
option: Flag('from_delete?', autofill=True, cli_name='from_delete', default=False)
option: DeprecatedParam('from_delete?', cli_name='from_delete', default=False)
option: Str('gecos', attribute=True, autofill=True, cli_name='gecos', multivalue=False, required=False)
option: Int('gidnumber', attribute=True, cli_name='gidnumber', minvalue=1, multivalue=False, required=False)
option: Str('givenname', attribute=True, cli_name='first', multivalue=False, required=True)
@ -5371,6 +5371,14 @@ option: Str('version?', exclude='webui')
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: PrimaryKey('value', None, None)
command: user_stage
args: 1,2,3
arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=True, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
option: Flag('continue', autofill=True, cli_name='continue', default=False)
option: Str('version?', exclude='webui')
output: Output('result', <type 'dict'>, None)
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
output: ListOfPrimaryKeys('value', None, None)
command: user_status
args: 1,4,4
arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)

View File

@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
IPA_API_VERSION_MINOR=151
# Last change: cheimes - Add flag to list all service and user vaults
IPA_API_VERSION_MINOR=152
# Last change: mbasti - add 'user-stage' command

View File

@ -23,7 +23,8 @@ import posixpath
import os
from copy import deepcopy
from ipalib import api, errors
from ipalib import Flag, Int, Password, Str, Bool, StrEnum, DateTime
from ipalib import (Flag, Int, Password, Str, Bool, StrEnum, DateTime,
DeprecatedParam)
from ipalib.plugable import Registry
from ipalib.plugins.baseldap import LDAPCreate, LDAPQuery, LDAPSearch, DN, entry_to_dict, pkey_to_value
from ipalib.plugins import baseldap
@ -260,7 +261,7 @@ class stageuser_add(baseuser_add):
has_output_params = baseuser_add.has_output_params + stageuser_output_params
takes_options = LDAPCreate.takes_options + (
Flag('from_delete?',
DeprecatedParam('from_delete?',
doc=_('Create Stage user in from a delete user'),
cli_name='from_delete',
default=False,
@ -270,13 +271,12 @@ class stageuser_add(baseuser_add):
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
assert isinstance(dn, DN)
if not options.get('from_delete'):
# then givenname and sn are required attributes
if 'givenname' not in entry_attrs:
raise errors.RequirementError(name='givenname', error=_('givenname is required'))
# then givenname and sn are required attributes
if 'givenname' not in entry_attrs:
raise errors.RequirementError(name='givenname', error=_('givenname is required'))
if 'sn' not in entry_attrs:
raise errors.RequirementError(name='sn', error=_('sn is required'))
if 'sn' not in entry_attrs:
raise errors.RequirementError(name='sn', error=_('sn is required'))
# we don't want an user private group to be created for this user
# add NO_UPG_MAGIC description attribute to let the DS plugin know
@ -367,34 +367,6 @@ class stageuser_add(baseuser_add):
return dn
def execute(self, *keys, **options):
'''
A stage entry may be taken from the Delete container.
In that case we rather do 'MODRDN' than 'ADD'.
'''
if options.get('from_delete'):
ldap = self.obj.backend
staging_dn = self.obj.get_dn(*keys, **options)
delete_dn = DN(staging_dn[0], self.obj.delete_container_dn, api.env.basedn)
new_dn = DN(staging_dn[0], self.obj.stage_container_dn, api.env.basedn)
# Check that this value is a Active user
try:
entry_attrs = self._exc_wrapper(keys, options, ldap.get_entry)(delete_dn, ['dn'])
except errors.NotFound:
self.obj.handle_not_found(*keys)
self._exc_wrapper(keys, options, ldap.move_entry)(
delete_dn, new_dn)
entry_attrs = entry_to_dict(entry_attrs, **options)
entry_attrs['dn'] = new_dn
if self.obj.primary_key and keys[-1] is not None:
return dict(result=entry_attrs, value=keys[-1])
return dict(result=entry_attrs, value=u'')
else:
return super(stageuser_add, self).execute(*keys, **options)
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN)
config = ldap.get_ipa_config()

View File

@ -859,6 +859,57 @@ class user_undel(LDAPQuery):
value=pkey_to_value(keys[0], options),
)
@register()
class user_stage(LDAPMultiQuery):
__doc__ = _('Move deleted user into staged area')
has_output = output.standard_multi_delete
msg_summary = _('Staged user account "%(value)s"')
def execute(self, *keys, **options):
staged = []
failed = []
for key in keys[-1]:
single_keys = keys[:-1] + (key,)
multi_keys = keys[:-1] + ((key,),)
user = self.api.Command.user_show(*single_keys, all=True)['result']
new_options = {}
for param in self.api.Command.stageuser_add.options():
try:
value = user[param.name]
except KeyError:
continue
if param.multivalue and not isinstance(value, (list, tuple)):
value = [value]
elif not param.multivalue and isinstance(value, (list, tuple)):
value = value[0]
new_options[param.name] = value
try:
self.api.Command.stageuser_add(*single_keys, **new_options)
try:
self.api.Command.user_del(*multi_keys, preserve=False)
except errors.ExecutionError:
self.api.Command.stageuser_del(*multi_keys)
raise
except errors.ExecutionError:
if not options['continue']:
raise
failed.append(key)
else:
staged.append(key)
return dict(
result=dict(
failed=pkey_to_value(failed, options),
),
value=pkey_to_value(staged, options),
)
@register()
class user_disable(LDAPQuery):
__doc__ = _('Disable a user account.')