From e963be1dda58494a80198a8d8a1cec5f2c898ca2 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 1 Oct 2008 15:56:04 -0600 Subject: Renamed plugins/example.py to plugins/f_user.py --- ipalib/plugins/f_user.py | 178 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 ipalib/plugins/f_user.py (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py new file mode 100644 index 00000000..e4d7dc10 --- /dev/null +++ b/ipalib/plugins/f_user.py @@ -0,0 +1,178 @@ +# Authors: +# Jason Gerard DeRose +# +# Copyright (C) 2008 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2 only +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" +Some example plugins. +""" + +from ipalib import frontend +from ipalib import crud +from ipalib.frontend import Param +from ipalib import api + +class user(frontend.Object): + 'User object' + takes_params = ( + 'givenname', + 'sn', + Param('uid', + primary_key=True, + default_from=lambda givenname, sn: givenname[0] + sn, + normalize=lambda value: value.lower(), + ), + Param('krbprincipalname', + default_from=lambda uid: '%s@EXAMPLE.COM' % uid, + ), + Param('homedirectory', + default_from=lambda uid: '/home/%s' % uid, + ) + ) +api.register(user) + + +# Hypothetical functional commands (not associated with any object): +class krbtest(frontend.Command): + 'Test your Kerberos ticket.' +api.register(krbtest) + +class discover(frontend.Command): + 'Discover IPA servers on network.' +api.register(discover) + +# Command to get the idea how plugins will interact with api.env +class envtest(frontend.Command): + 'Show current environment.' + def run(*args, **kw): + print "" + print "Environment variables:" + for var in api.env: + val = api.env[var] + if var is 'servers': + print "" + print " Servers:" + for item in api.env.servers: + print " %s" % item + print "" + else: + print " %s: %s" % (var, val) +api.register(envtest) + +# Register some methods for the 'user' object: +class user_add(crud.Add): + 'Add a new user.' + def execute(self, *args, **kw): + return 1 +api.register(user_add) + +class user_del(crud.Del): + 'Delete an existing user.' +api.register(user_del) + +class user_mod(crud.Mod): + 'Edit an existing user.' +api.register(user_mod) + +class user_find(crud.Find): + 'Search the users.' + def execute(self, *args, **kw): + uid=args[0] + result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) + return result +api.register(user_find) + +class user_show(crud.Get): + 'Examine an existing user.' +api.register(user_show) + + +# Register some properties for the 'user' object: +#class user_givenname(frontend.Property): +# 'User first name' +# required = True +#api.register(user_givenname) + +#class user_sn(frontend.Property): +# 'User last name' +# required = True +#api.register(user_sn) + +#class user_login(frontend.Property): +# 'User login' +# required = True +# default_from = frontend.DefaultFrom( +# lambda first, last: (first[0] + last).lower(), +# 'givenname', 'sn' +# ) +#api.register(user_login) + +#class user_initials(frontend.Property): +# 'User initials' +# required = True +# default_from = frontend.DefaultFrom( +# lambda first, last: first[0] + last[0], +# 'givenname', 'sn' +# ) +#api.register(user_initials) + + +# Register some methods for the 'group' object: +class group_add(frontend.Method): + 'Add a new group.' +api.register(group_add) + +class group_del(frontend.Method): + 'Delete an existing group.' +api.register(group_del) + +class group_mod(frontend.Method): + 'Edit an existing group.' +api.register(group_mod) + +class group_find(frontend.Method): + 'Search the groups.' +api.register(group_find) + + +# Register some methods for the 'service' object +class service_add(frontend.Method): + 'Add a new service.' +api.register(service_add) + +class service_del(frontend.Method): + 'Delete an existing service.' +api.register(service_del) + +class service_mod(frontend.Method): + 'Edit an existing service.' +api.register(service_mod) + +class service_find(frontend.Method): + 'Search the services.' +api.register(service_find) + + +# And to emphasis that the registration order doesn't matter, +# we'll register the objects last: +class group(frontend.Object): + 'Group object' +api.register(group) + +class service(frontend.Object): + 'Service object' +api.register(service) -- cgit From c846c7d91f0654dc4f52bedb053a79166c8d6adf Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 1 Oct 2008 16:10:41 -0600 Subject: Removed the everything except the envtest command and the user related plugins from f_user.py --- ipalib/plugins/f_user.py | 135 ++++++++++------------------------------------- 1 file changed, 28 insertions(+), 107 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index e4d7dc10..a482a963 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -18,7 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ -Some example plugins. +Frontend plugins for user (Identity). """ from ipalib import frontend @@ -26,34 +26,6 @@ from ipalib import crud from ipalib.frontend import Param from ipalib import api -class user(frontend.Object): - 'User object' - takes_params = ( - 'givenname', - 'sn', - Param('uid', - primary_key=True, - default_from=lambda givenname, sn: givenname[0] + sn, - normalize=lambda value: value.lower(), - ), - Param('krbprincipalname', - default_from=lambda uid: '%s@EXAMPLE.COM' % uid, - ), - Param('homedirectory', - default_from=lambda uid: '/home/%s' % uid, - ) - ) -api.register(user) - - -# Hypothetical functional commands (not associated with any object): -class krbtest(frontend.Command): - 'Test your Kerberos ticket.' -api.register(krbtest) - -class discover(frontend.Command): - 'Discover IPA servers on network.' -api.register(discover) # Command to get the idea how plugins will interact with api.env class envtest(frontend.Command): @@ -73,21 +45,46 @@ class envtest(frontend.Command): print " %s: %s" % (var, val) api.register(envtest) -# Register some methods for the 'user' object: + +class user(frontend.Object): + """ + User object. + """ + takes_params = ( + 'givenname', + 'sn', + Param('uid', + primary_key=True, + default_from=lambda givenname, sn: givenname[0] + sn, + normalize=lambda value: value.lower(), + ), + Param('krbprincipalname', + default_from=lambda uid: '%s@EXAMPLE.COM' % uid, + ), + Param('homedirectory', + default_from=lambda uid: '/home/%s' % uid, + ) + ) +api.register(user) + + class user_add(crud.Add): 'Add a new user.' def execute(self, *args, **kw): return 1 api.register(user_add) + class user_del(crud.Del): 'Delete an existing user.' api.register(user_del) + class user_mod(crud.Mod): 'Edit an existing user.' api.register(user_mod) + class user_find(crud.Find): 'Search the users.' def execute(self, *args, **kw): @@ -96,83 +93,7 @@ class user_find(crud.Find): return result api.register(user_find) + class user_show(crud.Get): 'Examine an existing user.' api.register(user_show) - - -# Register some properties for the 'user' object: -#class user_givenname(frontend.Property): -# 'User first name' -# required = True -#api.register(user_givenname) - -#class user_sn(frontend.Property): -# 'User last name' -# required = True -#api.register(user_sn) - -#class user_login(frontend.Property): -# 'User login' -# required = True -# default_from = frontend.DefaultFrom( -# lambda first, last: (first[0] + last).lower(), -# 'givenname', 'sn' -# ) -#api.register(user_login) - -#class user_initials(frontend.Property): -# 'User initials' -# required = True -# default_from = frontend.DefaultFrom( -# lambda first, last: first[0] + last[0], -# 'givenname', 'sn' -# ) -#api.register(user_initials) - - -# Register some methods for the 'group' object: -class group_add(frontend.Method): - 'Add a new group.' -api.register(group_add) - -class group_del(frontend.Method): - 'Delete an existing group.' -api.register(group_del) - -class group_mod(frontend.Method): - 'Edit an existing group.' -api.register(group_mod) - -class group_find(frontend.Method): - 'Search the groups.' -api.register(group_find) - - -# Register some methods for the 'service' object -class service_add(frontend.Method): - 'Add a new service.' -api.register(service_add) - -class service_del(frontend.Method): - 'Delete an existing service.' -api.register(service_del) - -class service_mod(frontend.Method): - 'Edit an existing service.' -api.register(service_mod) - -class service_find(frontend.Method): - 'Search the services.' -api.register(service_find) - - -# And to emphasis that the registration order doesn't matter, -# we'll register the objects last: -class group(frontend.Object): - 'Group object' -api.register(group) - -class service(frontend.Object): - 'Service object' -api.register(service) -- cgit From 6000b6b5c62181d25783b6d45adb2ed6f3928480 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 2 Oct 2008 17:02:24 -0600 Subject: Implemented basic Command.forward() method --- ipalib/plugins/f_user.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index a482a963..29f0f8a0 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -87,10 +87,10 @@ api.register(user_mod) class user_find(crud.Find): 'Search the users.' - def execute(self, *args, **kw): - uid=args[0] - result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) - return result +# def execute(self, *args, **kw): +# uid=args[0] +# result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) +# return result api.register(user_find) -- cgit From 7e4b0a072e69351496010d7b2151c9b434c8fdb0 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Sat, 4 Oct 2008 01:50:59 -0400 Subject: Implement user-find and user-add backend functions so they work over XML-RPC Change port to 8880 to not conflict with a running IPA v1 instance Encode incoming values from unicode as utf-8 before sending to LDAP --- ipalib/plugins/f_user.py | 91 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 6 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 29f0f8a0..320666aa 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -25,7 +25,10 @@ from ipalib import frontend from ipalib import crud from ipalib.frontend import Param from ipalib import api - +from ipa_server import servercore +from ipa_server import ipaldap +import ldap +from ipa_server.context import context # Command to get the idea how plugins will interact with api.env class envtest(frontend.Command): @@ -71,7 +74,79 @@ api.register(user) class user_add(crud.Add): 'Add a new user.' def execute(self, *args, **kw): - return 1 + """args[0] = uid of the user to add + kw{container} is the location in the DIT to add the user, not + required + kw otherwise contains all the attributes + """ + # FIXME: ug, really? + if not kw.get('container'): + user_container = servercore.DefaultUserContainer + else: + user_container = kw['container'] + del kw['container'] + + user = kw + + if not isinstance(user, dict): + # FIXME, need proper error + raise SyntaxError + + user['uid'] = args[0] + + # dn is set here, not by the user + try: + del user['dn'] + except KeyError: + pass + + # No need to set empty fields, and they can cause issues when they + # get to LDAP, like: + # TypeError: ('expected a string in the list', None) + for k in user.keys(): + if not user[k] or len(user[k]) == 0 or (isinstance(user[k],list) and len(user[k]) == 1 and '' in user[k]): + del user[k] + + dn="uid=%s,%s,%s" % (ldap.dn.escape_dn_chars(user['uid']), + user_container,servercore.basedn) + + entry = ipaldap.Entry(dn) + + # Let us add in some missing attributes + # FIXME, get config +# if user.get('homedirectory') is None: +# user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid')) +# user['homedirectory'] = user['homedirectory'].replace('//', '/') +# user['homedirectory'] = user['homedirectory'].rstrip('/') +# if user.get('loginshell') is None: +# user['loginshell'] = config.get('ipadefaultloginshell') + if user.get('gecos') is None: + user['gecos'] = user['uid'] + + # FIXME: add to default group + user['gidNumber'] = "500" + + if user.get('krbprincipalname') is None: + user['krbprincipalname'] = "%s@%s" % (user.get('uid'), self.realm) + + # FIXME. This is a hack so we can request separate First and Last + # name in the GUI. + if user.get('cn') is None: + user['cn'] = "%s %s" % (user.get('givenname'), + user.get('sn')) + + # some required objectclasses + # FIXME + # entry.setValues('objectClass', (config.get('ipauserobjectclasses'))) + entry.setValues('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'inetUser', 'posixAccount', 'krbPrincipalAux']) + + # fill in our new entry with everything sent by the user + for u in user: + entry.setValues(u, user[u]) + + result = context.conn.getConn().addEntry(entry) + return result + api.register(user_add) @@ -87,10 +162,14 @@ api.register(user_mod) class user_find(crud.Find): 'Search the users.' -# def execute(self, *args, **kw): -# uid=args[0] -# result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) -# return result + def execute(self, *args, **kw): + uid=args[0] + result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) + return result + def forward(self, *args, **kw): + result = super(crud.Find, self).forward(*args, **kw) + for a in result: + print a, ": ", res[a] api.register(user_find) -- cgit From cb795fa14bc2798fd8f1c6e2b87d19432e3f84a1 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Sat, 4 Oct 2008 05:17:11 -0400 Subject: Add group plugin, routine to get cn=ipaconfig --- ipalib/plugins/f_user.py | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 320666aa..0e62b833 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -112,19 +112,35 @@ class user_add(crud.Add): entry = ipaldap.Entry(dn) + # Get our configuration + config = servercore.get_ipa_config() + # Let us add in some missing attributes - # FIXME, get config -# if user.get('homedirectory') is None: -# user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid')) -# user['homedirectory'] = user['homedirectory'].replace('//', '/') -# user['homedirectory'] = user['homedirectory'].rstrip('/') -# if user.get('loginshell') is None: -# user['loginshell'] = config.get('ipadefaultloginshell') + if user.get('homedirectory') is None: + user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid')) + user['homedirectory'] = user['homedirectory'].replace('//', '/') + user['homedirectory'] = user['homedirectory'].rstrip('/') + if user.get('loginshell') is None: + user['loginshell'] = config.get('ipadefaultloginshell') if user.get('gecos') is None: user['gecos'] = user['uid'] - # FIXME: add to default group - user['gidNumber'] = "500" + # If uidnumber is blank the the FDS dna_plugin will automatically + # assign the next value. So we don't have to do anything with it. + + group_dn="cn=%s,%s,%s" % (config.get('ipadefaultprimarygroup'), servercore.DefaultGroupContainer, servercore.basedn) + try: + default_group = servercore.get_entry_by_dn(group_dn, ['dn','gidNumber']) + if default_group: + user['gidnumber'] = default_group.get('gidnumber') +# except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e: +# raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, message=None, nested_exception=e.detail) +# except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): +# # Fake an LDAP error so we can return something useful to the user +# raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup')) + except Exception, e: + # FIXME + raise e if user.get('krbprincipalname') is None: user['krbprincipalname'] = "%s@%s" % (user.get('uid'), self.realm) @@ -136,9 +152,8 @@ class user_add(crud.Add): user.get('sn')) # some required objectclasses - # FIXME - # entry.setValues('objectClass', (config.get('ipauserobjectclasses'))) - entry.setValues('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'inetUser', 'posixAccount', 'krbPrincipalAux']) + entry.setValues('objectClass', (config.get('ipauserobjectclasses'))) + # entry.setValues('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'inetUser', 'posixAccount', 'krbPrincipalAux']) # fill in our new entry with everything sent by the user for u in user: @@ -169,7 +184,7 @@ class user_find(crud.Find): def forward(self, *args, **kw): result = super(crud.Find, self).forward(*args, **kw) for a in result: - print a, ": ", res[a] + print a, ": ", result[a] api.register(user_find) -- cgit From 69bc5ad77adecaf7d8fde4a6578c3d2f3ef355df Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 7 Oct 2008 02:10:15 -0400 Subject: Add some more supporting functions Do a little bit more error handling and checking --- ipalib/plugins/f_user.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 0e62b833..49b6a370 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -28,7 +28,6 @@ from ipalib import api from ipa_server import servercore from ipa_server import ipaldap import ldap -from ipa_server.context import context # Command to get the idea how plugins will interact with api.env class envtest(frontend.Command): @@ -94,6 +93,13 @@ class user_add(crud.Add): user['uid'] = args[0] + if not servercore.is_user_unique(user['uid']): + # FIXME, specific error + raise SyntaxError("user already exists") + if servercore.uid_too_long(user['uid']): + # FIXME, specific error + raise SyntaxError("uid is too long") + # dn is set here, not by the user try: del user['dn'] @@ -159,8 +165,12 @@ class user_add(crud.Add): for u in user: entry.setValues(u, user[u]) - result = context.conn.getConn().addEntry(entry) + result = servercore.add_entry(entry) return result + def forward(self, *args, **kw): + result = super(crud.Add, self).forward(*args, **kw) + if result != False: + print result api.register(user_add) -- cgit From e012e860b472bcb5a00a089e73113fb6989fde20 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 7 Oct 2008 04:31:22 -0400 Subject: Implement user-mod --- ipalib/plugins/f_user.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 49b6a370..0b424d35 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -170,7 +170,7 @@ class user_add(crud.Add): def forward(self, *args, **kw): result = super(crud.Add, self).forward(*args, **kw) if result != False: - print result + print "User %s added" % args[0] api.register(user_add) @@ -182,6 +182,25 @@ api.register(user_del) class user_mod(crud.Mod): 'Edit an existing user.' + def execute(self, *args, **kw): + uid=args[0] + result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) + + user = kw + dn = result.get('dn') + del result['dn'] + entry = ipaldap.Entry((dn, servercore.convert_scalar_values(result))) + + for u in user: + entry.setValues(u, user[u]) + + result = servercore.update_entry(entry.toDict()) + + return result + def forward(self, *args, **kw): + result = super(crud.Mod, self).forward(*args, **kw) + if result != False: + print "User %s modified" % args[0] api.register(user_mod) -- cgit From db9d8dd3e0924bb9c7f9c89a56e6b6057dabc710 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 7 Oct 2008 06:15:34 -0400 Subject: Implement a real user_find and move existing user_find to user_show --- ipalib/plugins/f_user.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 0b424d35..e560d03c 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -208,15 +208,33 @@ class user_find(crud.Find): 'Search the users.' def execute(self, *args, **kw): uid=args[0] - result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) + result = servercore.find_users(uid, ["*"]) return result def forward(self, *args, **kw): - result = super(crud.Find, self).forward(*args, **kw) - for a in result: - print a, ": ", result[a] + users = super(crud.Find, self).forward(*args, **kw) + counter = users[0] + users = users[1:] + if counter == 0: + print "No entries found for", args[0] + return + elif counter == -1: + print "These results are truncated." + print "Please refine your search and try again." + + for u in users: + for a in u.keys(): + print "%s: %s" % (a, u[a]) api.register(user_find) class user_show(crud.Get): 'Examine an existing user.' + def execute(self, *args, **kw): + uid=args[0] + result = servercore.get_user_by_uid(uid, ["*"]) + return result + def forward(self, *args, **kw): + result = super(crud.Get, self).forward(*args, **kw) + for a in result: + print a, ": ", result[a] api.register(user_show) -- cgit From 4a68c719f03c176bc63a96007c089d0ac7ae5fc1 Mon Sep 17 00:00:00 2001 From: Martin Nagy Date: Fri, 3 Oct 2008 17:08:37 +0200 Subject: Implement config file reading --- ipalib/plugins/f_user.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 29f0f8a0..150d48ea 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -35,10 +35,10 @@ class envtest(frontend.Command): print "Environment variables:" for var in api.env: val = api.env[var] - if var is 'servers': + if var is 'server': print "" print " Servers:" - for item in api.env.servers: + for item in api.env.server: print " %s" % item print "" else: -- cgit From 672c07566df8d838b46edb6b80ba73ade2a27d55 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 7 Oct 2008 23:38:00 -0400 Subject: Implement user-del rename is_user_unique() to user_exists() --- ipalib/plugins/f_user.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index b006c24b..f87ddea1 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -93,7 +93,7 @@ class user_add(crud.Add): user['uid'] = args[0] - if not servercore.is_user_unique(user['uid']): + if servercore.user_exists(user['uid']): # FIXME, specific error raise SyntaxError("user already exists") if servercore.uid_too_long(user['uid']): @@ -177,6 +177,31 @@ api.register(user_add) class user_del(crud.Del): 'Delete an existing user.' + def execute(self, *args, **kw): + """args[0] = uid of the user to remove + + Delete a user. Not to be confused with inactivate_user. This + makes the entry go away completely. + + uid is the uid of the user to delete + + The memberOf plugin handles removing the user from any other + groups. + """ + uid = args[0] + if uid == "admin": + raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED) +# logging.info("IPA: delete_user '%s'" % uid) + user = servercore.get_user_by_uid(uid, ['dn', 'uid']) + if not user: + # FIXME, specific error + raise SyntaxError("user doesn't exist") + + return servercore.delete_entry(user['dn']) + def forward(self, *args, **kw): + result = super(crud.Del, self).forward(*args, **kw) + if result != False: + print "User %s removed" % args[0] api.register(user_del) -- cgit From 83bb41faebc0a61269f2869e9123166254fff5b3 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 8 Oct 2008 23:31:49 -0400 Subject: Mechanism to convert from xmlrpclib.Fault to an IPAError exception Include slew of new exceptions, not all of which are used yet --- ipalib/plugins/f_user.py | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index f87ddea1..8a1c3045 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -25,6 +25,7 @@ from ipalib import frontend from ipalib import crud from ipalib.frontend import Param from ipalib import api +from ipalib import errors from ipa_server import servercore from ipa_server import ipaldap import ldap @@ -32,7 +33,7 @@ import ldap # Command to get the idea how plugins will interact with api.env class envtest(frontend.Command): 'Show current environment.' - def run(*args, **kw): + def run(self, *args, **kw): print "" print "Environment variables:" for var in api.env: @@ -87,18 +88,12 @@ class user_add(crud.Add): user = kw - if not isinstance(user, dict): - # FIXME, need proper error - raise SyntaxError - user['uid'] = args[0] if servercore.user_exists(user['uid']): - # FIXME, specific error - raise SyntaxError("user already exists") + raise errors.Duplicate("user already exists") if servercore.uid_too_long(user['uid']): - # FIXME, specific error - raise SyntaxError("uid is too long") + raise errors.UsernameTooLong # dn is set here, not by the user try: @@ -139,17 +134,15 @@ class user_add(crud.Add): default_group = servercore.get_entry_by_dn(group_dn, ['dn','gidNumber']) if default_group: user['gidnumber'] = default_group.get('gidnumber') -# except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e: -# raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, message=None, nested_exception=e.detail) -# except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): -# # Fake an LDAP error so we can return something useful to the user -# raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup')) + except errors.NotFound: + # Fake an LDAP error so we can return something useful to the user + raise ipalib.NotFound, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup') except Exception, e: - # FIXME + # catch everything else raise e if user.get('krbprincipalname') is None: - user['krbprincipalname'] = "%s@%s" % (user.get('uid'), self.realm) + user['krbprincipalname'] = "%s@%s" % (user.get('uid'), servercore.realm) # FIXME. This is a hack so we can request separate First and Last # name in the GUI. @@ -169,7 +162,7 @@ class user_add(crud.Add): return result def forward(self, *args, **kw): result = super(crud.Add, self).forward(*args, **kw) - if result != False: + if result: print "User %s added" % args[0] api.register(user_add) @@ -190,17 +183,18 @@ class user_del(crud.Del): """ uid = args[0] if uid == "admin": - raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED) + # FIXME: do we still want a "special" user? + raise SyntaxError("admin required") +# raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED) # logging.info("IPA: delete_user '%s'" % uid) user = servercore.get_user_by_uid(uid, ['dn', 'uid']) if not user: - # FIXME, specific error - raise SyntaxError("user doesn't exist") + raise errors.NotFound return servercore.delete_entry(user['dn']) def forward(self, *args, **kw): result = super(crud.Del, self).forward(*args, **kw) - if result != False: + if result: print "User %s removed" % args[0] api.register(user_del) @@ -224,7 +218,7 @@ class user_mod(crud.Mod): return result def forward(self, *args, **kw): result = super(crud.Mod, self).forward(*args, **kw) - if result != False: + if result: print "User %s modified" % args[0] api.register(user_mod) @@ -259,7 +253,11 @@ class user_show(crud.Get): result = servercore.get_user_by_uid(uid, ["*"]) return result def forward(self, *args, **kw): - result = super(crud.Get, self).forward(*args, **kw) - for a in result: - print a, ": ", result[a] + try: + result = super(crud.Get, self).forward(*args, **kw) + if not result: return + for a in result: + print a, ": ", result[a] + except errors.NotFound: + print "User %s not found" % args[0] api.register(user_show) -- cgit From 75bad44c27bff471c03ddc86283506f53f47520c Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Fri, 10 Oct 2008 05:23:00 -0400 Subject: Enable the verbose flag to pass thru xmlrpc --- ipalib/plugins/f_user.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 8a1c3045..9dbc93cb 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -231,6 +231,8 @@ class user_find(crud.Find): return result def forward(self, *args, **kw): users = super(crud.Find, self).forward(*args, **kw) + if not users: + return counter = users[0] users = users[1:] if counter == 0: -- cgit From 0ebaad646207c8819097124d0e483251d9d5d47d Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mon, 13 Oct 2008 14:59:48 -0400 Subject: Do a more specific search for the user --- ipalib/plugins/f_user.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 9dbc93cb..573a2a43 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -203,7 +203,9 @@ class user_mod(crud.Mod): 'Edit an existing user.' def execute(self, *args, **kw): uid=args[0] - result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"]) + + # Get the existing user entry + result = servercore.get_sub_entry("cn=accounts," + servercore.basedn, "uid=%s" % uid, ["*"]) user = kw dn = result.get('dn') -- cgit From 6d2705b363e95b5bd692b695cdcbbfcbca6d12b9 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mon, 13 Oct 2008 17:17:00 -0400 Subject: Implement user lock and unlock --- ipalib/plugins/f_user.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 573a2a43..ff459b3d 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -26,6 +26,7 @@ from ipalib import crud from ipalib.frontend import Param from ipalib import api from ipalib import errors +from ipalib import ipa_types from ipa_server import servercore from ipa_server import ipaldap import ldap @@ -136,7 +137,7 @@ class user_add(crud.Add): user['gidnumber'] = default_group.get('gidnumber') except errors.NotFound: # Fake an LDAP error so we can return something useful to the user - raise ipalib.NotFound, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup') + raise errors.NotFound, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup') except Exception, e: # catch everything else raise e @@ -265,3 +266,34 @@ class user_show(crud.Get): except errors.NotFound: print "User %s not found" % args[0] api.register(user_show) + +class user_lock(frontend.Command): + 'Lock a user account.' + takes_args = ( + Param('uid', primary_key=True), + ) + def execute(self, *args, **kw): + uid = args[0] + user = servercore.get_user_by_uid(uid, ['dn', 'uid']) + return servercore.mark_entry_inactive(user['dn']) + def forward(self, *args, **kw): + result = super(user_lock, self).forward(*args, **kw) + if result: + print "User locked" +api.register(user_lock) + +class user_unlock(frontend.Command): + 'Unlock a user account.' + takes_args = ( + Param('uid', primary_key=True), + ) + def execute(self, *args, **kw): + uid = args[0] + user = servercore.get_user_by_uid(uid, ['dn', 'uid']) + return servercore.mark_entry_active(user['dn']) + def forward(self, *args, **kw): + result = super(user_unlock, self).forward(*args, **kw) + if result: + print "User unlocked" +api.register(user_unlock) + -- cgit From b6dcd183a66ca6056f9d23637de0f12aee15efcc Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 13 Oct 2008 20:31:10 -0600 Subject: CLI now maps Param.cli_name to Param.name --- ipalib/plugins/f_user.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index ff459b3d..22fb8a27 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -55,9 +55,10 @@ class user(frontend.Object): User object. """ takes_params = ( - 'givenname', - 'sn', + Param('givenname', cli_name='firstname'), + Param('sn', cli_name='lastname'), Param('uid', + cli_name='user', primary_key=True, default_from=lambda givenname, sn: givenname[0] + sn, normalize=lambda value: value.lower(), @@ -78,7 +79,7 @@ class user_add(crud.Add): """args[0] = uid of the user to add kw{container} is the location in the DIT to add the user, not required - kw otherwise contains all the attributes + kw otherwise contains all the attributes """ # FIXME: ug, really? if not kw.get('container'): @@ -296,4 +297,3 @@ class user_unlock(frontend.Command): if result: print "User unlocked" api.register(user_unlock) - -- cgit From 1480224724864cb7cf34c9be755b905c61f885b9 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 14 Oct 2008 01:45:30 -0600 Subject: Started roughing out user_add() using api.Backend.ldap; added Command.output_for_cli() to take care of formatting print output --- ipalib/plugins/f_user.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 22fb8a27..571f6fa8 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -75,12 +75,26 @@ api.register(user) class user_add(crud.Add): 'Add a new user.' - def execute(self, *args, **kw): - """args[0] = uid of the user to add - kw{container} is the location in the DIT to add the user, not - required - kw otherwise contains all the attributes + + def execute(self, uid, **kw): + """ + Execute the user-add operation. + + The dn should not be passed as a keyword argument as it is constructed + by this method. + + Returns the entry as it will be created in LDAP. + + :param uid: The login name of the user being added. + :param kw: Keyword arguments for the other LDAP attributes. """ + assert 'uid' not in kw + assert 'dn' not in kw + kw['uid'] = uid + kw['dn'] = self.api.Backend.ldap.get_user_dn(uid) + + return kw + # FIXME: ug, really? if not kw.get('container'): user_container = servercore.DefaultUserContainer @@ -162,10 +176,6 @@ class user_add(crud.Add): result = servercore.add_entry(entry) return result - def forward(self, *args, **kw): - result = super(crud.Add, self).forward(*args, **kw) - if result: - print "User %s added" % args[0] api.register(user_add) -- cgit From 9788800aa41146551baee6d36314a20203fd9d20 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 14 Oct 2008 02:23:56 -0600 Subject: More work on making user-add use Backend.ldap --- ipalib/plugins/f_user.py | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 571f6fa8..b35a1122 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -55,20 +55,36 @@ class user(frontend.Object): User object. """ takes_params = ( - Param('givenname', cli_name='firstname'), - Param('sn', cli_name='lastname'), + Param('givenname', + cli_name='first', + doc='User first name', + ), + Param('sn', + cli_name='last', + doc='User last name', + ), Param('uid', cli_name='user', primary_key=True, default_from=lambda givenname, sn: givenname[0] + sn, normalize=lambda value: value.lower(), ), - Param('krbprincipalname', - default_from=lambda uid: '%s@EXAMPLE.COM' % uid, + Param('gecos', + doc='GECOS field', + default_from=lambda uid: uid, ), Param('homedirectory', + cli_name='home', + doc='Path of user home directory', default_from=lambda uid: '/home/%s' % uid, - ) + ), + Param('shell', + default=u'/bin/sh', + doc='Login shell', + ), + Param('krbprincipalname?', cli_name='principal', + default_from=lambda uid: '%s@EXAMPLE.COM' % uid, + ), ) api.register(user) @@ -90,21 +106,11 @@ class user_add(crud.Add): """ assert 'uid' not in kw assert 'dn' not in kw + ldap = self.api.Backend.ldap kw['uid'] = uid - kw['dn'] = self.api.Backend.ldap.get_user_dn(uid) - - return kw - - # FIXME: ug, really? - if not kw.get('container'): - user_container = servercore.DefaultUserContainer - else: - user_container = kw['container'] - del kw['container'] - - user = kw + kw['dn'] = ldap.get_user_dn(uid) + return ldap.create(**kw) - user['uid'] = args[0] if servercore.user_exists(user['uid']): raise errors.Duplicate("user already exists") -- cgit From ff88652a405c7fd9236a9b1d80dd8955a9ca056d Mon Sep 17 00:00:00 2001 From: Martin Nagy Date: Tue, 14 Oct 2008 21:22:44 +0200 Subject: Convert string values to boolean when generating environment --- ipalib/plugins/f_user.py | 1 + 1 file changed, 1 insertion(+) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index b35a1122..b2c191fb 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -47,6 +47,7 @@ class envtest(frontend.Command): print "" else: print " %s: %s" % (var, val) + return {} api.register(envtest) -- cgit From 30664cde88b70f478d75a768426db5f655c5f867 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 14 Oct 2008 17:46:36 -0400 Subject: Move some functionality from user-add to the backend ldap create function --- ipalib/plugins/f_user.py | 73 +++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 50 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index b35a1122..03bc9aa8 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -69,16 +69,17 @@ class user(frontend.Object): default_from=lambda givenname, sn: givenname[0] + sn, normalize=lambda value: value.lower(), ), - Param('gecos', + Param('gecos?', doc='GECOS field', default_from=lambda uid: uid, ), - Param('homedirectory', + Param('homedirectory?', cli_name='home', doc='Path of user home directory', default_from=lambda uid: '/home/%s' % uid, ), - Param('shell', + Param('loginshell?', + cli_name='shell', default=u'/bin/sh', doc='Login shell', ), @@ -109,44 +110,22 @@ class user_add(crud.Add): ldap = self.api.Backend.ldap kw['uid'] = uid kw['dn'] = ldap.get_user_dn(uid) - return ldap.create(**kw) - - if servercore.user_exists(user['uid']): - raise errors.Duplicate("user already exists") - if servercore.uid_too_long(user['uid']): + if servercore.uid_too_long(kw['uid']): raise errors.UsernameTooLong - # dn is set here, not by the user - try: - del user['dn'] - except KeyError: - pass - - # No need to set empty fields, and they can cause issues when they - # get to LDAP, like: - # TypeError: ('expected a string in the list', None) - for k in user.keys(): - if not user[k] or len(user[k]) == 0 or (isinstance(user[k],list) and len(user[k]) == 1 and '' in user[k]): - del user[k] - - dn="uid=%s,%s,%s" % (ldap.dn.escape_dn_chars(user['uid']), - user_container,servercore.basedn) - - entry = ipaldap.Entry(dn) - # Get our configuration config = servercore.get_ipa_config() # Let us add in some missing attributes - if user.get('homedirectory') is None: - user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid')) - user['homedirectory'] = user['homedirectory'].replace('//', '/') - user['homedirectory'] = user['homedirectory'].rstrip('/') - if user.get('loginshell') is None: - user['loginshell'] = config.get('ipadefaultloginshell') - if user.get('gecos') is None: - user['gecos'] = user['uid'] + if kw.get('homedirectory') is None: + kw['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), kw.get('uid')) + kw['homedirectory'] = kw['homedirectory'].replace('//', '/') + kw['homedirectory'] = kw['homedirectory'].rstrip('/') + if kw.get('loginshell') is None: + kw['loginshell'] = config.get('ipadefaultloginshell') + if kw.get('gecos') is None: + kw['gecos'] = kw['uid'] # If uidnumber is blank the the FDS dna_plugin will automatically # assign the next value. So we don't have to do anything with it. @@ -155,33 +134,27 @@ class user_add(crud.Add): try: default_group = servercore.get_entry_by_dn(group_dn, ['dn','gidNumber']) if default_group: - user['gidnumber'] = default_group.get('gidnumber') + kw['gidnumber'] = default_group.get('gidnumber') except errors.NotFound: - # Fake an LDAP error so we can return something useful to the user - raise errors.NotFound, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup') + # Fake an LDAP error so we can return something useful to the kw + raise errors.NotFound, "The default group for new kws, '%s', cannot be found." % config.get('ipadefaultprimarygroup') except Exception, e: # catch everything else raise e - if user.get('krbprincipalname') is None: - user['krbprincipalname'] = "%s@%s" % (user.get('uid'), servercore.realm) + if kw.get('krbprincipalname') is None: + kw['krbprincipalname'] = "%s@%s" % (kw.get('uid'), servercore.realm) # FIXME. This is a hack so we can request separate First and Last # name in the GUI. - if user.get('cn') is None: - user['cn'] = "%s %s" % (user.get('givenname'), - user.get('sn')) + if kw.get('cn') is None: + kw['cn'] = "%s %s" % (kw.get('givenname'), + kw.get('sn')) # some required objectclasses - entry.setValues('objectClass', (config.get('ipauserobjectclasses'))) - # entry.setValues('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'inetUser', 'posixAccount', 'krbPrincipalAux']) - - # fill in our new entry with everything sent by the user - for u in user: - entry.setValues(u, user[u]) + kw['objectClass'] = config.get('ipauserobjectclasses') - result = servercore.add_entry(entry) - return result + return ldap.create(**kw) api.register(user_add) -- cgit From 1c3f81852cb8337e2305f968be5bd8165997d27e Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 14 Oct 2008 17:46:36 -0400 Subject: Move some functionality from user-add to the backend ldap create function --- ipalib/plugins/f_user.py | 73 +++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 50 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index b2c191fb..e3ecd223 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -70,16 +70,17 @@ class user(frontend.Object): default_from=lambda givenname, sn: givenname[0] + sn, normalize=lambda value: value.lower(), ), - Param('gecos', + Param('gecos?', doc='GECOS field', default_from=lambda uid: uid, ), - Param('homedirectory', + Param('homedirectory?', cli_name='home', doc='Path of user home directory', default_from=lambda uid: '/home/%s' % uid, ), - Param('shell', + Param('loginshell?', + cli_name='shell', default=u'/bin/sh', doc='Login shell', ), @@ -110,44 +111,22 @@ class user_add(crud.Add): ldap = self.api.Backend.ldap kw['uid'] = uid kw['dn'] = ldap.get_user_dn(uid) - return ldap.create(**kw) - - if servercore.user_exists(user['uid']): - raise errors.Duplicate("user already exists") - if servercore.uid_too_long(user['uid']): + if servercore.uid_too_long(kw['uid']): raise errors.UsernameTooLong - # dn is set here, not by the user - try: - del user['dn'] - except KeyError: - pass - - # No need to set empty fields, and they can cause issues when they - # get to LDAP, like: - # TypeError: ('expected a string in the list', None) - for k in user.keys(): - if not user[k] or len(user[k]) == 0 or (isinstance(user[k],list) and len(user[k]) == 1 and '' in user[k]): - del user[k] - - dn="uid=%s,%s,%s" % (ldap.dn.escape_dn_chars(user['uid']), - user_container,servercore.basedn) - - entry = ipaldap.Entry(dn) - # Get our configuration config = servercore.get_ipa_config() # Let us add in some missing attributes - if user.get('homedirectory') is None: - user['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), user.get('uid')) - user['homedirectory'] = user['homedirectory'].replace('//', '/') - user['homedirectory'] = user['homedirectory'].rstrip('/') - if user.get('loginshell') is None: - user['loginshell'] = config.get('ipadefaultloginshell') - if user.get('gecos') is None: - user['gecos'] = user['uid'] + if kw.get('homedirectory') is None: + kw['homedirectory'] = '%s/%s' % (config.get('ipahomesrootdir'), kw.get('uid')) + kw['homedirectory'] = kw['homedirectory'].replace('//', '/') + kw['homedirectory'] = kw['homedirectory'].rstrip('/') + if kw.get('loginshell') is None: + kw['loginshell'] = config.get('ipadefaultloginshell') + if kw.get('gecos') is None: + kw['gecos'] = kw['uid'] # If uidnumber is blank the the FDS dna_plugin will automatically # assign the next value. So we don't have to do anything with it. @@ -156,33 +135,27 @@ class user_add(crud.Add): try: default_group = servercore.get_entry_by_dn(group_dn, ['dn','gidNumber']) if default_group: - user['gidnumber'] = default_group.get('gidnumber') + kw['gidnumber'] = default_group.get('gidnumber') except errors.NotFound: - # Fake an LDAP error so we can return something useful to the user - raise errors.NotFound, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup') + # Fake an LDAP error so we can return something useful to the kw + raise errors.NotFound, "The default group for new kws, '%s', cannot be found." % config.get('ipadefaultprimarygroup') except Exception, e: # catch everything else raise e - if user.get('krbprincipalname') is None: - user['krbprincipalname'] = "%s@%s" % (user.get('uid'), servercore.realm) + if kw.get('krbprincipalname') is None: + kw['krbprincipalname'] = "%s@%s" % (kw.get('uid'), servercore.realm) # FIXME. This is a hack so we can request separate First and Last # name in the GUI. - if user.get('cn') is None: - user['cn'] = "%s %s" % (user.get('givenname'), - user.get('sn')) + if kw.get('cn') is None: + kw['cn'] = "%s %s" % (kw.get('givenname'), + kw.get('sn')) # some required objectclasses - entry.setValues('objectClass', (config.get('ipauserobjectclasses'))) - # entry.setValues('objectClass', ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'inetUser', 'posixAccount', 'krbPrincipalAux']) - - # fill in our new entry with everything sent by the user - for u in user: - entry.setValues(u, user[u]) + kw['objectClass'] = config.get('ipauserobjectclasses') - result = servercore.add_entry(entry) - return result + return ldap.create(**kw) api.register(user_add) -- cgit From cfc8450efd92dc0fb6648e97b27416c67625adfb Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 14 Oct 2008 22:22:01 -0400 Subject: Port user-show to new CrudBackend framework --- ipalib/plugins/f_user.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index e3ecd223..1e79c4b8 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -110,7 +110,7 @@ class user_add(crud.Add): assert 'dn' not in kw ldap = self.api.Backend.ldap kw['uid'] = uid - kw['dn'] = ldap.get_user_dn(uid) + kw['dn'] = ldap.make_user_dn(uid) if servercore.uid_too_long(kw['uid']): raise errors.UsernameTooLong @@ -244,18 +244,23 @@ api.register(user_find) class user_show(crud.Get): 'Examine an existing user.' - def execute(self, *args, **kw): - uid=args[0] - result = servercore.get_user_by_uid(uid, ["*"]) - return result - def forward(self, *args, **kw): - try: - result = super(crud.Get, self).forward(*args, **kw) - if not result: return - for a in result: - print a, ": ", result[a] - except errors.NotFound: - print "User %s not found" % args[0] + def execute(self, uid, **kw): + """ + Execute the user-show operation. + + The dn should not be passed as a keyword argument as it is constructed + by this method. + + Returns the entry + + :param uid: The login name of the user to retrieve. + :param kw: Not used. + """ + ldap = self.api.Backend.ldap + dn = ldap.find_entry_dn("uid", uid, ["*"], "posixAccount") + # FIXME: should kw contain the list of attributes? + return ldap.retrieve(dn) + api.register(user_show) class user_lock(frontend.Command): -- cgit From f7c044495ae22d372fb064dbacfe0ff027c437a7 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 14 Oct 2008 22:48:57 -0400 Subject: Port user_del to CrudBackend Override output_for_cli() to generate nicer output --- ipalib/plugins/f_user.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 1e79c4b8..79c45735 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -157,23 +157,30 @@ class user_add(crud.Add): return ldap.create(**kw) + def output_for_cli(self, ret): + """ + Output result of this command to command line interface. + """ + if ret: + print "User added" + api.register(user_add) class user_del(crud.Del): 'Delete an existing user.' - def execute(self, *args, **kw): - """args[0] = uid of the user to remove - - Delete a user. Not to be confused with inactivate_user. This + def execute(self, uid, **kw): + """Delete a user. Not to be confused with inactivate_user. This makes the entry go away completely. uid is the uid of the user to delete The memberOf plugin handles removing the user from any other groups. + + :param uid: The login name of the user being added. + :param kw: Not used. """ - uid = args[0] if uid == "admin": # FIXME: do we still want a "special" user? raise SyntaxError("admin required") @@ -183,11 +190,16 @@ class user_del(crud.Del): if not user: raise errors.NotFound - return servercore.delete_entry(user['dn']) - def forward(self, *args, **kw): - result = super(crud.Del, self).forward(*args, **kw) - if result: - print "User %s removed" % args[0] + ldap = self.api.Backend.ldap + dn = ldap.find_entry_dn("uid", uid, ["*"], "posixAccount") + return ldap.delete(dn) + def output_for_cli(self, ret): + """ + Output result of this command to command line interface. + """ + if ret: + print "User deleted" + api.register(user_del) -- cgit From 789a248daa71d5d1377e0dc9f0cd3afe107d4f2a Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 15 Oct 2008 09:58:29 -0400 Subject: Port user-mod to use ldap update() method --- ipalib/plugins/f_user.py | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 79c45735..e95ee3b2 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -205,27 +205,31 @@ api.register(user_del) class user_mod(crud.Mod): 'Edit an existing user.' - def execute(self, *args, **kw): - uid=args[0] + def execute(self, uid, **kw): + """ + Execute the user-mod operation. - # Get the existing user entry - result = servercore.get_sub_entry("cn=accounts," + servercore.basedn, "uid=%s" % uid, ["*"]) + The dn should not be passed as a keyword argument as it is constructed + by this method. - user = kw - dn = result.get('dn') - del result['dn'] - entry = ipaldap.Entry((dn, servercore.convert_scalar_values(result))) + Returns the entry - for u in user: - entry.setValues(u, user[u]) + :param uid: The login name of the user to retrieve. + :param kw: Keyword arguments for the other LDAP attributes. + """ + assert 'uid' not in kw + assert 'dn' not in kw + ldap = self.api.Backend.ldap + dn = ldap.find_entry_dn("uid", uid, "posixAccount") + return ldap.update(dn, **kw) - result = servercore.update_entry(entry.toDict()) + def output_for_cli(self, ret): + """ + Output result of this command to command line interface. + """ + if ret: + print "User updated" - return result - def forward(self, *args, **kw): - result = super(crud.Mod, self).forward(*args, **kw) - if result: - print "User %s modified" % args[0] api.register(user_mod) @@ -269,7 +273,7 @@ class user_show(crud.Get): :param kw: Not used. """ ldap = self.api.Backend.ldap - dn = ldap.find_entry_dn("uid", uid, ["*"], "posixAccount") + dn = ldap.find_entry_dn("uid", uid, "posixAccount") # FIXME: should kw contain the list of attributes? return ldap.retrieve(dn) -- cgit From 3268b65ae0dfc7ffdeba685e8e2515a437bf092e Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 15 Oct 2008 16:11:34 -0400 Subject: Initial implementation of a generic search routine. --- ipalib/plugins/f_user.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index a1078fe7..c2bb7b6f 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -237,11 +237,10 @@ api.register(user_mod) class user_find(crud.Find): 'Search the users.' def execute(self, *args, **kw): - uid=args[0] - result = servercore.find_users(uid, ["*"]) - return result - def forward(self, *args, **kw): - users = super(crud.Find, self).forward(*args, **kw) + ldap = self.api.Backend.ldap + kw['uid'] = args[0] + return ldap.search(**kw) + def output_for_cli(self, users): if not users: return counter = users[0] -- cgit From 14a33d461960b4183ac25a83a8ef9f375fd75d49 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 15 Oct 2008 16:50:46 -0400 Subject: Fix some remaining merge issues and don't use forward() in user-*lock() --- ipalib/plugins/f_user.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index c2bb7b6f..ed88ef9f 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -154,8 +154,6 @@ class user_add(crud.Add): # some required objectclasses kw['objectClass'] = config.get('ipauserobjectclasses') -<<<<<<< HEAD:ipalib/plugins/f_user.py -======= return ldap.create(**kw) def output_for_cli(self, ret): @@ -288,9 +286,8 @@ class user_lock(frontend.Command): uid = args[0] user = servercore.get_user_by_uid(uid, ['dn', 'uid']) return servercore.mark_entry_inactive(user['dn']) - def forward(self, *args, **kw): - result = super(user_lock, self).forward(*args, **kw) - if result: + def output_for_cli(self, ret): + if ret: print "User locked" api.register(user_lock) @@ -303,8 +300,7 @@ class user_unlock(frontend.Command): uid = args[0] user = servercore.get_user_by_uid(uid, ['dn', 'uid']) return servercore.mark_entry_active(user['dn']) - def forward(self, *args, **kw): - result = super(user_unlock, self).forward(*args, **kw) - if result: + def output_for_cli(self, ret): + if ret: print "User unlocked" api.register(user_unlock) -- cgit From 12f1e7fdf75b001ed2b73525a242feb15b272d51 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 16 Oct 2008 10:32:20 -0400 Subject: Remove all references to ipa_server.* from user plugin --- ipalib/plugins/f_user.py | 64 +++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index ed88ef9f..9fec1bd4 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -27,9 +27,6 @@ from ipalib.frontend import Param from ipalib import api from ipalib import errors from ipalib import ipa_types -from ipa_server import servercore -from ipa_server import ipaldap -import ldap # Command to get the idea how plugins will interact with api.env class envtest(frontend.Command): @@ -112,11 +109,12 @@ class user_add(crud.Add): kw['uid'] = uid kw['dn'] = ldap.make_user_dn(uid) - if servercore.uid_too_long(kw['uid']): - raise errors.UsernameTooLong + # FIXME: enforce this elsewhere +# if servercore.uid_too_long(kw['uid']): +# raise errors.UsernameTooLong # Get our configuration - config = servercore.get_ipa_config() + config = ldap.get_ipa_config() # Let us add in some missing attributes if kw.get('homedirectory') is None: @@ -131,20 +129,21 @@ class user_add(crud.Add): # If uidnumber is blank the the FDS dna_plugin will automatically # assign the next value. So we don't have to do anything with it. - group_dn="cn=%s,%s,%s" % (config.get('ipadefaultprimarygroup'), servercore.DefaultGroupContainer, servercore.basedn) - try: - default_group = servercore.get_entry_by_dn(group_dn, ['dn','gidNumber']) - if default_group: - kw['gidnumber'] = default_group.get('gidnumber') - except errors.NotFound: - # Fake an LDAP error so we can return something useful to the kw - raise errors.NotFound, "The default group for new kws, '%s', cannot be found." % config.get('ipadefaultprimarygroup') - except Exception, e: - # catch everything else - raise e + if not kw.get('gidnumber'): + try: + group_dn = ldap.find_entry_dn("cn", config.get('ipadefaultprimarygroup')) + default_group = ldap.retrieve(group_dn, ['dn','gidNumber']) + if default_group: + kw['gidnumber'] = default_group.get('gidnumber') + except errors.NotFound: + # Fake an LDAP error so we can return something useful to the kw + raise errors.NotFound, "The default group for new kws, '%s', cannot be found." % config.get('ipadefaultprimarygroup') + except Exception, e: + # catch everything else + raise e if kw.get('krbprincipalname') is None: - kw['krbprincipalname'] = "%s@%s" % (kw.get('uid'), servercore.realm) + kw['krbprincipalname'] = "%s@%s" % (kw.get('uid'), self.api.env.realm) # FIXME. This is a hack so we can request separate First and Last # name in the GUI. @@ -185,12 +184,9 @@ class user_del(crud.Del): raise SyntaxError("admin required") # raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED) # logging.info("IPA: delete_user '%s'" % uid) - user = servercore.get_user_by_uid(uid, ['dn', 'uid']) - if not user: - raise errors.NotFound ldap = self.api.Backend.ldap - dn = ldap.find_entry_dn("uid", uid, ["*"], "posixAccount") + dn = ldap.find_entry_dn("uid", uid, "posixAccount") return ldap.delete(dn) def output_for_cli(self, ret): """ @@ -234,9 +230,9 @@ api.register(user_mod) class user_find(crud.Find): 'Search the users.' - def execute(self, *args, **kw): + def execute(self, uid, **kw): ldap = self.api.Backend.ldap - kw['uid'] = args[0] + kw['uid'] = uid return ldap.search(**kw) def output_for_cli(self, users): if not users: @@ -244,7 +240,7 @@ class user_find(crud.Find): counter = users[0] users = users[1:] if counter == 0: - print "No entries found for", args[0] + print "No entries found" return elif counter == -1: print "These results are truncated." @@ -272,7 +268,7 @@ class user_show(crud.Get): """ ldap = self.api.Backend.ldap dn = ldap.find_entry_dn("uid", uid, "posixAccount") - # FIXME: should kw contain the list of attributes? + # FIXME: should kw contain the list of attributes to display? return ldap.retrieve(dn) api.register(user_show) @@ -282,10 +278,10 @@ class user_lock(frontend.Command): takes_args = ( Param('uid', primary_key=True), ) - def execute(self, *args, **kw): - uid = args[0] - user = servercore.get_user_by_uid(uid, ['dn', 'uid']) - return servercore.mark_entry_inactive(user['dn']) + def execute(self, uid, **kw): + ldap = self.api.Backend.ldap + dn = ldap.find_entry_dn("uid", uid, "posixAccount") + return ldap.mark_entry_inactive(dn) def output_for_cli(self, ret): if ret: print "User locked" @@ -296,10 +292,10 @@ class user_unlock(frontend.Command): takes_args = ( Param('uid', primary_key=True), ) - def execute(self, *args, **kw): - uid = args[0] - user = servercore.get_user_by_uid(uid, ['dn', 'uid']) - return servercore.mark_entry_active(user['dn']) + def execute(self, uid, **kw): + ldap = self.api.Backend.ldap + dn = ldap.find_entry_dn("uid", uid, "posixAccount") + return ldap.mark_entry_active(dn) def output_for_cli(self, ret): if ret: print "User unlocked" -- cgit From f777f72de6a7c1d3ef29088fbf89722c1148f246 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 16 Oct 2008 15:00:30 -0400 Subject: Use the search fields from the configuration when searching Generalize the attribute -> objectclass search helper --- ipalib/plugins/f_user.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 9fec1bd4..da0262b6 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -186,7 +186,7 @@ class user_del(crud.Del): # logging.info("IPA: delete_user '%s'" % uid) ldap = self.api.Backend.ldap - dn = ldap.find_entry_dn("uid", uid, "posixAccount") + dn = ldap.find_entry_dn("uid", uid) return ldap.delete(dn) def output_for_cli(self, ret): """ @@ -215,7 +215,7 @@ class user_mod(crud.Mod): assert 'uid' not in kw assert 'dn' not in kw ldap = self.api.Backend.ldap - dn = ldap.find_entry_dn("uid", uid, "posixAccount") + dn = ldap.find_entry_dn("uid", uid) return ldap.update(dn, **kw) def output_for_cli(self, ret): @@ -230,9 +230,20 @@ api.register(user_mod) class user_find(crud.Find): 'Search the users.' - def execute(self, uid, **kw): + def execute(self, term, **kw): ldap = self.api.Backend.ldap - kw['uid'] = uid + + # Pull the list of searchable attributes out of the configuration. + config = ldap.get_ipa_config() + search_fields_conf_str = config.get('ipausersearchfields') + search_fields = search_fields_conf_str.split(",") + + for s in search_fields: + kw[s] = term + + object_type = ldap.get_object_type("uid") + if object_type and not kw.get('objectclass'): + kw['objectclass'] = ldap.get_object_type("uid") return ldap.search(**kw) def output_for_cli(self, users): if not users: @@ -267,7 +278,7 @@ class user_show(crud.Get): :param kw: Not used. """ ldap = self.api.Backend.ldap - dn = ldap.find_entry_dn("uid", uid, "posixAccount") + dn = ldap.find_entry_dn("uid", uid) # FIXME: should kw contain the list of attributes to display? return ldap.retrieve(dn) @@ -280,7 +291,7 @@ class user_lock(frontend.Command): ) def execute(self, uid, **kw): ldap = self.api.Backend.ldap - dn = ldap.find_entry_dn("uid", uid, "posixAccount") + dn = ldap.find_entry_dn("uid", uid) return ldap.mark_entry_inactive(dn) def output_for_cli(self, ret): if ret: @@ -294,7 +305,7 @@ class user_unlock(frontend.Command): ) def execute(self, uid, **kw): ldap = self.api.Backend.ldap - dn = ldap.find_entry_dn("uid", uid, "posixAccount") + dn = ldap.find_entry_dn("uid", uid) return ldap.mark_entry_active(dn) def output_for_cli(self, ret): if ret: -- cgit From ae8370be44d95b9f6793ded46ef81126aebef3e0 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Fri, 17 Oct 2008 19:20:23 -0400 Subject: Port f_service to LDAP backend Add new keyword, 'filter', that can be passed to the search function. This is globbed onto the filter that is auto-created. --- ipalib/plugins/f_user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index da0262b6..8b4def80 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -243,7 +243,7 @@ class user_find(crud.Find): object_type = ldap.get_object_type("uid") if object_type and not kw.get('objectclass'): - kw['objectclass'] = ldap.get_object_type("uid") + kw['objectclass'] = object_type return ldap.search(**kw) def output_for_cli(self, users): if not users: -- cgit From d615e4dafb9c4f3d737143f826ed20be918317fe Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mon, 20 Oct 2008 16:12:19 -0400 Subject: Port pwpolicy plugin to use b_ldap Add basic output_for_cli() function to user-show --- ipalib/plugins/f_user.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 8b4def80..6aebddfa 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -281,6 +281,10 @@ class user_show(crud.Get): dn = ldap.find_entry_dn("uid", uid) # FIXME: should kw contain the list of attributes to display? return ldap.retrieve(dn) + def output_for_cli(self, user): + if user: + for a in user.keys(): + print "%s: %s" % (a, user[a]) api.register(user_show) -- cgit From 475265ed378cd0879d22e2b9bc59f7eab742fee9 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 21 Oct 2008 09:31:44 -0400 Subject: Implement --all option to display all attributes. Still need to strip the dn when not doing all. --- ipalib/plugins/f_user.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 6aebddfa..972ee075 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -265,6 +265,9 @@ api.register(user_find) class user_show(crud.Get): 'Examine an existing user.' + takes_options = ( + Param('all?', type=ipa_types.Bool(), doc='Display all user attributes'), + ) def execute(self, uid, **kw): """ Execute the user-show operation. @@ -275,12 +278,15 @@ class user_show(crud.Get): Returns the entry :param uid: The login name of the user to retrieve. - :param kw: Not used. + :param kw: "all" set to True = return all attributes """ ldap = self.api.Backend.ldap dn = ldap.find_entry_dn("uid", uid) # FIXME: should kw contain the list of attributes to display? - return ldap.retrieve(dn) + if kw.get('all', False): + return ldap.retrieve(dn) + else: + return ldap.retrieve(dn, ['uid','givenname','sn','homeDirectory','loginshell']) def output_for_cli(self, user): if user: for a in user.keys(): -- cgit From 8d07faed4df28b8397971d06a2b101078c88ef86 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 21 Oct 2008 16:32:30 -0400 Subject: Update the command-line options to more closely match v1 --- ipalib/plugins/f_user.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 972ee075..70952b29 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -55,11 +55,11 @@ class user(frontend.Object): takes_params = ( Param('givenname', cli_name='first', - doc='User first name', + doc='User\'s first name', ), Param('sn', cli_name='last', - doc='User last name', + doc='User\'s last name', ), Param('uid', cli_name='user', @@ -68,22 +68,40 @@ class user(frontend.Object): normalize=lambda value: value.lower(), ), Param('gecos?', - doc='GECOS field', + doc='Set the GECOS field', default_from=lambda uid: uid, ), Param('homedirectory?', cli_name='home', - doc='Path of user home directory', + doc='Set the User\'s home directory', default_from=lambda uid: '/home/%s' % uid, ), Param('loginshell?', cli_name='shell', default=u'/bin/sh', - doc='Login shell', + doc='Set User\'s Login shell', ), Param('krbprincipalname?', cli_name='principal', - default_from=lambda uid: '%s@EXAMPLE.COM' % uid, + doc='Set User\'s Kerberos Principal name', + default_from=lambda uid: '%s@%s' % (uid, api.env.realm), ), + Param('mailaddress?', + cli_name='mail', + doc='Set User\'s e-mail address', + ), + Param('userpassword?', + cli_name='password', + doc='Set User\'s password', + ), + Param('groups?', + doc='Add account to one or more groups (comma-separated)', + ), + Param('uidnumber?', + cli_name='uid', + type=ipa_types.Int(), + doc='The uid to use for this user. If not included one is automatically set.', + ), + ) api.register(user) -- cgit From d2b46f176e5dbc40b67ebd90e6953498c5d6249a Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 23 Oct 2008 14:36:24 -0400 Subject: Use common display function for user-show and user-find. Add --all option to user-find Fix command-line help to make sense on searches as well --- ipalib/plugins/f_user.py | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 70952b29..d8bb49e2 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -47,6 +47,24 @@ class envtest(frontend.Command): return {} api.register(envtest) +def display_user(user): + # FIXME: for now delete dn here. In the future pass in the kw to + # output_for_cli() + attr = sorted(user.keys()) + # Always have sn following givenname + try: + l = attr.index('givenname') + attr.remove('sn') + attr.insert(l+1, 'sn') + except ValueError: + pass + + for a in attr: + if a != 'dn': + print "%s: %s" % (a, user[a]) + +default_attributes = ['uid','givenname','sn','homeDirectory','loginshell'] + class user(frontend.Object): """ @@ -68,30 +86,30 @@ class user(frontend.Object): normalize=lambda value: value.lower(), ), Param('gecos?', - doc='Set the GECOS field', + doc='GECOS field', default_from=lambda uid: uid, ), Param('homedirectory?', cli_name='home', - doc='Set the User\'s home directory', + doc='User\'s home directory', default_from=lambda uid: '/home/%s' % uid, ), Param('loginshell?', cli_name='shell', default=u'/bin/sh', - doc='Set User\'s Login shell', + doc='User\'s Login shell', ), Param('krbprincipalname?', cli_name='principal', - doc='Set User\'s Kerberos Principal name', + doc='User\'s Kerberos Principal name', default_from=lambda uid: '%s@%s' % (uid, api.env.realm), ), Param('mailaddress?', cli_name='mail', - doc='Set User\'s e-mail address', + doc='User\'s e-mail address', ), Param('userpassword?', cli_name='password', - doc='Set User\'s password', + doc='User\'s password', ), Param('groups?', doc='Add account to one or more groups (comma-separated)', @@ -248,6 +266,9 @@ api.register(user_mod) class user_find(crud.Find): 'Search the users.' + takes_options = ( + Param('all?', type=ipa_types.Bool(), doc='Retrieve all user attributes'), + ) def execute(self, term, **kw): ldap = self.api.Backend.ldap @@ -262,6 +283,10 @@ class user_find(crud.Find): object_type = ldap.get_object_type("uid") if object_type and not kw.get('objectclass'): kw['objectclass'] = object_type + if kw.get('all', False): + kw['attributes'] = ['*'] + else: + kw['attributes'] = default_attributes return ldap.search(**kw) def output_for_cli(self, users): if not users: @@ -276,15 +301,15 @@ class user_find(crud.Find): print "Please refine your search and try again." for u in users: - for a in u.keys(): - print "%s: %s" % (a, u[a]) + display_user(u) + print "" api.register(user_find) class user_show(crud.Get): 'Examine an existing user.' takes_options = ( - Param('all?', type=ipa_types.Bool(), doc='Display all user attributes'), + Param('all?', type=ipa_types.Bool(), doc='Retrieve all user attributes'), ) def execute(self, uid, **kw): """ @@ -304,11 +329,10 @@ class user_show(crud.Get): if kw.get('all', False): return ldap.retrieve(dn) else: - return ldap.retrieve(dn, ['uid','givenname','sn','homeDirectory','loginshell']) + return ldap.retrieve(dn, default_attributes) def output_for_cli(self, user): if user: - for a in user.keys(): - print "%s: %s" % (a, user[a]) + display_user(user) api.register(user_show) -- cgit From dd9206deb62c1c96344d2280f672353a53a7fd11 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Fri, 31 Oct 2008 17:03:10 -0400 Subject: Uncomment some logging statements ported over from v1. --- ipalib/plugins/f_user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index d8bb49e2..3adb328c 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -219,7 +219,7 @@ class user_del(crud.Del): # FIXME: do we still want a "special" user? raise SyntaxError("admin required") # raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED) -# logging.info("IPA: delete_user '%s'" % uid) + self.log.info("IPA: user-del '%s'" % uid) ldap = self.api.Backend.ldap dn = ldap.find_entry_dn("uid", uid) -- cgit From 42bf555a3ad1f1777b26a4092b49512b9360c882 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 17 Nov 2008 15:27:08 -0700 Subject: Started updated user_* commands to use textui --- ipalib/plugins/f_user.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 3adb328c..e96d787b 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -191,18 +191,21 @@ class user_add(crud.Add): kw['objectClass'] = config.get('ipauserobjectclasses') return ldap.create(**kw) - def output_for_cli(self, ret): + + def output_for_cli(self, textui, result, *args, **options): """ Output result of this command to command line interface. """ - if ret: - print "User added" + textui.print_name(self.name) + textui.print_entry(result) + textui.print_dashed('Added user "%s"' % result['uid']) api.register(user_add) class user_del(crud.Del): 'Delete an existing user.' + def execute(self, uid, **kw): """Delete a user. Not to be confused with inactivate_user. This makes the entry go away completely. @@ -224,12 +227,12 @@ class user_del(crud.Del): ldap = self.api.Backend.ldap dn = ldap.find_entry_dn("uid", uid) return ldap.delete(dn) - def output_for_cli(self, ret): + + def output_for_cli(self, textui, result, uid): """ Output result of this command to command line interface. """ - if ret: - print "User deleted" + textui.print_plain('Deleted user "%s"' % uid) api.register(user_del) @@ -254,12 +257,13 @@ class user_mod(crud.Mod): dn = ldap.find_entry_dn("uid", uid) return ldap.update(dn, **kw) - def output_for_cli(self, ret): + def output_for_cli(self, textui, result, uid, **options): """ Output result of this command to command line interface. """ - if ret: - print "User updated" + textui.print_name(self.name) + textui.print_entry(result) + textui.print_dashed('Updated user "%s"' % result['uid']) api.register(user_mod) @@ -330,9 +334,10 @@ class user_show(crud.Get): return ldap.retrieve(dn) else: return ldap.retrieve(dn, default_attributes) - def output_for_cli(self, user): - if user: - display_user(user) + + def output_for_cli(self, textui, result, uid, **options): + if result: + display_user(result) api.register(user_show) -- cgit From 12dc0a0aa916c9289fe7fb36eddf887e3a53775e Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 17 Nov 2008 16:40:42 -0700 Subject: user-find now works again, uses textui --- ipalib/plugins/f_user.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index e96d787b..eed6d8ab 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -292,21 +292,26 @@ class user_find(crud.Find): else: kw['attributes'] = default_attributes return ldap.search(**kw) - def output_for_cli(self, users): - if not users: + + def output_for_cli(self, textui, result, uid, **options): + counter = result[0] + users = result[1:] + if counter == 0 or len(users) == 0: + textui.print_plain("No entries found") return - counter = users[0] - users = users[1:] - if counter == 0: - print "No entries found" + if len(users) == 1: + textui.print_entry(users[0]) return - elif counter == -1: - print "These results are truncated." - print "Please refine your search and try again." - + textui.print_name(self.name) for u in users: - display_user(u) - print "" + textui.print_plain('%(givenname)s %(sn)s:' % u) + textui.print_entry(u) + textui.print_plain('') + if counter == -1: + textui.print_plain('These results are truncated.') + textui.print_plain('Please refine your search and try again.') + textui.print_count(users, '%d users matched') + api.register(user_find) -- cgit From 5c16047092652d2d56c86d83259c56eff883b485 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 17 Nov 2008 18:15:40 -0700 Subject: user-lock and user-unlock commands now use textui, which finishes the user plugins --- ipalib/plugins/f_user.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index eed6d8ab..ad7572c2 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -348,28 +348,37 @@ api.register(user_show) class user_lock(frontend.Command): 'Lock a user account.' + takes_args = ( Param('uid', primary_key=True), ) + def execute(self, uid, **kw): ldap = self.api.Backend.ldap dn = ldap.find_entry_dn("uid", uid) return ldap.mark_entry_inactive(dn) - def output_for_cli(self, ret): - if ret: - print "User locked" + + def output_for_cli(self, textui, result, uid): + if result: + textui.print_plain('Locked user "%s"' % uid) + api.register(user_lock) + class user_unlock(frontend.Command): 'Unlock a user account.' + takes_args = ( Param('uid', primary_key=True), ) + def execute(self, uid, **kw): ldap = self.api.Backend.ldap dn = ldap.find_entry_dn("uid", uid) return ldap.mark_entry_active(dn) - def output_for_cli(self, ret): - if ret: - print "User unlocked" + + def output_for_cli(self, textui, result, uid): + if result: + textui.print_plain('Unlocked user "%s"' % uid) + api.register(user_unlock) -- cgit From 0a60a6bcc4c8eaa7d42dc25fa6fc69d837e3e816 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 18 Nov 2008 11:30:16 -0700 Subject: Added textui.prompt_password() method; added logic in cli for dealing with 'password' flag in param.flags --- ipalib/plugins/f_user.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index ad7572c2..e1076242 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -109,7 +109,8 @@ class user(frontend.Object): ), Param('userpassword?', cli_name='password', - doc='User\'s password', + doc="Set user's password", + flags=['password'], ), Param('groups?', doc='Add account to one or more groups (comma-separated)', -- cgit From fc8ac693726ec33b5c0924f9b8ff5d663705a5a3 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Fri, 5 Dec 2008 15:31:18 -0500 Subject: Port plugins to use the new output_for_cli() argument list Fix some errors uncovered by the nosetests --- ipalib/plugins/f_user.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index e1076242..c8b819dd 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -305,7 +305,9 @@ class user_find(crud.Find): return textui.print_name(self.name) for u in users: - textui.print_plain('%(givenname)s %(sn)s:' % u) + gn = u.get('givenname', '') + sn= u.get('sn', '') + textui.print_plain('%s %s:' % (gn, sn)) textui.print_entry(u) textui.print_plain('') if counter == -1: -- cgit From 46bd3974af5ce312cb1dd3ca12e6184d78dc470e Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 10 Dec 2008 16:45:07 -0500 Subject: Don't pass along the kw dictionary we were passed by XML-RPC. We generally want to just search indexed attributes. We get this list of attributes from the configuration, use it. --- ipalib/plugins/f_user.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index c8b819dd..8cd3a592 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -282,17 +282,18 @@ class user_find(crud.Find): search_fields_conf_str = config.get('ipausersearchfields') search_fields = search_fields_conf_str.split(",") + search_kw = {} for s in search_fields: - kw[s] = term + search_kw[s] = term object_type = ldap.get_object_type("uid") if object_type and not kw.get('objectclass'): - kw['objectclass'] = object_type + search_kw['objectclass'] = object_type if kw.get('all', False): - kw['attributes'] = ['*'] + search_kw['attributes'] = ['*'] else: - kw['attributes'] = default_attributes - return ldap.search(**kw) + search_kw['attributes'] = default_attributes + return ldap.search(**search_kw) def output_for_cli(self, textui, result, uid, **options): counter = result[0] -- cgit From 285fa3d33077b336784a8ea7633b0e011646adaa Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 17 Dec 2008 23:18:14 -0700 Subject: Removed depreciated envtest command from f_user.py --- ipalib/plugins/f_user.py | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index e1076242..45ee59f4 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -28,24 +28,6 @@ from ipalib import api from ipalib import errors from ipalib import ipa_types -# Command to get the idea how plugins will interact with api.env -class envtest(frontend.Command): - 'Show current environment.' - def run(self, *args, **kw): - print "" - print "Environment variables:" - for var in api.env: - val = api.env[var] - if var is 'server': - print "" - print " Servers:" - for item in api.env.server: - print " %s" % item - print "" - else: - print " %s: %s" % (var, val) - return {} -api.register(envtest) def display_user(user): # FIXME: for now delete dn here. In the future pass in the kw to -- cgit From fdda31c50bcf79ef4e4017dc8075d55b3e5df466 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 14 Jan 2009 22:59:44 -0700 Subject: Fixed a problem in the host plugin module; added not in TODO about using Param.query --- ipalib/plugins/f_user.py | 67 +++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 35 deletions(-) (limited to 'ipalib/plugins/f_user.py') diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py index 04d7c930..506ad14d 100644 --- a/ipalib/plugins/f_user.py +++ b/ipalib/plugins/f_user.py @@ -21,12 +21,9 @@ Frontend plugins for user (Identity). """ -from ipalib import frontend -from ipalib import crud -from ipalib.frontend import Param -from ipalib import api -from ipalib import errors -from ipalib import ipa_types +from ipalib import api, crud, errors +from ipalib import Object, Command # Plugin base classes +from ipalib import Str, Password, Flag, Int # Parameter types def display_user(user): @@ -48,62 +45,62 @@ def display_user(user): default_attributes = ['uid','givenname','sn','homeDirectory','loginshell'] -class user(frontend.Object): +class user(Object): """ User object. """ + takes_params = ( - Param('givenname', + Str('givenname', cli_name='first', - doc='User\'s first name', + doc="User's first name", ), - Param('sn', + Str('sn', cli_name='last', - doc='User\'s last name', + doc="User's last name", ), - Param('uid', + Str('uid', cli_name='user', primary_key=True, default_from=lambda givenname, sn: givenname[0] + sn, - normalize=lambda value: value.lower(), + normalizer=lambda value: value.lower(), ), - Param('gecos?', + Str('gecos?', doc='GECOS field', default_from=lambda uid: uid, ), - Param('homedirectory?', + Str('homedirectory?', cli_name='home', - doc='User\'s home directory', + doc="User's home directory", default_from=lambda uid: '/home/%s' % uid, ), - Param('loginshell?', + Str('loginshell?', cli_name='shell', default=u'/bin/sh', - doc='User\'s Login shell', + doc="User's Login shell", ), - Param('krbprincipalname?', cli_name='principal', - doc='User\'s Kerberos Principal name', + Str('krbprincipalname?', + cli_name='principal', + doc="User's Kerberos Principal name", default_from=lambda uid: '%s@%s' % (uid, api.env.realm), ), - Param('mailaddress?', - cli_name='mail', - doc='User\'s e-mail address', + Str('mailaddress?', + cli_name='email', + doc="User's e-mail address", ), - Param('userpassword?', + Password('userpassword?', cli_name='password', doc="Set user's password", - flags=['password'], ), - Param('groups?', + Str('groups?', doc='Add account to one or more groups (comma-separated)', ), - Param('uidnumber?', + Int('uidnumber?', cli_name='uid', - type=ipa_types.Int(), doc='The uid to use for this user. If not included one is automatically set.', ), - ) + api.register(user) @@ -254,7 +251,7 @@ api.register(user_mod) class user_find(crud.Find): 'Search the users.' takes_options = ( - Param('all?', type=ipa_types.Bool(), doc='Retrieve all user attributes'), + Flag('all', doc='Retrieve all user attributes'), ) def execute(self, term, **kw): ldap = self.api.Backend.ldap @@ -304,7 +301,7 @@ api.register(user_find) class user_show(crud.Get): 'Examine an existing user.' takes_options = ( - Param('all?', type=ipa_types.Bool(), doc='Retrieve all user attributes'), + Flag('all', doc='Retrieve all user attributes'), ) def execute(self, uid, **kw): """ @@ -332,11 +329,11 @@ class user_show(crud.Get): api.register(user_show) -class user_lock(frontend.Command): +class user_lock(Command): 'Lock a user account.' takes_args = ( - Param('uid', primary_key=True), + Str('uid', primary_key=True), ) def execute(self, uid, **kw): @@ -351,11 +348,11 @@ class user_lock(frontend.Command): api.register(user_lock) -class user_unlock(frontend.Command): +class user_unlock(Command): 'Unlock a user account.' takes_args = ( - Param('uid', primary_key=True), + Str('uid', primary_key=True), ) def execute(self, uid, **kw): -- cgit