[wiki] Ajout d'un module d'authentification via le CAS
This commit is contained in:
parent
1e4b2a4612
commit
19eb6c8e7b
2 changed files with 123 additions and 0 deletions
123
wiki/auth/cas.py
Normal file
123
wiki/auth/cas.py
Normal file
|
@ -0,0 +1,123 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
"""
|
||||
MoinMoin - CAS authentication
|
||||
|
||||
Jasig CAS (see http://www.jasig.org/cas) authentication module.
|
||||
|
||||
@copyright: 2012 MoinMoin:RichardLiao
|
||||
@license: GNU GPL, see COPYING for details.
|
||||
"""
|
||||
|
||||
import sys
|
||||
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", action="login_cas", create_user=False, fallback_url=None):
|
||||
BaseAuth.__init__(self)
|
||||
self.cas = PyCAS(auth_server, login_path=login_path,
|
||||
validate_path=validate_path, logout_path=logout_path)
|
||||
self.action = action
|
||||
self.create_user = create_user
|
||||
self.fallback_url = fallback_url
|
||||
|
||||
def request(self, request, user_obj, **kw):
|
||||
ticket = request.args.get("ticket", "")
|
||||
action = request.args.get("action", "")
|
||||
logoutRequest = request.args.get("logoutRequest", [])
|
||||
p = urlparse.urlparse(request.url)
|
||||
url = urlparse.urlunparse(('https', p.netloc, p.path, "", "", ""))
|
||||
|
||||
# authenticated user
|
||||
if user_obj and user_obj.valid:
|
||||
return user_obj, True
|
||||
|
||||
# anonymous
|
||||
if not ticket and not self.action == action:
|
||||
return user_obj, True
|
||||
|
||||
# valid ticket on CAS
|
||||
if ticket:
|
||||
valid, username = self.cas.validate_ticket(url, ticket)
|
||||
if valid:
|
||||
u = user.User(request, auth_username=username, auth_method=self.name)
|
||||
# auto create user ?
|
||||
if self.create_user:
|
||||
u.valid = valid
|
||||
u.create_or_update(True)
|
||||
else:
|
||||
u.valid = u.exists()
|
||||
if self.fallback_url and not u.valid:
|
||||
request.http_redirect(self.fallback_url)
|
||||
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:
|
||||
user_obj.valid = False
|
||||
request.cfg.session_service.destroy_session(request, request.session)
|
||||
|
||||
p = urlparse.urlparse(request.url)
|
||||
url = urlparse.urlunparse((p.scheme, p.netloc, p.path, "", "", ""))
|
||||
request.http_redirect(self.cas.logout_url(url))
|
||||
return user_obj, False
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue