From 457c9746709042e6f4f8f37a85ca8ad562962405 Mon Sep 17 00:00:00 2001 From: Martin Basti Date: Thu, 5 Nov 2015 17:11:23 +0100 Subject: Allow multiple managers per user - CLI part Added commands: * user-add-manager * user-remove-manager * stageuser-add-manager * stageuser-remove-manager Commit contains override of convert_attribute_members method in baseuser class that ensures the managers will be returned in 'manager' attribute due to backward compatibility instead of 'manager_user' as would be expected. https://fedorahosted.org/freeipa/ticket/5344 This patch also fixes: https://fedorahosted.org/freeipa/ticket/5387 Reviewed-By: David Kupka Reviewed-By: Jan Cholasta --- ipalib/plugins/baseuser.py | 50 ++++++++++++++++++++++++++++++--------------- ipalib/plugins/stageuser.py | 22 ++++++++++++++------ ipalib/plugins/user.py | 24 +++++++++++++++------- 3 files changed, 67 insertions(+), 29 deletions(-) (limited to 'ipalib/plugins') diff --git a/ipalib/plugins/baseuser.py b/ipalib/plugins/baseuser.py index cf0fd88d9..e2572930e 100644 --- a/ipalib/plugins/baseuser.py +++ b/ipalib/plugins/baseuser.py @@ -27,8 +27,9 @@ import six from ipalib import api, errors from ipalib import Flag, Int, Password, Str, Bool, StrEnum, DateTime, Bytes from ipalib.plugable import Registry -from ipalib.plugins.baseldap import DN, LDAPObject, \ - LDAPCreate, LDAPUpdate, LDAPSearch, LDAPDelete, LDAPRetrieve +from ipalib.plugins.baseldap import ( + DN, LDAPObject, LDAPCreate, LDAPUpdate, LDAPSearch, LDAPDelete, + LDAPRetrieve, LDAPAddMember, LDAPRemoveMember) from ipalib.plugins.service import validate_certificate from ipalib.plugins import baseldap from ipalib.request import context @@ -201,6 +202,7 @@ class baseuser(LDAPObject): ] uuid_attribute = 'ipauniqueid' attribute_members = { + 'manager': ['user'], 'memberof': ['group', 'netgroup', 'role', 'hbacrule', 'sudorule'], 'memberofindirect': ['group', 'netgroup', 'role', 'hbacrule', 'sudorule'], } @@ -338,6 +340,7 @@ class baseuser(LDAPObject): Str('title?', label=_('Job Title'), ), + # keep backward compatibility using single value manager option Str('manager?', label=_('Manager'), ), @@ -428,6 +431,7 @@ class baseuser(LDAPObject): if not isinstance(manager, list): manager = [manager] + try: container_dn = DN(container, api.env.basedn) for i, mgr in enumerate(manager): @@ -443,17 +447,6 @@ class baseuser(LDAPObject): return manager - def convert_manager(self, entry_attrs, **options): - """ - Convert a manager dn into a userid - """ - if options.get('raw', False): - return - - if 'manager' in entry_attrs: - for i, mgr in enumerate(entry_attrs['manager']): - entry_attrs['manager'][i] = self.get_primary_key_from_dn(mgr) - def _user_status(self, user, container): assert isinstance(user, DN) return user.endswith(container) @@ -480,6 +473,26 @@ class baseuser(LDAPObject): entry_attrs['usercertificate'] = entry_attrs.pop( 'usercertificate;binary') + def convert_attribute_members(self, entry_attrs, *keys, **options): + super(baseuser, self).convert_attribute_members( + entry_attrs, *keys, **options) + + if options.get("raw", False): + return + + # due the backward compatibility, managers have to be returned in + # 'manager' attribute instead of 'manager_user' + try: + entry_attrs['failed_manager'] = entry_attrs.pop('manager') + except KeyError: + pass + + try: + entry_attrs['manager'] = entry_attrs.pop('manager_user') + except KeyError: + pass + + class baseuser_add(LDAPCreate): """ Prototype command plugin to be implemented by real plugin @@ -578,7 +591,6 @@ class baseuser_mod(LDAPUpdate): # 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) self.obj.convert_usercertificate_post(entry_attrs, **options) convert_sshpubkey_post(ldap, dn, entry_attrs) @@ -609,7 +621,6 @@ class baseuser_find(LDAPSearch): 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) self.obj.convert_usercertificate_post(attrs, **options) if (lockout): @@ -624,8 +635,15 @@ class baseuser_show(LDAPRetrieve): """ 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) self.obj.convert_usercertificate_post(entry_attrs, **options) convert_sshpubkey_post(ldap, dn, entry_attrs) radius_dn2pk(self.api, entry_attrs) + + +class baseuser_add_manager(LDAPAddMember): + member_attributes = ['manager'] + + +class baseuser_remove_manager(LDAPRemoveMember): + member_attributes = ['manager'] diff --git a/ipalib/plugins/stageuser.py b/ipalib/plugins/stageuser.py index 47c96bb71..995f67923 100644 --- a/ipalib/plugins/stageuser.py +++ b/ipalib/plugins/stageuser.py @@ -31,12 +31,12 @@ from ipalib import (Flag, Int, Password, Str, Bool, StrEnum, DateTime, 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 -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 - +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, + baseuser_add_manager, baseuser_remove_manager) from ipalib.request import context from ipalib import _, ngettext from ipalib import output @@ -716,3 +716,13 @@ class stageuser_activate(LDAPQuery): return dict(result=result_entry, summary=unicode(_('Stage user %s activated' % staging_dn[0].value)), value=pkey_to_value(args[-1], options)) + + +@register() +class stageuser_add_manager(baseuser_add_manager): + __doc__ = _("Add a manager to the stage user entry") + + +@register() +class stageuser_remove_manager(baseuser_remove_manager): + __doc__ = _("Remove a manager to the stage user entry") diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py index 81a707035..2b792af62 100644 --- a/ipalib/plugins/user.py +++ b/ipalib/plugins/user.py @@ -27,12 +27,13 @@ import six from ipalib import api, errors, util from ipalib import Flag, Int, Password, Str, Bool, StrEnum, DateTime -from ipalib.plugins.baseuser import baseuser, baseuser_add, baseuser_del, \ - baseuser_mod, baseuser_find, baseuser_show, \ - NO_UPG_MAGIC, UPG_DEFINITION_DN, baseuser_output_params, \ - status_baseuser_output_params, baseuser_pwdchars, \ - validate_nsaccountlock, radius_dn2pk, convert_nsaccountlock, split_principal, validate_principal, \ - normalize_principal, fix_addressbook_permission_bindrule +from ipalib.plugins.baseuser import ( + baseuser, baseuser_add, baseuser_del, baseuser_mod, baseuser_find, + baseuser_show, NO_UPG_MAGIC, UPG_DEFINITION_DN, baseuser_output_params, + status_baseuser_output_params, baseuser_pwdchars, validate_nsaccountlock, + radius_dn2pk, convert_nsaccountlock, split_principal, validate_principal, + normalize_principal, fix_addressbook_permission_bindrule, + baseuser_add_manager, baseuser_remove_manager) from ipalib.plugins.idviews import remove_ipaobject_overrides from ipalib.plugable import Registry from ipalib.plugins.baseldap import * @@ -542,7 +543,6 @@ class user_add(baseuser_add): except errors.AlreadyGroupMember: pass - self.obj.convert_manager(entry_attrs, **options) # delete description attribute NO_UPG_MAGIC if present if options.get('noprivate', False): if not options.get('all', False): @@ -1157,3 +1157,13 @@ class user_remove_cert(LDAPRemoveAttribute): self.obj.convert_usercertificate_post(entry_attrs, **options) return dn + + +@register() +class user_add_manager(baseuser_add_manager): + __doc__ = _("Add a manager to the user entry") + + +@register() +class user_remove_manager(baseuser_remove_manager): + __doc__ = _("Remove a manager to the user entry") -- cgit