From eebaa73d3df425e309893d30f1f9dd6f43124439 Mon Sep 17 00:00:00 2001 From: "rcritten@redhat.com" Date: Tue, 28 Aug 2007 13:52:08 -0400 Subject: Implement delete users and groups Implement adding a group to a group Some other small fixups Add new cmd-line tool ipa-delgroup --- ipa-admintools/ipa-delgroup | 69 +++++++++++++++++++++++++++++ ipa-admintools/ipa-deluser | 2 +- ipa-admintools/ipa-groupmod | 3 +- ipa-python/ipaclient.py | 24 ++++++++-- ipa-python/rpcclient.py | 41 +++++++++++++++++ ipa-server/ipaserver/ipaldap.py | 12 +++++ ipa-server/xmlrpc-server/funcs.py | 83 +++++++++++++++++++++++++++++++++-- ipa-server/xmlrpc-server/ipaxmlrpc.py | 3 ++ 8 files changed, 227 insertions(+), 10 deletions(-) create mode 100644 ipa-admintools/ipa-delgroup diff --git a/ipa-admintools/ipa-delgroup b/ipa-admintools/ipa-delgroup new file mode 100644 index 00000000..50967a49 --- /dev/null +++ b/ipa-admintools/ipa-delgroup @@ -0,0 +1,69 @@ +#! /usr/bin/python -E +# Authors: Rob Crittenden +# +# Copyright (C) 2007 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 +# + +import sys +from optparse import OptionParser +import ipa +import ipa.ipaclient as ipaclient +import ipa.config + +import xmlrpclib +import kerberos + +def usage(): + print "ipa-delgroup group" + sys.exit(1) + +def parse_options(): + parser = OptionParser() + parser.add_option("--usage", action="store_true", + help="Program usage") + + args = ipa.config.init_config(sys.argv) + options, args = parser.parse_args(args) + + return options, args + +def main(): + options, args = parse_options() + + if len(args) != 2: + usage() + + try: + client = ipaclient.IPAClient() + ret = client.delete_group(args[1]) + if (ret == "Success"): + print args[1] + " successfully deleted" + else: + print args[1] + " " + ret + except xmlrpclib.Fault, f: + print f.faultString + return 1 + except kerberos.GSSError, e: + print "Could not initialize GSSAPI: %s/%s" % (e[0][0][0], e[0][1][0]) + return 1 + except xmlrpclib.ProtocolError, e: + print "Unable to connect to IPA server: %s" % (e.errmsg) + return 1 + + return 0 + +main() diff --git a/ipa-admintools/ipa-deluser b/ipa-admintools/ipa-deluser index 10d24806..bcee2afd 100644 --- a/ipa-admintools/ipa-deluser +++ b/ipa-admintools/ipa-deluser @@ -28,7 +28,7 @@ import xmlrpclib import kerberos def usage(): - print "ipa-adduser user" + print "ipa-deluser user" sys.exit(1) def parse_options(): diff --git a/ipa-admintools/ipa-groupmod b/ipa-admintools/ipa-groupmod index eea96b43..f3de9263 100644 --- a/ipa-admintools/ipa-groupmod +++ b/ipa-admintools/ipa-groupmod @@ -58,7 +58,6 @@ def main(): group=ipa.group.Group() options, args = parse_options() - print "len = ", len(args) if (options.add or options.remove) and (len(args) != 3): usage() if (options.desc and (len(args) != 2)): @@ -68,7 +67,7 @@ def main(): client = ipaclient.IPAClient() if options.add: client.add_user_to_group(args[1], args[2]) - print args[1] + " successfully added" + print args[1] + " successfully added to " + args[2] elif options.remove: client.remove_user_from_group(args[1], args[2]) print args[1] + " successfully removed" diff --git a/ipa-python/ipaclient.py b/ipa-python/ipaclient.py index 71def70f..9fd51db3 100644 --- a/ipa-python/ipaclient.py +++ b/ipa-python/ipaclient.py @@ -113,6 +113,14 @@ class IPAClient: result = self.transport.update_user(user.origDataDict(), user.toDict()) return result + def delete_user(self,uid): + """Delete a user entry.""" + + realm = config.config.get_realm() + + result = self.transport.delete_user(uid) + return result + def mark_user_deleted(self,uid): """Set a user as inactive by uid.""" @@ -202,7 +210,17 @@ class IPAClient: def update_group(self,group): """Update a group entry.""" - realm = config.config.get_realm() + return self.transport.update_group(group.origDataDict(), group.toDict()) - result = self.transport.update_group(group.origDataDict(), group.toDict()) - return result + def delete_group(self,group_cn): + """Delete a group entry.""" + + return self.transport.delete_group(group_cn) + + def add_group_to_group(self, group_cn, tgroup_cn): + """Add a group to an existing group. + group_cn is a cn of the group to add + tgroup_cn is the cn of the group to be added to + """ + + return self.transport.add_group_to_group(group_cn, tgroup_cn) diff --git a/ipa-python/rpcclient.py b/ipa-python/rpcclient.py index 3e5bb113..7d41caee 100644 --- a/ipa-python/rpcclient.py +++ b/ipa-python/rpcclient.py @@ -181,6 +181,19 @@ class RPCClient: return ipautil.unwrap_binary_data(result) + def delete_user(self,uid): + """Delete a user. uid is the uid of the user to delete.""" + server = self.setup_server() + + try: + result = server.delete_user(uid) + except xmlrpclib.Fault, fault: + raise ipaerror.gen_exception(fault.faultCode, fault.faultString) + except socket.error, (value, msg): + raise xmlrpclib.Fault(value, msg) + + return result + def mark_user_deleted(self,uid): """Mark a user as deleted/inactive""" server = self.setup_server() @@ -344,3 +357,31 @@ class RPCClient: raise xmlrpclib.Fault(value, msg) return ipautil.unwrap_binary_data(result) + + def delete_group(self,group_cn): + """Delete a group. group_cn is the cn of the group to be deleted.""" + server = self.setup_server() + + try: + result = server.delete_group(group_cn) + except xmlrpclib.Fault, fault: + raise ipaerror.gen_exception(fault.faultCode, fault.faultString) + except socket.error, (value, msg): + raise xmlrpclib.Fault(value, msg) + + return ipautil.unwrap_binary_data(result) + + def add_group_to_group(self, group_cn, tgroup_cn): + """Add a group to an existing group. + group_cn is a cn of the group to add + tgroup_cn is the cn of the group to be added to + """ + server = self.setup_server() + try: + result = server.add_group_to_group(group_cn, tgroup_cn) + except xmlrpclib.Fault, fault: + raise ipaerror.gen_exception(fault.faultCode, fault.faultString) + except socket.error, (value, msg): + raise xmlrpclib.Fault(value, msg) + + return ipautil.unwrap_binary_data(result) diff --git a/ipa-server/ipaserver/ipaldap.py b/ipa-server/ipaserver/ipaldap.py index 344e6dc3..188d9be5 100644 --- a/ipa-server/ipaserver/ipaldap.py +++ b/ipa-server/ipaserver/ipaldap.py @@ -389,6 +389,18 @@ class IPAdmin(SimpleLDAPObject): raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) return "Success" + def deleteEntry(self,*args): + """This wraps the delete function. Use with caution.""" + + sctrl = self.__get_server_controls__() + + try: + self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl) + self.delete_s(*args) + except ldap.LDAPError, e: + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) + return "Success" + def __wrapmethods(self): """This wraps all methods of SimpleLDAPObject, so that we can intercept the methods that deal with entries. Instead of using a raw list of tuples diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py index fe48a1ff..0a8952b0 100644 --- a/ipa-server/xmlrpc-server/funcs.py +++ b/ipa-server/xmlrpc-server/funcs.py @@ -466,6 +466,29 @@ class IPAServer: _LDAPPool.releaseConn(m1) return res + def delete_user (self, uid, opts=None): + """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. + """ + if opts: + self.set_principal(opts['remoteuser']) + + dn = self.get_dn_from_principal(self.princ) + + user_dn = self.get_user_by_uid(uid, ['dn', 'uid', 'objectclass'], opts) + if user_dn is None: + raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND) + + m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) + res = m1.deleteEntry(user_dn['dn']) + _LDAPPool.releaseConn(m1) + return res + # Group support def __is_group_unique(self, cn, opts): @@ -473,11 +496,10 @@ class IPAServer: cn = self.__safe_filter(cn) filter = "(&(cn=%s)(objectclass=posixGroup))" % cn - entry = self.__get_entry(self.basedn, filter, ['dn','cn'], opts) - - if entry is not None: + try: + entry = self.__get_entry(self.basedn, filter, ['dn','cn'], opts) return 0 - else: + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): return 1 def get_group_by_cn (self, cn, sattrs=None, opts=None): @@ -681,6 +703,59 @@ class IPAServer: """Update a group in LDAP""" return self.__update_entry(oldgroup, newgroup, opts) + def delete_group (self, group_cn, opts=None): + """Delete a group + group_cn is the cn of the group to delete + + The memberOf plugin handles removing the group from any other + groups. + """ + if opts: + self.set_principal(opts['remoteuser']) + + dn = self.get_dn_from_principal(self.princ) + + group = self.get_group_by_cn(group_cn, ['dn', 'cn'], opts) + + if len(group) != 1: + raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND) + + m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) + res = m1.deleteEntry(group[0]['dn']) + _LDAPPool.releaseConn(m1) + return res + + def add_group_to_group(self, group, tgroup, opts=None): + """Add a user to an existing group. + group is a cn of the group to add + tgroup is the cn of the group to be added to + """ + + if opts: + self.set_principal(opts['remoteuser']) + + old_group = self.get_group_by_cn(tgroup, None, opts) + if old_group is None: + raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND) + new_group = copy.deepcopy(old_group) + + group_dn = self.get_group_by_cn(group, ['dn', 'cn', 'objectclass'], opts) + if group_dn is None: + raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND) + + if new_group.get('uniquemember') is not None: + if ((isinstance(new_group.get('uniquemember'), str)) or (isinstance(new_group.get('uniquemember'), unicode))): + new_group['uniquemember'] = [new_group['uniquemember']] + new_group['uniquemember'].append(group_dn['dn']) + else: + new_group['uniquemember'] = group_dn['dn'] + + try: + ret = self.__update_entry(old_group, new_group, opts) + except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST): + raise + return ret + def ldap_search_escape(match): """Escapes out nasty characters from the ldap search. See RFC 2254.""" diff --git a/ipa-server/xmlrpc-server/ipaxmlrpc.py b/ipa-server/xmlrpc-server/ipaxmlrpc.py index 16ced2cd..5dc60b51 100644 --- a/ipa-server/xmlrpc-server/ipaxmlrpc.py +++ b/ipa-server/xmlrpc-server/ipaxmlrpc.py @@ -300,6 +300,7 @@ def handler(req, profiling=False): h.register_function(f.get_all_users) h.register_function(f.find_users) h.register_function(f.update_user) + h.register_function(f.delete_user) h.register_function(f.mark_user_deleted) h.register_function(f.get_group_by_cn) h.register_function(f.get_group_by_dn) @@ -307,9 +308,11 @@ def handler(req, profiling=False): h.register_function(f.find_groups) h.register_function(f.add_user_to_group) h.register_function(f.add_users_to_group) + h.register_function(f.add_group_to_group) h.register_function(f.remove_user_from_group) h.register_function(f.remove_users_from_group) h.register_function(f.update_group) + h.register_function(f.delete_group) h.handle_request(req) finally: pass -- cgit From ef2dc5cefa2f9ba94edea7cfce8913e3f25723bd Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Tue, 28 Aug 2007 09:20:12 -0700 Subject: Changes for larger data demo. Add fields to search results Put result() call inside try block - it's throwing an exception Trap ADMINLIMIT and SIZELIMIT exceptions --- ipa-server/ipa-gui/ipagui/controllers.py | 2 +- ipa-server/ipa-gui/ipagui/templates/userlist.kid | 28 ++++++++++++++++++++++-- ipa-server/ipaserver/ipaldap.py | 7 ++++-- ipa-server/xmlrpc-server/funcs.py | 2 +- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py index 7dff9c90..ca2d15a2 100644 --- a/ipa-server/ipa-gui/ipagui/controllers.py +++ b/ipa-server/ipa-gui/ipagui/controllers.py @@ -145,7 +145,7 @@ class Root(controllers.RootController): try: users = client.find_users(uid.encode('utf-8')) except ipaerror.IPAError, e: - turbogears.flash("User show failed: " + str(e)) + turbogears.flash("User list failed: " + str(e)) raise turbogears.redirect("/userlist") return dict(users=users, fields=forms.user.UserFields()) diff --git a/ipa-server/ipa-gui/ipagui/templates/userlist.kid b/ipa-server/ipa-gui/ipagui/templates/userlist.kid index df3e247e..1b4a1201 100644 --- a/ipa-server/ipa-gui/ipagui/templates/userlist.kid +++ b/ipa-server/ipa-gui/ipagui/templates/userlist.kid @@ -15,7 +15,7 @@

