Add an editors group. This is used to generally grant access for users

to edit other users (the Edit link won't appear otherwise). Additional
delegation is need to grant permission to individual attributes.
Update the failed login page to indicate that it is a permission issue.
Don't allow access to policy at all for non-admins.
By default users can only edit themselves.
This commit is contained in:
Rob Crittenden 2007-11-14 10:49:03 -05:00
parent 7502ebe479
commit 3e715a04cf
10 changed files with 63 additions and 48 deletions

View File

@ -35,7 +35,7 @@ class DelegationController(IPAController):
raise turbogears.redirect("/delegate/list")
@expose("ipagui.templates.delegatenew")
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def new(self):
"""Display delegate page"""
client = self.get_ipaclient()
@ -46,7 +46,7 @@ class DelegationController(IPAController):
return dict(form=delegate_form, delegate=delegate)
@expose()
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def create(self, **kw):
"""Creates a new delegation"""
self.restrict_post()
@ -107,7 +107,7 @@ class DelegationController(IPAController):
raise turbogears.redirect('/delegate/list')
@expose("ipagui.templates.delegateedit")
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def edit(self, acistr, tg_errors=None):
"""Display delegate page"""
if tg_errors:
@ -134,7 +134,7 @@ class DelegationController(IPAController):
@expose()
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def update(self, **kw):
"""Display delegate page"""
self.restrict_post()
@ -230,7 +230,7 @@ class DelegationController(IPAController):
fields=ipagui.forms.delegate.DelegateFields())
@expose()
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def delete(self, acistr):
"""Display delegate page"""
self.restrict_post()

View File

@ -168,7 +168,7 @@ class GroupController(IPAController):
@expose("ipagui.templates.groupedit")
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def edit(self, cn, tg_errors=None):
"""Displays the edit group form"""
if tg_errors:
@ -214,7 +214,7 @@ class GroupController(IPAController):
raise turbogears.redirect('/group/show', uid=cn)
@expose()
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def update(self, **kw):
"""Updates an existing group"""
self.restrict_post()

View File

@ -26,11 +26,12 @@ ipapolicy_edit_form = ipagui.forms.ipapolicy.IPAPolicyForm()
class IPAPolicyController(IPAController):
@expose()
@identity.require(identity.in_group("admins"))
def index(self):
raise turbogears.redirect("/ipapolicy/show")
@expose("ipagui.templates.ipapolicyshow")
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def show(self, tg_errors=None):
"""Displays the one policy page"""
@ -45,7 +46,7 @@ class IPAPolicyController(IPAController):
return dict(ipapolicy=ipapolicy,fields=ipagui.forms.ipapolicy.IPAPolicyFields())
@expose("ipagui.templates.ipapolicyedit")
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def edit(self, tg_errors=None):
"""Displays the edit IPA policy form"""
if tg_errors:
@ -68,7 +69,7 @@ class IPAPolicyController(IPAController):
@expose()
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def update(self, **kw):
"""Display delegate page"""
self.restrict_post()

View File

@ -23,7 +23,7 @@ log = logging.getLogger(__name__)
class PolicyController(IPAController):
@expose("ipagui.templates.policyindex")
@identity.require(identity.not_anonymous())
@identity.require(identity.in_group("admins"))
def index(self, tg_errors=None):
"""Displays the one policy page"""

View File

@ -96,7 +96,7 @@ class UserController(IPAController):
raise turbogears.redirect("/user/list")
@expose("ipagui.templates.usernew")
@identity.require(identity.in_group("admins"))
@identity.require(identity.in_any_group("admins","editors"))
def new(self, tg_errors=None):
"""Displays the new user form"""
if tg_errors:
@ -106,7 +106,7 @@ class UserController(IPAController):
return dict(form=user_new_form, user={})
@expose()
@identity.require(identity.in_group("admins"))
@identity.require(identity.in_any_group("admins","editors"))
def create(self, **kw):
"""Creates a new user"""
self.restrict_post()
@ -377,6 +377,15 @@ class UserController(IPAController):
kw = self.fix_incoming_fields(kw, 'pager', 'pagers')
kw = self.fix_incoming_fields(kw, 'homephone', 'homephones')
# admins and editors can update anybody. A user can only update
# themselves. We need this check because it is very easy to guess
# the edit URI.
if ((not 'admins' in turbogears.identity.current.groups and
not 'editors' in turbogears.identity.current.groups) and
(kw.get('uid') != turbogears.identity.current.display_name)):
turbogears.flash("You do not have permission to update this user.")
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')))

