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

This commit is contained in:
Michael McGrath 2008-03-06 21:18:22 -06:00
commit b7088d5029
5 changed files with 148 additions and 22 deletions

View file

@ -102,12 +102,20 @@ visit_identity_table = Table('visit_identity', metadata,
class People(SABase): class People(SABase):
'''Records for all the contributors to Fedora.''' '''Records for all the contributors to Fedora.'''
def by_id(cls, id):
'''
A class method that can be used to search users
based on their unique id
'''
return cls.query.filter_by(id=id).one()
by_id = classmethod(by_id)
def by_email_address(cls, email): def by_email_address(cls, email):
''' '''
A class method that can be used to search users A class method that can be used to search users
based on their email addresses since it is unique. based on their email addresses since it is unique.
''' '''
return cls.query.join('emails').filter_by(email=email).first() return cls.query.join(['email_purposes', 'person_email']).filter_by(email=email).one()
by_email_address = classmethod(by_email_address) by_email_address = classmethod(by_email_address)
@ -292,6 +300,24 @@ class Configs(SABase):
class Groups(SABase): class Groups(SABase):
'''Group that people can belong to.''' '''Group that people can belong to.'''
def by_id(cls, id):
'''
A class method that can be used to search groups
based on their unique id
'''
return cls.query.filter_by(id=id).one()
by_id = classmethod(by_id)
def by_email_address(cls, email):
'''
A class method that can be used to search groups
based on their email addresses since it is unique.
'''
return cls.query.join(['group_email_purposes', 'group_email']).filter_by(email=email).one()
by_email_address = classmethod(by_email_address)
def by_name(cls, name): def by_name(cls, name):
''' '''
A class method that permits to search groups A class method that permits to search groups
@ -403,7 +429,7 @@ mapper(People, PeopleTable, properties = {
primaryjoin = PeopleTable.c.id==UnApprovedRoles.c.person_id) primaryjoin = PeopleTable.c.id==UnApprovedRoles.c.person_id)
}) })
mapper(PersonEmails, PersonEmailsTable, properties = { mapper(PersonEmails, PersonEmailsTable, properties = {
'person': relation(People, uselist = False, 'person': relation(People, backref = 'person_emails', uselist = False,
primaryjoin = PeopleTable.c.id==PersonEmailsTable.c.person_id) primaryjoin = PeopleTable.c.id==PersonEmailsTable.c.person_id)
}) })
mapper(EmailPurposes, EmailPurposesTable, properties = { mapper(EmailPurposes, EmailPurposesTable, properties = {
@ -430,7 +456,7 @@ mapper(Groups, GroupsTable, properties = {
primaryjoin = GroupsTable.c.prerequisite_id==GroupsTable.c.id) primaryjoin = GroupsTable.c.prerequisite_id==GroupsTable.c.id)
}) })
mapper(GroupEmails, GroupEmailsTable, properties = { mapper(GroupEmails, GroupEmailsTable, properties = {
'group': relation(Groups, uselist = False, 'group': relation(Groups, backref = 'group_emails', uselist = False,
primaryjoin = GroupsTable.c.id==GroupEmailsTable.c.group_id) primaryjoin = GroupsTable.c.id==GroupEmailsTable.c.group_id)
}) })
mapper(GroupEmailPurposes, GroupEmailPurposesTable, properties = { mapper(GroupEmailPurposes, GroupEmailPurposesTable, properties = {

View file

View file

@ -0,0 +1,47 @@
<!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>${_('Manage Emails')}</title>
</head>
<body>
<h2>${_('Managing Emails for %s') % person.username}</h2>
<h3>Available Emails</h3>
<table>
<thead>
<tr>
<th>${_('Email')}</th>
<th>${_('Description')}</th>
<th>${_('Verified')}</th>
</tr>
</thead>
<tbody>
<tr py:for="email in person.person_emails">
<td><a href="mailto:${email.email}">${email.email}</a></td>
<td>${email.description}</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>
</tr>
</tbody>
</table>
<h3>Set Emails</h3>
<table>
<thead>
<tr>
<th>${_('Email')}</th>
<th>${_('Description')}</th>
<th>${_('Purpose')}</th>
</tr>
</thead>
<tbody>
<tr py:for="purpose in person.email_purposes.values()">
<td><a href="mailto:${purpose.email}">${purpose.email}</a></td>
<td>${purpose.person_email.description}</td>
<td>${purpose.purpose}</td>
</tr>
</tbody>
</table>
</body>
</html>

View file

@ -13,9 +13,11 @@ import subprocess
from fas.model import People from fas.model import People
from fas.model import PersonEmails from fas.model import PersonEmails
from fas.model import EmailPurposes
from fas.model import Log from fas.model import Log
from fas.auth import * from fas.auth import *
from fas.user_email import Email, NonFedoraEmail
from random import Random from random import Random
import sha import sha
@ -32,14 +34,6 @@ class KnownUser(validators.FancyValidator):
except InvalidRequestError: except InvalidRequestError:
raise validators.Invalid(_("'%s' does not exist.") % value, value, state) raise validators.Invalid(_("'%s' does not exist.") % value, value, state)
class NonFedoraEmail(validators.FancyValidator):
'''Make sure that an email address is not @fedoraproject.org'''
def _to_python(self, value, state):
return value.strip()
def validate_python(self, value, state):
if value.endswith('@fedoraproject.org'):
raise validators.Invalid(_("To prevent email loops, your email address cannot be @fedoraproject.org."), value, state)
class UnknownUser(validators.FancyValidator): class UnknownUser(validators.FancyValidator):
'''Make sure that a user doesn't already exist''' '''Make sure that a user doesn't already exist'''
def _to_python(self, value, state): def _to_python(self, value, state):
@ -62,15 +56,14 @@ class ValidSSHKey(validators.FancyValidator):
def validate_python(self, value, state): def validate_python(self, value, state):
# value = value.file.read() # value = value.file.read()
print dir(value) print dir(value)
email_pattern = "[a-zA-Z0-9\.\+\-_]+@[a-zA-Z0-9\.\-]+"
keylines = value.split('\n') keylines = value.split('\n')
print "KEYLINES: %s" % keylines print "KEYLINES: %s" % keylines
for keyline in keylines: for keyline in keylines:
if not keyline: if not keyline:
continue continue
keyline = keyline.strip() keyline = keyline.strip()
m = re.match('ssh-[dr]s[as] [^ ]+ ' + email_pattern, keyline) m = re.match('^(rsa|dsa|ssh-rsa|ssh-dss) [ \t]*[^ \t]+.*$', keyline)
if not m or m.end() < len(keyline): if not m:
raise validators.Invalid(_('Error - Not a valid ssh key: %s') % keyline, value, state) raise validators.Invalid(_('Error - Not a valid ssh key: %s') % keyline, value, state)
class ValidUsername(validators.FancyValidator): class ValidUsername(validators.FancyValidator):
@ -153,6 +146,8 @@ def generate_salt(length=8):
class User(controllers.Controller): class User(controllers.Controller):
email = Email()
def __init__(self): def __init__(self):
'''Create a User Controller. '''Create a User Controller.
''' '''
@ -316,7 +311,6 @@ class User(controllers.Controller):
newpass = generate_password() newpass = generate_password()
message = turbomail.Message(config.get('accounts_mail'), person.emails['primary'], _('Welcome to the Fedora Project!')) message = turbomail.Message(config.get('accounts_mail'), person.emails['primary'], _('Welcome to the Fedora Project!'))
HERE
message.plain = _(''' message.plain = _('''
You have created a new Fedora account! You have created a new Fedora account!
Your new password is: %s Your new password is: %s

59
fas/fas/user_email.py Normal file
View file

@ -0,0 +1,59 @@
import turbogears
from turbogears import controllers, expose, paginate, identity, redirect, widgets, validate, validators, error_handler, config
from turbogears.database import session
import cherrypy
from fas.model import People
from fas.model import PersonEmails
from fas.model import EmailPurposes
from fas.model import Log
class NonFedoraEmail(validators.FancyValidator):
'''Make sure that an email address is not @fedoraproject.org'''
def _to_python(self, value, state):
return value.strip()
def validate_python(self, value, state):
if value.endswith('@fedoraproject.org'):
raise validators.Invalid(_("To prevent email loops, your email address cannot be @fedoraproject.org."), value, state)
class EmailCreate(validators.Schema):
email = validators.All(
validators.Email(not_empty=True, strip=True),
NonFedoraEmail(not_empty=True, strip=True),
)
#fedoraPersonBugzillaMail = validators.Email(strip=True)
postal_address = validators.String(max=512)
class Email(controllers.Controller):
def __init__(self):
'''Create an Email Controller.
'''
@identity.require(turbogears.identity.not_anonymous())
def index(self):
'''Redirect to manage
'''
turbogears.redirect('/user/email/manage/%s' % turbogears.identity.current.user_name)
@expose(template="fas.templates.error")
def error(self, tg_errors=None):
'''Show a friendly error message'''
if not tg_errors:
turbogears.redirect('/')
return dict(tg_errors=tg_errors)
@identity.require(turbogears.identity.not_anonymous())
#@validate(validators=UserView())
@error_handler(error)
@expose(template="fas.templates.user.email.manage", allow_json=True)
def manage(self, username=None):
'''
Manage a person's emails.
'''
if not username:
username = turbogears.identity.current.user_name
person = People.by_username(username)
return dict(person=person)