[wiki/auth/cas] Sigle Sign Out
This commit is contained in:
parent
90875b1faf
commit
d885233c75
1 changed files with 51 additions and 2 deletions
|
@ -9,9 +9,12 @@
|
|||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time, re
|
||||
import urlparse
|
||||
import urllib, urllib2
|
||||
from lxml import etree
|
||||
from lxml.etree import XMLSyntaxError
|
||||
|
||||
from MoinMoin import log
|
||||
logging = log.getLogger(__name__)
|
||||
|
@ -19,7 +22,6 @@ 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."""
|
||||
|
||||
|
@ -53,6 +55,14 @@ class PyCAS(object):
|
|||
url += "&renew=true"
|
||||
return url
|
||||
|
||||
def singlesignout(self, callback, body):
|
||||
try:
|
||||
nodes = etree.fromstring(body).xpath("/samlp:LogoutRequest/samlp:SessionIndex", namespaces={'samlp' : 'urn:oasis:names:tc:SAML:2.0:protocol'})
|
||||
for node in nodes:
|
||||
callback(node.text)
|
||||
except XMLSyntaxError:
|
||||
pass
|
||||
|
||||
def validate_ticket(self, service, ticket):
|
||||
"""Validate the given ticket against the given service."""
|
||||
f = urllib2.urlopen(self.validate_url(service, ticket))
|
||||
|
@ -68,13 +78,14 @@ class CASAuth(BaseAuth):
|
|||
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):
|
||||
def __init__(self, auth_server, login_path="/login", logout_path="/logout", validate_path="/validate", action="login_cas", create_user=False, fallback_url=None, ticket_path=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
|
||||
self.ticket_path = ticket_path
|
||||
|
||||
def request(self, request, user_obj, **kw):
|
||||
ticket = request.args.get("ticket", "")
|
||||
|
@ -84,10 +95,46 @@ class CASAuth(BaseAuth):
|
|||
p = urlparse.urlparse(request.url)
|
||||
url = urlparse.urlunparse(('https', p.netloc, p.path, "", "", ""))
|
||||
|
||||
def store_ticket(ticket, username):
|
||||
with open(self.ticket_path + ticket, 'w') as f:
|
||||
f.write(username)
|
||||
|
||||
def username_of_ticket(ticket):
|
||||
try:
|
||||
with open(self.ticket_path + ticket) as f:
|
||||
username = f.read()
|
||||
os.remove(self.ticket_path + ticket)
|
||||
return username
|
||||
except IOError:
|
||||
return None
|
||||
|
||||
def logout_user(ticket):
|
||||
username = username_of_ticket(ticket)
|
||||
if username:
|
||||
u = user.User(request, None, username)
|
||||
checks = []
|
||||
if u.exists():
|
||||
def user_matches(session):
|
||||
try:
|
||||
return session['user.id'] == u.id
|
||||
except KeyError:
|
||||
return False
|
||||
session_service = request.cfg.session_service
|
||||
for sid in session_service.get_all_session_ids(request):
|
||||
session = session_service.get_session(request, sid)
|
||||
|
||||
if user_matches(session):
|
||||
session_service.destroy_session(request, session)
|
||||
|
||||
# authenticated user
|
||||
if not force and user_obj and user_obj.valid:
|
||||
return user_obj, True
|
||||
|
||||
if self.ticket_path and request.method == 'POST':
|
||||
logoutRequest=request.form.get('logoutRequest', None)
|
||||
if logoutRequest is not None:
|
||||
self.cas.singlesignout(logout_user, logoutRequest)
|
||||
|
||||
# anonymous
|
||||
if not ticket and not self.action == action:
|
||||
return user_obj, True
|
||||
|
@ -105,6 +152,8 @@ class CASAuth(BaseAuth):
|
|||
u.valid = u.exists()
|
||||
if self.fallback_url and not u.valid:
|
||||
request.http_redirect("%s?action=%s&wiki_url=%s" % (self.fallback_url, self.action, url))
|
||||
if u.valid:
|
||||
store_ticket(ticket, username)
|
||||
return u, True
|
||||
|
||||
# login
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue