Merge branch 'master' of ssh://git.fedorahosted.org/git/fedora-infrastructure

Fix Conflicts with the latest fix.
This commit is contained in:
Toshio Kuratomi 2008-02-26 22:24:47 -08:00
commit 9e9ee86ec2
8 changed files with 86 additions and 61 deletions

View file

@ -37,11 +37,13 @@ def canAdminGroup(person, group):
return True
else:
try:
role = PersonRoles.query.filter_by(group_id=g.id, person_id=p.id).one()
role = PersonRoles.query.filter_by(group_id=group.id, person_id=person.id).one()
except IndexError:
''' Not in the group '''
return False
if r.role_status == 'approved' and r.role_type == 'administrator':
except InvalidRequestError:
return False
if role.role_status == 'approved' and role.role_type == 'administrator':
return True
return False
@ -165,16 +167,22 @@ def canApplyGroup(person, group, applicant):
# owner of the group (when they initially make it).
prerequisite = group.prerequisite
# TODO: Make this return more useful info.
if prequisite:
if prerequisite:
if prerequisite in person.approved_memberships:
pass
else:
print "GOT HERE %s" % prerequisite
turbogears.flash(_('%s membership required before application to this group is allowed' % prerequisite.name))
return False
# A user can apply themselves, and FAS admins can apply other people.
if (username == applicant) or \
if (person == applicant) or \
canAdminGroup(person, group):
return True
else:
turbogears.flash(_('%s membership required before application to this group is allowed' % prerequisite.name))
return False
def canSponsorUser(person, group, target):
@ -197,10 +205,12 @@ def canRemoveUser(person, group, target):
return False
# A user can remove themself from a group if user_can_remove is 1
# Otherwise, a sponsor can remove sponsors/users.
elif ((person == target) and (group.user_can_remove == 1)) or \
elif ((person == target) and (group.user_can_remove == True)) or \
canSponsorGroup(person, group):
print "GOT HERE TRUE"
return True
else:
print "GOT HERE FALSE"
return False
def canUpgradeUser(person, group, target):

View file