View File

@ -12,7 +12,8 @@ edit_url = tg.url('/group/edit', cn=group.get('cn')[0])
<div id="details">
<h1>View Group</h1>
<input class="submitbutton" type="button"
<input py:if="'editors' in tg.identity.groups or 'admins' in tg.identity.groups"
class="submitbutton" type="button"
onclick="document.location.href='${edit_url}'"
value="Edit Group" />
@ -84,7 +85,8 @@ edit_url = tg.url('/group/edit', cn=group.get('cn')[0])
<br/>
<hr />
<input class="submitbutton" type="button"
<input py:if="'editors' in tg.identity.groups or 'admins' in tg.identity.groups"
class="submitbutton" type="button"
onclick="document.location.href='${edit_url}'"
value="Edit Group" />
</div>

View File

@ -1,35 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://purl.org/kid/ns#">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
py:extends="'master.kid'">
<head>
<meta content="text/html; charset=UTF-8"
http-equiv="content-type" py:replace="''"/>
<title>Login Failure</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
<title>Permission Denied</title>
</head>
<body>
<div id="header">
<div id="logo">
<a href="${tg.url('/')}"><img
src="${tg.url('/static/images/logo.png')}"
border="0" alt="homepage"
/></a>
</div>
<div id="headerinfo">
<div id="login">
<div py:if="tg.config('identity.on') and not defined('logging_in')" id="page
Login">
<span py:if="tg.identity.anonymous">
Kerberos login failed.
</span>
<span py:if="not tg.identity.anonymous">
Logged in as: ${tg.identity.user.display_name}
</span>
<div id="main_content">
<div id="details">
<div id="alertbox" py:if="value_of('tg_flash', None)">
<p py:content="XML(tg_flash)"></p></div>
<h1>Permission Denied</h1>
<div class="instructions">
<p>
You do not have permission to access this page.
</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -77,12 +77,14 @@
<li py:if="'admins' in tg.identity.groups"><a href="${tg.url('/group/new')}">Add Group</a></li>
<li><a href="${tg.url('/group/list')}">Find Groups</a></li>
</ul>
<ul>
<li py:if="'admins' in tg.identity.groups"><a href="${tg.url('/policy/index')}">Manage Policy</a></li>
<li><a href="${tg.url('/user/edit/', principal=tg.identity.user.display_name)}">Self Service</a></li>
<ul py:if="'admins' in tg.identity.groups">
<li><a href="${tg.url('/policy/index')}">Manage Policy</a></li>
</ul>
<ul>
<li py:if="'admins' in tg.identity.groups"><a href="${tg.url('/delegate/list')}">Delegations</a></li>
<li><a href="${tg.url('/user/edit/', principal=tg.identity.user.display_name)}">Self Service</a></li>
</ul>
<ul py:if="'admins' in tg.identity.groups">
<li><a href="${tg.url('/delegate/list')}">Delegations</a></li>
</ul>
</div>

View File

@ -11,7 +11,8 @@ edit_url = tg.url('/user/edit', uid=user.get('uid'))
?>
<h1>View Person</h1>
<input class="submitbutton" type="button"
<input py:if="'editors' in tg.identity.groups or 'admins' in tg.identity.groups"
class="submitbutton" type="button"
onclick="document.location.href='${edit_url}'"
value="Edit Person" />
@ -373,7 +374,8 @@ else:
<br/>
<hr />
<input class="submitbutton" type="button"
<input py:if="'editors' in tg.identity.groups or 'admins' in tg.identity.groups"
class="submitbutton" type="button"
onclick="document.location.href='${edit_url}'"
value="Edit Person" />
</body>

View File

@ -84,4 +84,14 @@ objectClass: top
objectClass: groupofuniquenames
objectClass: posixGroup
gidNumber: 1002
description: Default group for all users
cn: ipausers
dn: cn=editors,cn=groups,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofuniquenames
objectClass: posixGroup
gidNumber: 1003
description: Limited admins who can edit other users
cn: editors