Ticket #3649: sage-3649.patch

File sage-3649.patch, 13.2 kB (added by TimothyClemans, 4 months ago)
  • a/sage/server/notebook/server_conf.py

    old new  
    1414             
    1515            'save_interval':360,        # seconds 
    1616 
    17             'doc_pool_size':128 
     17            'doc_pool_size':128, 
     18            'email':False  
    1819           } 
    1920 
    2021class ServerConfiguration(conf.Configuration): 
  • a/sage/server/notebook/template.py

    old new  
    3939for name in templates: 
    4040    G[name + '_template'] =  PageTemplate(pjoin(path, '%s.template'%name)) 
    4141 
    42 def login_page_template(accounts, default_user, is_username_error=False, is_password_error=False, welcome=None): 
     42def login_page_template(accounts, default_user, is_username_error=False, is_password_error=False, welcome=None, recover=False): 
    4343    if accounts: 
    4444        reg = "<a href='/register'><b>Sign up for a new SAGE Notebook account</b></a>" 
    4545    else: 
    4646        reg = "" 
     47    if recover: 
     48        forgot_pass = "<a href='/forgotpass'><b>Forgot password</b></a>" 
     49    else: 
     50        forgot_pass = '' 
    4751    if is_username_error: 
    4852        u_e = '<tr><td align=right><span style="color:red">Error:</span></td><td>Username is not in the system</td></tr>' 
    4953    else: 
     
    5660        welcome = '<h2>Congratulations %s! You can now sign into the Sage Notebook.</h2>' % welcome 
    5761    else: 
    5862        welcome = '' 
    59     return login_template(register = reg, default=default_user, username_error=u_e, password_error=p_e, welcome=welcome
     63    return login_template(register = reg, default=default_user, username_error=u_e, password_error=p_e, welcome=welcome, forgot_pass=forgot_pass
    6064 
    61 def registration_page_template(error=None, input=None): 
     65def registration_page_template(is_email=False, error=None, input=None): 
    6266    keywords = dict([(i, '') for i in ['error', 'username', 'username_error', 'password_error', 'confirm_pass_error', 'email', 'email_error']]) 
    6367    def error_html(msg): 
    6468        return '<p><span class="error">Error:</span> ' + msg + '</p>' 
     
    9094        if 'retype_password' in input: 
    9195            del input['retype_password'] 
    9296        keywords.update(input) 
     97         
     98    if is_email: 
     99        e_box = """<li><h2>Enter your e-mail address</h2> 
     100<p>Your e-mail address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.</p> 
     101<input type="text" name="email" value="%s" class="entry" /> 
     102%s 
     103</li>""" % (keywords['email'], keywords['email_error']) 
     104    else: 
     105        e_box = '' 
     106    keywords['email_box'] = e_box 
     107    del keywords['email'] 
     108    del keywords['email_error'] 
    93109    template = Template(file.read()).substitute(keywords) 
    94110    file.close() 
    95111    return template 
  • a/sage/server/notebook/twist.py

    old new  
    885885            if not error: #webbrowser may auto fill in "old password" even though the user may nto want to change her passwords    
    886886                notebook.change_password(self.username, request.args['Newpass'][0]) 
    887887                redirect_to_logout = True 
    888          
    889         if 'Newemail' in request.args: 
    890             notebook.user(self.username).set_email(request.args['Newemail'][0]) 
    891             redirect_to_home = True 
     888        if notebook.conf()['email']: 
     889            if 'Newemail' in request.args: 
     890                notebook.user(self.username).set_email(request.args['Newemail'][0]) 
     891                redirect_to_home = True 
    892892         
    893893        if error: 
    894894            return http.Response(stream=message(error, '/settings')) 
     
    960960        for i in range(1, 10, 2): 
    961961            s += '<option%s>%s</option>' % (' selected' if notebook.user(self.username)['autosave_interval']/60 == i else '', i) 
    962962        s += '</select></div></div>' 
     963        if notebook.conf()['email']: 
     964            email_section = """ 
     965            <div class="section"> 
     966          <h2>Change E-mail Address</h2> 
     967     
     968          <div> 
     969            <table style="float:right"><tr><td>Current e-mail:</td><td>%s</td></tr> 
     970            <tr><td></td><td>%s</td></tr> 
     971            <tr><td style="text-align:right">New e-mail:</td><td><input type="text" name="Newemail" class="c1" /></td></tr></table> 
     972            <div style="clear:both"></div> 
     973          </div> 
     974        </div> 
     975            """ % ('None' if notebook.user(self.username)._User__email == '' else notebook.user(self.username)._User__email, 'Not confirmed' if not notebook.user(self.username).is_email_confirmed() else 'Confirmed') 
     976        else: email_section = '' 
    963977        s += """ 
    964978    <div class="section"> 
    965979      <h2>Change Password</h2> 
     
    970984      </div> 
    971985    </div> 
    972986 
    973     <div class="section"> 
    974       <h2>Change E-mail Address</h2> 
    975  
    976       <div> 
    977         <table style="float:right"><tr><td>Current e-mail:</td><td>%s</td></tr> 
    978         <tr><td></td><td>%s</td></tr> 
    979         <tr><td style="text-align:right">New e-mail:</td><td><input type="text" name="Newemail" class="c1" /></td></tr></table> 
    980         <div style="clear:both"></div> 
    981       </div> 
    982     </div> 
     987    %s 
    983988    <div id="buttons"> 
    984     <input type="submit" value="Save">""" % ('None' if notebook.user(self.username)._User__email == '' else notebook.user(self.username)._User__email, 'Not confirmed' if not notebook.user(self.username).is_email_confirmed() else 'Confirmed') 
     989    <input type="submit" value="Save">""" % email_section 
    985990        s += '<input type="button" value="Cancel" style="margin-left:5px" onClick="parent.location=\'/home/%s\'">' % self.username 
    986991        s += """     
    987992    </div> 
     
    17521757#################################### 
    17531758class RegConfirmation(resource.Resource): 
    17541759    def render(self, request): 
     1760        if not notebook.conf()['email']: 
     1761            return http.Response(stream=message('The confirmation system is not active.'))  
    17551762        key = request.args['key'][0] 
    17561763        global notebook 
    17571764        invalid_confirm_key = """\ 
     
    18981905        self.userdb = userdb 
    18991906         
    19001907    def render(self, request):         
    1901         input_boxes = ['username', 'password', 'retype_password', 'email'] 
     1908        input_boxes = ['username', 'password', 'retype_password'] 
     1909        if notebook.conf()['email']: 
     1910            input_boxes.append('email') 
    19021911        is_valid_dict = {'username': is_valid_username, 'password': is_valid_password, 
    19031912                         'retype_password': do_passwords_match, 'email': is_valid_email} 
    19041913        missing = [False] * len(input_boxes) 
     
    19321941                    missing[i] = True 
    19331942             
    19341943            if set(missing) == set([True]): 
    1935                 return http.Response(stream=registration_page_template()) 
     1944                return http.Response(stream=registration_page_template(is_email=notebook.conf()['email'])) 
    19361945            elif set(missing) == set([False]): 
    19371946                for i, box in enumerate(input_boxes): 
    19381947                    filled_in[box] = request.args[box][0] 
     
    19641973            return http.Response(stream=registration_page_template(error=errors, input=filled_in)) 
    19651974        else: 
    19661975            try: 
     1976                e = filled_in['email'] if notebook.conf()['email'] else '' 
    19671977                self.userdb.add_user(filled_in['username'], request.args['password'][0], 
    1968                                      filled_in['email']
     1978                                     e
    19691979            except ValueError: 
    19701980                errors.append('username_taken') 
    19711981                return http.Response(stream=registration_page_template(error=errors, input=filled_in)) 
    19721982             
    1973             destaddr = filled_in['email'] 
    1974             from sage.server.notebook.smtpsend import send_mail 
    1975             from sage.server.notebook.register import make_key, build_msg 
    1976             # TODO: make this come from the server settings 
    1977             key = make_key() 
    1978             listenaddr = notebook.address 
    1979             port = notebook.port 
    1980             fromaddr = 'no-reply@%s' % listenaddr 
    1981             body = build_msg(key, filled_in['username'], listenaddr, port, 
    1982                              notebook.secure) 
    1983  
    1984             # Send a confirmation message to the user. 
    1985             try: 
    1986                 send_mail(self, fromaddr, destaddr, "Sage Notebook Registration",body) 
    1987                 waiting[key] = filled_in['username'] 
    1988             except ValueError: 
    1989                 pass 
     1983            if notebook.conf()['email']: 
     1984                destaddr = filled_in['email'] 
     1985                from sage.server.notebook.smtpsend import send_mail 
     1986                from sage.server.notebook.register import make_key, build_msg 
     1987                # TODO: make this come from the server settings 
     1988                key = make_key() 
     1989                listenaddr = notebook.address 
     1990                port = notebook.port 
     1991                fromaddr = 'no-reply@%s' % listenaddr 
     1992                body = build_msg(key, filled_in['username'], listenaddr, port, 
     1993                                 notebook.secure) 
     1994     
     1995                # Send a confirmation message to the user. 
     1996                try: 
     1997                    send_mail(self, fromaddr, destaddr, "Sage Notebook Registration",body) 
     1998                    waiting[key] = filled_in['username'] 
     1999                except ValueError: 
     2000                    pass 
    19902001             
    19912002            return http.Response(stream=login_page_template(notebook.get_accounts(), 
    1992                                                             notebook.default_user(), welcome=filled_in['username'])) 
     2003                                                            notebook.default_user(), welcome=filled_in['username'], 
     2004                                                            recover=notebook.conf()['email'])) 
    19932005     
    19942006class ForgotPassPage(resource.Resource): 
    19952007         
    19962008    def render(self, request): 
     2009        if not notebook.conf()['email']: 
     2010            return http.Response(stream=message('The account recovery system is not active.')) 
     2011         
    19972012        if request.args.has_key('username'): 
    19982013            def error(msg): 
    19992014                return http.Response(stream=message(msg, '/forgotpass')) 
     
    21002115        self.username = username if username else 'guest' 
    21012116 
    21022117    def render(self, ctx): 
    2103         return http.Response(stream =  login_page_template(notebook.get_accounts(), notebook.default_user())) 
     2118        return http.Response(stream =  login_page_template(notebook.get_accounts(), notebook.default_user(), recover=notebook.conf()['email'])) 
    21042119 
    21052120    def userchildFactory(self, request, name): 
    21062121        return InvalidPage(msg = "unauthorized request", username = self.username) 
     
    21182133 
    21192134class LoginResourceClass(resource.Resource): 
    21202135    def render(self, ctx): 
    2121         return http.Response(stream =  login_page_template(notebook.get_accounts(), notebook.default_user())) 
     2136        return http.Response(stream =  login_page_template(notebook.get_accounts(), notebook.default_user(), recover=notebook.conf()['email'])) 
    21222137     
    21232138    def childFactory(self, request, name): 
    21242139        return LoginResource 
     
    21522167    #child_login = LoginResource 
    21532168     
    21542169    def render(self, ctx): 
    2155         return http.Response(stream =  login_page_template(notebook.get_accounts(), notebook.default_user())) 
     2170        return http.Response(stream =  login_page_template(notebook.get_accounts(), notebook.default_user(), recover=notebook.conf()['email'])) 
    21562171 
    21572172class FailedToplevel(Toplevel): 
    21582173    def __init__(self, info, problem, username=None): 
     
    21652180        # worksheets and ratings, this gives no new information way. 
    21662181        # If published pages were disabled, then this should be disabled too. 
    21672182        if self.problem == 'username': 
    2168             return http.Response(stream = login_page_template(notebook.get_accounts(), notebook.default_user(), is_username_error=True)) 
     2183            return http.Response(stream = login_page_template(notebook.get_accounts(), notebook.default_user(), is_username_error=True, recover=notebook.conf()['email'])) 
    21692184        else: 
    2170             return http.Response(stream = login_page_template(notebook.get_accounts(), self.username, is_password_error=True)) 
     2185            return http.Response(stream = login_page_template(notebook.get_accounts(), self.username, is_password_error=True, recover=notebook.conf()['email'])) 
    21712186 
    21722187 
    21732188class UserToplevel(Toplevel):