# CASified login module for Trac from trac.core import * from trac.web.api import IAuthenticator, IRequestHandler from trac.web.chrome import INavigationContributor from trac.util import escape, hex_entropy, Markup from trac.web.auth import LoginModule from pycas import PyCAS class CasLoginModule(LoginModule): """A CAS-based login module.""" def __init__(self): url = self.config.get('cas','server').strip() paths = { 'login_path': self.config.get('cas','login_path','/login').strip(), 'logout_path': self.config.get('cas','logout_path','/logout').strip(), 'validate_path': self.config.get('cas','validate_path','/validate').strip(), } self.cas = PyCAS(url, **paths) self.service = self.env.abs_href.login() # IAuthenticatorMethods def authenticate(self, req): ticket = req.args.get('ticket') if ticket: valid, user = self.cas.validate_ticket(self.service, ticket) if valid: req.remote_user = user return super(CasLoginModule, self).authenticate(req) # INavigationContributor methods def get_navigation_items(self, req): if req.authname and req.authname != 'anonymous': yield ('metanav', 'login', 'logged in as %s' % req.authname) yield ('metanav', 'logout', Markup('Logout' % escape(self.env.href.logout()))) else: yield ('metanav', 'login', Markup('Login' % escape(self.cas.login_url(self.service)))) def _do_logout(self, req): if req.authname: super(CasLoginModule, self)._do_logout(req) req.redirect(self.cas.logout_url(self.env.abs_href())) else: req.redirect(self.env.abs_href())