Results

- +
+ + + + + + + +
Name + Phone + + Unit + + Title + + License Plate +
${user.uid} - ${user.cn} + ${user.givenName} ${user.sn} + + ${user.telephoneNumber} + + ${user.ou} + + ${user.title} + + ${user.carLicense}
diff --git a/ipa-server/ipaserver/ipaldap.py b/ipa-server/ipaserver/ipaldap.py index 188d9be5..f626f2f3 100644 --- a/ipa-server/ipaserver/ipaldap.py +++ b/ipa-server/ipaserver/ipaldap.py @@ -260,12 +260,12 @@ class IPAdmin(SimpleLDAPObject): try: res = self.search(*args) + type, obj = self.result(res) # res = self.search_ext(args[0], args[1], filterstr=args[2], attrlist=args[3], serverctrls=sctrl) except ldap.LDAPError, e: raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) - type, obj = self.result(res) if not obj: raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, "no such entry for " + str(args)) @@ -283,10 +283,13 @@ class IPAdmin(SimpleLDAPObject): try: res = self.search(*args) + type, obj = self.result(res) + except (ldap.ADMINLIMIT_EXCEEDED, ldap.SIZELIMIT_EXCEEDED), e: + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, + "Too many results returned by search", e) except ldap.LDAPError, e: raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) - type, obj = self.result(res) if not obj: raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, "no such entry for " + str(args)) diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py index 0a8952b0..a0af41d4 100644 --- a/ipa-server/xmlrpc-server/funcs.py +++ b/ipa-server/xmlrpc-server/funcs.py @@ -385,7 +385,7 @@ class IPAServer: # Assume the list of fields to search will come from a central # configuration repository. A good format for that would be # a comma-separated list of fields - search_fields_conf_str = "uid,givenName,sn,telephoneNumber" + search_fields_conf_str = "uid,givenName,sn,telephoneNumber,ou,carLicense,title" search_fields = string.split(search_fields_conf_str, ",") criteria = self.__safe_filter(criteria) -- cgit From e9bd8dee3b0350c08d16d57bfd008a72cb283c48 Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Tue, 28 Aug 2007 16:01:07 -0700 Subject: Change user search to be asynchronous. This way it returns results even if the search times out. The find_users() search now returns a counter as the first result, which is set to -1 if the results are partial. --- ipa-python/ipaclient.py | 10 ++++--- ipa-python/rpcclient.py | 5 ++-- ipa-server/ipa-gui/ipagui/controllers.py | 6 ++++ ipa-server/ipa-gui/ipagui/static/css/style.css | 2 +- ipa-server/ipa-gui/ipagui/templates/userlist.kid | 4 +-- ipa-server/ipaserver/ipaldap.py | 38 ++++++++++++++++++++++++ ipa-server/xmlrpc-server/funcs.py | 26 +++++++++++----- 7 files changed, 74 insertions(+), 17 deletions(-) diff --git a/ipa-python/ipaclient.py b/ipa-python/ipaclient.py index 9fd51db3..fcfb29f1 100644 --- a/ipa-python/ipaclient.py +++ b/ipa-python/ipaclient.py @@ -94,12 +94,14 @@ class IPAClient: return result def find_users(self, criteria, sattrs=None): - """Find users whose uid matches the criteria. Wildcards are - acceptable. Returns a list of User objects.""" + """Return a list: counter followed by a User object for each user that + matches the criteria. If the results are truncated, counter will + be set to -1""" result = self.transport.find_users(criteria, sattrs) + counter = result[0] - users = [] - for attrs in result: + users = [counter] + for attrs in result[1:]: if attrs is not None: users.append(user.User(attrs)) diff --git a/ipa-python/rpcclient.py b/ipa-python/rpcclient.py index 7d41caee..e0d6e2ee 100644 --- a/ipa-python/rpcclient.py +++ b/ipa-python/rpcclient.py @@ -151,8 +151,9 @@ class RPCClient: return ipautil.unwrap_binary_data(result) def find_users (self, criteria, sattrs=None): - """Return a list containing a User object for each user that matches - the criteria.""" + """Return a list: counter followed by a User object for each user that + matches the criteria. If the results are truncated, counter will + be set to -1""" server = self.setup_server() try: diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py index ca2d15a2..ebd0b20d 100644 --- a/ipa-server/ipa-gui/ipagui/controllers.py +++ b/ipa-server/ipa-gui/ipagui/controllers.py @@ -140,10 +140,16 @@ class Root(controllers.RootController): def userlist(self, **kw): """Retrieve a list of all users and display them in one huge list""" users = None + counter = 0 uid = kw.get('uid') if uid != None and len(uid) > 0: try: users = client.find_users(uid.encode('utf-8')) + counter = users[0] + users = users[1:] + if counter == -1: + turbogears.flash("These results are truncated.\n" + + "Please refine your search and try again.") except ipaerror.IPAError, e: turbogears.flash("User list failed: " + str(e)) raise turbogears.redirect("/userlist") diff --git a/ipa-server/ipa-gui/ipagui/static/css/style.css b/ipa-server/ipa-gui/ipagui/static/css/style.css index b5bd8280..152175e1 100644 --- a/ipa-server/ipa-gui/ipagui/static/css/style.css +++ b/ipa-server/ipa-gui/ipagui/static/css/style.css @@ -129,7 +129,7 @@ body { #status_block { margin: 0 auto 0.5em auto; padding: 15px 10px 15px 55px; - background: #cec URL('../images/ok.png') left center no-repeat; + background: #cec; border: 1px solid #9c9; width: 450px; font-size: 120%; diff --git a/ipa-server/ipa-gui/ipagui/templates/userlist.kid b/ipa-server/ipa-gui/ipagui/templates/userlist.kid index 1b4a1201..c3b53272 100644 --- a/ipa-server/ipa-gui/ipagui/templates/userlist.kid +++ b/ipa-server/ipa-gui/ipagui/templates/userlist.kid @@ -8,13 +8,13 @@
-

