summaryrefslogtreecommitdiffstats
path: root/ipa-server
diff options
context:
space:
mode:
authorKevin McCarthy <kmccarth@redhat.com>2007-10-04 17:10:18 -0700
committerKevin McCarthy <kmccarth@redhat.com>2007-10-04 17:10:18 -0700
commitd5fedb5f978d7aaa31db9c177286872c6244c12a (patch)
treef21c78c2ab442d1001f4dcc1e45517bbdb1e64cb /ipa-server
parent6f7c918e5922afd3461514ddd58b41c5b86e9691 (diff)
downloadfreeipa-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')
-rw-r--r--ipa-server/ipa-gui/ipagui/controllers.py950
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/__init__.py1
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/group.py386
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/ipacontroller.py58
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/user.py537
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupedit.kid2
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupeditform.kid2
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/grouplayout.kid6
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/grouplist.kid4
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupnew.kid2
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupnewform.kid2
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupshow.kid6
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/master.kid8
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/useredit.kid2
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/usereditform.kid4
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/userlayout.kid4
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/userlist.kid4
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/usernew.kid2
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/usernewform.kid8
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/usershow.kid8
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 92b131d4d..340d6f9f6 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 000000000..143f486c0
--- /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 000000000..1be9d2f14
--- /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 000000000..77ebe8dd0
--- /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 000000000..40d57510d
--- /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 f1d309ca9..9fe966634 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 764637f2b..86c0590aa 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 edaf716e9..0f53060a1 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 2fbefa4b7..0bb8cb345 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 083efd780..a3f764d6e 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 29c79cfb9..538cfbdc8 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 7be0db845..225692a50 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 4ed69a170..52b88e37c 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 e4d492b0a..3ce4e9f62 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 a21f0b7d1..7c5bc0c28 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 ecd49f3b9..215141197 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 c78199efd..529a009c8 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 ee5d0fcd5..ab207e81a 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 dc755ecd3..bb144c16b 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 311500289..6250fe6d8 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) &gt; 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/>