Trac is being migrated to new services! Issues can be found in our new
YouTrack instance and WIKI pages can be found on our
website.
| File acct_mgr.patch, 7.2 KB (added by datallah, 17 years ago) |
|
Patch to display "Last Modified" information on all wiki pages (against rev# 1709)
|
-
|
|
|
|
| 10 | 10 | # Author: Matthew Good <trac@matt-good.net> |
| 11 | 11 | |
| 12 | 12 | from __future__ import generators |
| | 13 | import time |
| | 14 | import urlparse |
| 13 | 15 | |
| 14 | 16 | import random |
| 15 | 17 | import string |
| … |
… |
|
| 20 | 22 | from trac.notification import NotificationSystem, NotifyEmail |
| 21 | 23 | from trac.web import auth |
| 22 | 24 | from trac.web.api import IAuthenticator |
| 23 | | from trac.web.main import IRequestHandler |
| | 25 | from trac.web.main import IRequestHandler, IRequestFilter |
| 24 | 26 | from trac.web.chrome import INavigationContributor, ITemplateProvider |
| 25 | 27 | from trac.util import Markup |
| 26 | 28 | |
| … |
… |
|
| 114 | 116 | module must be set in trac.ini in order to use this. |
| 115 | 117 | """ |
| 116 | 118 | |
| 117 | | implements(INavigationContributor, IRequestHandler, ITemplateProvider) |
| | 119 | implements(INavigationContributor, IRequestHandler, ITemplateProvider, IRequestFilter) |
| 118 | 120 | |
| 119 | 121 | _password_chars = string.ascii_letters + string.digits |
| 120 | 122 | password_length = IntOption('account-manager', 'generated_password_length', 8, |
| … |
… |
|
| 132 | 134 | 'store does not support writing.') |
| 133 | 135 | return writable |
| 134 | 136 | |
| | 137 | #IRequestFilter methods |
| | 138 | def pre_process_request(self, req, handler): |
| | 139 | # Catch the user leaving /account and redirect to non-secure |
| | 140 | if (req.scheme == 'https' and req.path_info != '/account'): |
| | 141 | r = req.get_header('Referer') or '' |
| | 142 | if (r.find('/account') != -1): |
| | 143 | req.redirect(urlparse.urlunparse(('http', req.server_name, req.base_path + req.path_info, None, None, None))) |
| | 144 | |
| | 145 | return handler |
| | 146 | |
| | 147 | def post_process_request(self, req, template, content_type): |
| | 148 | return template, content_type |
| | 149 | |
| 135 | 150 | #INavigationContributor methods |
| 136 | 151 | def get_active_navigation_item(self, req): |
| 137 | 152 | return 'account' |
| … |
… |
|
| 150 | 165 | |
| 151 | 166 | def process_request(self, req): |
| 152 | 167 | if req.path_info == '/account': |
| | 168 | if req.scheme.lower() != 'https': |
| | 169 | req.redirect(urlparse.urlunparse(('https', req.server_name, req.base_path + req.path_info, None, None, None))) |
| 153 | 170 | self._do_account(req) |
| 154 | 171 | return 'account.cs', None |
| 155 | 172 | elif req.path_info == '/reset_password': |
| | 173 | if req.scheme.lower() != 'https': |
| | 174 | req.redirect(urlparse.urlunparse(('https', req.server_name, req.base_path + req.path_info, None, None, None))) |
| 156 | 175 | self._do_reset_password(req) |
| 157 | 176 | return 'reset_password.cs', None |
| 158 | 177 | |
| | 178 | |
| 159 | 179 | def _do_account(self, req): |
| 160 | 180 | if req.authname == 'anonymous': |
| 161 | 181 | req.redirect(self.env.href.wiki()) |
| … |
… |
|
| 296 | 316 | def process_request(self, req): |
| 297 | 317 | if req.authname != 'anonymous': |
| 298 | 318 | req.redirect(self.env.href.account()) |
| | 319 | if req.scheme.lower() != 'https': |
| | 320 | req.redirect(urlparse.urlunparse(('https', req.server_name, req.base_path + req.path_info, None, None, None))) |
| 299 | 321 | action = req.args.get('action') |
| 300 | 322 | if req.method == 'POST' and action == 'create': |
| 301 | 323 | try: |
| … |
… |
|
| 303 | 325 | except TracError, e: |
| 304 | 326 | req.hdf['registration.error'] = e.message |
| 305 | 327 | else: |
| 306 | | req.redirect(self.env.href.login()) |
| | 328 | req.redirect(self.env.href.login() + '?referer=/') |
| 307 | 329 | req.hdf['reset_password_enabled'] = \ |
| 308 | 330 | (self.env.is_component_enabled(AccountModule) |
| 309 | 331 | and NotificationSystem(self.env).smtp_enabled) |
| … |
… |
|
| 355 | 377 | req.hdf['trac.href.reset_password'] = req.href.reset_password() |
| 356 | 378 | if req.method == 'POST': |
| 357 | 379 | req.hdf['login.error'] = 'Invalid username or password' |
| | 380 | |
| | 381 | if req.scheme.lower() != 'https': |
| | 382 | querystr = '' |
| | 383 | if req.hdf['referer']: |
| | 384 | querystr = 'referer=' + req.hdf['referer'] |
| | 385 | |
| | 386 | req.redirect(urlparse.urlunparse(('https', req.server_name, req.base_path + req.path_info, None, querystr, None))) |
| | 387 | |
| 358 | 388 | return 'login.cs', None |
| 359 | 389 | return auth.LoginModule.process_request(self, req) |
| 360 | 390 | |
| | 391 | def _get_name_for_cookie(self, req, cookie): |
| | 392 | name = auth.LoginModule._get_name_for_cookie(self, req, cookie) |
| | 393 | if name and not req.incookie.has_key('trac_auth_session'): |
| | 394 | self.env.log.debug('Updating auth cookie %s for user %s' % |
| | 395 | (cookie.value, name)) |
| | 396 | db = self.env.get_db_cnx() |
| | 397 | cursor = db.cursor() |
| | 398 | cursor.execute('UPDATE auth_cookie SET time=%s WHERE cookie=%s', |
| | 399 | (int(time.time()), cookie.value)) |
| | 400 | req.outcookie['trac_auth'] = cookie.value |
| | 401 | req.outcookie['trac_auth']['path'] = self.env.href() |
| | 402 | req.outcookie['trac_auth']['expires'] = 86400 * 30 |
| | 403 | req.outcookie['trac_auth_session'] = '1' |
| | 404 | req.outcookie['trac_auth_session']['path'] = self.env.href() |
| | 405 | return name |
| | 406 | |
| 361 | 407 | def _do_login(self, req): |
| 362 | 408 | if not req.remote_user: |
| 363 | 409 | req.redirect(self.env.abs_href()) |
| 364 | | return auth.LoginModule._do_login(self, req) |
| | 410 | res = auth.LoginModule._do_login(self, req) |
| | 411 | if req.args.get('rememberme', '0') == '1': |
| | 412 | req.outcookie['trac_auth']['expires'] = 86400 * 30 |
| | 413 | return res |
| 365 | 414 | |
| | 415 | def _do_logout(self, req): |
| | 416 | """Log the user out. |
| | 417 | |
| | 418 | Simply deletes the corresponding record from the auth_cookie table. |
| | 419 | """ |
| | 420 | if req.authname == 'anonymous': |
| | 421 | # Not logged in |
| | 422 | return |
| | 423 | |
| | 424 | # While deleting this cookie we also take the opportunity to delete |
| | 425 | # cookies older than 30 days |
| | 426 | db = self.env.get_db_cnx() |
| | 427 | cursor = db.cursor() |
| | 428 | cursor.execute("DELETE FROM auth_cookie WHERE name=%s OR time < %s", |
| | 429 | (req.authname, int(time.time()) - 86400 * 30)) |
| | 430 | db.commit() |
| | 431 | self._expire_cookie(req) |
| | 432 | |
| 366 | 433 | def _remote_user(self, req): |
| 367 | 434 | user = req.args.get('user') |
| 368 | 435 | password = req.args.get('password') |
| … |
… |
|
| 375 | 442 | def _redirect_back(self, req): |
| 376 | 443 | """Redirect the user back to the URL she came from.""" |
| 377 | 444 | referer = self._referer(req) |
| 378 | | if referer and not referer.startswith(req.base_url): |
| 379 | | # don't redirect to external sites |
| 380 | | referer = None |
| | 445 | if referer: |
| | 446 | u = urlparse.urlparse(referer) |
| | 447 | r = urlparse.urlparse(req.base_url) |
| | 448 | if u[1] != r[1]: |
| | 449 | # don't redirect to external sites |
| | 450 | referer = self.env.abs_href() |
| | 451 | u = urlparse.urlparse(referer) |
| | 452 | r = tuple(['http', u[1], u[2], None, None, None]) |
| | 453 | referer = urlparse.urlunparse(r) |
| | 454 | |
| 381 | 455 | req.redirect(referer or self.env.abs_href()) |
| 382 | 456 | |
| 383 | 457 | def _referer(self, req): |
-
|
|
|
|
| 24 | 24 | <label for="password">Password:</label> |
| 25 | 25 | <input type="password" id="password" name="password" class="textwidget" size="20" /> |
| 26 | 26 | </div> |
| | 27 | <div> |
| | 28 | <input type="checkbox" id="rememberme" name="rememberme" value="1" /> <label for="rememberme">Remember me</label> |
| | 29 | </div> |
| 27 | 30 | <input type="submit" value="Login" /> |
| 28 | 31 | |
| 29 | 32 | <?cs if trac.href.reset_password ?> |
Download in other formats:
All information, including names and email addresses, entered onto this website or sent to mailing lists affiliated with this website will be public. Do not post confidential information, especially passwords!