Merge branch 'master' into cas-version-2-and-3
Conflicts: flask_cas/__init__.py flask_cas/routing.py setup.py tests/test_routing.py
This commit is contained in:
commit
4a33cd1774
7 changed files with 63 additions and 16 deletions
|
@ -1,5 +1,6 @@
|
|||
language: python
|
||||
python:
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
- "3.3"
|
||||
- "3.4"
|
||||
|
|
22
README.md
22
README.md
|
@ -86,6 +86,26 @@ configuration value.
|
|||
The `/logout/` route will redirect the user to the CAS logout page and
|
||||
the `username` 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.
|
||||
|
||||
```python
|
||||
from flask.ext.cas import login
|
||||
from flask.ext.cas import logout
|
||||
```
|
||||
|
||||
If you would like to require that a user is logged in before continuing
|
||||
you may use the `cas.login_required` method.
|
||||
|
||||
```python
|
||||
from flask.ext.cas import login_required
|
||||
|
||||
app.route('/foo')
|
||||
@login_required
|
||||
def foo():
|
||||
pass
|
||||
```
|
||||
|
||||
### Configuration ###
|
||||
|
||||
#### Required Configs ####
|
||||
|
@ -112,6 +132,7 @@ the `username` will be removed from the session.
|
|||
import flask
|
||||
from flask import Flask
|
||||
from flask.ext.cas import CAS
|
||||
from flask.ext.cas import login_required
|
||||
|
||||
app = Flask(__name__)
|
||||
cas = CAS(app, '/cas')
|
||||
|
@ -119,6 +140,7 @@ app.config['CAS_SERVER'] = 'https://sso.pdx.edu'
|
|||
app.config['CAS_AFTER_LOGIN'] = 'route_root'
|
||||
|
||||
@app.route('/')
|
||||
@login_required
|
||||
def route_root():
|
||||
return flask.render_template(
|
||||
'layout.html',
|
||||
|
|
|
@ -15,6 +15,7 @@ except ImportError:
|
|||
|
||||
from . import routing
|
||||
|
||||
from functools import wraps
|
||||
|
||||
class CAS(object):
|
||||
"""
|
||||
|
@ -81,3 +82,19 @@ class CAS(object):
|
|||
def attributes(self):
|
||||
return flask.session.get(
|
||||
self.app.config['CAS_ATTRIBUTES_SESSION_KEY'], None)
|
||||
|
||||
def login():
|
||||
return flask.redirect(flask.url_for('cas.login', _external=True))
|
||||
|
||||
def logout():
|
||||
return flask.redirect(flask.url_for('cas.logout', _external=True))
|
||||
|
||||
def login_required(function):
|
||||
@wraps(function)
|
||||
def wrap(*args, **kwargs):
|
||||
if 'CAS_USERNAME' not in flask.session:
|
||||
flask.session['CAS_AFTER_LOGIN_SESSION_URL'] = flask.request.path
|
||||
return login()
|
||||
else:
|
||||
return function(*args, **kwargs)
|
||||
return wrap
|
||||
|
|
|
@ -59,7 +59,7 @@ def create_url(base, path=None, *query):
|
|||
# Remove key/value pairs with None values.
|
||||
query = filter(lambda pair: pair[1] is not None, query)
|
||||
# Add the query string to the url
|
||||
url = urljoin(url, '?{}'.format(urlencode(list(query))))
|
||||
url = urljoin(url, '?{0}'.format(urlencode(list(query))))
|
||||
return url
|
||||
|
||||
|
||||
|
|
|
@ -40,12 +40,15 @@ def login():
|
|||
if cas_token_session_key in flask.session:
|
||||
|
||||
if validate(flask.session[cas_token_session_key]):
|
||||
redirect_url = flask.url_for(
|
||||
current_app.config['CAS_AFTER_LOGIN'])
|
||||
if 'CAS_AFTER_LOGIN_SESSION_URL' in flask.session:
|
||||
redirect_url = flask.session.pop('CAS_AFTER_LOGIN_SESSION_URL')
|
||||
else:
|
||||
redirect_url = flask.url_for(
|
||||
current_app.config['CAS_AFTER_LOGIN'])
|
||||
else:
|
||||
del flask.session[cas_token_session_key]
|
||||
|
||||
current_app.logger.debug('Redirecting to: {}'.format(redirect_url))
|
||||
current_app.logger.debug('Redirecting to: {0}'.format(redirect_url))
|
||||
|
||||
return flask.redirect(redirect_url)
|
||||
|
||||
|
@ -68,7 +71,7 @@ def logout():
|
|||
current_app.config['CAS_VERSION'],
|
||||
)
|
||||
|
||||
current_app.logger.debug('Redirecting to: {}'.format(redirect_url))
|
||||
current_app.logger.debug('Redirecting to: {0}'.format(redirect_url))
|
||||
return flask.redirect(redirect_url)
|
||||
|
||||
|
||||
|
@ -80,7 +83,9 @@ def validate(ticket):
|
|||
key `CAS_USERNAME_SESSION_KEY`.
|
||||
"""
|
||||
|
||||
current_app.logger.debug("validating token {}".format(ticket))
|
||||
cas_username_session_key = current_app.config['CAS_USERNAME_SESSION_KEY']
|
||||
|
||||
current_app.logger.debug("validating token {0}".format(ticket))
|
||||
|
||||
_PROTOCOLS = {'1': _validate_cas1, '2': _validate_cas2, '3': _validate_cas3}
|
||||
if current_app.config['CAS_VERSION'] not in _PROTOCOLS:
|
||||
|
@ -93,7 +98,7 @@ def validate(ticket):
|
|||
ticket,
|
||||
version=current_app.config['CAS_VERSION'])
|
||||
|
||||
current_app.logger.debug("Making GET request to {}".format(
|
||||
current_app.logger.debug("Making GET request to {0}".format(
|
||||
cas_validate_url))
|
||||
|
||||
response = urlopen(cas_validate_url)
|
||||
|
|
2
setup.py
2
setup.py
|
@ -8,7 +8,7 @@ import textwrap
|
|||
if __name__ == "__main__":
|
||||
setuptools.setup(
|
||||
name="Flask-CAS",
|
||||
version="1.0.0",
|
||||
version="0.5.1",
|
||||
description="Flask extension for CAS",
|
||||
author="Cameron Brandon White",
|
||||
author_email="cameronbwhite90@gmail.com",
|
||||
|
|
|
@ -71,18 +71,16 @@ class test_cas_1_routing(test_routing):
|
|||
with client.session_transaction() as s:
|
||||
s[self.app.config['CAS_TOKEN_SESSION_KEY']] = ticket
|
||||
client.get('/login/')
|
||||
self.assertNotIn(
|
||||
self.app.config['CAS_USERNAME_SESSION_KEY'],
|
||||
flask.session)
|
||||
self.assertNotIn(
|
||||
self.app.config['CAS_TOKEN_SESSION_KEY'],
|
||||
flask.session)
|
||||
self.assertTrue(
|
||||
self.app.config['CAS_USERNAME_SESSION_KEY'] not in flask.session)
|
||||
self.assertTrue(
|
||||
self.app.config['CAS_TOKEN_SESSION_KEY'] not in flask.session)
|
||||
|
||||
@mock.patch.object(routing, 'validate', return_value=True)
|
||||
def test_login_by_cas_valid(self, m):
|
||||
with self.app.test_client() as client:
|
||||
ticket = '12345-abcdefg-cas'
|
||||
response = client.get('/login/?ticket={}'.format(ticket))
|
||||
response = client.get('/login/?ticket={0}'.format(ticket))
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(
|
||||
response.headers['Location'],
|
||||
|
@ -95,7 +93,7 @@ class test_cas_1_routing(test_routing):
|
|||
def test_login_by_cas_invalid(self, m):
|
||||
with self.app.test_client() as client:
|
||||
ticket = '12345-abcdefg-cas'
|
||||
response = client.get('/login/?ticket={}'.format(ticket))
|
||||
response = client.get('/login/?ticket={0}'.format(ticket))
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(
|
||||
response.headers['Location'],
|
||||
|
@ -244,3 +242,7 @@ class test_cas_3_routing(test_routing):
|
|||
self.assertNotIn(
|
||||
self.app.config['CAS_TOKEN_SESSION_KEY'],
|
||||
flask.session)
|
||||
self.assertTrue(
|
||||
self.app.config['CAS_USERNAME_SESSION_KEY'] not in flask.session)
|
||||
self.assertTrue(
|
||||
self.app.config['CAS_TOKEN_SESSION_KEY'] not in flask.session)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue