diff options
author | Kevin McCarthy <kmccarth@redhat.com> | 2007-10-04 17:10:18 -0700 |
---|---|---|
committer | Kevin McCarthy <kmccarth@redhat.com> | 2007-10-04 17:10:18 -0700 |
commit | d5fedb5f978d7aaa31db9c177286872c6244c12a (patch) | |
tree | f21c78c2ab442d1001f4dcc1e45517bbdb1e64cb /ipa-server/ipa-gui | |
parent | 6f7c918e5922afd3461514ddd58b41c5b86e9691 (diff) | |
download | freeipa-d5fedb5f978d7aaa31db9c177286872c6244c12a.tar.gz freeipa-d5fedb5f978d7aaa31db9c177286872c6244c12a.tar.xz freeipa-d5fedb5f978d7aaa31db9c177286872c6244c12a.zip |
Split the controllers out into separate user and group controllers.
Diffstat (limited to 'ipa-server/ipa-gui')
20 files changed, 1021 insertions, 975 deletions
diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py index 92b131d4..340d6f9f 100644 --- a/ipa-server/ipa-gui/ipagui/controllers.py +++ b/ipa-server/ipa-gui/ipagui/controllers.py @@ -1,9 +1,3 @@ -import random -from pickle import dumps, loads -from base64 import b64encode, b64decode -import re - -import os import cherrypy import turbogears from turbogears import controllers, expose, flash @@ -17,79 +11,15 @@ from turbogears import identity import ipa.config import ipa.ipaclient -import ipa.user -from ipa.entity import utf8_encode_values -import xmlrpclib -import forms.user -import forms.group -from helpers import userhelper -from ipa import ipaerror - -ipa.config.init_config() -user_new_form = forms.user.UserNewForm() -user_edit_form = forms.user.UserEditForm() -group_new_form = forms.group.GroupNewForm() -group_edit_form = forms.group.GroupEditForm() - -password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - -client = ipa.ipaclient.IPAClient(True) - -user_fields = ['*', 'nsAccountLock'] -group_fields = ['*'] - -def restrict_post(): - if cherrypy.request.method != "POST": - turbogears.flash("This method only accepts posts") - raise turbogears.redirect("/") - -def utf8_encode(value): - if value != None: - value = value.encode('utf-8') - return value - -def sort_group_member(a, b): - """Comparator function used for sorting group members.""" - if a.getValue('uid') and b.getValue('uid'): - if a.getValue('givenname') == b.getValue('givenname'): - if a.getValue('sn') == b.getValue('sn'): - if a.getValue('uid') == b.getValue('uid'): - return 0 - elif a.getValue('uid') < b.getValue('uid'): - return -1 - else: - return 1 - elif a.getValue('sn') < b.getValue('sn'): - return -1 - else: - return 1 - elif a.getValue('givenname') < b.getValue('givenname'): - return -1 - else: - return 1 - elif a.getValue('uid'): - return -1 - elif b.getValue('uid'): - return 1 - else: - if a.getValue('cn') == b.getValue('cn'): - return 0 - elif a.getValue('cn') < b.getValue('cn'): - return -1 - else: - return 1 +from subcontrollers.user import UserController +from subcontrollers.group import GroupController -def sort_by_cn(a, b): - """Comparator function used for sorting groups.""" - if a.getValue('cn') == b.getValue('cn'): - return 0 - elif a.getValue('cn') < b.getValue('cn'): - return -1 - else: - return 1 +ipa.config.init_config() class Root(controllers.RootController): + user = UserController() + group = GroupController() @expose(template="ipagui.templates.welcome") @identity.require(identity.not_anonymous()) @@ -100,875 +30,9 @@ class Root(controllers.RootController): @identity.require(identity.not_anonymous()) def topsearch(self, **kw): if kw.get('searchtype') == "Users": - return self.userlist(uid=kw.get('searchvalue')) + return Root.user.list(uid=kw.get('searchvalue')) else: - return self.grouplist(criteria=kw.get('searchvalue')) - - - - ######## - # User # - ######## - - @expose("ipagui.templates.usernew") - @identity.require(identity.not_anonymous()) - def usernew(self, tg_errors=None): - """Displays the new user form""" - if tg_errors: - turbogears.flash("There was a problem with the form!") - - return dict(form=user_new_form, user={}) - - @expose() - @identity.require(identity.not_anonymous()) - def usercreate(self, **kw): - """Creates a new user""" - restrict_post() - client.set_krbccache(os.environ["KRB5CCNAME"]) - if kw.get('submit') == 'Cancel': - turbogears.flash("Add user cancelled") - raise turbogears.redirect('/userlist') - - tg_errors, kw = self.usercreatevalidate(**kw) - if tg_errors: - return dict(form=user_new_form, user=kw, - tg_template='ipagui.templates.usernew') - - # - # Create the user itself - # - try: - new_user = ipa.user.User() - new_user.setValue('title', kw.get('title')) - new_user.setValue('givenname', kw.get('givenname')) - new_user.setValue('sn', kw.get('sn')) - new_user.setValue('cn', kw.get('cn')) - new_user.setValue('displayname', kw.get('displayname')) - new_user.setValue('initials', kw.get('initials')) - - new_user.setValue('uid', kw.get('uid')) - new_user.setValue('loginshell', kw.get('loginshell')) - new_user.setValue('gecos', kw.get('gecos')) - - new_user.setValue('mail', kw.get('mail')) - new_user.setValue('telephonenumber', kw.get('telephonenumber')) - new_user.setValue('facsimiletelephonenumber', - kw.get('facsimiletelephonenumber')) - new_user.setValue('mobile', kw.get('mobile')) - new_user.setValue('pager', kw.get('pager')) - new_user.setValue('homephone', kw.get('homephone')) - - new_user.setValue('street', kw.get('street')) - new_user.setValue('l', kw.get('l')) - new_user.setValue('st', kw.get('st')) - new_user.setValue('postalcode', kw.get('postalcode')) - - new_user.setValue('ou', kw.get('ou')) - new_user.setValue('businesscategory', kw.get('businesscategory')) - new_user.setValue('description', kw.get('description')) - new_user.setValue('employeetype', kw.get('employeetype')) - # new_user.setValue('manager', kw.get('manager')) - new_user.setValue('roomnumber', kw.get('roomnumber')) - # new_user.setValue('secretary', kw.get('secretary')) - - new_user.setValue('carlicense', kw.get('carlicense')) - new_user.setValue('labeleduri', kw.get('labeleduri')) - - if kw.get('nsAccountLock'): - new_user.setValue('nsAccountLock', 'true') - - rv = client.add_user(new_user) - except ipaerror.exception_for(ipaerror.LDAP_DUPLICATE): - turbogears.flash("Person with login '%s' already exists" % - kw.get('uid')) - return dict(form=user_new_form, user=kw, - tg_template='ipagui.templates.usernew') - except ipaerror.IPAError, e: - turbogears.flash("User add failed: " + str(e)) - return dict(form=user_new_form, user=kw, - tg_template='ipagui.templates.usernew') - - # - # NOTE: from here on, the user account now exists. - # on any error, we redirect to the _edit_ user page. - # this code does data setup, similar to useredit() - # - user = client.get_user_by_uid(kw['uid'], user_fields) - user_dict = user.toDict() - - user_groups_dicts = [] - user_groups_data = b64encode(dumps(user_groups_dicts)) - - # store a copy of the original user for the update later - user_data = b64encode(dumps(user_dict)) - user_dict['user_orig'] = user_data - user_dict['user_groups_data'] = user_groups_data - - # preserve group add info in case of errors - user_dict['dnadd'] = kw.get('dnadd') - user_dict['dn_to_info_json'] = kw.get('dn_to_info_json') - - # - # Password change - # TODO - # - - # - # Add groups - # - failed_adds = [] - try: - dnadds = kw.get('dnadd') - if dnadds != None: - if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)): - dnadds = [dnadds] - failed_adds = client.add_groups_to_user( - utf8_encode_values(dnadds), user.dn) - kw['dnadd'] = failed_adds - except ipaerror.IPAError, e: - failed_adds = dnadds - - if len(failed_adds) > 0: - message = "Person successfully created.<br />" - message += "There was an error adding groups.<br />" - message += "Failures have been preserved in the add/remove lists." - turbogears.flash(message) - return dict(form=user_edit_form, user=user_dict, - user_groups=user_groups_dicts, - tg_template='ipagui.templates.useredit') - - turbogears.flash("%s added!" % kw['uid']) - raise turbogears.redirect('/usershow', uid=kw['uid']) - - @expose("ipagui.templates.dynamiceditsearch") - @identity.require(identity.not_anonymous()) - def useredit_search(self, **kw): - """Searches for groups and displays list of results in a table. - This method is used for the ajax search on the user edit page.""" - client.set_krbccache(os.environ["KRB5CCNAME"]) - groups = [] - groups_counter = 0 - searchlimit = 100 - criteria = kw.get('criteria') - if criteria != None and len(criteria) > 0: - try: - groups = client.find_groups(criteria.encode('utf-8'), None, - searchlimit) - groups_counter = groups[0] - groups = groups[1:] - except ipaerror.IPAError, e: - turbogears.flash("search failed: " + str(e)) - - return dict(users=None, groups=groups, criteria=criteria, - counter=groups_counter) - - - @expose("ipagui.templates.useredit") - @identity.require(identity.not_anonymous()) - def useredit(self, uid, tg_errors=None): - """Displays the edit user form""" - if tg_errors: - turbogears.flash("There was a problem with the form!") - - client.set_krbccache(os.environ["KRB5CCNAME"]) - try: - user = client.get_user_by_uid(uid, user_fields) - user_dict = user.toDict() - # Edit shouldn't fill in the password field. - if user_dict.has_key('userpassword'): - del(user_dict['userpassword']) - - user_groups = client.get_groups_by_member(user.dn, ['dn', 'cn']) - user_groups.sort(sort_by_cn) - user_groups_dicts = map(lambda group: group.toDict(), user_groups) - user_groups_data = b64encode(dumps(user_groups_dicts)) - - # store a copy of the original user for the update later - user_data = b64encode(dumps(user_dict)) - user_dict['user_orig'] = user_data - user_dict['user_groups_data'] = user_groups_data - - return dict(form=user_edit_form, user=user_dict, - user_groups=user_groups_dicts) - except ipaerror.IPAError, e: - turbogears.flash("User edit failed: " + str(e)) - raise turbogears.redirect('/usershow', uid=kw.get('uid')) - - @expose() - @identity.require(identity.not_anonymous()) - def userupdate(self, **kw): - """Updates an existing user""" - restrict_post() - client.set_krbccache(os.environ["KRB5CCNAME"]) - if kw.get('submit') == 'Cancel Edit': - turbogears.flash("Edit user cancelled") - raise turbogears.redirect('/usershow', uid=kw.get('uid')) - - # Decode the group data, in case we need to round trip - user_groups_dicts = loads(b64decode(kw.get('user_groups_data'))) - - tg_errors, kw = self.userupdatevalidate(**kw) - if tg_errors: - return dict(form=user_edit_form, user=kw, - user_groups=user_groups_dicts, - tg_template='ipagui.templates.useredit') - - password_change = False - user_modified = False - - # - # Update the user itself - # - try: - orig_user_dict = loads(b64decode(kw.get('user_orig'))) - - new_user = ipa.user.User(orig_user_dict) - new_user.setValue('title', kw.get('title')) - new_user.setValue('givenname', kw.get('givenname')) - new_user.setValue('sn', kw.get('sn')) - new_user.setValue('cn', kw.get('cn')) - new_user.setValue('displayname', kw.get('displayname')) - new_user.setValue('initials', kw.get('initials')) - - new_user.setValue('loginshell', kw.get('loginshell')) - new_user.setValue('gecos', kw.get('gecos')) - - new_user.setValue('mail', kw.get('mail')) - new_user.setValue('telephonenumber', kw.get('telephonenumber')) - new_user.setValue('facsimiletelephonenumber', - kw.get('facsimiletelephonenumber')) - new_user.setValue('mobile', kw.get('mobile')) - new_user.setValue('pager', kw.get('pager')) - new_user.setValue('homephone', kw.get('homephone')) - - new_user.setValue('street', kw.get('street')) - new_user.setValue('l', kw.get('l')) - new_user.setValue('st', kw.get('st')) - new_user.setValue('postalcode', kw.get('postalcode')) - - new_user.setValue('ou', kw.get('ou')) - new_user.setValue('businesscategory', kw.get('businesscategory')) - new_user.setValue('description', kw.get('description')) - new_user.setValue('employeetype', kw.get('employeetype')) - # new_user.setValue('manager', kw.get('manager')) - new_user.setValue('roomnumber', kw.get('roomnumber')) - # new_user.setValue('secretary', kw.get('secretary')) - - new_user.setValue('carlicense', kw.get('carlicense')) - new_user.setValue('labeleduri', kw.get('labeleduri')) - - - if kw.get('nsAccountLock'): - new_user.setValue('nsAccountLock', 'true') - else: - new_user.setValue('nsAccountLock', None) - if kw.get('editprotected') == 'true': - if kw.get('userpassword'): - password_change = True - new_user.setValue('uidnumber', str(kw.get('uidnumber'))) - new_user.setValue('gidnumber', str(kw.get('gidnumber'))) - new_user.setValue('homedirectory', str(kw.get('homedirectory'))) - - rv = client.update_user(new_user) - # - # If the user update succeeds, but below operations fail, we - # need to make sure a subsequent submit doesn't try to update - # the user again. - # - user_modified = True - kw['user_orig'] = b64encode(dumps(new_user.toDict())) - except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST), e: - # could be a password change - # could be groups change - # too much work to figure out unless someone really screams - pass - except ipaerror.IPAError, e: - turbogears.flash("User update failed: " + str(e)) - return dict(form=user_edit_form, user=kw, - user_groups=user_groups_dicts, - tg_template='ipagui.templates.useredit') - - # - # Password change - # - try: - if password_change: - rv = client.modifyPassword(kw['krbprincipalname'], "", kw.get('userpassword')) - except ipaerror.IPAError, e: - turbogears.flash("User password change failed: " + str(e)) - return dict(form=user_edit_form, user=kw, - user_groups=user_groups_dicts, - tg_template='ipagui.templates.useredit') - - # - # Add groups - # - failed_adds = [] - try: - dnadds = kw.get('dnadd') - if dnadds != None: - if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)): - dnadds = [dnadds] - failed_adds = client.add_groups_to_user( - utf8_encode_values(dnadds), new_user.dn) - kw['dnadd'] = failed_adds - except ipaerror.IPAError, e: - failed_adds = dnadds - - # - # Remove groups - # - failed_dels = [] - try: - dndels = kw.get('dndel') - if dndels != None: - if not(isinstance(dndels,list) or isinstance(dndels,tuple)): - dndels = [dndels] - failed_dels = client.remove_groups_from_user( - utf8_encode_values(dndels), new_user.dn) - kw['dndel'] = failed_dels - except ipaerror.IPAError, e: - failed_dels = dndels - - if (len(failed_adds) > 0) or (len(failed_dels) > 0): - message = "There was an error updating groups.<br />" - message += "Failures have been preserved in the add/remove lists." - if user_modified: - message = "User Details successfully updated.<br />" + message - if password_change: - message = "User password successfully updated.<br />" + message - turbogears.flash(message) - return dict(form=user_edit_form, user=kw, - user_groups=user_groups_dicts, - tg_template='ipagui.templates.useredit') - - turbogears.flash("%s updated!" % kw['uid']) - raise turbogears.redirect('/usershow', uid=kw['uid']) - - - @expose("ipagui.templates.userlist") - @identity.require(identity.not_anonymous()) - def userlist(self, **kw): - """Searches for users and displays list of results""" - client.set_krbccache(os.environ["KRB5CCNAME"]) - users = None - counter = 0 - uid = kw.get('uid') - if uid != None and len(uid) > 0: - try: - users = client.find_users(uid.encode('utf-8'), None, 0, 2) - counter = users[0] - users = users[1:] - if counter == -1: - turbogears.flash("These results are truncated.<br />" + - "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, uid=uid, fields=forms.user.UserFields()) - - - @expose("ipagui.templates.usershow") - @identity.require(identity.not_anonymous()) - def usershow(self, uid): - """Retrieve a single user for display""" - client.set_krbccache(os.environ["KRB5CCNAME"]) - try: - user = client.get_user_by_uid(uid, user_fields) - user_groups = client.get_groups_by_member(user.dn, ['cn']) - user_groups.sort(sort_by_cn) - user_reports = client.get_users_by_manager(user.dn, - ['givenname', 'sn', 'uid']) - user_reports.sort(sort_group_member) - - user_manager = None - try: - if user.manager: - user_manager = client.get_user_by_dn(user.manager, - ['givenname', 'sn', 'uid']) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - pass - - return dict(user=user.toDict(), fields=forms.user.UserFields(), - user_groups=user_groups, user_reports=user_reports, - user_manager=user_manager) - except ipaerror.IPAError, e: - turbogears.flash("User show failed: " + str(e)) - raise turbogears.redirect("/") - - @validate(form=user_new_form) - @identity.require(identity.not_anonymous()) - def usercreatevalidate(self, tg_errors=None, **kw): - return tg_errors, kw - - @validate(form=user_edit_form) - @identity.require(identity.not_anonymous()) - def userupdatevalidate(self, tg_errors=None, **kw): - return tg_errors, kw - - @expose() - def userindex(self): - raise turbogears.redirect("/userlist") - - # @expose() - def generate_password(self): - password = "" - generator = random.SystemRandom() - for char in range(8): - index = generator.randint(0, len(password_chars) - 1) - password += password_chars[index] - - return password - - @expose() - @identity.require(identity.not_anonymous()) - def suggest_uid(self, givenname, sn): - # filter illegal uid characters out - givenname = re.sub(r'[^a-zA-Z_\-0-9]', "", givenname) - sn = re.sub(r'[^a-zA-Z_\-0-9]', "", sn) - - if (len(givenname) == 0) or (len(sn) == 0): - return "" - - client.set_krbccache(os.environ["KRB5CCNAME"]) - givenname = givenname.lower() - sn = sn.lower() - - uid = givenname[0] + sn[:7] - try: - client.get_user_by_uid(uid) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - return uid - - uid = givenname[:7] + sn[0] - try: - client.get_user_by_uid(uid) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - return uid - - uid = (givenname + sn)[:8] - try: - client.get_user_by_uid(uid) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - return uid - - uid = sn[:8] - try: - client.get_user_by_uid(uid) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - return uid - - suffix = 2 - template = givenname[0] + sn[:7] - while suffix < 20: - uid = template[:8 - len(str(suffix))] + str(suffix) - try: - client.get_user_by_uid(uid) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - return uid - suffix += 1 - - return "" - - @expose() - @identity.require(identity.not_anonymous()) - def suggest_email(self, givenname, sn): - # remove illegal email characters - givenname = re.sub(r'[^a-zA-Z0-9!#\$%\*/?\|\^\{\}`~&\'\+\-=_]', "", givenname) - sn = re.sub(r'[^a-zA-Z0-9!#\$%\*/?\|\^\{\}`~&\'\+\-=_]', "", sn) - - if (len(givenname) == 0) or (len(sn) == 0): - return "" - - client.set_krbccache(os.environ["KRB5CCNAME"]) - givenname = givenname.lower() - sn = sn.lower() - - # TODO - get from config - domain = "freeipa.org" - - return "%s.%s@%s" % (givenname, sn, domain) - - - # TODO - mail is currently not indexed nor searchable. - # implement when it's done - # email = givenname + "." + sn + domain - # users = client.find_users(email, ['mail']) - # if len(filter(lambda u: u['mail'] == email, users[1:])) == 0: - # return email - - # email = self.suggest_uid(givenname, sn) + domain - # users = client.find_users(email, ['mail']) - # if len(filter(lambda u: u['mail'] == email, users[1:])) == 0: - # return email - - # suffix = 2 - # template = givenname + "." + sn - # while suffix < 20: - # email = template + str(suffix) + domain - # users = client.find_users(email, ['mail']) - # if len(filter(lambda u: u['mail'] == email, users[1:])) == 0: - # return email - # suffix += 1 - - # return "" - - - - ######### - # Group # - ######### - - @expose("ipagui.templates.groupindex") - @identity.require(identity.not_anonymous()) - def groupindex(self, tg_errors=None): - client.set_krbccache(os.environ["KRB5CCNAME"]) - return dict() - - @expose("ipagui.templates.groupnew") - @identity.require(identity.not_anonymous()) - def groupnew(self, tg_errors=None): - """Displays the new group form""" - if tg_errors: - turbogears.flash("There was a problem with the form!") - - client.set_krbccache(os.environ["KRB5CCNAME"]) - - return dict(form=group_new_form, group={}) - - @expose() - @identity.require(identity.not_anonymous()) - def groupcreate(self, **kw): - """Creates a new group""" - restrict_post() - client.set_krbccache(os.environ["KRB5CCNAME"]) - - if kw.get('submit') == 'Cancel': - turbogears.flash("Add group cancelled") - raise turbogears.redirect('/') - - tg_errors, kw = self.groupcreatevalidate(**kw) - if tg_errors: - return dict(form=group_new_form, group=kw, - tg_template='ipagui.templates.groupnew') - - # - # Create the group itself - # - try: - new_group = ipa.group.Group() - new_group.setValue('cn', kw.get('cn')) - new_group.setValue('description', kw.get('description')) - - rv = client.add_group(new_group) - except ipaerror.exception_for(ipaerror.LDAP_DUPLICATE): - turbogears.flash("Group with name '%s' already exists" % - kw.get('cn')) - return dict(form=group_new_form, group=kw, - tg_template='ipagui.templates.groupnew') - except ipaerror.IPAError, e: - turbogears.flash("Group add failed: " + str(e) + "<br/>" + str(e.detail)) - return dict(form=group_new_form, group=kw, - tg_template='ipagui.templates.groupnew') - - # - # NOTE: from here on, the group now exists. - # on any error, we redirect to the _edit_ group page. - # this code does data setup, similar to groupedit() - # - group = client.get_group_by_cn(kw['cn'], group_fields) - group_dict = group.toDict() - member_dicts = [] - - # store a copy of the original group for the update later - group_data = b64encode(dumps(group_dict)) - member_data = b64encode(dumps(member_dicts)) - group_dict['group_orig'] = group_data - group_dict['member_data'] = member_data - - # preserve group add info in case of errors - group_dict['dnadd'] = kw.get('dnadd') - group_dict['dn_to_info_json'] = kw.get('dn_to_info_json') - - # - # Add members - # - failed_adds = [] - try: - dnadds = kw.get('dnadd') - if dnadds != None: - if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)): - dnadds = [dnadds] - failed_adds = client.add_members_to_group( - utf8_encode_values(dnadds), group.dn) - kw['dnadd'] = failed_adds - except ipaerror.IPAError, e: - failed_adds = dnadds - - if len(failed_adds) > 0: - message = "Group successfully created.<br />" - message += "There was an error adding group members.<br />" - message += "Failures have been preserved in the add/remove lists." - turbogears.flash(message) - return dict(form=group_edit_form, group=group_dict, - members=member_dicts, - tg_template='ipagui.templates.groupedit') - - turbogears.flash("%s added!" % kw.get('cn')) - raise turbogears.redirect('/groupshow', cn=kw.get('cn')) - - @expose("ipagui.templates.dynamiceditsearch") - @identity.require(identity.not_anonymous()) - def groupedit_search(self, **kw): - """Searches for users+groups and displays list of results in a table. - This method is used for the ajax search on the group edit page.""" - client.set_krbccache(os.environ["KRB5CCNAME"]) - users = [] - groups = [] - counter = 0 - searchlimit = 100 - criteria = kw.get('criteria') - if criteria != None and len(criteria) > 0: - try: - users = client.find_users(criteria.encode('utf-8'), None, searchlimit) - users_counter = users[0] - users = users[1:] - - groups = client.find_groups(criteria.encode('utf-8'), None, - searchlimit) - groups_counter = groups[0] - groups = groups[1:] - - if users_counter < 0 or groups_counter < 0: - counter = -1 - else: - counter = users_counter + groups_counter - except ipaerror.IPAError, e: - turbogears.flash("search failed: " + str(e)) - - return dict(users=users, groups=groups, criteria=criteria, - counter=counter) - - - @expose("ipagui.templates.groupedit") - @identity.require(identity.not_anonymous()) - def groupedit(self, cn, tg_errors=None): - """Displays the edit group form""" - if tg_errors: - turbogears.flash("There was a problem with the form!") - - client.set_krbccache(os.environ["KRB5CCNAME"]) - try: - group = client.get_group_by_cn(cn, group_fields) - - group_dict = group.toDict() - - # - # convert members to users, for easier manipulation on the page - # - member_dns = [] - if group_dict.has_key('uniquemember'): - member_dns = group_dict.get('uniquemember') - # remove from dict - it's not needed for update - # and we are storing the members in a different form - del group_dict['uniquemember'] - if not(isinstance(member_dns,list) or isinstance(member_dns,tuple)): - member_dns = [member_dns] - - # TODO: convert this into an efficient (single) function call - # Note: this isn't quite right, since it can be users and groups. - members = map( - lambda dn: client.get_user_by_dn(dn, ['dn', 'givenname', 'sn', - 'uid', 'cn']), - member_dns) - members.sort(sort_group_member) - - # Map users into an array of dicts, which can be serialized - # (so we don't have to do this on each round trip) - member_dicts = map(lambda member: member.toDict(), members) - - # store a copy of the original group for the update later - group_data = b64encode(dumps(group_dict)) - member_data = b64encode(dumps(member_dicts)) - group_dict['group_orig'] = group_data - group_dict['member_data'] = member_data - - return dict(form=group_edit_form, group=group_dict, members=member_dicts) - except ipaerror.IPAError, e: - turbogears.flash("Group edit failed: " + str(e)) - raise turbogears.redirect('/groupshow', uid=cn) - - @expose() - @identity.require(identity.not_anonymous()) - def groupupdate(self, **kw): - """Updates an existing group""" - restrict_post() - client.set_krbccache(os.environ["KRB5CCNAME"]) - if kw.get('submit') == 'Cancel Edit': - turbogears.flash("Edit group cancelled") - raise turbogears.redirect('/groupshow', cn=kw.get('cn')) - - # Decode the member data, in case we need to round trip - member_dicts = loads(b64decode(kw.get('member_data'))) - - - tg_errors, kw = self.groupupdatevalidate(**kw) - if tg_errors: - return dict(form=group_edit_form, group=kw, members=member_dicts, - tg_template='ipagui.templates.groupedit') - - group_modified = False - - # - # Update group itself - # - try: - orig_group_dict = loads(b64decode(kw.get('group_orig'))) - - new_group = ipa.group.Group(orig_group_dict) - if new_group.description != kw.get('description'): - group_modified = True - new_group.setValue('description', kw.get('description')) - if kw.get('editprotected') == 'true': - new_gid = str(kw.get('gidnumber')) - if new_group.gidnumber != new_gid: - group_modified = True - new_group.setValue('gidnumber', new_gid) - - if group_modified: - rv = client.update_group(new_group) - # - # If the group update succeeds, but below operations fail, we - # need to make sure a subsequent submit doesn't try to update - # the group again. - # - kw['group_orig'] = b64encode(dumps(new_group.toDict())) - except ipaerror.IPAError, e: - turbogears.flash("Group update failed: " + str(e)) - return dict(form=group_edit_form, group=kw, members=member_dicts, - tg_template='ipagui.templates.groupedit') - - # - # Add members - # - failed_adds = [] - try: - dnadds = kw.get('dnadd') - if dnadds != None: - if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)): - dnadds = [dnadds] - failed_adds = client.add_members_to_group( - utf8_encode_values(dnadds), new_group.dn) - kw['dnadd'] = failed_adds - except ipaerror.IPAError, e: - turbogears.flash("Group update failed: " + str(e)) - return dict(form=group_edit_form, group=kw, members=member_dicts, - tg_template='ipagui.templates.groupedit') - - # - # Remove members - # - failed_dels = [] - try: - dndels = kw.get('dndel') - if dndels != None: - if not(isinstance(dndels,list) or isinstance(dndels,tuple)): - dndels = [dndels] - failed_dels = client.remove_members_from_group( - utf8_encode_values(dndels), new_group.dn) - kw['dndel'] = failed_dels - except ipaerror.IPAError, e: - turbogears.flash("Group update failed: " + str(e)) - return dict(form=group_edit_form, group=kw, members=member_dicts, - tg_template='ipagui.templates.groupedit') - - # - # TODO - check failed ops to see if it's because of another update. - # handle "someone else already did it" errors better - perhaps - # not even as an error - # TODO - update the Group Members list. - # (note that we have to handle the above todo first, or else - # there will be an error message, but the add/del lists will - # be empty) - # - if (len(failed_adds) > 0) or (len(failed_dels) > 0): - message = "There was an error updating group members.<br />" - message += "Failures have been preserved in the add/remove lists." - if group_modified: - message = "Group Details successfully updated.<br />" + message - turbogears.flash(message) - return dict(form=group_edit_form, group=kw, members=member_dicts, - tg_template='ipagui.templates.groupedit') - - turbogears.flash("%s updated!" % kw['cn']) - raise turbogears.redirect('/groupshow', cn=kw['cn']) - - - @expose("ipagui.templates.grouplist") - @identity.require(identity.not_anonymous()) - def grouplist(self, **kw): - """Search for groups and display results""" - client.set_krbccache(os.environ["KRB5CCNAME"]) - groups = None - # counter = 0 - criteria = kw.get('criteria') - if criteria != None and len(criteria) > 0: - try: - groups = client.find_groups(criteria.encode('utf-8'), None, 0, 2) - counter = groups[0] - groups = groups[1:] - if counter == -1: - turbogears.flash("These results are truncated.<br />" + - "Please refine your search and try again.") - except ipaerror.IPAError, e: - turbogears.flash("Find groups failed: " + str(e)) - raise turbogears.redirect("/grouplist") - - return dict(groups=groups, criteria=criteria, fields=forms.group.GroupFields()) - - @expose("ipagui.templates.groupshow") - @identity.require(identity.not_anonymous()) - def groupshow(self, cn): - """Retrieve a single group for display""" - client.set_krbccache(os.environ["KRB5CCNAME"]) - try: - group = client.get_group_by_cn(cn, group_fields) - group_dict = group.toDict() - - # - # convert members to users, for display on the page - # - member_dns = [] - if group_dict.has_key('uniquemember'): - member_dns = group_dict.get('uniquemember') - if not(isinstance(member_dns,list) or isinstance(member_dns,tuple)): - member_dns = [member_dns] - - # TODO: convert this into an efficient (single) function call - # Note: this isn't quite right, since it can be users and groups. - members = map( - lambda dn: client.get_user_by_dn(dn, ['dn', 'givenname', 'sn', - 'uid', 'cn']), - member_dns) - members.sort(sort_group_member) - member_dicts = map(lambda member: member.toDict(), members) - - return dict(group=group_dict, fields=forms.group.GroupFields(), - members = member_dicts) - except ipaerror.IPAError, e: - turbogears.flash("Group show failed: " + str(e)) - raise turbogears.redirect("/") - - @validate(form=group_new_form) - @identity.require(identity.not_anonymous()) - def groupcreatevalidate(self, tg_errors=None, **kw): - return tg_errors, kw - - @validate(form=group_edit_form) - @identity.require(identity.not_anonymous()) - def groupupdatevalidate(self, tg_errors=None, **kw): - return tg_errors, kw + return Root.group.list(criteria=kw.get('searchvalue')) @expose("ipagui.templates.loginfailed") def loginfailed(self, **kw): diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/__init__.py b/ipa-server/ipa-gui/ipagui/subcontrollers/__init__.py new file mode 100644 index 00000000..143f486c --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/subcontrollers/__init__.py @@ -0,0 +1 @@ +# __init__.py diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py new file mode 100644 index 00000000..1be9d2f1 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py @@ -0,0 +1,386 @@ +import os +from pickle import dumps, loads +from base64 import b64encode, b64decode + +import cherrypy +import turbogears +from turbogears import controllers, expose, flash +from turbogears import validators, validate +from turbogears import widgets, paginate +from turbogears import error_handler +from turbogears import identity + +from ipacontroller import IPAController +import ipa.config +import ipa.ipaclient +import ipa.group +from ipa.entity import utf8_encode_values +from ipa import ipaerror +import ipagui.forms.group + +ipa.config.init_config() +client = ipa.ipaclient.IPAClient(True) + +group_new_form = ipagui.forms.group.GroupNewForm() +group_edit_form = ipagui.forms.group.GroupEditForm() + +group_fields = ['*'] + +class GroupController(IPAController): + + + ######### + # Group # + ######### + + @expose("ipagui.templates.groupindex") + @identity.require(identity.not_anonymous()) + def index(self, tg_errors=None): + client.set_krbccache(os.environ["KRB5CCNAME"]) + return dict() + + @expose("ipagui.templates.groupnew") + @identity.require(identity.not_anonymous()) + def new(self, tg_errors=None): + """Displays the new group form""" + if tg_errors: + turbogears.flash("There was a problem with the form!") + + client.set_krbccache(os.environ["KRB5CCNAME"]) + + return dict(form=group_new_form, group={}) + + @expose() + @identity.require(identity.not_anonymous()) + def create(self, **kw): + """Creates a new group""" + self.restrict_post() + client.set_krbccache(os.environ["KRB5CCNAME"]) + + if kw.get('submit') == 'Cancel': + turbogears.flash("Add group cancelled") + raise turbogears.redirect('/') + + tg_errors, kw = self.groupcreatevalidate(**kw) + if tg_errors: + return dict(form=group_new_form, group=kw, + tg_template='ipagui.templates.groupnew') + + # + # Create the group itself + # + try: + new_group = ipa.group.Group() + new_group.setValue('cn', kw.get('cn')) + new_group.setValue('description', kw.get('description')) + + rv = client.add_group(new_group) + except ipaerror.exception_for(ipaerror.LDAP_DUPLICATE): + turbogears.flash("Group with name '%s' already exists" % + kw.get('cn')) + return dict(form=group_new_form, group=kw, + tg_template='ipagui.templates.groupnew') + except ipaerror.IPAError, e: + turbogears.flash("Group add failed: " + str(e) + "<br/>" + str(e.detail)) + return dict(form=group_new_form, group=kw, + tg_template='ipagui.templates.groupnew') + + # + # NOTE: from here on, the group now exists. + # on any error, we redirect to the _edit_ group page. + # this code does data setup, similar to groupedit() + # + group = client.get_group_by_cn(kw['cn'], group_fields) + group_dict = group.toDict() + member_dicts = [] + + # store a copy of the original group for the update later + group_data = b64encode(dumps(group_dict)) + member_data = b64encode(dumps(member_dicts)) + group_dict['group_orig'] = group_data + group_dict['member_data'] = member_data + + # preserve group add info in case of errors + group_dict['dnadd'] = kw.get('dnadd') + group_dict['dn_to_info_json'] = kw.get('dn_to_info_json') + + # + # Add members + # + failed_adds = [] + try: + dnadds = kw.get('dnadd') + if dnadds != None: + if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)): + dnadds = [dnadds] + failed_adds = client.add_members_to_group( + utf8_encode_values(dnadds), group.dn) + kw['dnadd'] = failed_adds + except ipaerror.IPAError, e: + failed_adds = dnadds + + if len(failed_adds) > 0: + message = "Group successfully created.<br />" + message += "There was an error adding group members.<br />" + message += "Failures have been preserved in the add/remove lists." + turbogears.flash(message) + return dict(form=group_edit_form, group=group_dict, + members=member_dicts, + tg_template='ipagui.templates.groupedit') + + turbogears.flash("%s added!" % kw.get('cn')) + raise turbogears.redirect('/group/show', cn=kw.get('cn')) + + @expose("ipagui.templates.dynamiceditsearch") + @identity.require(identity.not_anonymous()) + def edit_search(self, **kw): + """Searches for users+groups and displays list of results in a table. + This method is used for the ajax search on the group edit page.""" + client.set_krbccache(os.environ["KRB5CCNAME"]) + users = [] + groups = [] + counter = 0 + searchlimit = 100 + criteria = kw.get('criteria') + if criteria != None and len(criteria) > 0: + try: + users = client.find_users(criteria.encode('utf-8'), None, searchlimit) + users_counter = users[0] + users = users[1:] + + groups = client.find_groups(criteria.encode('utf-8'), None, + searchlimit) + groups_counter = groups[0] + groups = groups[1:] + + if users_counter < 0 or groups_counter < 0: + counter = -1 + else: + counter = users_counter + groups_counter + except ipaerror.IPAError, e: + turbogears.flash("search failed: " + str(e)) + + return dict(users=users, groups=groups, criteria=criteria, + counter=counter) + + + @expose("ipagui.templates.groupedit") + @identity.require(identity.not_anonymous()) + def edit(self, cn, tg_errors=None): + """Displays the edit group form""" + if tg_errors: + turbogears.flash("There was a problem with the form!") + + client.set_krbccache(os.environ["KRB5CCNAME"]) + try: + group = client.get_group_by_cn(cn, group_fields) + + group_dict = group.toDict() + + # + # convert members to users, for easier manipulation on the page + # + member_dns = [] + if group_dict.has_key('uniquemember'): + member_dns = group_dict.get('uniquemember') + # remove from dict - it's not needed for update + # and we are storing the members in a different form + del group_dict['uniquemember'] + if not(isinstance(member_dns,list) or isinstance(member_dns,tuple)): + member_dns = [member_dns] + + # TODO: convert this into an efficient (single) function call + # Note: this isn't quite right, since it can be users and groups. + members = map( + lambda dn: client.get_user_by_dn(dn, ['dn', 'givenname', 'sn', + 'uid', 'cn']), + member_dns) + members.sort(self.sort_group_member) + + # Map users into an array of dicts, which can be serialized + # (so we don't have to do this on each round trip) + member_dicts = map(lambda member: member.toDict(), members) + + # store a copy of the original group for the update later + group_data = b64encode(dumps(group_dict)) + member_data = b64encode(dumps(member_dicts)) + group_dict['group_orig'] = group_data + group_dict['member_data'] = member_data + + return dict(form=group_edit_form, group=group_dict, members=member_dicts) + except ipaerror.IPAError, e: + turbogears.flash("Group edit failed: " + str(e)) + raise turbogears.redirect('/group/show', uid=cn) + + @expose() + @identity.require(identity.not_anonymous()) + def update(self, **kw): + """Updates an existing group""" + self.restrict_post() + client.set_krbccache(os.environ["KRB5CCNAME"]) + if kw.get('submit') == 'Cancel Edit': + turbogears.flash("Edit group cancelled") + raise turbogears.redirect('/group/show', cn=kw.get('cn')) + + # Decode the member data, in case we need to round trip + member_dicts = loads(b64decode(kw.get('member_data'))) + + + tg_errors, kw = self.groupupdatevalidate(**kw) + if tg_errors: + return dict(form=group_edit_form, group=kw, members=member_dicts, + tg_template='ipagui.templates.groupedit') + + group_modified = False + + # + # Update group itself + # + try: + orig_group_dict = loads(b64decode(kw.get('group_orig'))) + + new_group = ipa.group.Group(orig_group_dict) + if new_group.description != kw.get('description'): + group_modified = True + new_group.setValue('description', kw.get('description')) + if kw.get('editprotected') == 'true': + new_gid = str(kw.get('gidnumber')) + if new_group.gidnumber != new_gid: + group_modified = True + new_group.setValue('gidnumber', new_gid) + + if group_modified: + rv = client.update_group(new_group) + # + # If the group update succeeds, but below operations fail, we + # need to make sure a subsequent submit doesn't try to update + # the group again. + # + kw['group_orig'] = b64encode(dumps(new_group.toDict())) + except ipaerror.IPAError, e: + turbogears.flash("Group update failed: " + str(e)) + return dict(form=group_edit_form, group=kw, members=member_dicts, + tg_template='ipagui.templates.groupedit') + + # + # Add members + # + failed_adds = [] + try: + dnadds = kw.get('dnadd') + if dnadds != None: + if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)): + dnadds = [dnadds] + failed_adds = client.add_members_to_group( + utf8_encode_values(dnadds), new_group.dn) + kw['dnadd'] = failed_adds + except ipaerror.IPAError, e: + turbogears.flash("Group update failed: " + str(e)) + return dict(form=group_edit_form, group=kw, members=member_dicts, + tg_template='ipagui.templates.groupedit') + + # + # Remove members + # + failed_dels = [] + try: + dndels = kw.get('dndel') + if dndels != None: + if not(isinstance(dndels,list) or isinstance(dndels,tuple)): + dndels = [dndels] + failed_dels = client.remove_members_from_group( + utf8_encode_values(dndels), new_group.dn) + kw['dndel'] = failed_dels + except ipaerror.IPAError, e: + turbogears.flash("Group update failed: " + str(e)) + return dict(form=group_edit_form, group=kw, members=member_dicts, + tg_template='ipagui.templates.groupedit') + + # + # TODO - check failed ops to see if it's because of another update. + # handle "someone else already did it" errors better - perhaps + # not even as an error + # TODO - update the Group Members list. + # (note that we have to handle the above todo first, or else + # there will be an error message, but the add/del lists will + # be empty) + # + if (len(failed_adds) > 0) or (len(failed_dels) > 0): + message = "There was an error updating group members.<br />" + message += "Failures have been preserved in the add/remove lists." + if group_modified: + message = "Group Details successfully updated.<br />" + message + turbogears.flash(message) + return dict(form=group_edit_form, group=kw, members=member_dicts, + tg_template='ipagui.templates.groupedit') + + turbogears.flash("%s updated!" % kw['cn']) + raise turbogears.redirect('/group/show', cn=kw['cn']) + + + @expose("ipagui.templates.grouplist") + @identity.require(identity.not_anonymous()) + def list(self, **kw): + """Search for groups and display results""" + client.set_krbccache(os.environ["KRB5CCNAME"]) + groups = None + # counter = 0 + criteria = kw.get('criteria') + if criteria != None and len(criteria) > 0: + try: + groups = client.find_groups(criteria.encode('utf-8'), None, 0, 2) + counter = groups[0] + groups = groups[1:] + if counter == -1: + turbogears.flash("These results are truncated.<br />" + + "Please refine your search and try again.") + except ipaerror.IPAError, e: + turbogears.flash("Find groups failed: " + str(e)) + raise turbogears.redirect("/group/list") + + return dict(groups=groups, criteria=criteria, + fields=ipagui.forms.group.GroupFields()) + + @expose("ipagui.templates.groupshow") + @identity.require(identity.not_anonymous()) + def show(self, cn): + """Retrieve a single group for display""" + client.set_krbccache(os.environ["KRB5CCNAME"]) + try: + group = client.get_group_by_cn(cn, group_fields) + group_dict = group.toDict() + + # + # convert members to users, for display on the page + # + member_dns = [] + if group_dict.has_key('uniquemember'): + member_dns = group_dict.get('uniquemember') + if not(isinstance(member_dns,list) or isinstance(member_dns,tuple)): + member_dns = [member_dns] + + # TODO: convert this into an efficient (single) function call + # Note: this isn't quite right, since it can be users and groups. + members = map( + lambda dn: client.get_user_by_dn(dn, ['dn', 'givenname', 'sn', + 'uid', 'cn']), + member_dns) + members.sort(self.sort_group_member) + member_dicts = map(lambda member: member.toDict(), members) + + return dict(group=group_dict, fields=ipagui.forms.group.GroupFields(), + members = member_dicts) + except ipaerror.IPAError, e: + turbogears.flash("Group show failed: " + str(e)) + raise turbogears.redirect("/") + + @validate(form=group_new_form) + @identity.require(identity.not_anonymous()) + def groupcreatevalidate(self, tg_errors=None, **kw): + return tg_errors, kw + + @validate(form=group_edit_form) + @identity.require(identity.not_anonymous()) + def groupupdatevalidate(self, tg_errors=None, **kw): + return tg_errors, kw + diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/ipacontroller.py b/ipa-server/ipa-gui/ipagui/subcontrollers/ipacontroller.py new file mode 100644 index 00000000..77ebe8dd --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/subcontrollers/ipacontroller.py @@ -0,0 +1,58 @@ +import cherrypy +import turbogears +from turbogears import controllers, expose, flash +from turbogears import validators, validate +from turbogears import widgets, paginate +from turbogears import error_handler +from turbogears import identity + +class IPAController(controllers.Controller): + def restrict_post(self): + if cherrypy.request.method != "POST": + turbogears.flash("This method only accepts posts") + raise turbogears.redirect("/") + + def utf8_encode(self, value): + if value != None: + value = value.encode('utf-8') + return value + + def sort_group_member(self, a, b): + """Comparator function used for sorting group members.""" + if a.getValue('uid') and b.getValue('uid'): + if a.getValue('givenname') == b.getValue('givenname'): + if a.getValue('sn') == b.getValue('sn'): + if a.getValue('uid') == b.getValue('uid'): + return 0 + elif a.getValue('uid') < b.getValue('uid'): + return -1 + else: + return 1 + elif a.getValue('sn') < b.getValue('sn'): + return -1 + else: + return 1 + elif a.getValue('givenname') < b.getValue('givenname'): + return -1 + else: + return 1 + elif a.getValue('uid'): + return -1 + elif b.getValue('uid'): + return 1 + else: + if a.getValue('cn') == b.getValue('cn'): + return 0 + elif a.getValue('cn') < b.getValue('cn'): + return -1 + else: + return 1 + + def sort_by_cn(self, a, b): + """Comparator function used for sorting groups.""" + if a.getValue('cn') == b.getValue('cn'): + return 0 + elif a.getValue('cn') < b.getValue('cn'): + return -1 + else: + return 1 diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/user.py b/ipa-server/ipa-gui/ipagui/subcontrollers/user.py new file mode 100644 index 00000000..40d57510 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/subcontrollers/user.py @@ -0,0 +1,537 @@ +import os +import re +import random +from pickle import dumps, loads +from base64 import b64encode, b64decode + +import cherrypy +import turbogears +from turbogears import controllers, expose, flash +from turbogears import validators, validate +from turbogears import widgets, paginate +from turbogears import error_handler +from turbogears import identity + +from ipacontroller import IPAController +import ipa.config +import ipa.ipaclient +import ipa.user +from ipa.entity import utf8_encode_values +from ipa import ipaerror +import ipagui.forms.user + +ipa.config.init_config() +client = ipa.ipaclient.IPAClient(True) + +password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +user_new_form = ipagui.forms.user.UserNewForm() +user_edit_form = ipagui.forms.user.UserEditForm() + +user_fields = ['*', 'nsAccountLock'] + +class UserController(IPAController): + + @expose() + def index(self): + raise turbogears.redirect("/user/list") + + @expose("ipagui.templates.usernew") + @identity.require(identity.not_anonymous()) + def new(self, tg_errors=None): + """Displays the new user form""" + if tg_errors: + turbogears.flash("There was a problem with the form!") + + return dict(form=user_new_form, user={}) + + @expose() + @identity.require(identity.not_anonymous()) + def create(self, **kw): + """Creates a new user""" + self.restrict_post() + client.set_krbccache(os.environ["KRB5CCNAME"]) + if kw.get('submit') == 'Cancel': + turbogears.flash("Add user cancelled") + raise turbogears.redirect('/user/list') + + tg_errors, kw = self.usercreatevalidate(**kw) + if tg_errors: + return dict(form=user_new_form, user=kw, + tg_template='ipagui.templates.usernew') + + # + # Create the user itself + # + try: + new_user = ipa.user.User() + new_user.setValue('title', kw.get('title')) + new_user.setValue('givenname', kw.get('givenname')) + new_user.setValue('sn', kw.get('sn')) + new_user.setValue('cn', kw.get('cn')) + new_user.setValue('displayname', kw.get('displayname')) + new_user.setValue('initials', kw.get('initials')) + + new_user.setValue('uid', kw.get('uid')) + new_user.setValue('loginshell', kw.get('loginshell')) + new_user.setValue('gecos', kw.get('gecos')) + + new_user.setValue('mail', kw.get('mail')) + new_user.setValue('telephonenumber', kw.get('telephonenumber')) + new_user.setValue('facsimiletelephonenumber', + kw.get('facsimiletelephonenumber')) + new_user.setValue('mobile', kw.get('mobile')) + new_user.setValue('pager', kw.get('pager')) + new_user.setValue('homephone', kw.get('homephone')) + + new_user.setValue('street', kw.get('street')) + new_user.setValue('l', kw.get('l')) + new_user.setValue('st', kw.get('st')) + new_user.setValue('postalcode', kw.get('postalcode')) + + new_user.setValue('ou', kw.get('ou')) + new_user.setValue('businesscategory', kw.get('businesscategory')) + new_user.setValue('description', kw.get('description')) + new_user.setValue('employeetype', kw.get('employeetype')) + # new_user.setValue('manager', kw.get('manager')) + new_user.setValue('roomnumber', kw.get('roomnumber')) + # new_user.setValue('secretary', kw.get('secretary')) + + new_user.setValue('carlicense', kw.get('carlicense')) + new_user.setValue('labeleduri', kw.get('labeleduri')) + + if kw.get('nsAccountLock'): + new_user.setValue('nsAccountLock', 'true') + + rv = client.add_user(new_user) + except ipaerror.exception_for(ipaerror.LDAP_DUPLICATE): + turbogears.flash("Person with login '%s' already exists" % + kw.get('uid')) + return dict(form=user_new_form, user=kw, + tg_template='ipagui.templates.usernew') + except ipaerror.IPAError, e: + turbogears.flash("User add failed: " + str(e)) + return dict(form=user_new_form, user=kw, + tg_template='ipagui.templates.usernew') + + # + # NOTE: from here on, the user account now exists. + # on any error, we redirect to the _edit_ user page. + # this code does data setup, similar to useredit() + # + user = client.get_user_by_uid(kw['uid'], user_fields) + user_dict = user.toDict() + + user_groups_dicts = [] + user_groups_data = b64encode(dumps(user_groups_dicts)) + + # store a copy of the original user for the update later + user_data = b64encode(dumps(user_dict)) + user_dict['user_orig'] = user_data + user_dict['user_groups_data'] = user_groups_data + + # preserve group add info in case of errors + user_dict['dnadd'] = kw.get('dnadd') + user_dict['dn_to_info_json'] = kw.get('dn_to_info_json') + + # + # Password change + # TODO + # + + # + # Add groups + # + failed_adds = [] + try: + dnadds = kw.get('dnadd') + if dnadds != None: + if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)): + dnadds = [dnadds] + failed_adds = client.add_groups_to_user( + utf8_encode_values(dnadds), user.dn) + kw['dnadd'] = failed_adds + except ipaerror.IPAError, e: + failed_adds = dnadds + + if len(failed_adds) > 0: + message = "Person successfully created.<br />" + message += "There was an error adding groups.<br />" + message += "Failures have been preserved in the add/remove lists." + turbogears.flash(message) + return dict(form=user_edit_form, user=user_dict, + user_groups=user_groups_dicts, + tg_template='ipagui.templates.useredit') + + turbogears.flash("%s added!" % kw['uid']) + raise turbogears.redirect('/user/show', uid=kw['uid']) + + @expose("ipagui.templates.dynamiceditsearch") + @identity.require(identity.not_anonymous()) + def edit_search(self, **kw): + """Searches for groups and displays list of results in a table. + This method is used for the ajax search on the user edit page.""" + client.set_krbccache(os.environ["KRB5CCNAME"]) + groups = [] + groups_counter = 0 + searchlimit = 100 + criteria = kw.get('criteria') + if criteria != None and len(criteria) > 0: + try: + groups = client.find_groups(criteria.encode('utf-8'), None, + searchlimit) + groups_counter = groups[0] + groups = groups[1:] + except ipaerror.IPAError, e: + turbogears.flash("search failed: " + str(e)) + + return dict(users=None, groups=groups, criteria=criteria, + counter=groups_counter) + + + @expose("ipagui.templates.useredit") + @identity.require(identity.not_anonymous()) + def edit(self, uid, tg_errors=None): + """Displays the edit user form""" + if tg_errors: + turbogears.flash("There was a problem with the form!") + + client.set_krbccache(os.environ["KRB5CCNAME"]) + try: + user = client.get_user_by_uid(uid, user_fields) + user_dict = user.toDict() + # Edit shouldn't fill in the password field. + if user_dict.has_key('userpassword'): + del(user_dict['userpassword']) + + user_groups = client.get_groups_by_member(user.dn, ['dn', 'cn']) + user_groups.sort(self.sort_by_cn) + user_groups_dicts = map(lambda group: group.toDict(), user_groups) + user_groups_data = b64encode(dumps(user_groups_dicts)) + + # store a copy of the original user for the update later + user_data = b64encode(dumps(user_dict)) + user_dict['user_orig'] = user_data + user_dict['user_groups_data'] = user_groups_data + + return dict(form=user_edit_form, user=user_dict, + user_groups=user_groups_dicts) + except ipaerror.IPAError, e: + turbogears.flash("User edit failed: " + str(e)) + raise turbogears.redirect('/user/show', uid=kw.get('uid')) + + @expose() + @identity.require(identity.not_anonymous()) + def update(self, **kw): + """Updates an existing user""" + self.restrict_post() + client.set_krbccache(os.environ["KRB5CCNAME"]) + if kw.get('submit') == 'Cancel Edit': + turbogears.flash("Edit user cancelled") + raise turbogears.redirect('/user/show', uid=kw.get('uid')) + + # Decode the group data, in case we need to round trip + user_groups_dicts = loads(b64decode(kw.get('user_groups_data'))) + + tg_errors, kw = self.userupdatevalidate(**kw) + if tg_errors: + return dict(form=user_edit_form, user=kw, + user_groups=user_groups_dicts, + tg_template='ipagui.templates.useredit') + + password_change = False + user_modified = False + + # + # Update the user itself + # + try: + orig_user_dict = loads(b64decode(kw.get('user_orig'))) + + new_user = ipa.user.User(orig_user_dict) + new_user.setValue('title', kw.get('title')) + new_user.setValue('givenname', kw.get('givenname')) + new_user.setValue('sn', kw.get('sn')) + new_user.setValue('cn', kw.get('cn')) + new_user.setValue('displayname', kw.get('displayname')) + new_user.setValue('initials', kw.get('initials')) + + new_user.setValue('loginshell', kw.get('loginshell')) + new_user.setValue('gecos', kw.get('gecos')) + + new_user.setValue('mail', kw.get('mail')) + new_user.setValue('telephonenumber', kw.get('telephonenumber')) + new_user.setValue('facsimiletelephonenumber', + kw.get('facsimiletelephonenumber')) + new_user.setValue('mobile', kw.get('mobile')) + new_user.setValue('pager', kw.get('pager')) + new_user.setValue('homephone', kw.get('homephone')) + + new_user.setValue('street', kw.get('street')) + new_user.setValue('l', kw.get('l')) + new_user.setValue('st', kw.get('st')) + new_user.setValue('postalcode', kw.get('postalcode')) + + new_user.setValue('ou', kw.get('ou')) + new_user.setValue('businesscategory', kw.get('businesscategory')) + new_user.setValue('description', kw.get('description')) + new_user.setValue('employeetype', kw.get('employeetype')) + # new_user.setValue('manager', kw.get('manager')) + new_user.setValue('roomnumber', kw.get('roomnumber')) + # new_user.setValue('secretary', kw.get('secretary')) + + new_user.setValue('carlicense', kw.get('carlicense')) + new_user.setValue('labeleduri', kw.get('labeleduri')) + + + if kw.get('nsAccountLock'): + new_user.setValue('nsAccountLock', 'true') + else: + new_user.setValue('nsAccountLock', None) + if kw.get('editprotected') == 'true': + if kw.get('userpassword'): + password_change = True + new_user.setValue('uidnumber', str(kw.get('uidnumber'))) + new_user.setValue('gidnumber', str(kw.get('gidnumber'))) + new_user.setValue('homedirectory', str(kw.get('homedirectory'))) + + rv = client.update_user(new_user) + # + # If the user update succeeds, but below operations fail, we + # need to make sure a subsequent submit doesn't try to update + # the user again. + # + user_modified = True + kw['user_orig'] = b64encode(dumps(new_user.toDict())) + except ipaerror.exception_for(ipaerror.LDAP_EMPTY_MODLIST), e: + # could be a password change + # could be groups change + # too much work to figure out unless someone really screams + pass + except ipaerror.IPAError, e: + turbogears.flash("User update failed: " + str(e)) + return dict(form=user_edit_form, user=kw, + user_groups=user_groups_dicts, + tg_template='ipagui.templates.useredit') + + # + # Password change + # + try: + if password_change: + rv = client.modifyPassword(kw['krbprincipalname'], "", kw.get('userpassword')) + except ipaerror.IPAError, e: + turbogears.flash("User password change failed: " + str(e)) + return dict(form=user_edit_form, user=kw, + user_groups=user_groups_dicts, + tg_template='ipagui.templates.useredit') + + # + # Add groups + # + failed_adds = [] + try: + dnadds = kw.get('dnadd') + if dnadds != None: + if not(isinstance(dnadds,list) or isinstance(dnadds,tuple)): + dnadds = [dnadds] + failed_adds = client.add_groups_to_user( + utf8_encode_values(dnadds), new_user.dn) + kw['dnadd'] = failed_adds + except ipaerror.IPAError, e: + failed_adds = dnadds + + # + # Remove groups + # + failed_dels = [] + try: + dndels = kw.get('dndel') + if dndels != None: + if not(isinstance(dndels,list) or isinstance(dndels,tuple)): + dndels = [dndels] + failed_dels = client.remove_groups_from_user( + utf8_encode_values(dndels), new_user.dn) + kw['dndel'] = failed_dels + except ipaerror.IPAError, e: + failed_dels = dndels + + if (len(failed_adds) > 0) or (len(failed_dels) > 0): + message = "There was an error updating groups.<br />" + message += "Failures have been preserved in the add/remove lists." + if user_modified: + message = "User Details successfully updated.<br />" + message + if password_change: + message = "User password successfully updated.<br />" + message + turbogears.flash(message) + return dict(form=user_edit_form, user=kw, + user_groups=user_groups_dicts, + tg_template='ipagui.templates.useredit') + + turbogears.flash("%s updated!" % kw['uid']) + raise turbogears.redirect('/user/show', uid=kw['uid']) + + + @expose("ipagui.templates.userlist") + @identity.require(identity.not_anonymous()) + def list(self, **kw): + """Searches for users and displays list of results""" + client.set_krbccache(os.environ["KRB5CCNAME"]) + users = None + counter = 0 + uid = kw.get('uid') + if uid != None and len(uid) > 0: + try: + users = client.find_users(uid.encode('utf-8'), None, 0, 2) + counter = users[0] + users = users[1:] + if counter == -1: + turbogears.flash("These results are truncated.<br />" + + "Please refine your search and try again.") + except ipaerror.IPAError, e: + turbogears.flash("User list failed: " + str(e)) + raise turbogears.redirect("/user/list") + + return dict(users=users, uid=uid, fields=ipagui.forms.user.UserFields()) + + + @expose("ipagui.templates.usershow") + @identity.require(identity.not_anonymous()) + def show(self, uid): + """Retrieve a single user for display""" + client.set_krbccache(os.environ["KRB5CCNAME"]) + try: + user = client.get_user_by_uid(uid, user_fields) + user_groups = client.get_groups_by_member(user.dn, ['cn']) + user_groups.sort(self.sort_by_cn) + user_reports = client.get_users_by_manager(user.dn, + ['givenname', 'sn', 'uid']) + user_reports.sort(self.sort_group_member) + + user_manager = None + try: + if user.manager: + user_manager = client.get_user_by_dn(user.manager, + ['givenname', 'sn', 'uid']) + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): + pass + + return dict(user=user.toDict(), fields=ipagui.forms.user.UserFields(), + user_groups=user_groups, user_reports=user_reports, + user_manager=user_manager) + except ipaerror.IPAError, e: + turbogears.flash("User show failed: " + str(e)) + raise turbogears.redirect("/") + + @validate(form=user_new_form) + @identity.require(identity.not_anonymous()) + def usercreatevalidate(self, tg_errors=None, **kw): + return tg_errors, kw + + @validate(form=user_edit_form) + @identity.require(identity.not_anonymous()) + def userupdatevalidate(self, tg_errors=None, **kw): + return tg_errors, kw + + # @expose() + def generate_password(self): + password = "" + generator = random.SystemRandom() + for char in range(8): + index = generator.randint(0, len(password_chars) - 1) + password += password_chars[index] + + return password + + @expose() + @identity.require(identity.not_anonymous()) + def suggest_uid(self, givenname, sn): + # filter illegal uid characters out + givenname = re.sub(r'[^a-zA-Z_\-0-9]', "", givenname) + sn = re.sub(r'[^a-zA-Z_\-0-9]', "", sn) + + if (len(givenname) == 0) or (len(sn) == 0): + return "" + + client.set_krbccache(os.environ["KRB5CCNAME"]) + givenname = givenname.lower() + sn = sn.lower() + + uid = givenname[0] + sn[:7] + try: + client.get_user_by_uid(uid) + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): + return uid + + uid = givenname[:7] + sn[0] + try: + client.get_user_by_uid(uid) + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): + return uid + + uid = (givenname + sn)[:8] + try: + client.get_user_by_uid(uid) + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): + return uid + + uid = sn[:8] + try: + client.get_user_by_uid(uid) + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): + return uid + + suffix = 2 + template = givenname[0] + sn[:7] + while suffix < 20: + uid = template[:8 - len(str(suffix))] + str(suffix) + try: + client.get_user_by_uid(uid) + except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): + return uid + suffix += 1 + + return "" + + @expose() + @identity.require(identity.not_anonymous()) + def suggest_email(self, givenname, sn): + # remove illegal email characters + givenname = re.sub(r'[^a-zA-Z0-9!#\$%\*/?\|\^\{\}`~&\'\+\-=_]', "", givenname) + sn = re.sub(r'[^a-zA-Z0-9!#\$%\*/?\|\^\{\}`~&\'\+\-=_]', "", sn) + + if (len(givenname) == 0) or (len(sn) == 0): + return "" + + client.set_krbccache(os.environ["KRB5CCNAME"]) + givenname = givenname.lower() + sn = sn.lower() + + # TODO - get from config + domain = "freeipa.org" + + return "%s.%s@%s" % (givenname, sn, domain) + + + # TODO - mail is currently not indexed nor searchable. + # implement when it's done + # email = givenname + "." + sn + domain + # users = client.find_users(email, ['mail']) + # if len(filter(lambda u: u['mail'] == email, users[1:])) == 0: + # return email + + # email = self.suggest_uid(givenname, sn) + domain + # users = client.find_users(email, ['mail']) + # if len(filter(lambda u: u['mail'] == email, users[1:])) == 0: + # return email + + # suffix = 2 + # template = givenname + "." + sn + # while suffix < 20: + # email = template + str(suffix) + domain + # users = client.find_users(email, ['mail']) + # if len(filter(lambda u: u['mail'] == email, users[1:])) == 0: + # return email + # suffix += 1 + + # return "" diff --git a/ipa-server/ipa-gui/ipagui/templates/groupedit.kid b/ipa-server/ipa-gui/ipagui/templates/groupedit.kid index f1d309ca..9fe96663 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupedit.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupedit.kid @@ -16,6 +16,6 @@ <h2>Edit Group</h2> </div> - ${form.display(action="groupupdate", value=group, members=members)} + ${form.display(action=tg.url('/group/update'), value=group, members=members)} </body> </html> diff --git a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid index 764637f2..86c0590a 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid @@ -23,7 +23,7 @@ from ipagui.helpers import ipahelper <script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/dynamicedit.js')}"></script> - <?python searchurl = tg.url('/groupedit_search') ?> + <?python searchurl = tg.url('/group/edit_search') ?> <script type="text/javascript"> function toggleProtectedFields(checkbox) { diff --git a/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid b/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid index edaf716e..0f53060a 100644 --- a/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid +++ b/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid @@ -14,9 +14,9 @@ <!-- <div id="sidebar"> <h2>Tools</h2> - <a href="${tg.url('/groupindex')}">Add Group</a><br/> - <a href="${tg.url('/groupindex')}">Find Group</a><br/> - <a href="${tg.url('/groupindex')}">List Groups</a><br/> + <a href="${tg.url('/group/index')}">Add Group</a><br/> + <a href="${tg.url('/group/index')}">Find Group</a><br/> + <a href="${tg.url('/group/index')}">List Groups</a><br/> </div> --> </body> diff --git a/ipa-server/ipa-gui/ipagui/templates/grouplist.kid b/ipa-server/ipa-gui/ipagui/templates/grouplist.kid index 2fbefa4b..0bb8cb34 100644 --- a/ipa-server/ipa-gui/ipagui/templates/grouplist.kid +++ b/ipa-server/ipa-gui/ipagui/templates/grouplist.kid @@ -8,7 +8,7 @@ <body> <script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/tablekit.js')}"></script> <div id="search"> - <form action="${tg.url('/grouplist')}" method="get"> + <form action="${tg.url('/group/list')}" method="get"> <input id="criteria" type="text" name="criteria" value="${criteria}" /> <input type="submit" value="Find Groups"/> </form> @@ -32,7 +32,7 @@ <tbody> <tr py:for="group in groups"> <td> - <a href="${tg.url('/groupshow',cn=group.cn)}">${group.cn}</a> + <a href="${tg.url('/group/show',cn=group.cn)}">${group.cn}</a> </td> <td> ${group.description} diff --git a/ipa-server/ipa-gui/ipagui/templates/groupnew.kid b/ipa-server/ipa-gui/ipagui/templates/groupnew.kid index 083efd78..a3f764d6 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupnew.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupnew.kid @@ -8,6 +8,6 @@ <body> <h2>Add Group</h2> - ${form.display(action="groupcreate", value=group)} + ${form.display(action=tg.url('/group/create'), value=group)} </body> </html> diff --git a/ipa-server/ipa-gui/ipagui/templates/groupnewform.kid b/ipa-server/ipa-gui/ipagui/templates/groupnewform.kid index 29c79cfb..538cfbdc 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupnewform.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupnewform.kid @@ -18,7 +18,7 @@ from ipagui.helpers import ipahelper <script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/dynamicedit.js')}"></script> - <?python searchurl = tg.url('/groupedit_search') ?> + <?python searchurl = tg.url('/group/edit_search') ?> <script type="text/javascript"> function doSearch() { diff --git a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid index 7be0db84..225692a5 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid @@ -7,7 +7,7 @@ </head> <body> <?python -edit_url = tg.url('/groupedit', cn=group.get('cn')) +edit_url = tg.url('/group/edit', cn=group.get('cn')) ?> <h2>View Group</h2> @@ -48,12 +48,12 @@ edit_url = tg.url('/groupedit', cn=group.get('cn')) member_cn = "%s %s" % (member.get('givenName', ''), member.get('sn', '')) member_desc = "(%s)" % member_uid member_type = "user" - view_url = tg.url('usershow', uid=member_uid) + view_url = tg.url('/user/show', uid=member_uid) else: member_cn = "%s" % member.get('cn') member_desc = "[group]" member_type = "group" - view_url = tg.url('groupshow', cn=member_cn) + view_url = tg.url('/group/show', cn=member_cn) ?> <span py:if='member_type == "user"'> <a href="${view_url}" diff --git a/ipa-server/ipa-gui/ipagui/templates/master.kid b/ipa-server/ipa-gui/ipagui/templates/master.kid index 4ed69a17..52b88e37 100644 --- a/ipa-server/ipa-gui/ipagui/templates/master.kid +++ b/ipa-server/ipa-gui/ipagui/templates/master.kid @@ -66,12 +66,12 @@ <div id="sidebar"> <h2>Tasks</h2> <p> - <a href="${tg.url('/usernew')}">Add Person</a><br/> - <a href="${tg.url('/userlist')}">Find People</a><br/> + <a href="${tg.url('/user/new')}">Add Person</a><br/> + <a href="${tg.url('/user/list')}">Find People</a><br/> </p> <p> - <a href="${tg.url('/groupnew')}">Add Group</a><br/> - <a href="${tg.url('/grouplist')}">Find Groups</a><br/> + <a href="${tg.url('/group/new')}">Add Group</a><br/> + <a href="${tg.url('/group/list')}">Find Groups</a><br/> </p> <p> <a href="${tg.url('/')}">Manage Policy</a><br/> diff --git a/ipa-server/ipa-gui/ipagui/templates/useredit.kid b/ipa-server/ipa-gui/ipagui/templates/useredit.kid index e4d492b0..3ce4e9f6 100644 --- a/ipa-server/ipa-gui/ipagui/templates/useredit.kid +++ b/ipa-server/ipa-gui/ipagui/templates/useredit.kid @@ -35,6 +35,6 @@ else: Password has expired </div> - ${form.display(action="userupdate", value=user, user_groups=user_groups)} + ${form.display(action=tg.url('/user/update'), value=user, user_groups=user_groups)} </body> </html> diff --git a/ipa-server/ipa-gui/ipagui/templates/usereditform.kid b/ipa-server/ipa-gui/ipagui/templates/usereditform.kid index a21f0b7d..7c5bc0c2 100644 --- a/ipa-server/ipa-gui/ipagui/templates/usereditform.kid +++ b/ipa-server/ipa-gui/ipagui/templates/usereditform.kid @@ -24,7 +24,7 @@ from ipagui.helpers import ipahelper <script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/dynamicedit.js')}"></script> - <?python searchurl = tg.url('/useredit_search') ?> + <?python searchurl = tg.url('/user/edit_search') ?> <script type="text/javascript"> function toggleProtectedFields(checkbox) { @@ -196,7 +196,7 @@ from ipagui.helpers import ipahelper <span id="password_text">********</span> <input id="genpassword_button" type="button" value="Generate Password" disabled="true" - onclick="new Ajax.Request('${tg.url('/generate_password')}', + onclick="new Ajax.Request('${tg.url('/user/generate_password')}', { method: 'get', onSuccess: function(transport) { diff --git a/ipa-server/ipa-gui/ipagui/templates/userlayout.kid b/ipa-server/ipa-gui/ipagui/templates/userlayout.kid index ecd49f3b..21514119 100644 --- a/ipa-server/ipa-gui/ipagui/templates/userlayout.kid +++ b/ipa-server/ipa-gui/ipagui/templates/userlayout.kid @@ -14,8 +14,8 @@ <!-- <div id="sidebar"> <h2>Tools</h2> - <a href="${tg.url('/usernew')}">Add Person</a><br/> - <a href="${tg.url('/userlist')}">Find People</a><br/> + <a href="${tg.url('/user/new')}">Add Person</a><br/> + <a href="${tg.url('/user/list')}">Find People</a><br/> </div> --> </body> diff --git a/ipa-server/ipa-gui/ipagui/templates/userlist.kid b/ipa-server/ipa-gui/ipagui/templates/userlist.kid index c78199ef..529a009c 100644 --- a/ipa-server/ipa-gui/ipagui/templates/userlist.kid +++ b/ipa-server/ipa-gui/ipagui/templates/userlist.kid @@ -8,7 +8,7 @@ <body> <script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/tablekit.js')}"></script> <div id="search"> - <form action="${tg.url('/userlist')}" method="get"> + <form action="${tg.url('/user/list')}" method="get"> <input id="uid" type="text" name="uid" value="${uid}" /> <input type="submit" value="Find People"/> </form> @@ -38,7 +38,7 @@ <tbody> <tr py:for="user in users"> <td> - <a href="${tg.url('/usershow',uid=user.uid)}" + <a href="${tg.url('/user/show',uid=user.uid)}" >${user.givenName} ${user.sn}</a> (${user.uid}) </td> diff --git a/ipa-server/ipa-gui/ipagui/templates/usernew.kid b/ipa-server/ipa-gui/ipagui/templates/usernew.kid index ee5d0fcd..ab207e81 100644 --- a/ipa-server/ipa-gui/ipagui/templates/usernew.kid +++ b/ipa-server/ipa-gui/ipagui/templates/usernew.kid @@ -8,6 +8,6 @@ <body> <h2>Add Person</h2> - ${form.display(action="usercreate", value=user)} + ${form.display(action=tg.url("/user/create"), value=user)} </body> </html> diff --git a/ipa-server/ipa-gui/ipagui/templates/usernewform.kid b/ipa-server/ipa-gui/ipagui/templates/usernewform.kid index dc755ecd..bb144c16 100644 --- a/ipa-server/ipa-gui/ipagui/templates/usernewform.kid +++ b/ipa-server/ipa-gui/ipagui/templates/usernewform.kid @@ -18,7 +18,7 @@ from ipagui.helpers import ipahelper <script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/dynamicedit.js')}"></script> - <?python searchurl = tg.url('/useredit_search') ?> + <?python searchurl = tg.url('/user/edit_search') ?> <script type="text/javascript"> function doSearch() { @@ -123,7 +123,7 @@ from ipagui.helpers import ipahelper } if ((uid.value == "") || (uid.value == uid_suggest)) { - new Ajax.Request('${tg.url('/suggest_uid')}', { + new Ajax.Request('${tg.url('/user/suggest_uid')}', { method: 'get', parameters: {'givenname': givenname.value, 'sn': sn.value}, onSuccess: function(transport) { @@ -135,7 +135,7 @@ from ipagui.helpers import ipahelper } if ((mail.value == "") || (mail.value == mail_suggest)) { - new Ajax.Request('${tg.url('/suggest_email')}', { + new Ajax.Request('${tg.url('/user/suggest_email')}', { method: 'get', parameters: {'givenname': givenname.value, 'sn': sn.value}, onSuccess: function(transport) { @@ -230,7 +230,7 @@ from ipagui.helpers import ipahelper <!-- <input type="button" value="Generate Password" - onclick="new Ajax.Request('${tg.url('/generate_password')}', + onclick="new Ajax.Request('${tg.url('/user/generate_password')}', { method: 'get', onSuccess: function(transport) { diff --git a/ipa-server/ipa-gui/ipagui/templates/usershow.kid b/ipa-server/ipa-gui/ipagui/templates/usershow.kid index 31150028..6250fe6d 100644 --- a/ipa-server/ipa-gui/ipagui/templates/usershow.kid +++ b/ipa-server/ipa-gui/ipagui/templates/usershow.kid @@ -7,7 +7,7 @@ </head> <body> <?python -edit_url = tg.url('/useredit', uid=user.get('uid')) +edit_url = tg.url('/user/edit', uid=user.get('uid')) ?> <h2>View Person</h2> @@ -218,7 +218,7 @@ else: Manager: </th> <td> - <a href="${tg.url('/usershow', uid=user_manager.uid)}" + <a href="${tg.url('/user/show', uid=user_manager.uid)}" >${user_manager.givenname} ${user_manager.sn}</a> </td> </tr> @@ -254,13 +254,13 @@ else: <div class="formsection" py:if='len(user_reports) > 0'>Direct Reports</div> <div py:for="report in user_reports"> - <a href="${tg.url('/usershow', uid=report.uid)}" + <a href="${tg.url('/user/show', uid=report.uid)}" >${report.givenname} ${report.sn}</a> </div> <div class="formsection">Groups</div> <div py:for="group in user_groups"> - <a href="${tg.url('/groupshow', cn=group.cn)}">${group.cn}</a> + <a href="${tg.url('/group/show', cn=group.cn)}">${group.cn}</a> </div> <br/> |