Merge branch 'master' of ssh://git.fedorahosted.org/git/fedora-infrastructure
This commit is contained in:
commit
b7088d5029
5 changed files with 148 additions and 22 deletions
|
@ -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 = {
|
||||||
|
|
0
fas/fas/templates/user/email/__init__.py
Normal file
0
fas/fas/templates/user/email/__init__.py
Normal file
47
fas/fas/templates/user/email/manage.html
Normal file
47
fas/fas/templates/user/email/manage.html
Normal 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>
|
|
@ -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
59
fas/fas/user_email.py
Normal 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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue