Add UI for email forwarding
We nag users to update their forwarding address every time they renew membership.
This commit is contained in:
parent
9eefe615c5
commit
35179ec978
|
@ -9,7 +9,7 @@ Transactions are used in each method that modifies the database.
|
|||
Future changes to the members database that need to be atomic
|
||||
must also be moved into this module.
|
||||
"""
|
||||
import os, re, subprocess, ldap
|
||||
import os, re, subprocess, ldap, socket
|
||||
from ceo import conf, ldapi, terms, remote, ceo_pb2
|
||||
from ceo.excep import InvalidArgument
|
||||
|
||||
|
@ -164,6 +164,54 @@ def create_member(username, password, name, program, email):
|
|||
raise MemberException(e)
|
||||
|
||||
|
||||
def check_email(email):
|
||||
match = re.match('^\S+?@(\S+)$', email)
|
||||
if not match:
|
||||
return 'Invalid email address'
|
||||
|
||||
# some characters are treated specially in .forward
|
||||
for c in email:
|
||||
if c in ('"', "'", ',', '|', '$', '/', '#', ':'):
|
||||
return 'Invalid character in address: %s' % c
|
||||
|
||||
host = match.group(1)
|
||||
try:
|
||||
ip = socket.gethostbyname(host)
|
||||
except:
|
||||
return 'Invalid host: %s' % host
|
||||
|
||||
|
||||
def current_email(username):
|
||||
fwdpath = '%s/%s/.forward' % (cfg['member_home'], username)
|
||||
try:
|
||||
fwd = open(fwdpath).read().strip()
|
||||
if not check_email(fwd):
|
||||
return fwd
|
||||
except OSError:
|
||||
pass
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
|
||||
def change_email(username, forward):
|
||||
try:
|
||||
request = ceo_pb2.UpdateMail()
|
||||
request.username = username
|
||||
request.forward = forward
|
||||
|
||||
out = remote.run_remote('mail', request.SerializeToString())
|
||||
|
||||
response = ceo_pb2.AddUserResponse()
|
||||
response.ParseFromString(out)
|
||||
|
||||
if any(message.status != 0 for message in response.messages):
|
||||
return '\n'.join(message.message for message in response.messages)
|
||||
except remote.RemoteException, e:
|
||||
raise MemberException(e)
|
||||
except OSError, e:
|
||||
raise MemberException(e)
|
||||
|
||||
|
||||
def get(userid):
|
||||
"""
|
||||
Look up attributes of a member by userid.
|
||||
|
|
|
@ -87,15 +87,19 @@ def renew_member(*args, **kwargs):
|
|||
push_wizard("Renew Membership", [
|
||||
renew.IntroPage,
|
||||
renew.UserPage,
|
||||
renew.EmailPage,
|
||||
renew.EmailDonePage,
|
||||
renew.TermPage,
|
||||
renew.PayPage,
|
||||
renew.EndPage,
|
||||
])
|
||||
], (60, 15))
|
||||
|
||||
def renew_club_user(*args, **kwargs):
|
||||
push_wizard("Renew Club Rep Account", [
|
||||
renew.ClubUserIntroPage,
|
||||
renew.UserPage,
|
||||
renew.EmailPage,
|
||||
renew.EmailDonePage,
|
||||
(renew.TermPage, "clubuser"),
|
||||
(renew.EndPage, "clubuser"),
|
||||
], (60, 15))
|
||||
|
|
|
@ -49,6 +49,84 @@ class UserPage(WizardPanel):
|
|||
self.focus_widget(self.userid)
|
||||
return True
|
||||
|
||||
class EmailPage(WizardPanel):
|
||||
def init_widgets(self):
|
||||
self.email = SingleEdit("Email: ")
|
||||
|
||||
self.widgets = [
|
||||
urwid.Text( "Mail Forwarding" ),
|
||||
urwid.Divider(),
|
||||
urwid.Text("Please ensure the forwarding address for "
|
||||
"your CSC email is up to date."),
|
||||
urwid.Divider(),
|
||||
urwid.Text("Warning: Changing this overwrites ~/.forward"),
|
||||
urwid.Divider(),
|
||||
self.email,
|
||||
]
|
||||
def activate(self):
|
||||
cfwd = members.current_email(self.state['userid'])
|
||||
self.state['old_forward'] = cfwd if cfwd else ''
|
||||
self.email.set_edit_text(self.state['old_forward'])
|
||||
def check(self):
|
||||
fwd = self.email.get_edit_text().strip().lower()
|
||||
if fwd:
|
||||
msg = members.check_email(fwd)
|
||||
if msg:
|
||||
set_status(msg)
|
||||
return True
|
||||
if fwd == '%s@csclub.uwaterloo.ca' % self.state['userid']:
|
||||
set_status('You cannot forward your address to itself. Leave it blank to disable forwarding.')
|
||||
return True
|
||||
self.state['new_forward'] = fwd
|
||||
|
||||
class EmailDonePage(WizardPanel):
|
||||
def init_widgets(self):
|
||||
self.status = urwid.Text("")
|
||||
self.widgets = [
|
||||
urwid.Text("Mail Forwarding"),
|
||||
urwid.Divider(),
|
||||
self.status,
|
||||
]
|
||||
def focusable(self):
|
||||
return False
|
||||
def activate(self):
|
||||
if self.state['old_forward'] == self.state['new_forward']:
|
||||
if self.state['old_forward']:
|
||||
self.status.set_text(
|
||||
'You have chosen to leave your forwarding address '
|
||||
'as %s. Make sure to check this email for updates '
|
||||
'from the CSC.' % self.state['old_forward'])
|
||||
else:
|
||||
self.status.set_text(
|
||||
'You have chosen not to set a forwarding address. '
|
||||
'Please check your CSC email regularly (via IMAP, POP, or locally) '
|
||||
'for updates from the CSC.'
|
||||
'\n\n'
|
||||
'Note: If you do have a ~/.forward, we were not able to read it or '
|
||||
'it was not a single email address. Do not worry, we have left it '
|
||||
'as is.')
|
||||
else:
|
||||
try:
|
||||
msg = members.change_email(self.state['userid'], self.state['new_forward'])
|
||||
if msg:
|
||||
self.status.set_text("Errors occured updating your forwarding address:"
|
||||
"\n\n%s" % msg)
|
||||
else:
|
||||
if self.state['new_forward']:
|
||||
self.status.set_text(
|
||||
'Your email forwarding address has been successfully set '
|
||||
'to %s. Test it out by emailing %s@csclub.uwaterloo.ca and '
|
||||
'making sure you receive it at your forwarding address.'
|
||||
% (self.state['new_forward'], self.state['userid']))
|
||||
else:
|
||||
self.status.set_text(
|
||||
'Your email forwarding address has been successfully cleared. '
|
||||
'Please check your CSC email regularly (via IMAP, POP, or locally) '
|
||||
'for updates from the CSC.')
|
||||
except Exception, e:
|
||||
self.status.set_text(
|
||||
'An exception occured updating your email:\n\n%s' % e)
|
||||
|
||||
class TermPage(WizardPanel):
|
||||
def __init__(self, state, utype='member'):
|
||||
self.utype = utype
|
||||
|
|
Loading…
Reference in New Issue