Split CAS_USER into CAS_ATTRIBUTES and CAS_USERNAME

This commit is contained in:
Warren Nelson 2015-08-05 09:47:34 -04:00
parent 11ecbde9e8
commit 1073e86f01
4 changed files with 57 additions and 37 deletions

View file

@ -4,7 +4,7 @@ Flask-CAS
[![Build Status](https://travis-ci.org/cameronbwhite/Flask-CAS.png?branch=master)](https://travis-ci.org/cameronbwhite/Flask-CAS)
Flask-CAS is a Flask extension which makes it easy to
authenticate with a CAS.
authenticate with a CAS Server (v2.0+).
## What is CAS? ##
@ -80,11 +80,13 @@ The `/login/` route will redirect the user to the CAS specified by the
`CAS_SERVER` configuration value. If login is successful the user will
be redirect to the endpoint specified by the `CAS_AFTER_LOGIN`
configuration value, and the logged in user's `username` will be store
in the session under the key specified by the `CAS_USER_SESSION_KEY`
configuration value.
in the session under the key specified by the `CAS_USERNAME_SESSION_KEY`
configuration value. If `attributes` are available, they will be stored
in the session under the key specified by the
`CAS_ATTRIBUTES_SESSION_KEY`
The `/logout/` route will redirect the user to the CAS logout page and
the `username` will be removed from the session.
the `username` and `attributes` will be removed from the session.
For convenience you can use the `cas.login` and `cas.logout`
functions to redirect users to the login and logout pages.
@ -117,14 +119,15 @@ you may use the `cas.login_required` method.
#### Optional Configs ####
|Key | Default |
|-------------------------|-----------------------|
|CAS_TOKEN_SESSION_KEY | _CAS_TOKEN |
|CAS_USER_SESSION_KEY | CAS_USER |
|CAS_LOGIN_ROUTE | '/cas' |
|CAS_LOGOUT_ROUTE | '/cas/logout' |
|CAS_VALIDATE_ROUTE | '/cas/serviceValidate'|
|CAS_AFTER_LOGOUT | None |
|Key | Default |
|---------------------------|-----------------------|
|CAS_TOKEN_SESSION_KEY | _CAS_TOKEN |
|CAS_USERNAME_SESSION_KEY | CAS_USERNAME |
|CAS_ATTRIBUTES_SESSION_KEY | CAS_ATTRIBUTES |
|CAS_LOGIN_ROUTE | '/cas' |
|CAS_LOGOUT_ROUTE | '/cas/logout' |
|CAS_VALIDATE_ROUTE | '/cas/serviceValidate'|
|CAS_AFTER_LOGOUT | None |
## Example ##
@ -145,5 +148,6 @@ def route_root():
return flask.render_template(
'layout.html',
username = cas.username,
display_name = cas.attributes['cas:displayName']
)
```

View file

@ -28,14 +28,15 @@ class CAS(object):
Optional Configs:
|Key | Default |
|-------------------------|-----------------------|
|CAS_TOKEN_SESSION_KEY | _CAS_TOKEN |
|CAS_USER_SESSION_KEY | CAS_USER |
|CAS_LOGIN_ROUTE | '/cas' |
|CAS_LOGOUT_ROUTE | '/cas/logout' |
|CAS_VALIDATE_ROUTE | '/cas/serviceValidate'|
|CAS_AFTER_LOGOUT | None |
|Key | Default |
|---------------------------|-----------------------|
|CAS_TOKEN_SESSION_KEY | _CAS_TOKEN |
|CAS_USERNAME_SESSION_KEY | CAS_USERNAME |
|CAS_ATTRIBUTES_SESSION_KEY | CAS_ATTRIBUTES |
|CAS_LOGIN_ROUTE | '/cas' |
|CAS_LOGOUT_ROUTE | '/cas/logout' |
|CAS_VALIDATE_ROUTE | '/cas/serviceValidate'|
|CAS_AFTER_LOGOUT | None |
"""
def __init__(self, app=None, url_prefix=None):
@ -46,11 +47,12 @@ class CAS(object):
def init_app(self, app, url_prefix=None):
# Configuration defaults
app.config.setdefault('CAS_TOKEN_SESSION_KEY', '_CAS_TOKEN')
app.config.setdefault('CAS_USER_SESSION_KEY', 'CAS_USER')
app.config.setdefault('CAS_USERNAME_SESSION_KEY', 'CAS_USERNAME')
app.config.setdefault('CAS_ATTRIBUTES_SESSION_KEY', 'CAS_ATTRIBUTES')
app.config.setdefault('CAS_LOGIN_ROUTE', '/cas')
app.config.setdefault('CAS_LOGOUT_ROUTE', '/cas/logout')
app.config.setdefault('CAS_VALIDATE_ROUTE', '/cas/serviceValidate')
# Requires CAS 3.0
# Requires CAS 2.0
app.config.setdefault('CAS_AFTER_LOGOUT', None)
# Register Blueprint
app.register_blueprint(routing.blueprint, url_prefix=url_prefix)
@ -71,15 +73,15 @@ class CAS(object):
@property
def username(self):
if self.app.config['CAS_USER_SESSION_KEY'] in flask.session:
return flask.session.get(self.app.config['CAS_USER_SESSION_KEY'])[0]
if self.app.config['CAS_USERNAME_SESSION_KEY'] in flask.session:
return flask.session.get(self.app.config['CAS_USERNAME_SESSION_KEY'])
else:
return None
@property
def attributes(self):
if self.app.config['CAS_USER_SESSION_KEY'] in flask.session:
return flask.session.get(self.app.config['CAS_USER_SESSION_KEY'])[1]
if self.app.config['CAS_ATTRIBUTES_SESSION_KEY'] in flask.session:
return flask.session.get(self.app.config['CAS_ATTRIBUTES_SESSION_KEY'])
else:
return None
@ -97,7 +99,7 @@ def logout():
def login_required(function):
@wraps(function)
def wrap(*args, **kwargs):
if 'CAS_USER' not in flask.session:
if 'CAS_USERNAME' not in flask.session:
flask.session['CAS_AFTER_LOGIN_SESSION_URL'] = flask.request.path
return login()
else:

View file

@ -25,7 +25,9 @@ def login():
to login. If the login was successful, the CAS will respond to this
route with the ticket in the url. The ticket is then validated.
If validation was successful the logged in username is saved in
the user's session under the key `CAS_USER_SESSION_KEY`.
the user's session under the key `CAS_USERNAME_SESSION_KEY` and
the user's attributes are saved under the key
'CAS_USERNAME_ATTRIBUTE_KEY'
"""
cas_token_session_key = current_app.config['CAS_TOKEN_SESSION_KEY']
@ -60,10 +62,14 @@ def logout():
When the user accesses this route they are logged out.
"""
cas_user_session_key = current_app.config['CAS_USER_SESSION_KEY']
cas_username_session_key = current_app.config['CAS_USERNAME_SESSION_KEY']
cas_attributes_session_key = current_app.config['CAS_ATTRIBUTES_SESSION_KEY']
if cas_user_session_key in flask.session:
del flask.session[cas_user_session_key]
if cas_username_session_key in flask.session:
del flask.session[cas_username_session_key]
if cas_attributes_session_key in flask.session:
del flask.session[cas_attributes_session_key]
if(current_app.config['CAS_AFTER_LOGOUT'] != None):
redirect_url = create_cas_logout_url(
@ -84,10 +90,12 @@ def validate(ticket):
Will attempt to validate the ticket. If validation fails, then False
is returned. If validation is successful, then True is returned
and the validated username is saved in the session under the
key `CAS_USER_SESSION_KEY`.
key `CAS_USERNAME_SESSION_KEY` while tha validated attributes dictionary
is saved under the key 'CAS_ATTRIBUTES_SESSION_KEY'.
"""
cas_user_session_key = current_app.config['CAS_USER_SESSION_KEY']
cas_username_session_key = current_app.config['CAS_USERNAME_SESSION_KEY']
cas_attributes_session_key = current_app.config['CAS_ATTRIBUTES_SESSION_KEY']
current_app.logger.debug("validating token {0}".format(ticket))
@ -121,7 +129,8 @@ def validate(ticket):
for group_number in range(0, len(attributes['cas:memberOf'])):
attributes['cas:memberOf'][group_number] = attributes['cas:memberOf'][group_number].lstrip(' ').rstrip(' ')
flask.session[cas_user_session_key] = (username, attributes)
flask.session[cas_username_session_key] = username
flask.session[cas_attributes_session_key] = attributes
else:
current_app.logger.debug("invalid")

View file

@ -27,7 +27,8 @@ class test_routing(unittest.TestCase):
self.app.config['CAS_SERVER'] = 'http://cas.server.com'
self.app.config['CAS_TOKEN_SESSION_KEY'] = '_CAS_TOKEN'
self.app.config['CAS_USER_SESSION_KEY'] = 'CAS_USER'
self.app.config['CAS_USERNAME_SESSION_KEY'] = 'CAS_USERNAME'
self.app.config['CAS_ATTRIBUTES_SESSION_KEY'] = 'CAS_ATTRIBUTES'
self.app.config['CAS_AFTER_LOGIN'] = 'root'
self.app.config['CAS_LOGIN_ROUTE'] = '/cas'
self.app.config['CAS_LOGOUT_ROUTE'] = '/cas/logout'
@ -86,7 +87,9 @@ class test_routing(unittest.TestCase):
s[self.app.config['CAS_TOKEN_SESSION_KEY']] = ticket
client.get('/login/')
self.assertTrue(
self.app.config['CAS_USER_SESSION_KEY'] not in flask.session)
self.app.config['CAS_USERNAME_SESSION_KEY'] not in flask.session)
self.assertTrue(
self.app.config['CAS_ATTRIBUTES_SESSION_KEY'] not in flask.session)
self.assertTrue(
self.app.config['CAS_TOKEN_SESSION_KEY'] not in flask.session)
@ -155,6 +158,8 @@ class test_routing(unittest.TestCase):
ticket = '12345-abcdefg-cas'
self.assertEqual(routing.validate(ticket), False)
self.assertTrue(
self.app.config['CAS_USER_SESSION_KEY'] not in flask.session)
self.app.config['CAS_USERNAME_SESSION_KEY'] not in flask.session)
self.assertTrue(
self.app.config['CAS_ATTRIBUTES_SESSION_KEY'] not in flask.session)
self.assertTrue(
self.app.config['CAS_TOKEN_SESSION_KEY'] not in flask.session)