Changeset 1508
- Timestamp:
- 11/10/06 01:41:13 (2 years ago)
- Files:
-
- accountmanagerplugin/trunk/acct_mgr/templates/account.html (moved) (moved from accountmanagerplugin/trunk/acct_mgr/templates/account.cs) (1 diff)
- accountmanagerplugin/trunk/acct_mgr/templates/admin_accounts.html (modified) (1 diff)
- accountmanagerplugin/trunk/acct_mgr/templates/login.html (moved) (moved from accountmanagerplugin/trunk/acct_mgr/templates/login.cs) (1 diff)
- accountmanagerplugin/trunk/acct_mgr/templates/register.html (moved) (moved from accountmanagerplugin/trunk/acct_mgr/templates/register.cs) (1 diff)
- accountmanagerplugin/trunk/acct_mgr/templates/reset_password_email.txt (moved) (moved from accountmanagerplugin/trunk/acct_mgr/templates/reset_password_email.cs) (1 diff)
- accountmanagerplugin/trunk/acct_mgr/templates/reset_password.html (moved) (moved from accountmanagerplugin/trunk/acct_mgr/templates/reset_password.cs) (1 diff)
- accountmanagerplugin/trunk/acct_mgr/web_ui.py (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
accountmanagerplugin/trunk/acct_mgr/templates/account.html
r76 r1508 1 <?cs include "header.cs"?> 2 <?cs include "macros.cs"?> 1 <!DOCTYPE html 2 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml" 5 xmlns:py="http://genshi.edgewall.org/" 6 xmlns:xi="http://www.w3.org/2001/XInclude"> 7 <xi:include href="layout.html" /> 8 <head> 9 <title>My Account</title> 10 </head> 3 11 4 <div id="ctxtnav" class="nav"></div> 12 <body> 13 <div id="content" class="register"> 14 <h1>My Account</h1> 5 15 6 <div id="content" class="register">16 <p>Manage your user account.</p> 7 17 8 <h1>My Account</h1> 18 <div class="system-message" py:if="account_error"> 19 <h2>Error</h2> 20 <p>$account.error</p> 21 </div> 9 22 10 <p> 11 Manage your user account. 12 </p> 23 <p py:if="account.message">$account.message</p> 13 24 14 <?cs if account.error ?> 15 <div class="system-message"> 16 <h2>Error</h2> 17 <p><?cs var:account.error ?></p> 18 </div> 19 <?cs /if ?> 25 <form method="post" action=""> 26 <div> 27 <input type="hidden" name="action" value="change_password" /> 28 <label for="password">New Password:</label> 29 <input type="password" id="password" name="password" class="textwidget" 30 size="20" /> 31 </div> 32 <div> 33 <label for="password_confirm">Confirm Password:</label> 34 <input type="password" id="password_confirm" name="password_confirm" 35 class="textwidget" size="20" /> 36 </div> 37 <input type="submit" value="Change password" /> 38 </form> 20 39 21 <?cs if account.message ?> 22 <p><?cs var:account.message ?></p> 23 <?cs /if ?> 40 <form method="post" action="" 41 onsubmit="return confirm('Are you sure you want to delete your account?');"> 42 <input type="hidden" name="action" value="delete" /> 43 <input type="submit" value="Delete account" /> 44 </form> 24 45 25 <form method="post" action=""> 26 <div> 27 <input type="hidden" name="action" value="change_password" /> 28 <label for="password">New Password:</label> 29 <input type="password" id="password" name="password" class="textwidget" 30 size="20" /> 31 </div> 32 <div> 33 <label for="password_confirm">Confirm Password:</label> 34 <input type="password" id="password_confirm" name="password_confirm" 35 class="textwidget" size="20" /> 36 </div> 37 <input type="submit" value="Change password" /> 38 </form> 39 40 <form method="post" action="" 41 onsubmit="return confirm('Are you sure you want to delete your account?');"> 42 <input type="hidden" name="action" value="delete" /> 43 <input type="submit" value="Delete account" /> 44 </form> 45 46 </div> 47 48 <?cs include:"footer.cs"?> 46 </div> 47 </body> 48 </html> accountmanagerplugin/trunk/acct_mgr/templates/admin_accounts.html
r1503 r1508 7 7 <xi:include href="admin.html" /> 8 8 <head> 9 <title> Basics</title>9 <title>Accounts</title> 10 10 </head> 11 11 accountmanagerplugin/trunk/acct_mgr/templates/login.html
r1085 r1508 1 <?cs include "header.cs"?> 2 <?cs include "macros.cs"?> 1 <!DOCTYPE html 2 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml" 5 xmlns:py="http://genshi.edgewall.org/" 6 xmlns:xi="http://www.w3.org/2001/XInclude"> 7 <xi:include href="layout.html" /> 8 <head> 9 <title>Login</title> 10 </head> 3 11 4 <div id="ctxtnav" class="nav"></div> 12 <body> 13 <div id="ctxtnav" class="nav"></div> 5 14 6 <div id="content" class="login">15 <div id="content" class="login"> 7 16 8 <h1>Login</h1>17 <h1>Login</h1> 9 18 10 <?cs if login.error ?> 11 <div class="system-message"> 12 <h2>Error</h2> 13 <p><?cs var:login.error ?></p> 14 </div> 15 <?cs /if ?> 19 <div class="system-message" py:if="login_error"> 20 <h2>Error</h2> 21 <p>${login_error}</p> 22 </div> 16 23 17 <form method="post" action="">18 <input type="hidden" name="referer" value="<?cs var:referer ?>" />19 <div>20 <label for="user">Username:</label>21 <input type="text" id="user" name="user" class="textwidget" size="20" />22 </div>23 <div>24 <label for="password">Password:</label>25 <input type="password" id="password" name="password" class="textwidget" size="20" />26 </div>27 <input type="submit" value="Login" />24 <form method="post" action=""> 25 <input type="hidden" name="referer" value="${referer}" /> 26 <div> 27 <label for="user">Username:</label> 28 <input type="text" id="user" name="user" class="textwidget" size="20" /> 29 </div> 30 <div> 31 <label for="password">Password:</label> 32 <input type="password" id="password" name="password" class="textwidget" size="20" /> 33 </div> 34 <input type="submit" value="Login" /> 28 35 29 <?cs if trac.href.reset_password ?>30 <p><a href="<?cs var:trac.href.reset_password ?>">Forgot your password?</a></p>31 <?cs /if ?>32 </form>36 <p py:if="reset_password_enabled"> 37 <a href="${href.reset_password()}">Forgot your password?</a> 38 </p> 39 </form> 33 40 34 </div>35 36 < ?cs include:"footer.cs"?>41 </div> 42 </body> 43 </html> accountmanagerplugin/trunk/acct_mgr/templates/register.html
r1111 r1508 1 <?cs include "header.cs"?> 2 <?cs include "macros.cs"?> 1 <!DOCTYPE html 2 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml" 5 xmlns:py="http://genshi.edgewall.org/" 6 xmlns:xi="http://www.w3.org/2001/XInclude"> 7 <xi:include href="layout.html" /> 8 <head> 9 <title>Register</title> 10 </head> 3 11 4 <div id="ctxtnav" class="nav"></div> 12 <body> 13 <div id="content" class="register"> 14 <h1>Register an account</h1> 5 15 6 <div id="content" class="register"> 16 <div class="system-message" py:if="registration_error"> 17 <h2>Error</h2> 18 <p>$registration_error</p> 19 </div> 7 20 8 <h1>Register an account</h1> 9 10 <?cs if registration.error ?> 11 <div class="system-message"> 12 <h2>Error</h2> 13 <p><?cs var:registration.error ?></p> 14 </div> 15 <?cs /if ?> 16 17 <form method="post" action=""> 18 <fieldset> 19 <legend>Required</legend> 20 <div> 21 <input type="hidden" name="action" value="create" /> 22 <label>Username: 23 <input type="text" name="user" class="textwidget" size="20" /> 24 </label> 25 </div> 26 <div> 27 <label>Password: 28 <input type="password" name="password" class="textwidget" size="20" /> 29 </label> 30 </div> 31 <div> 32 <label>Confirm Password: 33 <input type="password" name="password_confirm" 34 class="textwidget" size="20" /> 35 </label> 36 </div> 37 </fieldset> 38 <fieldset> 39 <legend>Optional</legend> 40 <div> 41 <label>Name: 42 <input type="text" name="name" class="textwidget" size="20" /> 43 </label> 44 </div> 45 <div> 46 <label>Email: 47 <input type="text" name="email" class="textwidget" size="20" /> 48 </label> 49 <?cs if reset_password_enabled ?> 50 <p>Entering your email address will enable you to reset your 51 password if you ever forget it.</p> 52 <?cs /if ?> 53 </div> 54 </fieldset> 55 <input type="submit" value="Create account" /> 56 </form> 57 58 </div> 59 60 <?cs include:"footer.cs"?> 21 <form method="post" action=""> 22 <fieldset> 23 <legend>Required</legend> 24 <div> 25 <input type="hidden" name="action" value="create" /> 26 <label>Username: 27 <input type="text" name="user" class="textwidget" size="20" /> 28 </label> 29 </div> 30 <div> 31 <label>Password: 32 <input type="password" name="password" class="textwidget" size="20" /> 33 </label> 34 </div> 35 <div> 36 <label>Confirm Password: 37 <input type="password" name="password_confirm" 38 class="textwidget" size="20" /> 39 </label> 40 </div> 41 </fieldset> 42 <fieldset> 43 <legend>Optional</legend> 44 <div> 45 <label>Name: 46 <input type="text" name="name" class="textwidget" size="20" /> 47 </label> 48 </div> 49 <div> 50 <label>Email: 51 <input type="text" name="email" class="textwidget" size="20" /> 52 </label> 53 <p py:if="reset_password_enabled">Entering your email address will 54 enable you to reset your password if you ever forget it.</p> 55 </div> 56 </fieldset> 57 <input type="submit" value="Create account" /> 58 </form> 59 </div> 60 </body> 61 </html> accountmanagerplugin/trunk/acct_mgr/templates/reset_password_email.txt
r1085 r1508 3 3 Here is your account information: 4 4 5 Login URL: < <?cs var:login.link ?>>6 Username: <?cs var:account.username ?>7 Password: <?cs var:account.password ?>5 Login URL: <${login.link}> 6 Username: ${account.username} 7 Password: ${account.password} 8 8 9 9 -- 10 <?cs var:project.name ?> <<?cs var:project.url ?>>11 <?cs var:project.descr ?> 10 ${project.name} <${project.url}> 11 ${project.descr} 12 12 accountmanagerplugin/trunk/acct_mgr/templates/reset_password.html
r1085 r1508 1 <?cs include "header.cs"?> 2 <?cs include "macros.cs"?> 1 <!DOCTYPE html 2 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml" 5 xmlns:py="http://genshi.edgewall.org/" 6 xmlns:xi="http://www.w3.org/2001/XInclude"> 7 <xi:include href="layout.html" /> 8 <head> 9 <title>Reset Password</title> 10 </head> 3 11 4 <div id="ctxtnav" class="nav"></div> 12 <body> 13 <div id="content" class="register"> 14 <h1>Reset Password</h1> 5 15 6 <div id="content" class="register"> 16 <py:choose> 17 <div class="system-message" py:when="reset.logged_in"> 18 <h2>Already logged in</h2> 19 <p>You're already logged in. If you need to change your password please use 20 the <a href="${href.account()}">My Account</a> page.</p> 21 </div> 7 22 8 <h1>Reset Password</h1> 23 <p py:when="reset.sent_to_email">A new password has been emailed to you at 24 ${reset.sent_to_email}.</p> 9 25 10 <?cs if reset.logged_in ?> 11 <div class="system-message"> 12 <h2>Already logged in</h2> 13 <p> 14 You're already logged in. If you need to change your password please use 15 the <a href="<?cs var:account_href ?>">My Account</a> page. 16 </p> 17 </div> 18 <?cs elif reset.sent_to_email ?> 19 <p>A new password has been emailed to you at <?cs var:reset.sent_to_email ?>.</p> 20 <?cs else ?> 21 <p> 22 If you've forgot your password enter your username and email address below and you'll be emailed a new password. 23 </p> 26 <py:otherwise> 27 <p>If you've forgot your password enter your username and 28 email address below and you'll be emailed a new password.</p> 24 29 25 <?cs if reset.error ?> 26 <div class="system-message"> 27 <h2>Error</h2> 28 <p><?cs var:reset.error ?></p> 29 </div> 30 <?cs /if ?> 30 <div class="system-message" py:if="reset.error"> 31 <h2>Error</h2> 32 <p>$reset.error</p> 33 </div> 31 34 32 <?cs if reset.message ?> 33 <p><?cs var:reset.message ?></p> 34 <?cs /if ?> 35 <p py:if="reset.message">$reset.message</p> 35 36 36 <form method="post" action=""> 37 <div> 38 <label> 39 Username: 40 <input type="text" name="username" class="textwidget" size="20" /> 41 </label> 42 </div> 43 <div> 44 <label> 45 Email Address: 46 <input type="text" name="email" class="textwidget" size="20" /> 47 </label> 48 </div> 49 <input type="submit" value="Reset password" /> 50 </form> 51 <?cs /if ?> 52 53 </div> 54 55 <?cs include:"footer.cs"?> 56 37 <form method="post" action=""> 38 <div> 39 <label>Username: 40 <input type="text" name="username" class="textwidget" size="20" /> 41 </label> 42 </div> 43 <div> 44 <label>Email Address: 45 <input type="text" name="email" class="textwidget" size="20" /> 46 </label> 47 </div> 48 <input type="submit" value="Reset password" /> 49 </form> 50 </py:otherwise> 51 </py:choose> 52 </div> 53 </body> 54 </html> accountmanagerplugin/trunk/acct_mgr/web_ui.py
r1290 r1508 81 81 82 82 class PasswordResetNotification(NotifyEmail): 83 template_name = 'reset_password_email. cs'83 template_name = 'reset_password_email.txt' 84 84 _username = None 85 85 … … 99 99 # save the username for use in `get_smtp_address` 100 100 self._username = username 101 self.hdf['account.username'] = username 102 self.hdf['account.password'] = password 103 self.hdf['login.link'] = self.env.abs_href.login() 101 self.data.update({ 102 'account': { 103 'username': username, 104 'password': password, 105 }, 106 'login': { 107 'link': self.env.abs_href.login(), 108 } 109 }) 104 110 105 111 projname = self.config.get('project', 'name') … … 138 144 def process_request(self, req): 139 145 if req.path_info == '/account': 140 self._do_account(req)141 return 'account. cs', None146 data = {'account': self._do_account(req)} 147 return 'account.html', data, None 142 148 elif req.path_info == '/reset_password': 143 self._do_reset_password(req)144 return 'reset_password. cs', None149 data = {'reset': self._do_reset_password(req)} 150 return 'reset_password.html', data, None 145 151 146 152 def _do_account(self, req): … … 150 156 if req.method == 'POST': 151 157 if action == 'change_password': 152 self._do_change_password(req)158 return self._do_change_password(req) 153 159 elif action == 'delete': 154 self._do_delete(req) 160 return self._do_delete(req) 161 return {} 155 162 156 163 def _do_reset_password(self, req): 157 164 if req.authname != 'anonymous': 158 req.hdf['reset.logged_in'] = True 159 req.hdf['account_href'] = req.href.account() 160 return 161 if req.method == 'POST': 162 username = req.args.get('username') 163 email = req.args.get('email') 164 if not username: 165 req.hdf['reset.error'] = 'Username is required' 166 return 167 if not email: 168 req.hdf['reset.error'] = 'Email is required' 169 return 170 171 notifier = PasswordResetNotification(self.env) 172 173 if email != notifier.email_map.get(username): 174 req.hdf['reset.error'] = 'The email and username do not ' \ 175 'match a known account.' 176 return 177 178 new_password = self._random_password() 179 notifier.notify(username, new_password) 180 AccountManager(self.env).set_password(username, new_password) 181 req.hdf['reset.sent_to_email'] = email 165 return {'logged_in': True} 166 if req.method != 'POST': 167 return {} 168 username = req.args.get('username') 169 email = req.args.get('email') 170 if not username: 171 return {'error': 'Username is required'} 172 if not email: 173 return {'error': 'Email is required'} 174 175 notifier = PasswordResetNotification(self.env) 176 177 if email != notifier.email_map.get(username): 178 return {'error': 'The email and username do not ' 179 'match a known account.'} 180 181 new_password = self._random_password() 182 notifier.notify(username, new_password) 183 AccountManager(self.env).set_password(username, new_password) 184 return {'sent_to_email': email} 182 185 183 186 def _random_password(self): … … 189 192 password = req.args.get('password') 190 193 if not password: 191 req.hdf['account.error'] = 'Password cannot be empty.' 192 return 194 return {'error': 'Password cannot be empty.'} 193 195 194 196 if password != req.args.get('password_confirm'): 195 req.hdf['account.error'] = 'The passwords must match.' 196 return 197 return {'error': 'The passwords must match.'} 197 198 198 199 AccountManager(self.env).set_password(user, password) 199 re q.hdf['account.message'] = 'Password successfully updated.'200 return {'message': 'Password successfully updated.'} 200 201 201 202 def _do_delete(self, req): … … 246 247 req.redirect(self.env.href.account()) 247 248 action = req.args.get('action') 249 data = {} 248 250 if req.method == 'POST' and action == 'create': 249 251 try: 250 252 _create_user(req, self.env) 251 253 except TracError, e: 252 req.hdf['registration.error'] = e.message254 data['registration_error'] = e.message 253 255 else: 254 256 req.redirect(self.env.href.login()) 255 req.hdf['reset_password_enabled'] = \257 data['reset_password_enabled'] = \ 256 258 (self.env.is_component_enabled(AccountModule) 257 259 and NotificationSystem(self.env).smtp_enabled) 258 260 259 return 'register. cs', None261 return 'register.html', data, None 260 262 261 263 … … 298 300 def process_request(self, req): 299 301 if req.path_info.startswith('/login') and req.authname == 'anonymous': 300 req.hdf['referer'] = self._referer(req) 301 if self.env.is_component_enabled(AccountModule) \ 302 and NotificationSystem(self.env).smtp_enabled: 303 req.hdf['trac.href.reset_password'] = req.href.reset_password() 302 data = { 303 'referer': self._referer(req), 304 'reset_password_enabled': 305 (self.env.is_component_enabled(AccountModule) 306 and NotificationSystem(self.env).smtp_enabled) 307 } 304 308 if req.method == 'POST': 305 req.hdf['login.error'] = 'Invalid username or password'306 return 'login. cs', None309 data['login_error'] = 'Invalid username or password' 310 return 'login.html', data, None 307 311 return auth.LoginModule.process_request(self, req) 308 312