@ -58,7 +58,7 @@ class editGroup(validators.Schema):
class usernameGroupnameExists(validators.Schema):
groupname = validators.All(knownGroup(not_empty=True, max=10), validators.String(max=32, min=3))
username = validators.All(knownUser(not_empty=True, max=10), validators.String(max=32, min=3))
targetname = validators.All(knownUser(not_empty=True, max=10), validators.String(max=32, min=3))
class groupnameExists(validators.Schema):
groupname = validators.All(knownGroup(not_empty=True, max=10), validators.String(max=32, min=3))
@ -174,8 +174,8 @@ class Group(controllers.Controller):
return dict()
else:
try:
session.flush()
owner.apply(group, person) # Apply...
session.flush()
owner.sponsor(group, person)
owner.upgrade(group, person)
owner.upgrade(group, person)
@ -265,8 +265,8 @@ class Group(controllers.Controller):
group = Groups.by_name(groupname)
if not canApplyGroup(person, group, target):
turbogears.flash(_('%(user)s could not apply to %(group)s.') % \
{'user': target.username, 'group': group.name })
# turbogears.flash(_('%(user)s could not apply to %(group)s.') % \
# {'user': target.username, 'group': group.name })
turbogears.redirect('/group/view/%s' % group.name)
return dict()
else:
@ -277,16 +277,18 @@ class Group(controllers.Controller):
{'user': target.username, 'group': group.name})
else:
import turbomail
# TODO: CC to right place, put a bit more thought into how to most elegantly do this
message = turbomail.Message(config.get('accounts_mail'), '%s-sponsors@fedoraproject.org' % group.name, \
"Fedora '%(group)s' sponsor needed for %(user)s" % {'user': target.username, 'group': group.name})
url = config.get('base_url') + turbogears.url('/group/edit/%s' % groupname)
url = config.get('base_url_filter.base_url') + turbogears.url('/group/edit/%s' % groupname)
message.plain = dedent('''
Fedora user %(user)s, aka %(name)s <%(email)s> has requested
membership for %(applicant) (%(applicant_name)) in the %(group) group and needs a sponsor.
membership for %(applicant)s (%(applicant_name)s) in the %(group)s group and needs a sponsor.
Please go to %(url)s to take action.
''') % {'user': person.username, 'name': person.human_name, 'applicant': target.username, 'applicant_name': target.human_name, 'email': person.emails['primary'].email, 'url': url}
''' % {'user': person.username, 'name': person.human_name, 'applicant': target.username, 'applicant_name': target.human_name, 'email': person.emails['primary'].email, 'url': url, 'group': group.name} )
turbomail.enqueue(message)
turbogears.flash(_('%(user)s has applied to %(group)s!') % \
{'user': target.username, 'group': group.name})
@ -338,23 +340,23 @@ class Group(controllers.Controller):
# TODO: Add confirmation?
username = turbogears.identity.current.user_name
person = People.by_username(username)
target = People.by_username(targetname)
requester = People.by_username(targetname)
group = Groups.by_name(groupname)
if not canRemoveUser(person, group, target):
if not canRemoveUser(person, group, requester):
turbogears.flash(_("You cannot remove '%s'.") % target.username)
turbogears.redirect('/group/view/%s' % group.name)
return dict()
else:
try:
group.remove_person(person, target)
except:
person.remove(group, requester)
except KeyError:
turbogears.flash(_('%(name)s could not be removed from %(group)s!') % \
{'name': target.username, 'group': group.name})
{'name': requester.username, 'group': group.name})
turbogears.redirect('/group/view/%s' % group.name)
else:
import turbomail
message = turbomail.Message(config.get('accounts_mail'), target.emails['primary'].email, "Your Fedora '%s' membership has been removed" % group.name)
message = turbomail.Message(config.get('accounts_mail'), requester.emails['primary'].email, "Your Fedora '%s' membership has been removed" % group.name)
message.plain = dedent('''
%(name)s <%(email)s> has removed you from the '%(group)s'
group of the Fedora Accounts System This change is effective
@ -363,7 +365,7 @@ class Group(controllers.Controller):
''') % {'group': group.name, 'name': person.human_name, 'email': person.emails['primary'].email}
turbomail.enqueue(message)
turbogears.flash(_('%(name)s has been removed from %(group)s!') % \
{'name': target.username, 'group': group.name})
{'name': requester.username, 'group': group.name})
turbogears.redirect('/group/view/%s' % group.name)
return dict()

View file

@ -37,6 +37,8 @@ from sqlalchemy.orm.collections import column_mapped_collection
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy import select, and_
from turbogears.database import session
from turbogears import identity
from fas.json import SABase
@ -112,7 +114,7 @@ class People(SABase):
by_username = classmethod(by_username)
# If we're going to do logging here, we'll have to pass the person that did the applying.
def apply(cls, group, requestor):
def apply(cls, group, requester):
'''
Apply a person to a group
'''
@ -122,9 +124,9 @@ class People(SABase):
role.member = cls
role.group = group
def approve(cls, group, requestor):
def approve(cls, group, requester):
'''
Approve a person in a group - requestor for logging purposes
Approve a person in a group - requester for logging purposes
'''
if group in cls.approved_memberships:
raise '%s is already approved in %s' % (cls.username, group.name)
@ -132,9 +134,9 @@ class People(SABase):
role = PersonRoles.query.filter_by(person_id=cls.id, group_id=group.id).first()
role.role_status = 'approved'
def upgrade(cls, group, requestor):
def upgrade(cls, group, requester):
'''
Upgrade a user in a group - requestor for logging purposes
Upgrade a user in a group - requester for logging purposes
'''
if not group in cls.memberships:
raise '%s not a member of %s' % (group.name, cls.memberships)
@ -147,9 +149,9 @@ class People(SABase):
elif role.role_type == 'user':
role.role_type = 'sponsor'
def downgrade(cls, group, requestor):
def downgrade(cls, group, requester):
'''
Downgrade a user in a group - requestor for logging purposes
Downgrade a user in a group - requester for logging purposes
'''
if not group in cls.memberships:
raise '%s not a member of %s' % (group.name, cls.memberships)
@ -162,20 +164,20 @@ class People(SABase):
elif role.role_type == 'administrator':
role.role_type = 'sponsor'
def sponsor(cls, group, requestor):
def sponsor(cls, group, requester):
# If we want to do logging, this might be the place.
# TODO: Find out how to log timestamp
if not group in cls.memberships:
raise '%s not a member of %s' % (group.name, cls.memberships)
role = PersonRoles.query.filter_by(person_id=cls.id, group_id=group.id).first()
role.role_status = 'approved'
role.sponsor_id = requestor.id
role.sponsor_id = requester.id
def remove(cls, group, requestor):
def remove(cls, group, requester):
role = PersonRoles.query.filter_by(person_id=cls.id, group_id=group.id).first()
try:
session.delete(role)
except:
except TypeError:
pass
# Handle somehow.

View file

@ -39,11 +39,11 @@
<td><a href="${tg.url('/group/view/%s' % group.name)}">${group.name}</a></td>
<td>${ group.display_name }</td>
<td>
<a py:if="group in person.roles" href="${tg.url('/group/view/%s' % group)}">
<!--<span class="approved" py:if="myGroups[group].fedoraRoleStatus.lower() == 'approved'">${_('Approved')}</span>
<span class="unapproved" py:if="myGroups[group].fedoraRoleStatus.lower() == 'unapproved'">${_('Unapproved')}</span>-->
<a py:if="group in person.memberships" href="${tg.url('/group/view/%s' % group.name)}">
<span class="approved" py:if="group in person.approved_memberships">${_('Approved')}</span>
<span class="unapproved" py:if="group in person.unapproved_memberships">${_('Unapproved')}</span>
</a>
<a py:if="group not in person.roles" href="${tg.url('/group/apply/%s/%s' % (group, person))}"><span>${_('Apply')}</span></a>
<a py:if="group not in person.memberships" href="${tg.url('/group/apply/%s/%s' % (group.name, person.username))}"><span>${_('Apply')}</span></a>
</td>
</div>
</tr>

View file

@ -11,8 +11,8 @@
<h2>${group.display_name} (${group.name})</h2>
<h3>
${_('My Status:')}
<span py:if="auth.isApproved(person, group)" class="approved">${_('Approved')}</span>
<span py:if="not auth.isApproved(person, group)" class="unapproved">${_('Unapproved')}</span>
<span py:if="group in person.memberships and group in person.approved_memberships" class="approved">${_('Approved')}</span>
<span py:if="group in person.memberships and not group in person.approved_memberships" class="unapproved">${_('Unapproved')}</span>
<span py:if="not group in person.memberships">${_('Not a Member')}</span>
</h3>
<form py:if="not group in person.memberships" action="${tg.url('/group/apply/%s/%s' % (group.name, person.username))}">
@ -22,7 +22,7 @@
</div>
</form>
<a py:if="group in person.memberships" href="${tg.url('/group/remove/%s/%s' % (group.name, person.username))}">${_('Remove me')}</a>
<h3>Group Details <a href="${tg.url('/group/edit/%s' % group.name)}">${_('(edit)')}</a></h3>
<h3>Group Details <a py:if="auth.canAdminGroup(person, group)" href="${tg.url('/group/edit/%s' % group.name)}">${_('(edit)')}</a></h3>
<div class="userbox">
<dl>
<dt>${_('Name:')}</dt><dd>${group.name}&nbsp;</dd>
@ -38,6 +38,9 @@
<span py:if="group.user_can_remove == 0" py:strip="">${_('No')}</span>
&nbsp;</dd>
<dt>${_('Join Message:')}</dt><dd>${group.joinmsg}&nbsp;</dd>
<dt>${_('Prerequisite:')}</dt>
<dd py:if="group.prerequisite">${group.prerequisite.name}&nbsp;</dd>
<dd py:if="not group.prerequisite">&nbsp;</dd>
<dt>${_('Created:')}</dt><dd>${group.creation}&nbsp;</dd>
</dl>
</div>
@ -67,20 +70,20 @@
from datetime import datetime
from pytz import timezone
?>
<td><!--${datetime.fromtimestamp(float(role.member.creation), timezone(role.member.timezone)).strftime('%F %R %Z')}--></td>
<td>${role.member.creation}<!--${datetime.fromtimestamp(float(role.member.creation), timezone(role.member.timezone)).strftime('%F %R %Z')}--></td>
<td py:if="role.approval == 'none'">${role.member.creation}</td>
<td py:if="role.approval != 'none'"><!--${datetime.fromtimestamp(float(role.member.creation), timezone(role.member.timezone)).strftime('%F %R %Z')}--></td>
<td py:if="role.approval != 'none'">${role.member.timezone}<!--${datetime.fromtimestamp(float(role.member.creation), timezone(role.member.timezone)).strftime('%F %R %Z')}--></td>
<td>${role.role_status}</td>
<td>${role.role_type}</td>
<!--<td>${groups[user].fedoraRoleDomain}</td>-->
<!-- This section includes all action items -->
<td py:if="auth.canSponsorGroup(role.member, group)">
<ul>
<!--
<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'"
<li py:if="group in role.member.memberships">
<a py:if="group in role.member.unapproved_memberships"
href="${tg.url('/group/sponsor/%s/%s' % (group.name, role.member.username))}">${_('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)">
@ -90,9 +93,9 @@
<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>
<a href="${tg.url('/group/downgrade/%s/%s' % (groups[user].cn, user))}">${_('Downgrade')}</a>-->
</li>
-->
</ul>
</td>
</tr>

View file

@ -50,11 +50,11 @@
<div id="sidebar">
<ul>
<li class="first"><a href="${tg.url('/group/list')}">${_('Group List')}</a></li>
<!--<div py:if="'accounts' in tg.identity.groups" py:strip=''> -->
<div py:if="not tg.identity.anonymous and 'accounts' in tg.identity.groups" py:strip=''>
<!-- TODO: Make these use auth.py -->
<!-- <li><a href="${tg.url('/user/list')}">${_('User List')}</a></li>
<li><a href="${tg.url('/user/list')}">${_('User List')}</a></li>
<li><a href="${tg.url('/group/new')}">${_('New Group')}</a></li>
</div>-->
</div>
<li><a href="${tg.url('/group/list/A*')}">${_('Apply For a new Group')}</a></li>
<li><a href="http://fedoraproject.org/wiki/FWN/LatestIssue">${_('News')}</a></li>
</ul>

View file

@ -28,11 +28,11 @@
</tr>
</thead>
<tbody>
<tr py:for="user in sorted(users)">
<td><a href="${tg.url('/user/view/%s' % user)}">${user}</a></td>
<tr py:for="person in people">
<td><a href="${tg.url('/user/view/%s' % person.username)}">${person.username}</a></td>
<td>
<span py:if="claDone[user]" class="approved">${_('CLA Done')}</span>
<span py:if="not claDone[user]" class="unapproved">${_('CLA Not Done')}</span>
<span py:if="cla_done_group in person.memberships" class="approved">${_('CLA Done')}</span>
<span py:if="not cla_done_group in person.memberships" class="unapproved">${_('CLA Not Done')}</span>
</td>
</tr>
</tbody>

View file

@ -1,6 +1,7 @@
import turbogears
from turbogears import controllers, expose, paginate, identity, redirect, widgets, validate, validators, error_handler
from turbogears.database import session
import cherrypy
import ldap
@ -135,6 +136,11 @@ class User(controllers.Controller):
'''
turbogears.redirect('/user/view/%s' % turbogears.identity.current.user_name)
def jsonRequest(self):
return 'tg_format' in cherrypy.request.params and \
cherrypy.request.params['tg_format'] == 'json'
@expose(template="fas.templates.error")
def error(self, tg_errors=None):
'''Show a friendly error message'''
@ -222,17 +228,19 @@ class User(controllers.Controller):
return dict(target=target)
@identity.require(turbogears.identity.in_group("accounts")) #TODO: Use auth.py
@expose(template="fas.templates.user.list")
@expose(template="fas.templates.user.list", allow_json=True)
def list(self, search="a*"):
'''List users
'''
people = People.query.filter(People.username.like('%%%s%%' % username))
try:
people[0]
except:
turbogears.flash(_("No users found matching '%s'") % search)
people = []
return dict(users=users, search=search)
re_search = re.sub(r'\*', r'%', search).lower()
people = People.query.filter(People.username.like(re_search)).order_by('username')
if people.count() < 0:
turbogears.flash(_("No Users found matching '%s'") % search)
if self.jsonRequest():
return ({'users': users})
cla_done_group = Groups.by_name('cla_done')
return dict(people=people, search=search, cla_done_group=cla_done_group)
@expose(template='fas.templates.user.new')
def new(self):