Loading doc/source/admin/galaxy_options.rst +31 −0 Original line number Diff line number Diff line Loading @@ -4181,6 +4181,37 @@ :Type: str ~~~~~~~~~~~~~~~~~~~~~~ ``oidc_auth_pipeline`` ~~~~~~~~~~~~~~~~~~~~~~ :Description: Sets the full sequence of steps that Python Social Auth goes through when authenticating an OIDC login. Use when you want to completely customize the pipeline (e.g. for testing). By default, Galaxy uses galaxy.authnz.psa_authnz.AUTH_PIPELINE - see there for example steps. Each element should be an import path to a function, e.g. galaxy.authnz.psa_authnz.contains_required_data :Default: ``None`` :Type: seq ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``oidc_auth_pipeline_extra`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :Description: Sets additional authentication pipeline steps, added after the default steps (from galaxy.authnz.psa_authnz.AUTH_PIPELINE). Use when you want to keep the default pipeline, but add additional custom processing. Each element should be an import path to a function, e.g. galaxy.authnz.psa_authnz.contains_required_data :Default: ``None`` :Type: seq ~~~~~~~~~~~~~~~~~~~~~ ``oidc_scope_prefix`` ~~~~~~~~~~~~~~~~~~~~~ Loading lib/galaxy/authnz/psa_authnz.py +4 −1 Original line number Diff line number Diff line Loading @@ -118,7 +118,10 @@ class PSAAuthnz(IdentityProvider): self.config[setting_name("USER_MODEL")] = "models.User" # Use a custom auth pipeline if configured. auth_pipeline = app_config.get("oidc_auth_pipeline", AUTH_PIPELINE) auth_pipeline = app_config.oidc_auth_pipeline or AUTH_PIPELINE # Add extra steps to the auth pipeline if configured. if app_config.oidc_auth_pipeline_extra: auth_pipeline = auth_pipeline + tuple(app_config.oidc_auth_pipeline_extra) self.config["SOCIAL_AUTH_PIPELINE"] = auth_pipeline self.config["DISCONNECT_PIPELINE"] = DISCONNECT_PIPELINE self.config[setting_name("AUTHENTICATION_BACKENDS")] = (BACKENDS[provider],) Loading lib/galaxy/config/sample/galaxy.yml.sample +16 −7 Original line number Diff line number Diff line Loading @@ -2282,13 +2282,22 @@ galaxy: # <config_dir>. #oidc_backends_config_file: oidc_backends_config.xml # Sets a custom series of steps in the authentication pipeline # for OIDC authentication. The default is # galaxy.authnz.psa_authnz.AUTH_PIPELINE #oidc_auth_pipeline: # - social_core.pipeline.social_auth.social_details # - social_core.pipeline.social_auth.social_uid # Sets the full sequence of steps that Python Social Auth goes through # when authenticating an OIDC login. Use when you want to completely # customize the pipeline (e.g. for testing). # By default, Galaxy uses galaxy.authnz.psa_authnz.AUTH_PIPELINE - see # there for example steps. # Each element should be an import path to a function, e.g. # galaxy.authnz.psa_authnz.contains_required_data #oidc_auth_pipeline: null # Sets additional authentication pipeline steps, added after the # default steps (from galaxy.authnz.psa_authnz.AUTH_PIPELINE). # Use when you want to keep the default pipeline, but add additional # custom processing. # Each element should be an import path to a function, e.g. # galaxy.authnz.psa_authnz.contains_required_data #oidc_auth_pipeline_extra: null # Sets the prefix for OIDC scopes specific to this Galaxy instance. If # an API call is made against this Galaxy instance using an OIDC Loading lib/galaxy/config/schemas/config_schema.yml +19 −3 Original line number Diff line number Diff line Loading @@ -3085,10 +3085,26 @@ mapping: type: seq required: false desc: | Sets the sequence of steps that Python Social Auth goes through when authenticating an OIDC login. By default, Galaxy uses galaxy.authnz.psa_authnz.AUTH_PIPELINE - see Sets the full sequence of steps that Python Social Auth goes through when authenticating an OIDC login. Use when you want to completely customize the pipeline (e.g. for testing). By default, Galaxy uses galaxy.authnz.psa_authnz.AUTH_PIPELINE - see there for example steps. Each element should be an import path to a function, e.g. galaxy.authnz.psa_authnz.contains_required_data oidc_auth_pipeline_extra: type: seq required: false desc: | Sets additional authentication pipeline steps, added after the default steps (from galaxy.authnz.psa_authnz.AUTH_PIPELINE). Use when you want to keep the default pipeline, but add additional custom processing. Each element should be an import path to a function, e.g. galaxy.authnz.psa_authnz.contains_required_data Loading test/unit/authnz/test_psa_authnz.py +54 −3 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ from datetime import ( datetime, timedelta, ) from types import SimpleNamespace from typing import Optional from unittest.mock import MagicMock Loading @@ -31,6 +32,7 @@ from galaxy import model from galaxy.authnz.managers import AuthnzManager from galaxy.authnz.psa_authnz import ( _decode_access_token_helper, AUTH_PIPELINE, decode_access_token, PSAAuthnz, ) Loading Loading @@ -286,10 +288,11 @@ def test_decode_access_token_opaque_token(): def test_oidc_config_custom_auth_pipeline(mock_oidc_config_file, mock_oidc_backend_config_file): custom_auth_pipeline = ("custom", "auth", "steps") mock_app = MagicMock() mock_app.config.get.side_effect = lambda k, default=None: {"oidc_auth_pipeline": custom_auth_pipeline}.get( k, default mock_app.config = SimpleNamespace( oidc_auth_pipeline=custom_auth_pipeline, oidc_auth_pipeline_extra=None, oidc=defaultdict(dict), ) mock_app.config.oidc = defaultdict(dict) manager = AuthnzManager( app=mock_app, oidc_config_file=mock_oidc_config_file, oidc_backends_config_file=mock_oidc_backend_config_file ) Loading @@ -300,3 +303,51 @@ def test_oidc_config_custom_auth_pipeline(mock_oidc_config_file, mock_oidc_backe app_config=mock_app.config, ) assert psa_authnz.config["SOCIAL_AUTH_PIPELINE"] == custom_auth_pipeline def test_oidc_config_auth_pipeline_extra(mock_oidc_config_file, mock_oidc_backend_config_file): """ Test that the oidc_auth_pipeline_extra config option is used to extend the auth pipeline. """ custom_auth_pipeline_extra = ["extra", "auth", "steps"] mock_app = MagicMock() mock_app.config = SimpleNamespace( oidc_auth_pipeline=None, oidc_auth_pipeline_extra=custom_auth_pipeline_extra, oidc=defaultdict(dict), ) manager = AuthnzManager( app=mock_app, oidc_config_file=mock_oidc_config_file, oidc_backends_config_file=mock_oidc_backend_config_file ) psa_authnz = PSAAuthnz( provider="oidc", oidc_config=manager.oidc_config, oidc_backend_config=manager.oidc_backends_config, app_config=mock_app.config, ) assert psa_authnz.config["SOCIAL_AUTH_PIPELINE"] == AUTH_PIPELINE + tuple(custom_auth_pipeline_extra) def test_oidc_config_custom_auth_pipeline_and_extra(mock_oidc_config_file, mock_oidc_backend_config_file): """ Test that the oidc_auth_pipeline_extra config option is used to extend the auth pipeline, when a custom auth pipeline is also specified in the config file. """ custom_auth_pipeline = ("custom", "auth", "steps") custom_auth_pipeline_extra = ["extra", "auth", "steps"] mock_app = MagicMock() mock_app.config = SimpleNamespace( oidc_auth_pipeline=custom_auth_pipeline, oidc_auth_pipeline_extra=custom_auth_pipeline_extra, oidc=defaultdict(dict), ) manager = AuthnzManager( app=mock_app, oidc_config_file=mock_oidc_config_file, oidc_backends_config_file=mock_oidc_backend_config_file ) psa_authnz = PSAAuthnz( provider="oidc", oidc_config=manager.oidc_config, oidc_backend_config=manager.oidc_backends_config, app_config=mock_app.config, ) assert psa_authnz.config["SOCIAL_AUTH_PIPELINE"] == custom_auth_pipeline + tuple(custom_auth_pipeline_extra) Loading
doc/source/admin/galaxy_options.rst +31 −0 Original line number Diff line number Diff line Loading @@ -4181,6 +4181,37 @@ :Type: str ~~~~~~~~~~~~~~~~~~~~~~ ``oidc_auth_pipeline`` ~~~~~~~~~~~~~~~~~~~~~~ :Description: Sets the full sequence of steps that Python Social Auth goes through when authenticating an OIDC login. Use when you want to completely customize the pipeline (e.g. for testing). By default, Galaxy uses galaxy.authnz.psa_authnz.AUTH_PIPELINE - see there for example steps. Each element should be an import path to a function, e.g. galaxy.authnz.psa_authnz.contains_required_data :Default: ``None`` :Type: seq ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``oidc_auth_pipeline_extra`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :Description: Sets additional authentication pipeline steps, added after the default steps (from galaxy.authnz.psa_authnz.AUTH_PIPELINE). Use when you want to keep the default pipeline, but add additional custom processing. Each element should be an import path to a function, e.g. galaxy.authnz.psa_authnz.contains_required_data :Default: ``None`` :Type: seq ~~~~~~~~~~~~~~~~~~~~~ ``oidc_scope_prefix`` ~~~~~~~~~~~~~~~~~~~~~ Loading
lib/galaxy/authnz/psa_authnz.py +4 −1 Original line number Diff line number Diff line Loading @@ -118,7 +118,10 @@ class PSAAuthnz(IdentityProvider): self.config[setting_name("USER_MODEL")] = "models.User" # Use a custom auth pipeline if configured. auth_pipeline = app_config.get("oidc_auth_pipeline", AUTH_PIPELINE) auth_pipeline = app_config.oidc_auth_pipeline or AUTH_PIPELINE # Add extra steps to the auth pipeline if configured. if app_config.oidc_auth_pipeline_extra: auth_pipeline = auth_pipeline + tuple(app_config.oidc_auth_pipeline_extra) self.config["SOCIAL_AUTH_PIPELINE"] = auth_pipeline self.config["DISCONNECT_PIPELINE"] = DISCONNECT_PIPELINE self.config[setting_name("AUTHENTICATION_BACKENDS")] = (BACKENDS[provider],) Loading
lib/galaxy/config/sample/galaxy.yml.sample +16 −7 Original line number Diff line number Diff line Loading @@ -2282,13 +2282,22 @@ galaxy: # <config_dir>. #oidc_backends_config_file: oidc_backends_config.xml # Sets a custom series of steps in the authentication pipeline # for OIDC authentication. The default is # galaxy.authnz.psa_authnz.AUTH_PIPELINE #oidc_auth_pipeline: # - social_core.pipeline.social_auth.social_details # - social_core.pipeline.social_auth.social_uid # Sets the full sequence of steps that Python Social Auth goes through # when authenticating an OIDC login. Use when you want to completely # customize the pipeline (e.g. for testing). # By default, Galaxy uses galaxy.authnz.psa_authnz.AUTH_PIPELINE - see # there for example steps. # Each element should be an import path to a function, e.g. # galaxy.authnz.psa_authnz.contains_required_data #oidc_auth_pipeline: null # Sets additional authentication pipeline steps, added after the # default steps (from galaxy.authnz.psa_authnz.AUTH_PIPELINE). # Use when you want to keep the default pipeline, but add additional # custom processing. # Each element should be an import path to a function, e.g. # galaxy.authnz.psa_authnz.contains_required_data #oidc_auth_pipeline_extra: null # Sets the prefix for OIDC scopes specific to this Galaxy instance. If # an API call is made against this Galaxy instance using an OIDC Loading
lib/galaxy/config/schemas/config_schema.yml +19 −3 Original line number Diff line number Diff line Loading @@ -3085,10 +3085,26 @@ mapping: type: seq required: false desc: | Sets the sequence of steps that Python Social Auth goes through when authenticating an OIDC login. By default, Galaxy uses galaxy.authnz.psa_authnz.AUTH_PIPELINE - see Sets the full sequence of steps that Python Social Auth goes through when authenticating an OIDC login. Use when you want to completely customize the pipeline (e.g. for testing). By default, Galaxy uses galaxy.authnz.psa_authnz.AUTH_PIPELINE - see there for example steps. Each element should be an import path to a function, e.g. galaxy.authnz.psa_authnz.contains_required_data oidc_auth_pipeline_extra: type: seq required: false desc: | Sets additional authentication pipeline steps, added after the default steps (from galaxy.authnz.psa_authnz.AUTH_PIPELINE). Use when you want to keep the default pipeline, but add additional custom processing. Each element should be an import path to a function, e.g. galaxy.authnz.psa_authnz.contains_required_data Loading
test/unit/authnz/test_psa_authnz.py +54 −3 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ from datetime import ( datetime, timedelta, ) from types import SimpleNamespace from typing import Optional from unittest.mock import MagicMock Loading @@ -31,6 +32,7 @@ from galaxy import model from galaxy.authnz.managers import AuthnzManager from galaxy.authnz.psa_authnz import ( _decode_access_token_helper, AUTH_PIPELINE, decode_access_token, PSAAuthnz, ) Loading Loading @@ -286,10 +288,11 @@ def test_decode_access_token_opaque_token(): def test_oidc_config_custom_auth_pipeline(mock_oidc_config_file, mock_oidc_backend_config_file): custom_auth_pipeline = ("custom", "auth", "steps") mock_app = MagicMock() mock_app.config.get.side_effect = lambda k, default=None: {"oidc_auth_pipeline": custom_auth_pipeline}.get( k, default mock_app.config = SimpleNamespace( oidc_auth_pipeline=custom_auth_pipeline, oidc_auth_pipeline_extra=None, oidc=defaultdict(dict), ) mock_app.config.oidc = defaultdict(dict) manager = AuthnzManager( app=mock_app, oidc_config_file=mock_oidc_config_file, oidc_backends_config_file=mock_oidc_backend_config_file ) Loading @@ -300,3 +303,51 @@ def test_oidc_config_custom_auth_pipeline(mock_oidc_config_file, mock_oidc_backe app_config=mock_app.config, ) assert psa_authnz.config["SOCIAL_AUTH_PIPELINE"] == custom_auth_pipeline def test_oidc_config_auth_pipeline_extra(mock_oidc_config_file, mock_oidc_backend_config_file): """ Test that the oidc_auth_pipeline_extra config option is used to extend the auth pipeline. """ custom_auth_pipeline_extra = ["extra", "auth", "steps"] mock_app = MagicMock() mock_app.config = SimpleNamespace( oidc_auth_pipeline=None, oidc_auth_pipeline_extra=custom_auth_pipeline_extra, oidc=defaultdict(dict), ) manager = AuthnzManager( app=mock_app, oidc_config_file=mock_oidc_config_file, oidc_backends_config_file=mock_oidc_backend_config_file ) psa_authnz = PSAAuthnz( provider="oidc", oidc_config=manager.oidc_config, oidc_backend_config=manager.oidc_backends_config, app_config=mock_app.config, ) assert psa_authnz.config["SOCIAL_AUTH_PIPELINE"] == AUTH_PIPELINE + tuple(custom_auth_pipeline_extra) def test_oidc_config_custom_auth_pipeline_and_extra(mock_oidc_config_file, mock_oidc_backend_config_file): """ Test that the oidc_auth_pipeline_extra config option is used to extend the auth pipeline, when a custom auth pipeline is also specified in the config file. """ custom_auth_pipeline = ("custom", "auth", "steps") custom_auth_pipeline_extra = ["extra", "auth", "steps"] mock_app = MagicMock() mock_app.config = SimpleNamespace( oidc_auth_pipeline=custom_auth_pipeline, oidc_auth_pipeline_extra=custom_auth_pipeline_extra, oidc=defaultdict(dict), ) manager = AuthnzManager( app=mock_app, oidc_config_file=mock_oidc_config_file, oidc_backends_config_file=mock_oidc_backend_config_file ) psa_authnz = PSAAuthnz( provider="oidc", oidc_config=manager.oidc_config, oidc_backend_config=manager.oidc_backends_config, app_config=mock_app.config, ) assert psa_authnz.config["SOCIAL_AUTH_PIPELINE"] == custom_auth_pipeline + tuple(custom_auth_pipeline_extra)