Move more auth checking to auth.py, modify templates to use auth.py checks.

This commit is contained in:
Ricky Zhou (周家杰) 2007-08-29 13:07:18 -07:00
parent a68f64ec7f
commit 21229d6b9d
5 changed files with 194 additions and 95 deletions

View file

@ -53,11 +53,93 @@ def isApproved(userName, groupName, g=None):
except:
return False
def canEditUser(userName, editUserName):
def canEditUser(userName, editUserName, g=None):
if not g:
g = Groups.byUserName(userName)
if userName == editUserName:
return True
elif isAdmin(userName):
elif isAdmin(userName, g):
return True
else:
return False
def canCreateGroup(userName, groupName, g=None):
if not g:
g = Groups.byUserName(userName)
if isAdmin(userName, g):
return True
else:
return False
def canEditGroup(userName, groupName, g=None):
if not g:
g = Groups.byUserName(userName)
if canAdminGroup(userName, groupName):
return True
else:
return False
def canApplyGroup(userName, groupName, applyUserName, g=None):
# This is where we could make groups depend on other ones.
if not g:
g = Groups.byUserName(userName)
# A user can apply themselves, and FAS admins can apply other people.
if (userName == applyUserName) or \
isAdmin(userName, g):
return True
else:
return False
def canSponsorUser(userName, groupName, sponsorUserName, g=None):
if not g:
g = Groups.byUserName(userName)
# This is just here in case we want to add more complex checks in the future
if canSponsorGroup(userName, groupName, g):
return True
else:
return False
def canRemoveUser(userName, groupName, removeUserName, g=None):
if not g:
g = Groups.byUserName(userName)
group = Groups.groups(groupName)[groupName]
# Only administrators can remove administrators.
if canAdminGroup(removeUserName, groupName) and \
not canAdminGroup(userName, groupName, g):
return False
# A user can remove themself from a group if fedoraGroupUserCanRemove is TRUE
# Otherwise, a sponsor can remove sponsors/users.
elif ((userName == removeUserName) and (group.fedoraGroupUserCanRemove.lower() == 'TRUE')) or \
canSponsorGroup(userName, groupName, g):
return True
else:
return False
def canUpgradeUser(userName, groupName, sponsorUserName, g=None):
if not g:
g = Groups.byUserName(userName)
# Group admins can upgrade anybody (fasLDAP.py has the checks to prevent
# upgrading admins, etc.
if canAdminGroup(userName, groupName, g):
return True
# Sponsors can only upgrade non-sponsors (i.e. normal users) fasLDAP.py
# ensures that sponsorUserName is at least an approved user.
elif canSponsorGroup(userName, groupName, g) and \
not canSponsorGroup(sponsorUserName, groupName):
return True
else:
return False
def canDowngradeUser(userName, groupName, sponsorUserName, g=None):
if not g:
g = Groups.byUserName(userName)
# Group admins can downgrade anybody.
if canAdminGroup(userName, groupName, g):
return True
# Sponsors can only downgrade sponsors. (fasLDAP.py won't let you
# downgrade a normal user already)
elif canSponsorGroup(userName, groupName, g) and \
not canAdminGroup(sponsorUserName, groupName):
return True
else:
return False

View file

