mirror of
https://github.com/rommapp/romm.git
synced 2026-06-28 06:46:00 +00:00
feat(auth): add OIDC_ALLOW_REGISTRATION toggle
Gate automatic account creation on OIDC login behind a new OIDC_ALLOW_REGISTRATION environment variable. Defaults to true, preserving the current auto-provisioning behavior; set it to false to run OIDC in an "existing users only" mode, where a login from an email without an existing RomM account is rejected with a 403 instead of silently creating one. Existing users are unaffected either way. Adds the config constant, env.template and docs entries, and tests covering the enabled/disabled and existing-user paths. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,16 @@ def mock_oidc_enabled(mocker):
|
||||
mocker.patch("handler.auth.base_handler.OIDC_ENABLED", True)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_oidc_allow_registration_enabled(mocker):
|
||||
mocker.patch("handler.auth.base_handler.OIDC_ALLOW_REGISTRATION", True)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_oidc_allow_registration_disabled(mocker):
|
||||
mocker.patch("handler.auth.base_handler.OIDC_ALLOW_REGISTRATION", False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_token():
|
||||
return {
|
||||
@@ -171,6 +181,7 @@ async def test_oidc_valid_token_decoding(
|
||||
async def test_oidc_valid_add_user(
|
||||
mocker,
|
||||
mock_oidc_enabled,
|
||||
mock_oidc_allow_registration_enabled,
|
||||
mock_token,
|
||||
mock_openid_configuration,
|
||||
config_override,
|
||||
@@ -218,6 +229,85 @@ async def test_oidc_valid_add_user(
|
||||
assert mock_add_user.call_args.args[0].role == romm_role
|
||||
|
||||
|
||||
async def test_oidc_registration_disabled_rejects_unknown_user(
|
||||
mocker,
|
||||
mock_oidc_enabled,
|
||||
mock_oidc_allow_registration_disabled,
|
||||
mock_token,
|
||||
mock_openid_configuration,
|
||||
):
|
||||
"""Test that a login from an unknown email is rejected when registration is disabled."""
|
||||
mocker.patch(
|
||||
"handler.database.db_user_handler.get_user_by_email", return_value=None
|
||||
)
|
||||
mock_add_user = mocker.patch("handler.database.db_user_handler.add_user")
|
||||
mocker.patch.object(
|
||||
StarletteOAuth2App,
|
||||
"load_server_metadata",
|
||||
return_value=mock_openid_configuration,
|
||||
)
|
||||
|
||||
oidc_handler = OpenIDHandler()
|
||||
with pytest.raises(HTTPException, match="registration is disabled"):
|
||||
await oidc_handler.get_current_active_user_from_openid_token(mock_token)
|
||||
|
||||
mock_add_user.assert_not_called()
|
||||
|
||||
|
||||
async def test_oidc_registration_enabled_creates_unknown_user(
|
||||
mocker,
|
||||
mock_oidc_enabled,
|
||||
mock_oidc_allow_registration_enabled,
|
||||
mock_token,
|
||||
mock_openid_configuration,
|
||||
):
|
||||
"""Test that a login from an unknown email creates a new user when registration is enabled."""
|
||||
mocker.patch(
|
||||
"handler.database.db_user_handler.get_user_by_email", return_value=None
|
||||
)
|
||||
mock_user = MagicMock(enabled=True, role=Role.VIEWER)
|
||||
mock_add_user = mocker.patch(
|
||||
"handler.database.db_user_handler.add_user", return_value=mock_user
|
||||
)
|
||||
mocker.patch.object(
|
||||
StarletteOAuth2App,
|
||||
"load_server_metadata",
|
||||
return_value=mock_openid_configuration,
|
||||
)
|
||||
|
||||
oidc_handler = OpenIDHandler()
|
||||
user, _ = await oidc_handler.get_current_active_user_from_openid_token(mock_token)
|
||||
|
||||
mock_add_user.assert_called_once()
|
||||
assert user == mock_user
|
||||
|
||||
|
||||
async def test_oidc_registration_disabled_allows_existing_user(
|
||||
mocker,
|
||||
mock_oidc_enabled,
|
||||
mock_oidc_allow_registration_disabled,
|
||||
mock_token,
|
||||
mock_openid_configuration,
|
||||
):
|
||||
"""Test that an existing user can still log in when registration is disabled."""
|
||||
mock_user = MagicMock(enabled=True, role=Role.VIEWER)
|
||||
mocker.patch(
|
||||
"handler.database.db_user_handler.get_user_by_email", return_value=mock_user
|
||||
)
|
||||
mock_add_user = mocker.patch("handler.database.db_user_handler.add_user")
|
||||
mocker.patch.object(
|
||||
StarletteOAuth2App,
|
||||
"load_server_metadata",
|
||||
return_value=mock_openid_configuration,
|
||||
)
|
||||
|
||||
oidc_handler = OpenIDHandler()
|
||||
user, _ = await oidc_handler.get_current_active_user_from_openid_token(mock_token)
|
||||
|
||||
assert user == mock_user
|
||||
mock_add_user.assert_not_called()
|
||||
|
||||
|
||||
async def test_oidc_valid_edit_user_role(
|
||||
mocker,
|
||||
mock_oidc_enabled,
|
||||
|
||||
Reference in New Issue
Block a user