Results

+

${len(users)} results returned:

diff --git a/ipa-server/ipaserver/ipaldap.py b/ipa-server/ipaserver/ipaldap.py index f626f2f3..4d0630ee 100644 --- a/ipa-server/ipaserver/ipaldap.py +++ b/ipa-server/ipaserver/ipaldap.py @@ -300,6 +300,44 @@ class IPAdmin(SimpleLDAPObject): return all_users + def getListAsync(self,*args): + """This version performs an asynchronous search, to allow + results even if we hit a limit. + + It returns a list: counter followed by the results. + If the results are truncated, counter will be set to -1. + """ + + sctrl = self.__get_server_controls__() + if sctrl is not None: + self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl) + + entries = [] + partial = 0 + + try: + msgid = self.search_ext(*args) + type, result_list = self.result(msgid, 0) + while result_list: + for result in result_list: + entries.append(result) + type, result_list = self.result(msgid, 0) + except (ldap.ADMINLIMIT_EXCEEDED, ldap.SIZELIMIT_EXCEEDED), e: + partial = 1 + except ldap.LDAPError, e: + raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e) + + if not entries: + raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, + "no such entry for " + str(args)) + + if partial == 1: + counter = -1 + else: + counter = len(entries) + + return [counter] + entries + def addEntry(self,*args): """This wraps the add function. It assumes that the entry is already populated with all of the desired objectclasses and attributes""" diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py index a0af41d4..fd95470b 100644 --- a/ipa-server/xmlrpc-server/funcs.py +++ b/ipa-server/xmlrpc-server/funcs.py @@ -372,9 +372,8 @@ class IPAServer: return users def find_users (self, criteria, sattrs=None, opts=None): - """Return a list containing a User object for each - existing user that matches the criteria. - """ + """Returns a list: counter followed by the results. + If the results are truncated, counter will be set to -1.""" global _LDAPPool if opts: @@ -400,25 +399,36 @@ class IPAServer: m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn) try: try: - exact_results = m1.getList(self.basedn, self.scope, + exact_results = m1.getListAsync(self.basedn, self.scope, exact_match_filter, sattrs) except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - exact_results = [] + exact_results = [0] try: - partial_results = m1.getList(self.basedn, self.scope, + partial_results = m1.getListAsync(self.basedn, self.scope, partial_match_filter, sattrs) except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - partial_results = [] + partial_results = [0] finally: _LDAPPool.releaseConn(m1) + exact_counter = exact_results[0] + partial_counter = partial_results[0] + + exact_results = exact_results[1:] + partial_results = partial_results[1:] + # Remove exact matches from the partial_match list exact_dns = set(map(lambda e: e.dn, exact_results)) partial_results = filter(lambda e: e.dn not in exact_dns, partial_results) - users = [] + if (exact_counter == -1) or (partial_counter == -1): + counter = -1 + else: + counter = len(exact_results) + len(partial_results) + + users = [counter] for u in exact_results + partial_results: users.append(self.convert_entry(u)) -- cgit From 50450d6acb6f79f46aec531a8d8832a45e77ddee Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Wed, 29 Aug 2007 16:49:46 -0700 Subject: UI cleanup --- ipa-server/ipa-gui/ipagui/controllers.py | 4 +- ipa-server/ipa-gui/ipagui/static/css/style.css | 74 ++++++++++++---------- ipa-server/ipa-gui/ipagui/templates/groupindex.kid | 7 -- .../ipa-gui/ipagui/templates/grouplayout.kid | 7 +- ipa-server/ipa-gui/ipagui/templates/master.kid | 27 +++++--- ipa-server/ipa-gui/ipagui/templates/resindex.kid | 18 ------ ipa-server/ipa-gui/ipagui/templates/reslayout.kid | 22 ------- ipa-server/ipa-gui/ipagui/templates/useredit.kid | 4 +- ipa-server/ipa-gui/ipagui/templates/userlayout.kid | 7 +- ipa-server/ipa-gui/ipagui/templates/userlist.kid | 15 ++--- ipa-server/ipa-gui/ipagui/templates/usernew.kid | 4 +- ipa-server/ipa-gui/ipagui/templates/usershow.kid | 4 +- ipa-server/ipa-gui/ipagui/templates/welcome.kid | 6 +- 13 files changed, 86 insertions(+), 113 deletions(-) delete mode 100644 ipa-server/ipa-gui/ipagui/templates/resindex.kid delete mode 100644 ipa-server/ipa-gui/ipagui/templates/reslayout.kid diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py index ebd0b20d..d767f268 100644 --- a/ipa-server/ipa-gui/ipagui/controllers.py +++ b/ipa-server/ipa-gui/ipagui/controllers.py @@ -148,13 +148,13 @@ class Root(controllers.RootController): counter = users[0] users = users[1:] if counter == -1: - turbogears.flash("These results are truncated.\n" + + turbogears.flash("These results are truncated.
" + "Please refine your search and try again.") except ipaerror.IPAError, e: turbogears.flash("User list failed: " + str(e)) raise turbogears.redirect("/userlist") - return dict(users=users, fields=forms.user.UserFields()) + return dict(users=users, uid=uid, fields=forms.user.UserFields()) @expose("ipagui.templates.usershow") diff --git a/ipa-server/ipa-gui/ipagui/static/css/style.css b/ipa-server/ipa-gui/ipagui/static/css/style.css index 152175e1..3c260c21 100644 --- a/ipa-server/ipa-gui/ipagui/static/css/style.css +++ b/ipa-server/ipa-gui/ipagui/static/css/style.css @@ -33,7 +33,8 @@ body { #nav { background:#cc0000; color:#fff; - padding:5px; + min-height:3px; + max-height:3px; } #nav ul { @@ -58,15 +59,14 @@ body { background:#fff; float:right; width:85%; + min-height:500px; border-left: 1px solid #000; - padding-left: 15px; - padding-bottom: 15px; -/* color: black; - font-size: 127%; - background-color: white; - margin: 0 auto 0 auto; padding: 10px; - float: left; */ +} + +#main_content h1,h2 { + margin-top: 0px; + margin-bottom: 5px; } @@ -74,12 +74,8 @@ body { background:#ccc; /* should be same as #page */ float:left; width:10%; - /* border: 1px solid #aaa; - background-color: #eee; - margin: 0.5em; - padding: 1em; - float: left; - font-size: 88%; */ + padding: 5px; + font-size: small; } #sidebar h2 { @@ -91,17 +87,25 @@ body { padding-left: 0; } +#sidebar a:visited, +#sidebar a:link { + color:#000; +} + #footer { background:#fff; clear:both; border-top: 1px solid #000; - /* color: #999; - background-color: white; - padding: 10px; - font-size: 80%; + padding-top: 10px; text-align: center; - margin: 0 auto 1em auto; */ + font-size: x-small; +} + +#footer a:visited, +#footer a:link { + color:#777; + text-decoration: none; } @@ -129,26 +133,32 @@ body { #status_block { margin: 0 auto 0.5em auto; padding: 15px 10px 15px 55px; - background: #cec; - border: 1px solid #9c9; + background: #ecc; + border: 1px solid #c99; width: 450px; font-size: 120%; font-weight: bolder; } -.notice { - margin: 0.5em auto 0.5em auto; - padding: 15px 10px 15px 55px; - width: 450px; - background: #eef URL('../images/info.png') left center no-repeat; - border: 1px solid #cce; -} - .fielderror { - color: red; - font-weight: bold; + color: red; + font-weight: bold; } .requiredfield { - background: #eebbbb; + background: #eebbbb; +} + +#resultstable, +#resultstable th, +#resultstable td { + border-collapse: collapse; + border-style: solid; + border-width: 1px; + margin: 0px; + padding: 5px; +} + +#resultstable th { + background: #eee; } diff --git a/ipa-server/ipa-gui/ipagui/templates/groupindex.kid b/ipa-server/ipa-gui/ipagui/templates/groupindex.kid index 0bb70ac9..84a13846 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupindex.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupindex.kid @@ -7,12 +7,5 @@ Groups go here. -
-
-
-
-
-
-
diff --git a/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid b/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid index af05a808..edaf716e 100644 --- a/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid +++ b/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid @@ -6,17 +6,18 @@
-
+
-