@ -10,7 +10,7 @@ from fas.fasLDAP import Person
from fas.fasLDAP import Groups
from fas.fasLDAP import UserGroup
from fas.auth import isAdmin, canAdminGroup, canSponsorGroup, canEditUser
from fas.auth import *
from fas.user import knownUser, userNameExists
@ -102,7 +102,7 @@ class Group(controllers.Controller):
def new(self):
'''Display create group form'''
userName = turbogears.identity.current.user_name
if not isAdmin(userName):
if not canCreateGroup(userName):
turbogears.flash(_('Only FAS adminstrators can create groups.'))
turbogears.redirect('/')
return dict()
@ -114,7 +114,7 @@ class Group(controllers.Controller):
def create(self, groupName, fedoraGroupDesc, fedoraGroupOwner, fedoraGroupNeedsSponsor="FALSE", fedoraGroupUserCanRemove="FALSE", fedoraGroupJoinMsg=""):
'''Create a group'''
userName = turbogears.identity.current.user_name
if not isAdmin(userName):
if not canCreateGroup(userName):
turbogears.flash(_('Only FAS adminstrators can create groups.'))
turbogears.redirect('/')
try:
@ -168,24 +168,24 @@ class Group(controllers.Controller):
def save(self, groupName, fedoraGroupDesc, fedoraGroupOwner, fedoraGroupType=1, fedoraGroupNeedsSponsor="FALSE", fedoraGroupUserCanRemove="FALSE", fedoraGroupJoinMsg=""):
'''Edit a group'''
userName = turbogears.identity.current.user_name
if not canAdminGroup(userName, groupName):
if not canEditGroup(userName, groupName):
turbogears.flash(_("You cannot edit '%s'.") % groupName)
turbogears.redirect('/group/view/%s' % groupName)
# TODO: This is kind of an ugly hack.
base = 'cn=%s,ou=FedoraGroups,dc=fedoraproject,dc=org' % groupName
try:
fas.fasLDAP.modify(base, 'fedoraGroupDesc', fedoraGroupDesc.encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupOwner', fedoraGroupOwner.encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupType', str(fedoraGroupType).encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupNeedsSponsor', fedoraGroupNeedsSponsor.encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupUserCanRemove', fedoraGroupUserCanRemove.encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupJoinMsg', fedoraGroupJoinMsg.encode('utf8'))
except:
turbogears.flash(_('The group details could not be saved.'))
return dict()
else:
turbogears.flash(_('The group details have been saved.'))
turbogears.redirect('/group/view/%s' % groupName)
base = 'cn=%s,ou=FedoraGroups,dc=fedoraproject,dc=org' % groupName
try:
fas.fasLDAP.modify(base, 'fedoraGroupDesc', fedoraGroupDesc.encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupOwner', fedoraGroupOwner.encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupType', str(fedoraGroupType).encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupNeedsSponsor', fedoraGroupNeedsSponsor.encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupUserCanRemove', fedoraGroupUserCanRemove.encode('utf8'))
fas.fasLDAP.modify(base, 'fedoraGroupJoinMsg', fedoraGroupJoinMsg.encode('utf8'))
except:
turbogears.flash(_('The group details could not be saved.'))
else:
turbogears.flash(_('The group details have been saved.'))
turbogears.redirect('/group/view/%s' % groupName)
return dict()
@expose(template="fas.templates.group.list")
@ -205,16 +205,27 @@ class Group(controllers.Controller):
@error_handler(error)
@expose(template='fas.templates.group.view')
@identity.require(turbogears.identity.not_anonymous())
def apply(self, groupName, userName):
def apply(self, groupName, userName=None):
'''Apply to a group'''
try:
Groups.apply(groupName, userName)
except ldap.ALREADY_EXISTS:
turbogears.flash(_('%(user)s is already in %(group)s!') % {'user': userName, 'group': groupName})
applicant = turbogears.identity.current.user_name
if not userName:
userName = applicant
if not canApplyGroup(applicant, groupName, userName):
turbogears.flash(_('You cannot apply %(user)s for %(group)s!') % \
{'user': userName, 'group': groupName})
turbogears.redirect('/group/view/%s' % groupName)
return dict()
else:
turbogears.flash(_('%(user)s has applied to %(group)s!') % {'user': userName, 'group': groupName})
turbogears.redirect('/group/view/%s' % groupName)
try:
Groups.apply(groupName, userName)
except ldap.ALREADY_EXISTS:
turbogears.flash(_('%(user)s has already applied to %(group)s!') % \
{'user': userName, 'group': groupName})
else:
turbogears.flash(_('%(user)s has applied to %(group)s!') % \
{'user': userName, 'group': groupName})
turbogears.redirect('/group/view/%s' % groupName)
return dict()
@validate(validators=userNameGroupNameExists())
@error_handler(error)
@ -223,21 +234,24 @@ class Group(controllers.Controller):
def sponsor(self, groupName, userName):
'''Sponsor user'''
sponsor = turbogears.identity.current.user_name
if not canSponsorGroup(sponsor, groupName):
turbogears.flash(_("You are not a sponsor for '%s'") % groupName)
if not canSponsorUser(sponsor, groupName, userName):
turbogears.flash(_("You cannot sponsor '%s'") % userName)
turbogears.redirect('/group/view/%s' % groupName)
try:
group = Groups.groups(groupName)[groupName]
except KeyError:
turbogears.flash(_('Group Error: %s does not exist.') % groupName)
# The following line is kind of pointless- any suggestions?
turbogears.redirect('/group/view/%s' % groupName)
p = Person.byUserName(userName)
g = Groups.byGroupName(groupName, includeUnapproved=True)
# TODO: Check if the person actually applied to the group.
p.sponsor(groupName, sponsor)
turbogears.flash(_('%s has been sponsored!') % p.cn)
turbogears.redirect('/group/view/%s' % groupName)
return dict()
else:
p = Person.byUserName(userName)
# TODO: Check if the person actually applied to the group.
# (or should this be done in auth.py or fasLDAP.py?)
# this will probably give a 500 now if the user didn't apply
try:
p.sponsor(groupName, sponsor)
except:
turbogears.flash(_("'%s' could not be sponsored!") % p.cn)
turbogears.redirect('/group/view/%s' % groupName)
else:
turbogears.flash(_("'%s' has been sponsored!") % p.cn)
turbogears.redirect('/group/view/%s' % groupName)
return dict()
@validate(validators=userNameGroupNameExists())
@error_handler(error)
@ -247,23 +261,22 @@ class Group(controllers.Controller):
'''Remove user from group'''
# TODO: Add confirmation?
sponsor = turbogears.identity.current.user_name
if not canSponsorGroup(sponsor, groupName) \
and sponsor != userName: # Users can remove themselves
turbogears.flash(_("You are not a sponsor for '%s'") % groupName)
turbogears.redirect('/group/view/%s' % groupName)
if canAdminGroup(userName, groupName) \
and (not canAdminGroup(sponsor, groupName)):
turbogears.flash(_('Sponsors cannot remove administrators.') % userName)
turbogears.redirect('/group/view/%s' % groupName)
try:
Groups.remove(groupName, userName)
except TypeError:
turbogears.flash(_('%(name)s could not be removed from %(group)s!') % {'name': userName, 'group': groupName})
if not canRemoveUser(sponsor, groupName, userName):
turbogears.flash(_("You cannot remove '%s'.") % userName)
turbogears.redirect('/group/view/%s' % groupName)
return dict()
else:
turbogears.flash(_('%(name)s has been removed from %(group)s!') % {'name': userName, 'group': groupName})
turbogears.redirect('/group/view/%s' % groupName)
return dict()
try:
Groups.remove(groupName, userName)
except:
turbogears.flash(_('%(name)s could not be removed from %(group)s!') % \
{'name': userName, 'group': groupName})
turbogears.redirect('/group/view/%s' % groupName)
else:
turbogears.flash(_('%(name)s has been removed from %(group)s!') % \
{'name': userName, 'group': groupName})
turbogears.redirect('/group/view/%s' % groupName)
return dict()
@validate(validators=userNameGroupNameExists())
@error_handler(error)
@ -272,25 +285,21 @@ class Group(controllers.Controller):
def upgrade(self, groupName, userName):
'''Upgrade user in group'''
sponsor = turbogears.identity.current.user_name
if not canSponsorGroup(sponsor, groupName):
turbogears.flash(_("You are not a sponsor for '%s'") % groupName)
if not canUpgradeUser(sponsor, groupName, userName):
turbogears.flash(_("You cannot upgrade '%s'") % userName)
turbogears.redirect('/group/view/%s' % groupName)
# This is already checked in fasLDAP.py
#if canAdminGroup(userName, groupName):
# turbogears.flash(_('Group administators cannot be upgraded any further.'))
# turbogears.redirect('/group/view/%s' % groupName)
elif canSponsorGroup(userName, groupName) \
and (not canAdminGroup(sponsor, groupName)):
turbogears.flash(_('Sponsors cannot upgrade other sponsors.') % userName)
turbogears.redirect('/group/view/%s' % groupName)
p = Person.byUserName(userName)
try:
p.upgrade(groupName)
except:
turbogears.flash(_('%(name)s could not be upgraded!') % userName)
turbogears.redirect('/group/view/%s' % groupName)
turbogears.flash(_('%s has been upgraded!') % userName)
turbogears.redirect('/group/view/%s' % groupName)
return dict()
else:
p = Person.byUserName(userName)
try:
p.upgrade(groupName)
except:
turbogears.flash(_('%(name)s could not be upgraded!') % userName)
turbogears.redirect('/group/view/%s' % groupName)
else:
turbogears.flash(_('%s has been upgraded!') % userName)
turbogears.redirect('/group/view/%s' % groupName)
return dict()
@validate(validators=userNameGroupNameExists())
@error_handler(error)
@ -299,21 +308,21 @@ class Group(controllers.Controller):
def downgrade(self, groupName, userName):
'''Upgrade user in group'''
sponsor = turbogears.identity.current.user_name
if not canSponsorGroup(sponsor, groupName):
turbogears.flash(_("You are not a sponsor for '%s'") % groupName)
if not canDowngradeUser(sponsor, groupName, userName):
turbogears.flash(_("You cannot downgrade '%s'") % userName)
turbogears.redirect('/group/view/%s' % groupName)
if canAdminGroup(userName, groupName) \
and (not canAdminGroup(sponsor, groupName)):
turbogears.flash(_('Sponsors cannot downgrade group administrators.') % userName)
turbogears.redirect('/group/view/%s' % groupName)
p = Person.byUserName(userName)
try:
p.upgrade(groupName)
except:
turbogears.flash(_('%(name)s could not be downgraded!') % userName)
turbogears.redirect('/group/view/%s' % groupName)
turbogears.flash(_('%s has been downgraded!') % p.cn)
turbogears.redirect('/group/view/%s' % groupName)
return dict()
else:
p = Person.byUserName(userName)
try:
p.upgrade(groupName)
except:
turbogears.flash(_('%(name)s could not be downgraded!') % userName)
turbogears.redirect('/group/view/%s' % groupName)
else:
turbogears.flash(_('%s has been downgraded!') % p.cn)
turbogears.redirect('/group/view/%s' % groupName)
return dict()
@validate(validators=groupNameExists())
@error_handler(error)

View file

@ -70,13 +70,21 @@
<!-- This section includes all action items -->
<td py:if="auth.canSponsorGroup(userName, group.cn)">
<ul>
<li>
<a py:if="group.fedoraGroupNeedsSponsor.upper() == 'TRUE'" href="${tg.url('/group/sponsor/%s/%s' % (groups[user].cn, user))}">Sponsor</a>
<a py:if="not group.fedoraGroupNeedsSponsor.upper() == 'TRUE' and groups[user].fedoraRoleStatus.lower() != 'approved'" href="${tg.url('/group/sponsor/%s/%s' % (groups[user].cn, user))}">Approve</a>
<li py:if="groups[user].fedoraRoleStatus.lower() != 'approved'">
<a py:if="group.fedoraGroupNeedsSponsor.upper() == 'TRUE'"
href="${tg.url('/group/sponsor/%s/%s' % (groups[user].cn, user))}">Sponsor</a>
<a py:if="not group.fedoraGroupNeedsSponsor.upper() == 'TRUE'"
href="${tg.url('/group/sponsor/%s/%s' % (groups[user].cn, user))}">Approve</a>
</li>
<li py:if="auth.canRemoveUser(tg.identity.user.user_name, group.cn, userName)">
<a href="${tg.url('/group/remove/%s/%s' % (groups[user].cn, user))}">Remove</a>
</li>
<li py:if="auth.canUpgradeUser(tg.identity.user.user_name, group.cn, userName)">
<a href="${tg.url('/group/upgrade/%s/%s' % (groups[user].cn, user))}">Upgrade</a>
</li>
<li py:if="auth.canDowngradeUser(tg.identity.user.user_name, group.cn, userName)">
<a href="${tg.url('/group/downgrade/%s/%s' % (groups[user].cn, user))}">Downgrade</a>
</li>
<li><a href="${tg.url('/group/remove/%s/%s' % (groups[user].cn, user))}">Delete</a></li>
<li><a href="${tg.url('/group/upgrade/%s/%s' % (groups[user].cn, user))}">Upgrade</a></li>
<li><a href="${tg.url('/group/downgrade/%s/%s' % (groups[user].cn, user))}">Downgrade</a></li>
</ul>
</td>
</tr>

View file

@ -51,7 +51,7 @@
<li><a href="/">Invite a New Member...</a></li>
<li py:if="auth.canSponsorGroup(user.cn, group)"><a href="${tg.url('/group/view/%s' % group)}">View All Pending Group Membership Requests...</a></li>
<li><a href="${tg.url('/group/view/%s' % group)}">Manage Group Membership...</a></li>
<li py:if="auth.canAdminGroup(user.cn, group)"><a href="${tg.url('/group/edit/%s' % group)}">Manage Group Details...</a></li>
<li py:if="auth.canEditGroup(user.cn, group)"><a href="${tg.url('/group/edit/%s' % group)}">Manage Group Details...</a></li>
</ul>
</dd>
<div py:if="auth.canSponsorGroup(user.cn, group)" py:strip="">

View file

@ -10,7 +10,7 @@ from fas.fasLDAP import Person
from fas.fasLDAP import Groups
from fas.fasLDAP import UserGroup
from fas.auth import isAdmin, canAdminGroup, canSponsorGroup, canEditUser
from fas.auth import *
class knownUser(validators.FancyValidator):
'''Make sure that a user already exists'''