diff --git a/app/__init__.py b/app/__init__.py index dbbe1b081b..9614d55b3d 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -228,7 +228,9 @@ class ReverseProxied(object): def create_app(config_class=DevConfig): app = Flask(__name__, static_url_path="/ScoDoc/static", static_folder="static") - CAS(app, url_prefix="/cas") + from app.auth import cas + + CAS(app, url_prefix="/cas", configuration_function=cas.set_cas_configuration) app.wsgi_app = ReverseProxied(app.wsgi_app) app.json_encoder = ScoDocJSONEncoder diff --git a/app/auth/cas.py b/app/auth/cas.py index 2a037744a5..469617298a 100644 --- a/app/auth/cas.py +++ b/app/auth/cas.py @@ -42,7 +42,9 @@ def after_cas_login(): ) else: current_app.logger.info( - f"""CAS login denied for {user.user_name if user else ""} cas_id={cas_id} (unknown or inactive)""" + f"""CAS login denied for { + user.user_name if user else "" + } cas_id={cas_id} (unknown or inactive)""" ) else: current_app.logger.info( @@ -75,6 +77,7 @@ def set_cas_configuration(app: flask.app.Flask = None): """ app = app or current_app if ScoDocSiteConfig.is_cas_enabled(): + current_app.logger.info("CAS: set_cas_configuration") app.config["CAS_SERVER"] = ScoDocSiteConfig.get("cas_server") app.config["CAS_AFTER_LOGIN"] = "auth.after_cas_login" app.config["CAS_AFTER_LOGOUT"] = "auth.after_cas_logout" diff --git a/flask_cas/__init__.py b/flask_cas/__init__.py index 76e02c2524..eae4213916 100644 --- a/flask_cas/__init__.py +++ b/flask_cas/__init__.py @@ -17,6 +17,7 @@ from . import routing from functools import wraps + class CAS(object): """ Required Configs: @@ -39,68 +40,69 @@ class CAS(object): |CAS_AFTER_LOGOUT | None | """ - def __init__(self, app=None, url_prefix=None): + def __init__(self, app=None, url_prefix=None, configuration_function=None): self._app = app if app is not None: - self.init_app(app, url_prefix) + self.init_app(app, url_prefix, configuration_function) - def init_app(self, app, url_prefix=None): + def init_app(self, app, url_prefix=None, configuration_function=None): # Configuration defaults - app.config.setdefault('CAS_TOKEN_SESSION_KEY', '_CAS_TOKEN') - 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') + app.config.setdefault("CAS_TOKEN_SESSION_KEY", "_CAS_TOKEN") + 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") + app.config.setdefault("CAS_CONFIGURATION_FUNCTION", configuration_function) # Requires CAS 2.0 - app.config.setdefault('CAS_AFTER_LOGOUT', None) + app.config.setdefault("CAS_AFTER_LOGOUT", None) # Register Blueprint app.register_blueprint(routing.blueprint, url_prefix=url_prefix) # Use the newstyle teardown_appcontext if it's available, # otherwise fall back to the request context - if hasattr(app, 'teardown_appcontext'): + if hasattr(app, "teardown_appcontext"): app.teardown_appcontext(self.teardown) else: app.teardown_request(self.teardown) def teardown(self, exception): ctx = stack.top - + @property def app(self): return self._app or current_app @property def username(self): - return flask.session.get( - self.app.config['CAS_USERNAME_SESSION_KEY'], None) + return flask.session.get(self.app.config["CAS_USERNAME_SESSION_KEY"], None) @property def attributes(self): - return flask.session.get( - self.app.config['CAS_ATTRIBUTES_SESSION_KEY'], None) + return flask.session.get(self.app.config["CAS_ATTRIBUTES_SESSION_KEY"], None) @property def token(self): - return flask.session.get( - self.app.config['CAS_TOKEN_SESSION_KEY'], None) + return flask.session.get(self.app.config["CAS_TOKEN_SESSION_KEY"], None) + def login(): - return flask.redirect(flask.url_for('cas.login', _external=True)) + return flask.redirect(flask.url_for("cas.login", _external=True)) + def logout(): - return flask.redirect(flask.url_for('cas.logout', _external=True)) + 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.script_root + - flask.request.full_path + if "CAS_USERNAME" not in flask.session: + flask.session["CAS_AFTER_LOGIN_SESSION_URL"] = ( + flask.request.script_root + flask.request.full_path ) return login() else: return function(*args, **kwargs) + return wrap diff --git a/flask_cas/routing.py b/flask_cas/routing.py index fbc8809592..689530e71e 100644 --- a/flask_cas/routing.py +++ b/flask_cas/routing.py @@ -32,6 +32,9 @@ def login(): the user's attributes are saved under the key 'CAS_USERNAME_ATTRIBUTE_KEY' """ + conf_func = current_app.config.get("CAS_CONFIGURATION_FUNCTION") + if conf_func: # call function setting app configuration + conf_func(current_app) if not "CAS_SERVER" in current_app.config: current_app.logger.info("cas_login: no configuration") return "CAS configuration missing" @@ -72,7 +75,9 @@ def logout(): """ When the user accesses this route they are logged out. """ - + conf_func = current_app.config.get("CAS_CONFIGURATION_FUNCTION") + if conf_func: # call function setting app configuration + conf_func(current_app) cas_username_session_key = current_app.config["CAS_USERNAME_SESSION_KEY"] cas_attributes_session_key = current_app.config["CAS_ATTRIBUTES_SESSION_KEY"] cas_token_session_key = current_app.config["CAS_TOKEN_SESSION_KEY"] diff --git a/sco_version.py b/sco_version.py index 53ca178704..46167352f8 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.4.55" +SCOVERSION = "9.4.56" SCONAME = "ScoDoc"