diff --git a/fas/fas/model.py b/fas/fas/model.py
index 749aa83..c108d1b 100644
--- a/fas/fas/model.py
+++ b/fas/fas/model.py
@@ -101,13 +101,21 @@ visit_identity_table = Table('visit_identity', metadata,
class People(SABase):
'''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):
'''
A class method that can be used to search users
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)
@@ -133,7 +141,7 @@ class People(SABase):
role.role_type = 'user'
role.member = cls
role.group = group
-
+
def approve(cls, group, requester):
'''
Approve a person in a group - requester for logging purposes
@@ -143,7 +151,7 @@ class People(SABase):
else:
role = PersonRoles.query.filter_by(member=cls, group=group).one()
role.role_status = 'approved'
-
+
def upgrade(cls, group, requester):
'''
Upgrade a user in a group - requester for logging purposes
@@ -158,7 +166,7 @@ class People(SABase):
role.role_type = 'administrator'
elif role.role_type == 'user':
role.role_type = 'sponsor'
-
+
def downgrade(cls, group, requester):
'''
Downgrade a user in a group - requester for logging purposes
@@ -173,7 +181,7 @@ class People(SABase):
role.role_type = 'user'
elif role.role_type == 'administrator':
role.role_type = 'sponsor'
-
+
def sponsor(cls, group, requester):
# If we want to do logging, this might be the place.
if not group in cls.unapproved_memberships:
@@ -292,6 +300,24 @@ class Configs(SABase):
class Groups(SABase):
'''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):
'''
A class method that permits to search groups
@@ -364,7 +390,7 @@ class UnApprovedRoles(PersonRoles):
class Visit(SABase):
'''Track how many people are visiting the website.
-
+
It doesn't currently make sense for us to track this here so we clear this
table of stale records every hour.
'''
@@ -374,7 +400,7 @@ class Visit(SABase):
class VisitIdentity(SABase):
'''Associate a user with a visit cookie.
-
+
This allows users to log in to app.
'''
pass
@@ -403,7 +429,7 @@ mapper(People, PeopleTable, properties = {
primaryjoin = PeopleTable.c.id==UnApprovedRoles.c.person_id)
})
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)
})
mapper(EmailPurposes, EmailPurposesTable, properties = {
@@ -430,7 +456,7 @@ mapper(Groups, GroupsTable, properties = {
primaryjoin = GroupsTable.c.prerequisite_id==GroupsTable.c.id)
})
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)
})
mapper(GroupEmailPurposes, GroupEmailPurposesTable, properties = {
diff --git a/fas/fas/templates/user/email/__init__.py b/fas/fas/templates/user/email/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/fas/fas/templates/user/email/manage.html b/fas/fas/templates/user/email/manage.html
new file mode 100644
index 0000000..0d449b1
--- /dev/null
+++ b/fas/fas/templates/user/email/manage.html
@@ -0,0 +1,47 @@
+
+
+
+
+ ${_('Manage Emails')}
+
+
+ ${_('Managing Emails for %s') % person.username}
+ Available Emails
+
+ Set Emails
+
+
+
+ ${_('Email')} |
+ ${_('Description')} |
+ ${_('Purpose')} |
+
+
+
+
+ ${purpose.email} |
+ ${purpose.person_email.description} |
+ ${purpose.purpose} |
+
+
+
+
+
diff --git a/fas/fas/user.py b/fas/fas/user.py
index 3318393..a86173b 100644
--- a/fas/fas/user.py
+++ b/fas/fas/user.py
@@ -13,9 +13,11 @@ import subprocess
from fas.model import People
from fas.model import PersonEmails
+from fas.model import EmailPurposes
from fas.model import Log
from fas.auth import *
+from fas.user_email import Email, NonFedoraEmail
from random import Random
import sha
@@ -32,14 +34,6 @@ class KnownUser(validators.FancyValidator):
except InvalidRequestError:
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):
'''Make sure that a user doesn't already exist'''
def _to_python(self, value, state):
@@ -62,15 +56,14 @@ class ValidSSHKey(validators.FancyValidator):
def validate_python(self, value, state):
# value = value.file.read()
print dir(value)
- email_pattern = "[a-zA-Z0-9\.\+\-_]+@[a-zA-Z0-9\.\-]+"
keylines = value.split('\n')
print "KEYLINES: %s" % keylines
for keyline in keylines:
if not keyline:
continue
keyline = keyline.strip()
- m = re.match('ssh-[dr]s[as] [^ ]+ ' + email_pattern, keyline)
- if not m or m.end() < len(keyline):
+ m = re.match('^(rsa|dsa|ssh-rsa|ssh-dss) [ \t]*[^ \t]+.*$', keyline)
+ if not m:
raise validators.Invalid(_('Error - Not a valid ssh key: %s') % keyline, value, state)
class ValidUsername(validators.FancyValidator):
@@ -153,6 +146,8 @@ def generate_salt(length=8):
class User(controllers.Controller):
+ email = Email()
+
def __init__(self):
'''Create a User Controller.
'''
@@ -316,7 +311,6 @@ class User(controllers.Controller):
newpass = generate_password()
message = turbomail.Message(config.get('accounts_mail'), person.emails['primary'], _('Welcome to the Fedora Project!'))
- HERE
message.plain = _('''
You have created a new Fedora account!
Your new password is: %s
diff --git a/fas/fas/user_email.py b/fas/fas/user_email.py
new file mode 100644
index 0000000..2ef95c7
--- /dev/null
+++ b/fas/fas/user_email.py
@@ -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)
+