Merge branch 'master' of ssh://git.fedorahosted.org/git/fedora-infrastructure
This commit is contained in:
commit
366a39ac5a
7 changed files with 186 additions and 40 deletions
|
@ -25,6 +25,9 @@ import logging
|
||||||
import syslog
|
import syslog
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import codecs
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
|
||||||
from fedora.tg.client import BaseClient, AuthError, ServerError
|
from fedora.tg.client import BaseClient, AuthError, ServerError
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
@ -193,8 +196,8 @@ class MakeShellAccounts(BaseClient):
|
||||||
|
|
||||||
def passwd_text(self, people=None):
|
def passwd_text(self, people=None):
|
||||||
i = 0
|
i = 0
|
||||||
passwd_file = open(self.temp + '/passwd.txt', 'w')
|
passwd_file = codecs.open(self.temp + '/passwd.txt', mode='w', encoding='utf-8')
|
||||||
shadow_file = open(self.temp + '/shadow.txt', 'w')
|
shadow_file = codecs.open(self.temp + '/shadow.txt', mode='w', encoding='utf-8')
|
||||||
os.chmod(self.temp + '/shadow.txt', 00400)
|
os.chmod(self.temp + '/shadow.txt', 00400)
|
||||||
if not self.people:
|
if not self.people:
|
||||||
self.people = self.people_list()
|
self.people = self.people_list()
|
||||||
|
@ -332,7 +335,8 @@ class MakeShellAccounts(BaseClient):
|
||||||
if not os.path.exists(home_backup_dir):
|
if not os.path.exists(home_backup_dir):
|
||||||
os.makedirs(home_backup_dir)
|
os.makedirs(home_backup_dir)
|
||||||
syslog.syslog('Backed up %s to %s' % (user, home_backup_dir))
|
syslog.syslog('Backed up %s to %s' % (user, home_backup_dir))
|
||||||
move(os.path.join(home_base, user), os.path.join(home_backup_dir, user))
|
target = '%s-%s' % (user, time.mktime(datetime.datetime.now().timetuple()))
|
||||||
|
move(os.path.join(home_base, user), os.path.join(home_backup_dir, target))
|
||||||
|
|
||||||
def create_ssh_keys(self):
|
def create_ssh_keys(self):
|
||||||
''' Create ssh keys '''
|
''' Create ssh keys '''
|
||||||
|
|
|
@ -65,7 +65,7 @@ for person in c.fetchall():
|
||||||
try:
|
try:
|
||||||
session.flush()
|
session.flush()
|
||||||
except IntegrityError, e:
|
except IntegrityError, e:
|
||||||
print "\tCould not create %s - %s" % (username, e)
|
print "\tERROR - Could not create %s - %s" % (username, e)
|
||||||
session.close()
|
session.close()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ for person in c.fetchall():
|
||||||
try:
|
try:
|
||||||
person_email.email = email
|
person_email.email = email
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
print "\tCould not create email for %s (%s)" % (username, email)
|
print "\tERROR - Could not create email for %s (%s)" % (username, email)
|
||||||
session.close()
|
session.close()
|
||||||
continue
|
continue
|
||||||
person_email.person = p
|
person_email.person = p
|
||||||
|
@ -108,18 +108,18 @@ for group in c.fetchall():
|
||||||
group.group_type = group_type
|
group.group_type = group_type
|
||||||
group.needs_sponsor = bool(bool_dict[needs_sponsor])
|
group.needs_sponsor = bool(bool_dict[needs_sponsor])
|
||||||
group.user_can_remove = bool(bool_dict[user_can_remove])
|
group.user_can_remove = bool(bool_dict[user_can_remove])
|
||||||
if prerequisite_id:
|
# if prerequisite_id:
|
||||||
prerequisite = Groups.by_id(prerequisite_id)
|
# prerequisite = Groups.by_id(prerequisite_id)
|
||||||
group.prerequisite = prerequisite
|
# group.prerequisite = prerequisite
|
||||||
group.joinmsg = joinmsg
|
group.joinmsg = joinmsg
|
||||||
# Log here
|
# Log here
|
||||||
session.flush()
|
session.flush()
|
||||||
except IntegrityError, e:
|
except IntegrityError, e:
|
||||||
print "The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
print "\tERROR - The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
||||||
except FlushError, e:
|
except FlushError, e:
|
||||||
print "The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
print "\tERROR - The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
||||||
except InvalidRequestError, e:
|
except InvalidRequestError, e:
|
||||||
print "The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
print "\tERROR - The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
||||||
|
|
||||||
session.close()
|
session.close()
|
||||||
|
|
||||||
|
@ -130,13 +130,18 @@ for role in c.fetchall():
|
||||||
print "%s - %s" % (person_id, project_group_id)
|
print "%s - %s" % (person_id, project_group_id)
|
||||||
try:
|
try:
|
||||||
role = PersonRoles()
|
role = PersonRoles()
|
||||||
|
if len(role_status) > 10:
|
||||||
|
role_status = 'approved'
|
||||||
|
if role_status == 'declined':
|
||||||
|
''' No longer exists '''
|
||||||
|
continue
|
||||||
role.role_status = role_status
|
role.role_status = role_status
|
||||||
role.role_type = role_type
|
role.role_type = role_type
|
||||||
role.member = People.by_id(person_id)
|
role.member = People.by_id(person_id)
|
||||||
role.group = Groups.by_id(project_group_id)
|
role.group = Groups.by_id(project_group_id)
|
||||||
session.flush()
|
session.flush()
|
||||||
except ProgrammingError, e:
|
except ProgrammingError, e:
|
||||||
print "The role %s -> %s could not be created - %s" % (person_id, project_group_id, e)
|
print "\tERROR - The role %s -> %s could not be created - %s" % (person_id, project_group_id, e)
|
||||||
except IntegrityError, e:
|
except IntegrityError, e:
|
||||||
print "The role %s -> %s could not be created - %s" % (person_id, project_group_id, e)
|
print "\tERROR - The role %s -> %s could not be created - %s" % (person_id, project_group_id, e)
|
||||||
session.close()
|
session.close()
|
|
@ -23,8 +23,8 @@
|
||||||
</dl>
|
</dl>
|
||||||
</py:for>
|
</py:for>
|
||||||
<ul class="queue">
|
<ul class="queue">
|
||||||
<span py:if="cla == 'clicked'" class="approved">${_('Click-through CLA')}<py:if test="personal"> (<a href="${tg.url('/cla/')}">${_('GPG Sign it!')}</a></py:if>)</span>
|
<span py:if="cla == 'clicked'" class="approved">${_('Click-through CLA')} (<a href="${tg.url('/cla/')}">${_('GPG Sign it!')}</a>)</span>
|
||||||
<span py:if="not cla" class="unapproved">${_('Not Done')}<py:if test="personal"> (<a href="${tg.url('/cla/')}">${_('Sign it!')}</a>)</py:if></span>
|
<span py:if="not cla" class="unapproved">${_('Not Done')} (<a href="${tg.url('/cla/')}">${_('Sign it!')}</a>)</span>
|
||||||
|
|
||||||
<li py:if="cla == None">
|
<li py:if="cla == None">
|
||||||
${_('CLA Not Signed. To become a full Fedora Contributor please ')}<a href="${tg.url('/cla/')}">${_('sign the CLA')}</a>.
|
${_('CLA Not Signed. To become a full Fedora Contributor please ')}<a href="${tg.url('/cla/')}">${_('sign the CLA')}</a>.
|
||||||
|
|
|
@ -8,15 +8,15 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>${_('Add Email')}</h2>
|
<h2>${_('Add Email')}</h2>
|
||||||
<form action="${tg.url('/user/email/save/%s' % target.username)}" method="post" enctype="multipart/form-data">
|
<form action="${tg.url('/user/email/create/%s' % target.username)}" method="post">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="email">${_('Email')}:</label>
|
<label for="email">${_('Email:')}</label>
|
||||||
<input type="text" id="email" name="email" />
|
<input type="text" id="email" name="email" />
|
||||||
<!-- TODO: More generic documentation for adding an email -->
|
<!-- TODO: More generic documentation for adding an email -->
|
||||||
<script type="text/javascript">var hb1 = new HelpBalloon({dataURL: '${tg.url('/help/get_help/user_primary_email')}'});</script>
|
<script type="text/javascript">var hb1 = new HelpBalloon({dataURL: '${tg.url('/help/get_help/user_primary_email')}'});</script>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="description">${_('Description')}:</label>
|
<label for="description">${_('Description:')}</label>
|
||||||
<input type="text" id="description" name="description" />
|
<input type="text" id="description" name="description" />
|
||||||
<!-- TODO: Correct documentation for this -->
|
<!-- TODO: Correct documentation for this -->
|
||||||
<script type="text/javascript">var hb1 = new HelpBalloon({dataURL: '${tg.url('/help/get_help/user_primary_email')}'});</script>
|
<script type="text/javascript">var hb1 = new HelpBalloon({dataURL: '${tg.url('/help/get_help/user_primary_email')}'});</script>
|
||||||
|
|
28
fas/fas/templates/user/email/edit.html
Normal file
28
fas/fas/templates/user/email/edit.html
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:py="http://genshi.edgewall.org/"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
<xi:include href="../../master.html" />
|
||||||
|
<head>
|
||||||
|
<title>${_('Edit Email')}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>${_('Edit Email')}</h2>
|
||||||
|
<form action="${tg.url('/user/email/save/%s' % target.username)}" method="post">
|
||||||
|
<div class="field">
|
||||||
|
<label for="email">${_('Email:')}</label> <span>${email}</span>
|
||||||
|
<input type="hidden" id="email" name="email" value="${email}" />
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label for="description">${_('Description:')}</label>
|
||||||
|
<input type="text" id="description" name="description" value="${target.person_emails[email].description}" />
|
||||||
|
<!-- TODO: Correct documentation for this -->
|
||||||
|
<script type="text/javascript">var hb1 = new HelpBalloon({dataURL: '${tg.url('/help/get_help/user_primary_email')}'});</script>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<input type="submit" value="${_('Save!')}" />
|
||||||
|
<a href="${tg.url('/user/email/manage')}">${_('Cancel')}</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -22,11 +22,13 @@
|
||||||
<td><a href="mailto:${email.email}">${email.email}</a></td>
|
<td><a href="mailto:${email.email}">${email.email}</a></td>
|
||||||
<td>${email.description}</td>
|
<td>${email.description}</td>
|
||||||
<td py:if="email.verified"><span class="approved">${_('Verified')}</span></td>
|
<td py:if="email.verified"><span class="approved">${_('Verified')}</span></td>
|
||||||
<td py:if="not email.verified"><span class="unapproved">${_('Unverified')}</span> <a href="${tg.url('/email/verify')}">${_('Resend Verification')}</a></td>
|
<td py:if="not email.verified"><span class="unapproved">${_('Unverified')}</span> (<a href="${tg.url('/email/verify')}">${_('Resend Verification')}</a>)</td>
|
||||||
|
<td py:if="len(target.person_emails) > 1"><a href="${tg.url('/user/email/remove/%s/%s') % (target.username, email.email)}">${_('Remove')}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<h3>Set Emails</h3>
|
<h3>Set Emails</h3>
|
||||||
|
<form action="${tg.url('/user/email/map/%s' % target.username)}">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -37,11 +39,18 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr py:for="purpose in target.email_purposes.values()">
|
<tr py:for="purpose in target.email_purposes.values()">
|
||||||
<td><a href="mailto:${purpose.email}">${purpose.email}</a></td>
|
<td>
|
||||||
|
<select id="email" name="email">
|
||||||
|
<py:for each="person_email in target.person_emails.values()">
|
||||||
|
<option py:if="person_email.verified" value="person_email.email" py:attrs="{'selected': purpose.email == person_email.email and 'selected' or None}">${person_email.email} (${person_email.description})</option>
|
||||||
|
</py:for>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
<td>${purpose.person_email.description}</td>
|
<td>${purpose.person_email.description}</td>
|
||||||
<td>${purpose.purpose}</td>
|
<td>${purpose.purpose}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</form>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -36,6 +36,13 @@ def generate_validtoken(length=32):
|
||||||
token += random.choice(chars)
|
token += random.choice(chars)
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
# Note: I'm making some of these controllers really, really hideous
|
||||||
|
# (in the interest of allowing admins to modify pretty much everything)
|
||||||
|
# Is this really necessary (as in, can tg-admin shell be "good enough?"
|
||||||
|
# (I'm pretty much referring to passing the username around every
|
||||||
|
# instead of just using the current logged on person.)
|
||||||
|
|
||||||
|
# I hope all of this doesn't end up being too convoluted for most users...
|
||||||
class Email(controllers.Controller):
|
class Email(controllers.Controller):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -79,9 +86,68 @@ class Email(controllers.Controller):
|
||||||
return dict(target=target)
|
return dict(target=target)
|
||||||
|
|
||||||
@identity.require(turbogears.identity.not_anonymous())
|
@identity.require(turbogears.identity.not_anonymous())
|
||||||
|
# TODO: Validate!
|
||||||
#@validate(validators=UserView())
|
#@validate(validators=UserView())
|
||||||
@error_handler(error)
|
@error_handler(error)
|
||||||
@expose(template="fas.templates.user.email.add", allow_json=True)
|
@expose(template="fas.templates.user.email.edit")
|
||||||
|
# TODO: Should the purpose-setting part be moved in into user/save?
|
||||||
|
def edit(self, targetname, email):
|
||||||
|
'''
|
||||||
|
Display the form to edit an email
|
||||||
|
'''
|
||||||
|
username = turbogears.identity.current.user_name
|
||||||
|
person = People.by_username(username)
|
||||||
|
|
||||||
|
if targetname:
|
||||||
|
target = People.by_username(targetname)
|
||||||
|
else:
|
||||||
|
target = person
|
||||||
|
|
||||||
|
if not canEditUser(person, target):
|
||||||
|
turbogears.flash(_('You cannot edit %s') % target.username )
|
||||||
|
turbogears.redirect('/user/email/manage')
|
||||||
|
return dict()
|
||||||
|
return dict(email=email, target=target)
|
||||||
|
|
||||||
|
@identity.require(turbogears.identity.not_anonymous())
|
||||||
|
# TODO: Validate!
|
||||||
|
#@validate(validators=UserView())
|
||||||
|
@error_handler(error)
|
||||||
|
@expose()
|
||||||
|
# TODO: Should the purpose-setting part be moved in into user/save?
|
||||||
|
def save(self, targetname, email, description):
|
||||||
|
'''
|
||||||
|
Save an email entry
|
||||||
|
'''
|
||||||
|
username = turbogears.identity.current.user_name
|
||||||
|
person = People.by_username(username)
|
||||||
|
|
||||||
|
if targetname:
|
||||||
|
target = People.by_username(targetname)
|
||||||
|
else:
|
||||||
|
target = person
|
||||||
|
|
||||||
|
if not canEditUser(person, target):
|
||||||
|
turbogears.flash(_('You cannot edit %s') % target.username )
|
||||||
|
turbogears.redirect('/user/email/manage')
|
||||||
|
return dict()
|
||||||
|
|
||||||
|
try:
|
||||||
|
person.person_emails[email].description = description
|
||||||
|
except KeyError:
|
||||||
|
turbogears.flash(_('No such email is associated with your user.'))
|
||||||
|
turbogears.redirect('/user/email/manage')
|
||||||
|
return dict()
|
||||||
|
else:
|
||||||
|
turbogears.flash(_('Your email has been saved.'))
|
||||||
|
turbogears.redirect('/user/email/manage')
|
||||||
|
return dict()
|
||||||
|
|
||||||
|
@identity.require(turbogears.identity.not_anonymous())
|
||||||
|
# TODO: Validate!
|
||||||
|
#@validate(validators=UserView())
|
||||||
|
@error_handler(error)
|
||||||
|
@expose(template="fas.templates.user.email.add")
|
||||||
def add(self, targetname=None):
|
def add(self, targetname=None):
|
||||||
'''
|
'''
|
||||||
Display the form to add an email
|
Display the form to add an email
|
||||||
|
@ -101,13 +167,47 @@ class Email(controllers.Controller):
|
||||||
|
|
||||||
return dict(target=target)
|
return dict(target=target)
|
||||||
|
|
||||||
|
@identity.require(turbogears.identity.not_anonymous())
|
||||||
|
# TODO: Validate!
|
||||||
|
#@validate(validators=UserView())
|
||||||
|
@error_handler(error)
|
||||||
|
@expose(allow_json=True)
|
||||||
|
def remove(self, targetname, email):
|
||||||
|
'''
|
||||||
|
Remove an email
|
||||||
|
'''
|
||||||
|
username = turbogears.identity.current.user_name
|
||||||
|
person = People.by_username(username)
|
||||||
|
|
||||||
|
if targetname:
|
||||||
|
target = People.by_username(targetname)
|
||||||
|
else:
|
||||||
|
target = person
|
||||||
|
|
||||||
|
if not canEditUser(person, target):
|
||||||
|
turbogears.flash(_('You cannot edit %s') % target.username )
|
||||||
|
turbogears.redirect('/user/email/manage')
|
||||||
|
return dict()
|
||||||
|
|
||||||
|
try:
|
||||||
|
session.delete(target.person_emails[email])
|
||||||
|
session.flush()
|
||||||
|
except IntegrityError:
|
||||||
|
turbogears.flash(_('You cannot delete an email that is in use.'))
|
||||||
|
turbogears.redirect('/user/email/manage')
|
||||||
|
return dict()
|
||||||
|
else:
|
||||||
|
turbogears.flash(_('The email \'%s\' has been removed.') % email )
|
||||||
|
turbogears.redirect('/user/email/manage')
|
||||||
|
return dict()
|
||||||
|
|
||||||
@identity.require(turbogears.identity.not_anonymous())
|
@identity.require(turbogears.identity.not_anonymous())
|
||||||
@validate(validators=EmailSave())
|
@validate(validators=EmailSave())
|
||||||
@error_handler(error)
|
@error_handler(error)
|
||||||
@expose(template="fas.templates.user.email.add", allow_json=True)
|
@expose(template="fas.templates.user.email.add", allow_json=True)
|
||||||
def save(self, targetname, email, description):
|
def create(self, targetname, email, description):
|
||||||
'''
|
'''
|
||||||
Display the form to add an email
|
Create an email entry.
|
||||||
'''
|
'''
|
||||||
username = turbogears.identity.current.user_name
|
username = turbogears.identity.current.user_name
|
||||||
person = People.by_username(username)
|
person = People.by_username(username)
|
||||||
|
@ -144,8 +244,8 @@ Go to this URL to verify that you own this email address: %s
|
||||||
''') % validurl
|
''') % validurl
|
||||||
turbomail.enqueue(message)
|
turbomail.enqueue(message)
|
||||||
turbogears.flash(_('Your email has been added. Before you can use this email, you must verify it. The email you added should receive a message with instructions shortly.'))
|
turbogears.flash(_('Your email has been added. Before you can use this email, you must verify it. The email you added should receive a message with instructions shortly.'))
|
||||||
|
turbogears.redirect('/user/email/manage')
|
||||||
return dict(target=target)
|
return dict()
|
||||||
|
|
||||||
return dict(target=target)
|
return dict(target=target)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue