diff options
author | Thierry Bordaz <tbordaz@redhat.com> | 2015-05-12 15:03:58 +0200 |
---|---|---|
committer | Martin Kosek <mkosek@redhat.com> | 2015-05-18 09:37:21 +0200 |
commit | f2e986e01f973a95e95608e1853dca35dcffeb58 (patch) | |
tree | 2112238c250e2060928f1889590102f130e07dbf /ipalib | |
parent | dc668b1b6a75472ea79a6af4dbcd8c6a2c5a0384 (diff) | |
download | freeipa-f2e986e01f973a95e95608e1853dca35dcffeb58.tar.gz freeipa-f2e986e01f973a95e95608e1853dca35dcffeb58.tar.xz freeipa-f2e986e01f973a95e95608e1853dca35dcffeb58.zip |
User life cycle: new stageuser commands del/mod/find/show
Add plugin commands to stageuser plugin:
stageuser_del
stageuser_mod
stageuser_find
stageuser_show
https://fedorahosted.org/freeipa/ticket/3813
Reviewed-By: David Kupka <dkupka@redhat.com>
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/plugins/baseuser.py | 103 | ||||
-rw-r--r-- | ipalib/plugins/stageuser.py | 71 | ||||
-rw-r--r-- | ipalib/plugins/user.py | 83 |
3 files changed, 180 insertions, 77 deletions
diff --git a/ipalib/plugins/baseuser.py b/ipalib/plugins/baseuser.py index 16c7b2a88..4266e876c 100644 --- a/ipalib/plugins/baseuser.py +++ b/ipalib/plugins/baseuser.py @@ -459,13 +459,116 @@ class baseuser_mod(LDAPUpdate): """ Prototype command plugin to be implemented by real plugin """ + def check_namelength(self, ldap, **options): + if options.get('rename') is not None: + config = ldap.get_ipa_config() + if 'ipamaxusernamelength' in config: + if len(options['rename']) > int(config.get('ipamaxusernamelength')[0]): + raise errors.ValidationError( + name=self.obj.primary_key.cli_name, + error=_('can be at most %(len)d characters') % dict( + len = int(config.get('ipamaxusernamelength')[0]) + ) + ) + def check_mail(self, entry_attrs): + if 'mail' in entry_attrs: + entry_attrs['mail'] = self.obj.normalize_and_validate_email(entry_attrs['mail']) + + def check_manager(self, entry_attrs, container): + if 'manager' in entry_attrs: + entry_attrs['manager'] = self.obj.normalize_manager(entry_attrs['manager'], container) + + def check_userpassword(self, entry_attrs, **options): + if 'userpassword' not in entry_attrs and options.get('random'): + entry_attrs['userpassword'] = ipa_generate_password(baseuser_pwdchars) + # save the password so it can be displayed in post_callback + setattr(context, 'randompassword', entry_attrs['userpassword']) + + def check_objectclass(self, ldap, dn, entry_attrs): + if ('ipasshpubkey' in entry_attrs or 'ipauserauthtype' in entry_attrs + or 'userclass' in entry_attrs or 'ipatokenradiusconfiglink' in entry_attrs): + if 'objectclass' in entry_attrs: + obj_classes = entry_attrs['objectclass'] + else: + _entry_attrs = ldap.get_entry(dn, ['objectclass']) + obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass'] + + if 'ipasshpubkey' in entry_attrs and 'ipasshuser' not in obj_classes: + obj_classes.append('ipasshuser') + + if 'ipauserauthtype' in entry_attrs and 'ipauserauthtypeclass' not in obj_classes: + obj_classes.append('ipauserauthtypeclass') + + if 'userclass' in entry_attrs and 'ipauser' not in obj_classes: + obj_classes.append('ipauser') + + if 'ipatokenradiusconfiglink' in entry_attrs: + cl = entry_attrs['ipatokenradiusconfiglink'] + if cl: + if 'ipatokenradiusproxyuser' not in obj_classes: + obj_classes.append('ipatokenradiusproxyuser') + + answer = self.api.Object['radiusproxy'].get_dn_if_exists(cl) + entry_attrs['ipatokenradiusconfiglink'] = answer + + def pre_common_callback(self, ldap, dn, entry_attrs, **options): + assert isinstance(dn, DN) + self.check_namelength(ldap, **options) + + self.check_mail(entry_attrs) + + self.check_manager(entry_attrs, self.obj.active_container_dn) + + self.check_userpassword(entry_attrs, **options) + + self.check_objectclass(ldap, dn, entry_attrs) + + def post_common_callback(self, ldap, dn, entry_attrs, **options): + assert isinstance(dn, DN) + if options.get('random', False): + try: + entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword')) + except AttributeError: + # if both randompassword and userpassword options were used + pass + convert_nsaccountlock(entry_attrs) + self.obj.convert_manager(entry_attrs, **options) + self.obj.get_password_attributes(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) + radius_dn2pk(self.api, entry_attrs) class baseuser_find(LDAPSearch): """ Prototype command plugin to be implemented by real plugin """ + def common_enhance_options(self, newoptions, **options): + # assure the manager attr is a dn, not just a bare uid + manager = options.get('manager') + if manager is not None: + newoptions['manager'] = self.obj.normalize_manager(manager, self.obj.active_container_dn) + + # Ensure that the RADIUS config link is a dn, not just the name + cl = 'ipatokenradiusconfiglink' + if cl in options: + newoptions[cl] = self.api.Object['radiusproxy'].get_dn(options[cl]) + + def post_common_callback(self, ldap, entries, lockout=False, **options): + for attrs in entries: + self.obj.convert_manager(attrs, **options) + self.obj.get_password_attributes(ldap, attrs.dn, attrs) + if (lockout): + attrs['nsaccountlock'] = True + else: + convert_nsaccountlock(attrs) + convert_sshpubkey_post(ldap, attrs.dn, attrs) class baseuser_show(LDAPRetrieve): """ Prototype command plugin to be implemented by real plugin """ + def post_common_callback(self, ldap, dn, entry_attrs, **options): + assert isinstance(dn, DN) + self.obj.convert_manager(entry_attrs, **options) + self.obj.get_password_attributes(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) + radius_dn2pk(self.api, entry_attrs) diff --git a/ipalib/plugins/stageuser.py b/ipalib/plugins/stageuser.py index 2a9a7f413..f788061f0 100644 --- a/ipalib/plugins/stageuser.py +++ b/ipalib/plugins/stageuser.py @@ -27,7 +27,8 @@ from ipalib import Flag, Int, Password, Str, Bool, StrEnum, DateTime from ipalib.plugable import Registry from ipalib.plugins.baseldap import LDAPCreate, DN, entry_to_dict from ipalib.plugins import baseldap -from ipalib.plugins.baseuser import baseuser, baseuser_add, baseuser_mod, baseuser_find, \ +from ipalib.plugins.baseuser import baseuser, baseuser_add, baseuser_del, \ + baseuser_mod, baseuser_find, baseuser_show, \ NO_UPG_MAGIC, radius_dn2pk, \ baseuser_pwdchars, fix_addressbook_permission_bindrule, normalize_principal, validate_principal, \ baseuser_output_params, status_baseuser_output_params @@ -275,3 +276,71 @@ class stageuser_add(baseuser_add): convert_sshpubkey_post(ldap, dn, entry_attrs) radius_dn2pk(self.api, entry_attrs) return dn + +@register() +class stageuser_del(baseuser_del): + __doc__ = _('Delete a stage user.') + + msg_summary = _('Deleted stage user "%(value)s"') + +@register() +class stageuser_mod(baseuser_mod): + __doc__ = _('Modify a stage user.') + + msg_summary = _('Modified stage user "%(value)s"') + + has_output_params = baseuser_mod.has_output_params + stageuser_output_params + + def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): + self.pre_common_callback(ldap, dn, entry_attrs, **options) + # Make sure it is not possible to authenticate with a Stage user account + if 'nsaccountlock' in entry_attrs: + del entry_attrs['nsaccountlock'] + return dn + + def post_callback(self, ldap, dn, entry_attrs, *keys, **options): + self.post_common_callback(ldap, dn, entry_attrs, **options) + if 'nsaccountlock' in entry_attrs: + del entry_attrs['nsaccountlock'] + return dn + +@register() +class stageuser_find(baseuser_find): + __doc__ = _('Search for stage users.') + + member_attributes = ['memberof'] + has_output_params = baseuser_find.has_output_params + stageuser_output_params + + + def execute(self, *args, **options): + newoptions = {} + self.common_enhance_options(newoptions, **options) + options.update(newoptions) + + return super(stageuser_find, self).execute(self, *args, **options) + + def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *keys, **options): + assert isinstance(base_dn, DN) + + return (filter, base_dn, scope) + + def post_callback(self, ldap, entries, truncated, *args, **options): + if options.get('pkey_only', False): + return truncated + self.post_common_callback(ldap, entries, lockout=True, **options) + return truncated + + msg_summary = ngettext( + '%(count)d user matched', '%(count)d users matched', 0 + ) + +@register() +class stageuser_show(baseuser_show): + __doc__ = _('Display information about a stage user.') + + has_output_params = baseuser_show.has_output_params + stageuser_output_params + + def post_callback(self, ldap, dn, entry_attrs, *keys, **options): + entry_attrs['nsaccountlock'] = True + self.post_common_callback(ldap, dn, entry_attrs, **options) + return dn diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py index ab259cda3..4da6c5a1e 100644 --- a/ipalib/plugins/user.py +++ b/ipalib/plugins/user.py @@ -550,67 +550,12 @@ class user_mod(baseuser_mod): has_output_params = baseuser_mod.has_output_params + user_output_params def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): - assert isinstance(dn, DN) - if options.get('rename') is not None: - config = ldap.get_ipa_config() - if 'ipamaxusernamelength' in config: - if len(options['rename']) > int(config.get('ipamaxusernamelength')[0]): - raise errors.ValidationError( - name=self.obj.primary_key.cli_name, - error=_('can be at most %(len)d characters') % dict( - len = int(config.get('ipamaxusernamelength')[0]) - ) - ) - if 'mail' in entry_attrs: - entry_attrs['mail'] = self.obj.normalize_and_validate_email(entry_attrs['mail']) - if 'manager' in entry_attrs: - entry_attrs['manager'] = self.obj.normalize_manager(entry_attrs['manager'], self.obj.active_container_dn) + self.pre_common_callback(ldap, dn, entry_attrs, **options) validate_nsaccountlock(entry_attrs) - if 'userpassword' not in entry_attrs and options.get('random'): - entry_attrs['userpassword'] = ipa_generate_password(baseuser_pwdchars) - # save the password so it can be displayed in post_callback - setattr(context, 'randompassword', entry_attrs['userpassword']) - if ('ipasshpubkey' in entry_attrs or 'ipauserauthtype' in entry_attrs - or 'userclass' in entry_attrs or 'ipatokenradiusconfiglink' in entry_attrs): - if 'objectclass' in entry_attrs: - obj_classes = entry_attrs['objectclass'] - else: - _entry_attrs = ldap.get_entry(dn, ['objectclass']) - obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass'] - - if 'ipasshpubkey' in entry_attrs and 'ipasshuser' not in obj_classes: - obj_classes.append('ipasshuser') - - if 'ipauserauthtype' in entry_attrs and 'ipauserauthtypeclass' not in obj_classes: - obj_classes.append('ipauserauthtypeclass') - - if 'userclass' in entry_attrs and 'ipauser' not in obj_classes: - obj_classes.append('ipauser') - - if 'ipatokenradiusconfiglink' in entry_attrs: - cl = entry_attrs['ipatokenradiusconfiglink'] - if cl: - if 'ipatokenradiusproxyuser' not in obj_classes: - obj_classes.append('ipatokenradiusproxyuser') - - answer = self.api.Object['radiusproxy'].get_dn_if_exists(cl) - entry_attrs['ipatokenradiusconfiglink'] = answer - return dn def post_callback(self, ldap, dn, entry_attrs, *keys, **options): - assert isinstance(dn, DN) - if options.get('random', False): - try: - entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword')) - except AttributeError: - # if both randompassword and userpassword options were used - pass - convert_nsaccountlock(entry_attrs) - self.obj.convert_manager(entry_attrs, **options) - self.obj.get_password_attributes(ldap, dn, entry_attrs) - convert_sshpubkey_post(ldap, dn, entry_attrs) - radius_dn2pk(self.api, entry_attrs) + self.post_common_callback(ldap, dn, entry_attrs, **options) return dn @@ -629,15 +574,9 @@ class user_find(baseuser_find): ) def execute(self, *args, **options): - # assure the manager attr is a dn, not just a bare uid - manager = options.get('manager') - if manager is not None: - options['manager'] = self.obj.normalize_manager(manager, self.obj.active_container_dn) - - # Ensure that the RADIUS config link is a dn, not just the name - cl = 'ipatokenradiusconfiglink' - if cl in options: - options[cl] = self.api.Object['radiusproxy'].get_dn(options[cl]) + newoptions = {} + self.common_enhance_options(newoptions, **options) + options.update(newoptions) return super(user_find, self).execute(self, *args, **options) @@ -652,11 +591,7 @@ class user_find(baseuser_find): def post_callback(self, ldap, entries, truncated, *args, **options): if options.get('pkey_only', False): return truncated - for attrs in entries: - self.obj.convert_manager(attrs, **options) - self.obj.get_password_attributes(ldap, attrs.dn, attrs) - convert_nsaccountlock(attrs) - convert_sshpubkey_post(ldap, attrs.dn, attrs) + self.post_common_callback(ldap, entries, lockout=False, **options) return truncated msg_summary = ngettext( @@ -671,12 +606,8 @@ class user_show(baseuser_show): has_output_params = baseuser_show.has_output_params + user_output_params def post_callback(self, ldap, dn, entry_attrs, *keys, **options): - assert isinstance(dn, DN) convert_nsaccountlock(entry_attrs) - self.obj.convert_manager(entry_attrs, **options) - self.obj.get_password_attributes(ldap, dn, entry_attrs) - convert_sshpubkey_post(ldap, dn, entry_attrs) - radius_dn2pk(self.api, entry_attrs) + self.post_common_callback(ldap, dn, entry_attrs, **options) return dn |