/usr/share/pyshared/MoinMoin/auth/cas.py is in python-moinmoin 1.9.3-1ubuntu2.3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | # -*- coding: iso-8859-1 -*-
"""
MoinMoin - CAS authentication
Jasig CAS (see http://www.jasig.org/cas) authentication module.
@copyright: 2009 MoinMoin:RichardLiao
@license: GNU GPL, see COPYING for details.
"""
import time, re
import urlparse
import urllib, urllib2
from MoinMoin import log
logging = log.getLogger(__name__)
from MoinMoin.auth import BaseAuth
from MoinMoin import user, wikiutil
class PyCAS(object):
"""A class for working with a CAS server."""
def __init__(self, server_url, renew=False, login_path='/login', logout_path='/logout',
validate_path='/validate', coding='utf-8'):
self.server_url = server_url
self.renew = renew
self.login_path = login_path
self.logout_path = logout_path
self.validate_path = validate_path
self.coding = coding
def login_url(self, service):
"""Return the login URL for the given service."""
url = self.server_url + self.login_path + '?service=' + urllib.quote_plus(service)
if self.renew:
url += "&renew=true"
return url
def logout_url(self, redirect_url=None):
"""Return the logout URL."""
url = self.server_url + self.logout_path
if redirect_url:
url += '?url=' + urllib.quote_plus(redirect_url)
return url
def validate_url(self, service, ticket):
"""Return the validation URL for the given service. (For CAS 1.0)"""
url = self.server_url + self.validate_path + '?service=' + urllib.quote_plus(service) + '&ticket=' + urllib.quote_plus(ticket)
if self.renew:
url += "&renew=true"
return url
def validate_ticket(self, service, ticket):
"""Validate the given ticket against the given service."""
f = urllib2.urlopen(self.validate_url(service, ticket))
valid = f.readline()
valid = valid.strip() == 'yes'
user = f.readline().strip()
user = user.decode(self.coding)
return valid, user
class CASAuth(BaseAuth):
""" handle login from CAS """
name = 'CAS'
login_inputs = ['username', 'password']
logout_possible = True
def __init__(self, auth_server, login_path="/login", logout_path="/logout", validate_path="/validate"):
BaseAuth.__init__(self)
self.cas = PyCAS(auth_server, login_path=login_path,
validate_path=validate_path, logout_path=logout_path)
def request(self, request, user_obj, **kw):
ticket = request.args.get('ticket')
action = request.args.get("action", [])
logoutRequest = request.args.get('logoutRequest', [])
url = request.url_root + urllib.quote_plus(request.path.encode('utf-8'))
# # handle logout request from CAS
# if logoutRequest:
# logoutRequestMatch = re.search("<samlp:SessionIndex>(.*)</samlp:SessionIndex>", logoutRequest[0])
# service_ticket = logoutRequestMatch.group(1)
# if service_ticket:
# # TODO: logout
# return self.logout(request, user_obj)
# authenticated user
if user_obj and user_obj.valid:
return user_obj, True
# anonymous
if not ticket and not "login" in action:
return user_obj, True
# valid ticket on CAS
if ticket:
valid, username = self.cas.validate_ticket(url, ticket[0])
if valid:
u = user.User(request, auth_username=username, auth_method=self.name)
u.valid = valid
# auto create user
u.create_or_update(True)
return u, True
# login
request.http_redirect(self.cas.login_url(url))
return user_obj, True
def logout(self, request, user_obj, **kw):
if self.name and user_obj and user_obj.auth_method == self.name:
url = request.url_root + urllib.quote_plus(request.path.encode('utf-8'))
request.http_redirect(self.cas.logout_url(url))
user_obj.valid = False
return user_obj, True
|