Skip to content

Commit

Permalink
fix: Prevent Users From Being Created With Missing Group/Household (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-genson authored Nov 5, 2024
1 parent f4bde93 commit 0fed5f5
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
8 changes: 8 additions & 0 deletions mealie/db/models/users/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ def __init__(
else:
self.household = None

if self.group is None:
raise ValueError(f"Group {group} does not exist; cannot create user")
if self.household is None:
raise ValueError(
f'Household "{household}" does not exist on group '
f'"{self.group.name}" ({self.group.id}); cannot create user'
)

self.rated_recipes = []

self.password = password
Expand Down
37 changes: 37 additions & 0 deletions tests/unit_tests/core/security/providers/test_openid_provider.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import pytest
from pytest import MonkeyPatch, Session

from mealie.core.config import get_app_settings
from mealie.core.security.providers.openid_provider import OpenIDProvider
from mealie.repos.all_repositories import get_repositories
from tests.utils.factories import random_email, random_string
from tests.utils.fixture_schemas import TestUser


Expand Down Expand Up @@ -125,3 +127,38 @@ def test_has_admin_group_new_user(monkeypatch: MonkeyPatch, session: Session):
user = db.users.get_one("dude2", "username")
assert user is not None
assert user.admin


@pytest.mark.parametrize("valid_group", [True, False])
@pytest.mark.parametrize("valid_household", [True, False])
def test_ldap_user_creation_invalid_group_or_household(
monkeypatch: MonkeyPatch, session: Session, valid_group: bool, valid_household: bool
):
monkeypatch.setenv("OIDC_USER_GROUP", "mealie_user")
monkeypatch.setenv("OIDC_ADMIN_GROUP", "mealie_admin")
if not valid_group:
monkeypatch.setenv("DEFAULT_GROUP", random_string())
if not valid_household:
monkeypatch.setenv("DEFAULT_HOUSEHOLD", random_string())
get_app_settings.cache_clear()

data = {
"preferred_username": random_string(),
"email": random_email(),
"name": random_string(),
"groups": ["mealie_user"],
}
auth_provider = OpenIDProvider(session, data)

if valid_group and valid_household:
assert auth_provider.authenticate() is not None
else:
assert auth_provider.authenticate() is None

db = get_repositories(session, group_id=None, household_id=None)
user = db.users.get_one(data["preferred_username"], "username")

if valid_group and valid_household:
assert user is not None
else:
assert user is None
48 changes: 47 additions & 1 deletion tests/unit_tests/test_security.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pathlib import Path

import ldap
import pytest
from pytest import MonkeyPatch

from mealie.core import security
Expand All @@ -13,6 +14,7 @@
from mealie.core.security.providers.ldap_provider import LDAPProvider
from mealie.db.db_setup import session_context
from mealie.db.models.users.users import AuthMethod
from mealie.repos.repository_factory import AllRepositories
from mealie.schema.user.auth import CredentialsRequestForm
from mealie.schema.user.user import PrivateUser
from tests.utils import random_string
Expand Down Expand Up @@ -92,7 +94,7 @@ def start_tls_s(self):
pass


def setup_env(monkeypatch: MonkeyPatch):
def setup_env(monkeypatch: MonkeyPatch, **kwargs):
user = random_string(10)
mail = random_string(10)
name = random_string(10)
Expand Down Expand Up @@ -140,11 +142,55 @@ def ldap_initialize_mock(url):
provider = get_provider(session, user, password)
result = provider.get_user()

app_settings = get_app_settings()

assert result
assert result.username == user
assert result.email == mail
assert result.full_name == name
assert result.admin is False
assert result.group == app_settings.DEFAULT_GROUP
assert result.household == app_settings.DEFAULT_HOUSEHOLD
assert result.auth_method == AuthMethod.LDAP


@pytest.mark.parametrize("valid_group", [True, False])
@pytest.mark.parametrize("valid_household", [True, False])
def test_ldap_user_creation_invalid_group_or_household(
unfiltered_database: AllRepositories, monkeypatch: MonkeyPatch, valid_group: bool, valid_household: bool
):
user, mail, name, password, query_bind, query_password = setup_env(monkeypatch)
if not valid_group:
monkeypatch.setenv("DEFAULT_GROUP", random_string())
if not valid_household:
monkeypatch.setenv("DEFAULT_HOUSEHOLD", random_string())

def ldap_initialize_mock(url):
assert url == ""
return LdapConnMock(user, password, False, query_bind, query_password, mail, name)

monkeypatch.setattr(ldap, "initialize", ldap_initialize_mock)

get_app_settings.cache_clear()

with session_context() as session:
provider = get_provider(session, user, password)
try:
result = provider.get_user()
except ValueError:
result = None

if valid_group and valid_household:
assert result
else:
assert not result

# check if the user exists in the db
user = unfiltered_database.users.get_by_username(user)
if valid_group and valid_household:
assert user
else:
assert not user


def test_ldap_user_creation_fail(monkeypatch: MonkeyPatch):
Expand Down

0 comments on commit 0fed5f5

Please sign in to comment.