Ticket #442: enforce_emails.patch

File enforce_emails.patch, 11.6 kB (added by s0undt3ch, 6 months ago)
  • acct_mgr/admin.py

    old new  
    1313 
    1414from trac.core import * 
    1515from trac.config import Option 
     16from trac.notification import NotificationSystem 
    1617from trac.perm import PermissionSystem 
    1718from trac.util import sorted 
    1819from trac.util.datefmt import format_datetime 
     
    2021from trac.admin import IAdminPanelProvider 
    2122 
    2223from acct_mgr.api import AccountManager 
    23 from acct_mgr.web_ui import _create_user 
     24from acct_mgr.web_ui import _create_user, EmailVerificationModule 
    2425 
    2526def _getoptions(cls): 
    2627    if isinstance(cls, Component): 
     
    5657                newvalue = req.args.get('%s.%s' % (selected_class, attr)) 
    5758                if newvalue is not None: 
    5859                    self.config.set(option.section, option.name, newvalue) 
    59                     self.config.save() 
    6060            self.config.set('account-manager', 'force_passwd_change', 
    6161                            req.args.get('force_passwd_change')) 
     62            self.config.set('account-manager', 'enforce_emails', 
     63                            req.args.get('enforce_emails')) 
    6264            self.config.save() 
    6365 
    6466 
     
    8082            } for store in self.account_manager.stores 
    8183        ] 
    8284        sections = sorted(sections, key=lambda i: i['name']) 
     85        enforce_emails = (self.env.is_component_enabled(EmailVerificationModule) 
     86                          and NotificationSystem(self.env).smtp_enabled 
     87                          and self.env.config.getbool('account-manager', 
     88                                                      'enforce_emails')) 
    8389        data = {'sections': sections, 
    84                 'force_passwd_change': self.account_manager.force_passwd_change} 
     90                'force_passwd_change': self.account_manager.force_passwd_change, 
     91                'enforce_emails': enforce_emails} 
    8592        return 'admin_accountsconfig.html', data 
    8693 
    8794    def _do_users(self, req): 
     
    100107            if req.args.get('add'): 
    101108                if create_enabled: 
    102109                    try: 
    103                         _create_user(req, self.env, check_permissions=False) 
     110                        _create_user(req, self.env, check_permissions=False, 
     111                                     enforce_emails=False) 
    104112                    except TracError, e: 
    105113                        data['registration_error'] = e.message 
    106114                else: 
  • acct_mgr/web_ui.py

    old new  
    1616 
    1717from trac import perm, util 
    1818from trac.core import * 
    19 from trac.config import IntOption 
     19from trac.config import IntOption, BoolOption 
    2020from trac.notification import NotificationSystem, NotifyEmail 
    2121from trac.prefs import IPreferencePanelProvider 
    2222from trac.web import auth 
     
    2929from api import AccountManager 
    3030from acct_mgr.util import urandom 
    3131 
    32 def _create_user(req, env, check_permissions=True): 
     32def _create_user(req, env, check_permissions=True, enforce_emails=True): 
    3333    mgr = AccountManager(env) 
    3434 
    3535    user = req.args.get('user') 
     
    4545        if permission_system.get_user_permissions(user) != \ 
    4646           permission_system.get_user_permissions('authenticated'): 
    4747            raise TracError('Another account with that name already exists.') 
     48         
     49    if enforce_emails and not req.args.get('email'): 
     50        raise TracError('An email address is required to register.') 
    4851 
    4952    password = req.args.get('password') 
    5053    if not password: 
     
    324327    """ 
    325328 
    326329    implements(INavigationContributor, IRequestHandler, ITemplateProvider) 
     330    enforce_emails = BoolOption('account-manager', 'enforce_emails', True, 
     331                                doc="Enforce email submission for new " 
     332                                "registrations.") 
    327333 
    328334    def __init__(self): 
    329335        self._enable_check(log=True) 
     
    364370        if req.authname != 'anonymous': 
    365371            req.redirect(req.href.prefs('account')) 
    366372        action = req.args.get('action') 
    367         data = {} 
     373        enforce_emails = (self.env.is_component_enabled(EmailVerificationModule) 
     374                          and NotificationSystem(self.env).smtp_enabled 
     375                          and self.enforce_emails) 
     376        data = {'enforce_emails': enforce_emails} 
    368377        if req.method == 'POST' and action == 'create': 
    369378            try: 
    370                 _create_user(req, self.env
     379                _create_user(req, self.env, enforce_emails=enforce_emails
    371380            except TracError, e: 
    372381                data['registration_error'] = e.message 
    373382            else: 
     
    517526        return handler 
    518527 
    519528    def post_process_request(self, req, template, data, content_type): 
    520         if req.session.get('email') != req.session.get('email_verification_sent_to'): 
    521             req.session['email_verification_token'] = self._gen_token() 
    522             req.session['email_verification_sent_to'] = req.session.get('email') 
     529        enforce_emails = (self.env.is_component_enabled(EmailVerificationModule) 
     530                          and NotificationSystem(self.env).smtp_enabled and 
     531                          self.env.config.getbool('account-manager', 
     532                                                  'enforce_emails') and 
     533                          req.session.authenticated) 
     534 
     535        def send_notification():         
    523536            self._send_email(req) 
    524537            chrome.add_notice(req, MessageWrapper(tag.span( 
    525538                    'An email has been sent to ', req.session['email'], 
    526539                    ' with a token to ', 
    527540                    tag.a(href=req.href.verify_email())( 
    528541                        'verify your new email address')))) 
     542 
     543        def redirect_to_prefs(): 
     544            chrome.add_notice(req, MessageWrapper(tag.span( 
     545                'You are now required to fill in and confirm your email ' 
     546                'address. Please take the time to ', 
     547                tag.a('update', href=req.href.prefs()), ' it.'))) 
     548            redirect_url = req.href.prefs() 
     549            if req.path_info != redirect_url: 
     550                req.redirect(redirect_url) 
     551 
     552        if req.session.get('email') != \ 
     553                                req.session.get('email_verification_sent_to'): 
     554            # Matches old accounts that have email set, yet, have not yet 
     555            # verified them, and also matches email changes; 
     556            if req.session.get('email'): 
     557                # only generate token and notify if user provided an 
     558                # email address 
     559                req.session['email_verification_token'] = self._gen_token() 
     560                req.session['email_verification_sent_to'] = req.session['email'] 
     561                send_notification() 
     562            elif not req.session.get('email'): 
     563                # Matched, yet email is not set. 
     564                if 'email_verification_token' in req.session: 
     565                    # User deleted his email address, 
     566                    # remove email_verification_token to leave anonymous 
     567                    # users alone 
     568                    del req.session['email_verification_token'] 
     569                    req.session.save() 
     570                if enforce_emails: 
     571                    # user does not have email set. 
     572                    # We're enforcing emails, so force him. 
     573                    redirect_to_prefs()                 
     574        elif enforce_emails and not req.session.get('email'): 
     575            # if it's a new user, both email and email_verification_sent_to 
     576            # are not set, so they're equal and the above 'if' did not match. 
     577            # Since we're enforcing emails, force him to set it. 
     578            redirect_to_prefs() 
    529579        return template, data, content_type 
    530580 
    531581    # IRequestHandler methods 
     
    558608        return base64.urlsafe_b64encode(urandom(6)) 
    559609 
    560610    def _send_email(self, req): 
    561         notifier = EmailVerificationNotification(self.env) 
    562         notifier.notify(req.authname, req.session['email_verification_token']) 
     611        username = req.authname 
     612        if username == 'anonymous': 
     613            username = req.session.get('email') 
     614        if username: 
     615            notifier = EmailVerificationNotification(self.env) 
     616            notifier.notify(username, req.session['email_verification_token']) 
  • acct_mgr/templates/admin_accountsconfig.html

    old new  
    1010  </head> 
    1111 
    1212  <body> 
    13     <h2>Accounts: Configuration</h2> 
    1413 
    1514    <form id="accountsconfig" class="mod" method="post"> 
     15      <h2>Accounts: General Configuration</h2> 
     16      <fieldset> 
     17        <legend>Password Reset</legend> 
     18        <label for="force_passwd_change"> 
     19          Force users to change passwords after a password reset? 
     20        </label> 
     21        <input type="radio" name="force_passwd_change" value="true" 
     22          checked="${force_passwd_change and 'checked' or None}">Yes</input> 
     23        <input type="radio" name="force_passwd_change" value="false" 
     24          checked="${not force_passwd_change and 'checked' or None}">No</input> 
     25      </fieldset> 
     26      <fieldset> 
     27        <legend>Enforce Emails</legend> 
     28        <label for="enforce_emails"> 
     29          Force users to provide an email address on registration? 
     30        </label> 
     31        <input type="radio" name="enforce_emails" value="true" 
     32          checked="${enforce_emails and 'checked' or None}">Yes</input> 
     33        <input type="radio" name="enforce_emails" value="false" 
     34          checked="${not enforce_emails and 'checked' or None}">No</input> 
     35      </fieldset> 
     36      <div class="buttons"> 
     37        <input type="submit" name="save" value="Save" /> 
     38      </div> 
     39       
     40      <hr/> 
     41       
     42      <h2>Accounts: Store Configuration</h2> 
    1643      <fieldset py:for="section in sections"> 
    1744        <legend> 
    1845          <label> 
     
    2956          </label> 
    3057        </div> 
    3158      </fieldset> 
    32       <fieldset> 
    33         <legend>Password Reset</legend> 
    34         <label for="force_passwd_change"> 
    35           Force users to change passwords after a password reset? 
    36         </label> 
    37         <input type="radio" name="force_passwd_change" value="true" 
    38           checked="${force_passwd_change and 'checked' or None}">Yes</input> 
    39         <input type="radio" name="force_passwd_change" value="false" 
    40           checked="${not force_passwd_change and 'checked' or None}">No</input> 
    41       </fieldset> 
    4259      <div class="buttons"> 
    4360        <input type="submit" name="save" value="Save" /> 
    4461      </div> 
  • acct_mgr/templates/register.html

    old new  
    4343                     class="textwidget" size="20" /> 
    4444            </label> 
    4545          </div> 
     46          <div py:if="enforce_emails"> 
     47            <label>Email: 
     48              <input type="text" name="email" class="textwidget" size="20" /> 
     49            </label> 
     50            <p py:if="reset_password_enabled">Entering your email address will 
     51            enable you to reset your password if you ever forget it.</p> 
     52          </div> 
    4653        </fieldset> 
    4754        <fieldset> 
    4855          <legend>Optional</legend> 
     
    5158              <input type="text" name="name" class="textwidget" size="20" /> 
    5259            </label> 
    5360          </div> 
    54           <div
     61          <div py:if="not enforce_emails"
    5562            <label>Email: 
    5663              <input type="text" name="email" class="textwidget" size="20" /> 
    5764            </label>