mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-23 06:45:22 -07:00
Merge branch 'mealie-next' into mealie-next
This commit is contained in:
commit
782cdcfc77
22 changed files with 471 additions and 147 deletions
|
@ -12,7 +12,7 @@ repos:
|
|||
exclude: ^tests/data/
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.7.1
|
||||
rev: v0.7.2
|
||||
hooks:
|
||||
- id: ruff
|
||||
- id: ruff-format
|
||||
|
|
|
@ -61,6 +61,15 @@ Changing the webworker settings may cause unforeseen memory leak issues with Mea
|
|||
| --------------- | :-----: | ----------------------------------------------------------------------------- |
|
||||
| UVICORN_WORKERS | 1 | Sets the number of workers for the web server. [More info here][unicorn_workers] |
|
||||
|
||||
### TLS
|
||||
|
||||
Use this only when mealie is run without a webserver or reverse proxy.
|
||||
|
||||
| Variables | Default | Description |
|
||||
| -------------------- | :-----: | ------------------------ |
|
||||
| TLS_CERTIFICATE_PATH | None | File path to Certificate |
|
||||
| TLS_PRIVATE_KEY_PATH | None | File path to private key |
|
||||
|
||||
### LDAP
|
||||
|
||||
| Variables | Default | Description |
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
width="100%"
|
||||
max-width="1100px"
|
||||
:icon="$globals.icons.pages"
|
||||
:title="$t('general.edit')"
|
||||
:title="$tc('general.edit')"
|
||||
:submit-icon="$globals.icons.save"
|
||||
:submit-text="$tc('general.save')"
|
||||
:submit-disabled="!editTarget.queryFilterString"
|
||||
|
@ -25,7 +25,7 @@
|
|||
<v-toolbar-title class="headline"> {{ book.name }} </v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<BaseButton
|
||||
v-if="isOwnGroup"
|
||||
v-if="canEdit"
|
||||
class="mx-1"
|
||||
:edit="true"
|
||||
@click="handleEditCookbook"
|
||||
|
@ -79,6 +79,15 @@
|
|||
const tab = ref(null);
|
||||
const book = getOne(slug);
|
||||
|
||||
const isOwnHousehold = computed(() => {
|
||||
if (!($auth.user && book.value?.householdId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $auth.user.householdId === book.value.householdId;
|
||||
})
|
||||
const canEdit = computed(() => isOwnGroup.value && isOwnHousehold.value);
|
||||
|
||||
const dialogStates = reactive({
|
||||
edit: false,
|
||||
});
|
||||
|
@ -118,7 +127,7 @@
|
|||
recipes,
|
||||
removeRecipe,
|
||||
replaceRecipes,
|
||||
isOwnGroup,
|
||||
canEdit,
|
||||
dialogStates,
|
||||
editTarget,
|
||||
handleEditCookbook,
|
||||
|
|
|
@ -82,12 +82,17 @@ import { computed, defineComponent, onMounted, ref, useContext, useRoute } from
|
|||
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
||||
import AppHeader from "@/components/Layout/LayoutParts/AppHeader.vue";
|
||||
import AppSidebar from "@/components/Layout/LayoutParts/AppSidebar.vue";
|
||||
import { SidebarLinks } from "~/types/application-types";
|
||||
import { SideBarLink } from "~/types/application-types";
|
||||
import LanguageDialog from "~/components/global/LanguageDialog.vue";
|
||||
import TheSnackbar from "@/components/Layout/LayoutParts/TheSnackbar.vue";
|
||||
import { useAppInfo } from "~/composables/api";
|
||||
import { useCookbooks, usePublicCookbooks } from "~/composables/use-group-cookbooks";
|
||||
import { useCookbookPreferences } from "~/composables/use-users/preferences";
|
||||
import { useHouseholdStore, usePublicHouseholdStore } from "~/composables/store/use-household-store";
|
||||
import { useToggleDarkMode } from "~/composables/use-utils";
|
||||
import { ReadCookBook } from "~/lib/api/types/cookbook";
|
||||
import { HouseholdSummary } from "~/lib/api/types/household";
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
components: { AppHeader, AppSidebar, LanguageDialog, TheSnackbar },
|
||||
|
@ -99,6 +104,15 @@ export default defineComponent({
|
|||
const route = useRoute();
|
||||
const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || "");
|
||||
const { cookbooks } = isOwnGroup.value ? useCookbooks() : usePublicCookbooks(groupSlug.value || "");
|
||||
const cookbookPreferences = useCookbookPreferences();
|
||||
const { store: households } = isOwnGroup.value ? useHouseholdStore() : usePublicHouseholdStore(groupSlug.value || "");
|
||||
|
||||
const householdsById = computed(() => {
|
||||
return households.value.reduce((acc, household) => {
|
||||
acc[household.id] = household;
|
||||
return acc;
|
||||
}, {} as { [key: string]: HouseholdSummary });
|
||||
});
|
||||
|
||||
const appInfo = useAppInfo();
|
||||
const showImageImport = computed(() => appInfo.value?.enableOpenaiImageServices);
|
||||
|
@ -113,29 +127,57 @@ export default defineComponent({
|
|||
sidebar.value = !$vuetify.breakpoint.md;
|
||||
});
|
||||
|
||||
const cookbookLinks = computed(() => {
|
||||
if (!cookbooks.value) return [];
|
||||
return cookbooks.value.map((cookbook) => {
|
||||
return {
|
||||
key: cookbook.slug,
|
||||
icon: $globals.icons.pages,
|
||||
title: cookbook.name,
|
||||
to: `/g/${groupSlug.value}/cookbooks/${cookbook.slug as string}`,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
interface Link {
|
||||
insertDivider: boolean;
|
||||
icon: string;
|
||||
title: string;
|
||||
subtitle: string | null;
|
||||
to: string;
|
||||
restricted: boolean;
|
||||
hide: boolean;
|
||||
function cookbookAsLink(cookbook: ReadCookBook): SideBarLink {
|
||||
return {
|
||||
key: cookbook.slug || "",
|
||||
icon: $globals.icons.pages,
|
||||
title: cookbook.name,
|
||||
to: `/g/${groupSlug.value}/cookbooks/${cookbook.slug || ""}`,
|
||||
restricted: false,
|
||||
};
|
||||
}
|
||||
|
||||
const createLinks = computed<Link[]>(() => [
|
||||
const currentUserHouseholdId = computed(() => $auth.user?.householdId);
|
||||
const cookbookLinks = computed<SideBarLink[]>(() => {
|
||||
if (!cookbooks.value) {
|
||||
return [];
|
||||
}
|
||||
cookbooks.value.sort((a, b) => (a.position || 0) - (b.position || 0));
|
||||
|
||||
const ownLinks: SideBarLink[] = [];
|
||||
const links: SideBarLink[] = [];
|
||||
const cookbooksByHousehold = cookbooks.value.reduce((acc, cookbook) => {
|
||||
const householdName = householdsById.value[cookbook.householdId]?.name || "";
|
||||
if (!acc[householdName]) {
|
||||
acc[householdName] = [];
|
||||
}
|
||||
acc[householdName].push(cookbook);
|
||||
return acc;
|
||||
}, {} as Record<string, ReadCookBook[]>);
|
||||
|
||||
Object.entries(cookbooksByHousehold).forEach(([householdName, cookbooks]) => {
|
||||
if (cookbooks[0].householdId === currentUserHouseholdId.value) {
|
||||
ownLinks.push(...cookbooks.map(cookbookAsLink));
|
||||
} else {
|
||||
links.push({
|
||||
key: householdName,
|
||||
icon: $globals.icons.book,
|
||||
title: householdName,
|
||||
children: cookbooks.map(cookbookAsLink),
|
||||
restricted: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
links.sort((a, b) => a.title.localeCompare(b.title));
|
||||
if ($auth.user && cookbookPreferences.value.hideOtherHouseholds) {
|
||||
return ownLinks;
|
||||
} else {
|
||||
return [...ownLinks, ...links];
|
||||
}
|
||||
});
|
||||
|
||||
const createLinks = computed<SideBarLink[]>(() => [
|
||||
{
|
||||
insertDivider: false,
|
||||
icon: $globals.icons.link,
|
||||
|
@ -165,7 +207,7 @@ export default defineComponent({
|
|||
},
|
||||
]);
|
||||
|
||||
const bottomLinks = computed<SidebarLinks>(() => [
|
||||
const bottomLinks = computed<SideBarLink[]>(() => [
|
||||
{
|
||||
icon: $globals.icons.cog,
|
||||
title: i18n.tc("general.settings"),
|
||||
|
@ -174,7 +216,7 @@ export default defineComponent({
|
|||
},
|
||||
]);
|
||||
|
||||
const topLinks = computed<SidebarLinks>(() => [
|
||||
const topLinks = computed<SideBarLink[]>(() => [
|
||||
{
|
||||
icon: $globals.icons.silverwareForkKnife,
|
||||
to: `/g/${groupSlug.value}`,
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, reactive, toRefs, useContext } from "@nuxtjs/composition-api";
|
||||
import { computed, defineComponent, reactive, toRefs, useContext, watch } from "@nuxtjs/composition-api";
|
||||
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
||||
import { SidebarLinks } from "~/types/application-types";
|
||||
import UserAvatar from "~/components/Domain/User/UserAvatar.vue";
|
||||
|
@ -192,13 +192,29 @@ export default defineComponent({
|
|||
const userProfileLink = computed(() => $auth.user ? "/user/profile" : undefined);
|
||||
|
||||
const state = reactive({
|
||||
dropDowns: {},
|
||||
dropDowns: {} as Record<string, boolean>,
|
||||
topSelected: null as string[] | null,
|
||||
secondarySelected: null as string[] | null,
|
||||
bottomSelected: null as string[] | null,
|
||||
hasOpenedBefore: false as boolean,
|
||||
});
|
||||
|
||||
const allLinks = computed(() => [...props.topLink, ...(props.secondaryLinks || []), ...(props.bottomLinks || [])]);
|
||||
function initDropdowns() {
|
||||
allLinks.value.forEach((link) => {
|
||||
state.dropDowns[link.title] = link.childrenStartExpanded || false;
|
||||
})
|
||||
}
|
||||
watch(
|
||||
() => allLinks,
|
||||
() => {
|
||||
initDropdowns();
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
userFavoritesLink,
|
||||
|
|
|
@ -99,10 +99,10 @@ export const useCookbooks = function () {
|
|||
|
||||
loading.value = false;
|
||||
},
|
||||
async createOne() {
|
||||
async createOne(name: string | null = null) {
|
||||
loading.value = true;
|
||||
const { data } = await api.cookbooks.createOne({
|
||||
name: i18n.t("cookbook.household-cookbook-name", [household.value?.name || "", String((cookbookStore?.value?.length ?? 0) + 1)]) as string,
|
||||
name: name || i18n.t("cookbook.household-cookbook-name", [household.value?.name || "", String((cookbookStore?.value?.length ?? 0) + 1)]) as string,
|
||||
position: (cookbookStore?.value?.length ?? 0) + 1,
|
||||
queryFilterString: "",
|
||||
});
|
||||
|
@ -129,18 +129,18 @@ export const useCookbooks = function () {
|
|||
return data;
|
||||
},
|
||||
|
||||
async updateOrder() {
|
||||
if (!cookbookStore?.value) {
|
||||
async updateOrder(cookbooks: ReadCookBook[]) {
|
||||
if (!cookbooks?.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
|
||||
cookbookStore.value.forEach((element, index) => {
|
||||
cookbooks.forEach((element, index) => {
|
||||
element.position = index + 1;
|
||||
});
|
||||
|
||||
const { data } = await api.cookbooks.updateAll(cookbookStore.value);
|
||||
const { data } = await api.cookbooks.updateAll(cookbooks);
|
||||
|
||||
if (data && cookbookStore?.value) {
|
||||
this.refreshAll();
|
||||
|
|
|
@ -45,6 +45,10 @@ export interface UserParsingPreferences {
|
|||
parser: RegisteredParser;
|
||||
}
|
||||
|
||||
export interface UserCookbooksPreferences {
|
||||
hideOtherHouseholds: boolean;
|
||||
}
|
||||
|
||||
export function useUserMealPlanPreferences(): Ref<UserMealPlanPreferences> {
|
||||
const fromStorage = useLocalStorage(
|
||||
"meal-planner-preferences",
|
||||
|
@ -153,3 +157,17 @@ export function useParsingPreferences(): Ref<UserParsingPreferences> {
|
|||
|
||||
return fromStorage;
|
||||
}
|
||||
|
||||
export function useCookbookPreferences(): Ref<UserCookbooksPreferences> {
|
||||
const fromStorage = useLocalStorage(
|
||||
"cookbook-preferences",
|
||||
{
|
||||
hideOtherHouseholds: false,
|
||||
},
|
||||
{ mergeDefaults: true }
|
||||
// we cast to a Ref because by default it will return an optional type ref
|
||||
// but since we pass defaults we know all properties are set.
|
||||
) as unknown as Ref<UserCookbooksPreferences>;
|
||||
|
||||
return fromStorage;
|
||||
}
|
||||
|
|
|
@ -1327,6 +1327,8 @@
|
|||
"cookbook": {
|
||||
"cookbooks": "Cookbooks",
|
||||
"description": "Cookbooks are another way to organize recipes by creating cross sections of recipes, organizers, and other filters. Creating a cookbook will add an entry to the side-bar and all the recipes with the filters chosen will be displayed in the cookbook.",
|
||||
"hide-cookbooks-from-other-households": "Hide Cookbooks from Other Households",
|
||||
"hide-cookbooks-from-other-households-description": "When enabled, only cookbooks from your household will appear on the sidebar",
|
||||
"public-cookbook": "Public Cookbook",
|
||||
"public-cookbook-description": "Public Cookbooks can be shared with non-mealie users and will be displayed on your groups page.",
|
||||
"filter-options": "Filter Options",
|
||||
|
|
|
@ -48,20 +48,33 @@
|
|||
{{ $t('cookbook.description') }}
|
||||
</BasePageTitle>
|
||||
|
||||
<div class="my-6">
|
||||
<v-checkbox
|
||||
v-model="cookbookPreferences.hideOtherHouseholds"
|
||||
:label="$tc('cookbook.hide-cookbooks-from-other-households')"
|
||||
hide-details
|
||||
/>
|
||||
<div class="ml-8">
|
||||
<p class="text-subtitle-2 my-0 py-0">
|
||||
{{ $tc("cookbook.hide-cookbooks-from-other-households-description") }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create New -->
|
||||
<BaseButton create @click="createCookbook" />
|
||||
|
||||
<!-- Cookbook List -->
|
||||
<v-expansion-panels class="mt-2">
|
||||
<draggable
|
||||
v-model="cookbooks"
|
||||
v-model="myCookbooks"
|
||||
handle=".handle"
|
||||
delay="250"
|
||||
:delay-on-touch-only="true"
|
||||
style="width: 100%"
|
||||
@change="actions.updateOrder()"
|
||||
@change="actions.updateOrder(myCookbooks)"
|
||||
>
|
||||
<v-expansion-panel v-for="cookbook in cookbooks" :key="cookbook.id" class="my-2 left-border rounded">
|
||||
<v-expansion-panel v-for="cookbook in myCookbooks" :key="cookbook.id" class="my-2 left-border rounded">
|
||||
<v-expansion-panel-header disable-icon-rotate class="headline">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon large left>
|
||||
|
@ -110,11 +123,13 @@
|
|||
|
||||
<script lang="ts">
|
||||
|
||||
import { defineComponent, onBeforeUnmount, onMounted, reactive, ref } from "@nuxtjs/composition-api";
|
||||
import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref, useContext } from "@nuxtjs/composition-api";
|
||||
import draggable from "vuedraggable";
|
||||
import { useCookbooks } from "@/composables/use-group-cookbooks";
|
||||
import { useHouseholdSelf } from "@/composables/use-households";
|
||||
import CookbookEditor from "~/components/Domain/Cookbook/CookbookEditor.vue";
|
||||
import { ReadCookBook } from "~/lib/api/types/cookbook";
|
||||
import { useCookbookPreferences } from "~/composables/use-users/preferences";
|
||||
|
||||
export default defineComponent({
|
||||
components: { CookbookEditor, draggable },
|
||||
|
@ -124,13 +139,28 @@ export default defineComponent({
|
|||
create: false,
|
||||
delete: false,
|
||||
});
|
||||
const { cookbooks, actions } = useCookbooks();
|
||||
|
||||
const { $auth, i18n } = useContext();
|
||||
const { cookbooks: allCookbooks, actions } = useCookbooks();
|
||||
const myCookbooks = computed<ReadCookBook[]>({
|
||||
get: () => {
|
||||
return allCookbooks.value?.filter((cookbook) => {
|
||||
return cookbook.householdId === $auth.user?.householdId;
|
||||
}) || [];
|
||||
},
|
||||
set: (value: ReadCookBook[]) => {
|
||||
actions.updateOrder(value);
|
||||
},
|
||||
});
|
||||
const { household } = useHouseholdSelf();
|
||||
const cookbookPreferences = useCookbookPreferences()
|
||||
|
||||
// create
|
||||
const createTargetKey = ref(0);
|
||||
const createTarget = ref<ReadCookBook | null>(null);
|
||||
async function createCookbook() {
|
||||
await actions.createOne().then((cookbook) => {
|
||||
const name = i18n.t("cookbook.household-cookbook-name", [household.value?.name || "", String((myCookbooks.value?.length ?? 0) + 1)]) as string
|
||||
await actions.createOne(name).then((cookbook) => {
|
||||
createTarget.value = cookbook as ReadCookBook;
|
||||
createTargetKey.value++;
|
||||
});
|
||||
|
@ -177,7 +207,8 @@ export default defineComponent({
|
|||
});
|
||||
|
||||
return {
|
||||
cookbooks,
|
||||
myCookbooks,
|
||||
cookbookPreferences,
|
||||
actions,
|
||||
dialogStates,
|
||||
// create
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
|
||||
<!-- View By Label -->
|
||||
<div v-else>
|
||||
<div v-for="(value, key) in itemsByLabel" :key="key" class="mb-6">
|
||||
<div v-for="(value, key) in itemsByLabel" :key="key" class="pb-4">
|
||||
<v-btn
|
||||
:color="getLabelColor(value[0]) ? getLabelColor(value[0]) : '#959595'"
|
||||
:style="{
|
||||
|
@ -73,20 +73,20 @@
|
|||
<v-divider/>
|
||||
<v-expand-transition group>
|
||||
<div v-show="labelOpenState[key]">
|
||||
<draggable :value="value" handle=".handle" delay="250" :delay-on-touch-only="true" @start="loadingCounter += 1" @end="loadingCounter -= 1" @input="updateIndexUncheckedByLabel(key, $event)">
|
||||
<v-lazy v-for="(item, index) in value" :key="item.id" class="ml-2 my-2">
|
||||
<ShoppingListItem
|
||||
v-model="value[index]"
|
||||
:show-label=false
|
||||
:labels="allLabels || []"
|
||||
:units="allUnits || []"
|
||||
:foods="allFoods || []"
|
||||
:recipes="recipeMap"
|
||||
@checked="saveListItem"
|
||||
@save="saveListItem"
|
||||
@delete="deleteListItem(item)"
|
||||
/>
|
||||
</v-lazy>
|
||||
<draggable :value="value" handle=".handle" delay="250" :delay-on-touch-only="true" @start="loadingCounter += 1" @end="loadingCounter -= 1" @input="updateIndexUncheckedByLabel(key, $event)">
|
||||
<v-lazy v-for="(item, index) in value" :key="item.id" class="ml-2 my-2">
|
||||
<ShoppingListItem
|
||||
v-model="value[index]"
|
||||
:show-label=false
|
||||
:labels="allLabels || []"
|
||||
:units="allUnits || []"
|
||||
:foods="allFoods || []"
|
||||
:recipes="recipeMap"
|
||||
@checked="saveListItem"
|
||||
@save="saveListItem"
|
||||
@delete="deleteListItem(item)"
|
||||
/>
|
||||
</v-lazy>
|
||||
</draggable>
|
||||
</div>
|
||||
</v-expand-transition>
|
||||
|
@ -470,7 +470,7 @@ export default defineComponent({
|
|||
});
|
||||
|
||||
// =====================================
|
||||
// Collapsables
|
||||
// Collapsable Labels
|
||||
const labelOpenState = ref<{ [key: string]: boolean }>({});
|
||||
|
||||
const initializeLabelOpenStates = () => {
|
||||
|
@ -480,8 +480,8 @@ export default defineComponent({
|
|||
let hasChanges = false;
|
||||
|
||||
for (const item of shoppingList.value.listItems) {
|
||||
const labelName = item.label?.name;
|
||||
if (labelName && !existingLabels.has(labelName) && !(labelName in labelOpenState.value)) {
|
||||
const labelName = item.label?.name || i18n.tc("shopping-list.no-label");
|
||||
if (!existingLabels.has(labelName) && !(labelName in labelOpenState.value)) {
|
||||
labelOpenState.value[labelName] = true;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
@ -492,9 +492,13 @@ export default defineComponent({
|
|||
}
|
||||
};
|
||||
|
||||
const labelNames = computed(() =>
|
||||
new Set(shoppingList.value?.listItems?.map(item => item.label?.name).filter(Boolean) ?? [])
|
||||
);
|
||||
const labelNames = computed(() => {
|
||||
return new Set(
|
||||
shoppingList.value?.listItems
|
||||
?.map(item => item.label?.name || i18n.tc("shopping-list.no-label"))
|
||||
.filter(Boolean) ?? []
|
||||
);
|
||||
});
|
||||
|
||||
watch(labelNames, initializeLabelOpenStates, { immediate: true });
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ export interface SideBarLink {
|
|||
href?: string;
|
||||
title: string;
|
||||
children?: SideBarLink[];
|
||||
childrenStartExpanded?: boolean;
|
||||
restricted: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -353,6 +353,15 @@ class AppSettings(AppLoggingSettings):
|
|||
|
||||
model_config = SettingsConfigDict(arbitrary_types_allowed=True, extra="allow")
|
||||
|
||||
# ===============================================
|
||||
# TLS
|
||||
|
||||
TLS_CERTIFICATE_PATH: str | os.PathLike[str] | None = None
|
||||
"""Path where the certificate resides."""
|
||||
|
||||
TLS_PRIVATE_KEY_PATH: str | os.PathLike[str] | None = None
|
||||
"""Path where the private key resides."""
|
||||
|
||||
|
||||
def app_settings_constructor(data_dir: Path, production: bool, env_file: Path, env_encoding="utf-8") -> AppSettings:
|
||||
"""
|
||||
|
|
|
@ -151,6 +151,14 @@ class User(SqlAlchemyBase, BaseMixins):
|
|||
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
|
||||
|
|
|
@ -13,6 +13,8 @@ def main():
|
|||
log_config=log_config(),
|
||||
workers=settings.WORKERS,
|
||||
forwarded_allow_ips=settings.HOST_IP,
|
||||
ssl_keyfile=settings.TLS_PRIVATE_KEY_PATH,
|
||||
ssl_certfile=settings.TLS_CERTIFICATE_PATH,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ from collections.abc import Callable
|
|||
from logging import Logger
|
||||
from typing import Generic, TypeVar
|
||||
|
||||
import sqlalchemy.exc
|
||||
from fastapi import HTTPException, status
|
||||
from pydantic import UUID4, BaseModel
|
||||
|
||||
|
@ -57,10 +58,16 @@ class HttpRepo(Generic[C, R, U]):
|
|||
# Respond
|
||||
msg = self.get_exception_message(ex)
|
||||
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail=ErrorResponse.respond(message=msg, exception=str(ex)),
|
||||
)
|
||||
if isinstance(ex, sqlalchemy.exc.NoResultFound):
|
||||
raise HTTPException(
|
||||
status.HTTP_404_NOT_FOUND,
|
||||
detail=ErrorResponse.respond(message=msg, exception=str(ex)),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail=ErrorResponse.respond(message=msg, exception=str(ex)),
|
||||
)
|
||||
|
||||
def create_one(self, data: C) -> R | None:
|
||||
item: R | None = None
|
||||
|
|
|
@ -6,6 +6,7 @@ from fastapi import APIRouter, Depends, HTTPException
|
|||
from pydantic import UUID4
|
||||
|
||||
from mealie.core.exceptions import mealie_registered_exceptions
|
||||
from mealie.repos.all_repositories import get_repositories
|
||||
from mealie.routes._base import BaseCrudController, controller
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.routes._base.routers import MealieCrudRoute
|
||||
|
@ -26,9 +27,13 @@ router = APIRouter(prefix="/households/cookbooks", tags=["Households: Cookbooks"
|
|||
@controller(router)
|
||||
class GroupCookbookController(BaseCrudController):
|
||||
@cached_property
|
||||
def repo(self):
|
||||
def cookbooks(self):
|
||||
return self.repos.cookbooks
|
||||
|
||||
@cached_property
|
||||
def group_cookbooks(self):
|
||||
return get_repositories(self.session, group_id=self.group_id, household_id=None).cookbooks
|
||||
|
||||
def registered_exceptions(self, ex: type[Exception]) -> str:
|
||||
registered = {
|
||||
**mealie_registered_exceptions(self.translator),
|
||||
|
@ -38,14 +43,15 @@ class GroupCookbookController(BaseCrudController):
|
|||
@cached_property
|
||||
def mixins(self):
|
||||
return HttpRepo[CreateCookBook, ReadCookBook, UpdateCookBook](
|
||||
self.repo,
|
||||
self.cookbooks,
|
||||
self.logger,
|
||||
self.registered_exceptions,
|
||||
)
|
||||
|
||||
@router.get("", response_model=CookBookPagination)
|
||||
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
||||
response = self.repo.page_all(
|
||||
# Fetch all cookbooks for the group, rather than the household
|
||||
response = self.group_cookbooks.page_all(
|
||||
pagination=q,
|
||||
override=ReadCookBook,
|
||||
)
|
||||
|
@ -106,7 +112,8 @@ class GroupCookbookController(BaseCrudController):
|
|||
except ValueError:
|
||||
match_attr = "slug"
|
||||
|
||||
cookbook = self.repo.get_one(item_id, match_attr)
|
||||
# Allow fetching other households' cookbooks
|
||||
cookbook = self.group_cookbooks.get_one(item_id, match_attr)
|
||||
|
||||
if cookbook is None:
|
||||
raise HTTPException(status_code=404)
|
||||
|
|
|
@ -105,8 +105,8 @@ class BaseRecipeController(BaseCrudController):
|
|||
return get_repositories(self.session, group_id=self.group_id, household_id=None).recipes
|
||||
|
||||
@cached_property
|
||||
def cookbooks_repo(self) -> RepositoryGeneric[ReadCookBook, CookBook]:
|
||||
return self.repos.cookbooks
|
||||
def group_cookbooks(self) -> RepositoryGeneric[ReadCookBook, CookBook]:
|
||||
return get_repositories(self.session, group_id=self.group_id, household_id=None).cookbooks
|
||||
|
||||
@cached_property
|
||||
def service(self) -> RecipeService:
|
||||
|
@ -354,7 +354,7 @@ class RecipeController(BaseRecipeController):
|
|||
cb_match_attr = "id"
|
||||
except ValueError:
|
||||
cb_match_attr = "slug"
|
||||
cookbook_data = self.cookbooks_repo.get_one(search_query.cookbook, cb_match_attr)
|
||||
cookbook_data = self.group_cookbooks.get_one(search_query.cookbook, cb_match_attr)
|
||||
|
||||
if cookbook_data is None:
|
||||
raise HTTPException(status_code=404, detail="cookbook not found")
|
||||
|
|
138
poetry.lock
generated
138
poetry.lock
generated
|
@ -1464,13 +1464,13 @@ pyyaml = ">=5.1"
|
|||
|
||||
[[package]]
|
||||
name = "mkdocs-material"
|
||||
version = "9.5.43"
|
||||
version = "9.5.44"
|
||||
description = "Documentation that simply works"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "mkdocs_material-9.5.43-py3-none-any.whl", hash = "sha256:4aae0664c456fd12837a3192e0225c17960ba8bf55d7f0a7daef7e4b0b914a34"},
|
||||
{file = "mkdocs_material-9.5.43.tar.gz", hash = "sha256:83be7ff30b65a1e4930dfa4ab911e75780a3afc9583d162692e434581cb46979"},
|
||||
{file = "mkdocs_material-9.5.44-py3-none-any.whl", hash = "sha256:47015f9c167d58a5ff5e682da37441fc4d66a1c79334bfc08d774763cacf69ca"},
|
||||
{file = "mkdocs_material-9.5.44.tar.gz", hash = "sha256:f3a6c968e524166b3f3ed1fb97d3ed3e0091183b0545cedf7156a2a6804c56c0"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -1598,13 +1598,13 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
|
|||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "1.53.0"
|
||||
version = "1.54.1"
|
||||
description = "The official Python library for the openai API"
|
||||
optional = false
|
||||
python-versions = ">=3.7.1"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "openai-1.53.0-py3-none-any.whl", hash = "sha256:20f408c32fc5cb66e60c6882c994cdca580a5648e10045cd840734194f033418"},
|
||||
{file = "openai-1.53.0.tar.gz", hash = "sha256:be2c4e77721b166cce8130e544178b7d579f751b4b074ffbaade3854b6f85ec5"},
|
||||
{file = "openai-1.54.1-py3-none-any.whl", hash = "sha256:3cb49ccb6bfdc724ad01cc397d323ef8314fc7d45e19e9de2afdd6484a533324"},
|
||||
{file = "openai-1.54.1.tar.gz", hash = "sha256:5b832bf82002ba8c4f6e5e25c1c0f5d468c22f043711544c716eaffdb30dd6f1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -1622,69 +1622,69 @@ datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"]
|
|||
|
||||
[[package]]
|
||||
name = "orjson"
|
||||
version = "3.10.10"
|
||||
version = "3.10.11"
|
||||
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"},
|
||||
{file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"},
|
||||
{file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"},
|
||||
{file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"},
|
||||
{file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"},
|
||||
{file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"},
|
||||
{file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"},
|
||||
{file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"},
|
||||
{file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"},
|
||||
{file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"},
|
||||
{file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"},
|
||||
{file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"},
|
||||
{file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"},
|
||||
{file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"},
|
||||
{file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"},
|
||||
{file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"},
|
||||
{file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"},
|
||||
{file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"},
|
||||
{file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"},
|
||||
{file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"},
|
||||
{file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"},
|
||||
{file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"},
|
||||
{file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"},
|
||||
{file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"},
|
||||
{file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"},
|
||||
{file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"},
|
||||
{file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"},
|
||||
{file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"},
|
||||
{file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"},
|
||||
{file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"},
|
||||
{file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"},
|
||||
{file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"},
|
||||
{file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"},
|
||||
{file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"},
|
||||
{file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"},
|
||||
{file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"},
|
||||
{file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"},
|
||||
{file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"},
|
||||
{file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"},
|
||||
{file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"},
|
||||
{file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"},
|
||||
{file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"},
|
||||
{file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"},
|
||||
{file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"},
|
||||
{file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"},
|
||||
{file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"},
|
||||
{file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"},
|
||||
{file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"},
|
||||
{file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"},
|
||||
{file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"},
|
||||
{file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"},
|
||||
{file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"},
|
||||
{file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"},
|
||||
{file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"},
|
||||
{file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"},
|
||||
{file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"},
|
||||
{file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"},
|
||||
{file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"},
|
||||
{file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"},
|
||||
{file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"},
|
||||
{file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"},
|
||||
{file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"},
|
||||
{file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"},
|
||||
{file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"},
|
||||
{file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"},
|
||||
{file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"},
|
||||
{file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"},
|
||||
{file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"},
|
||||
{file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"},
|
||||
{file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"},
|
||||
{file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"},
|
||||
{file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"},
|
||||
{file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"},
|
||||
{file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"},
|
||||
{file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"},
|
||||
{file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"},
|
||||
{file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"},
|
||||
{file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"},
|
||||
{file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"},
|
||||
{file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"},
|
||||
{file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"},
|
||||
{file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"},
|
||||
{file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"},
|
||||
{file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"},
|
||||
{file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"},
|
||||
{file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"},
|
||||
{file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"},
|
||||
{file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"},
|
||||
{file = "orjson-3.10.11-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899"},
|
||||
{file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230"},
|
||||
{file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0"},
|
||||
{file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258"},
|
||||
{file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0"},
|
||||
{file = "orjson-3.10.11-cp313-none-win32.whl", hash = "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b"},
|
||||
{file = "orjson-3.10.11-cp313-none-win_amd64.whl", hash = "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270"},
|
||||
{file = "orjson-3.10.11-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87"},
|
||||
{file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205"},
|
||||
{file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446"},
|
||||
{file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c"},
|
||||
{file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350"},
|
||||
{file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c"},
|
||||
{file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204"},
|
||||
{file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3"},
|
||||
{file = "orjson-3.10.11-cp38-none-win32.whl", hash = "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161"},
|
||||
{file = "orjson-3.10.11-cp38-none-win_amd64.whl", hash = "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782"},
|
||||
{file = "orjson-3.10.11-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af"},
|
||||
{file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7"},
|
||||
{file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d"},
|
||||
{file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de"},
|
||||
{file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54"},
|
||||
{file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad"},
|
||||
{file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b"},
|
||||
{file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f"},
|
||||
{file = "orjson-3.10.11-cp39-none-win32.whl", hash = "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950"},
|
||||
{file = "orjson-3.10.11-cp39-none-win_amd64.whl", hash = "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017"},
|
||||
{file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2796,13 +2796,13 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
|
|||
|
||||
[[package]]
|
||||
name = "rich"
|
||||
version = "13.9.3"
|
||||
version = "13.9.4"
|
||||
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283"},
|
||||
{file = "rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e"},
|
||||
{file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"},
|
||||
{file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
|
@ -60,6 +60,8 @@ def test_create_cookbook(api_client: TestClient, unique_user: TestUser):
|
|||
page_data = get_page_data(unique_user.group_id, unique_user.household_id)
|
||||
response = api_client.post(api_routes.households_cookbooks, json=page_data, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
assert response.json()["groupId"] == unique_user.group_id
|
||||
assert response.json()["householdId"] == unique_user.household_id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name_input", ["", " ", "@"])
|
||||
|
@ -78,9 +80,22 @@ def test_create_cookbook_bad_name(api_client: TestClient, unique_user: TestUser,
|
|||
assert response.status_code == 422
|
||||
|
||||
|
||||
def test_read_cookbook(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
|
||||
@pytest.mark.parametrize("use_other_household", [True, False])
|
||||
def test_read_cookbook(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
h2_user: TestUser,
|
||||
cookbooks: list[TestCookbook],
|
||||
use_other_household: bool,
|
||||
):
|
||||
sample = random.choice(cookbooks)
|
||||
response = api_client.get(api_routes.households_cookbooks_item_id(sample.id), headers=unique_user.token)
|
||||
if use_other_household:
|
||||
headers = h2_user.token
|
||||
else:
|
||||
headers = unique_user.token
|
||||
|
||||
# all households should be able to fetch all cookbooks
|
||||
response = api_client.get(api_routes.households_cookbooks_item_id(sample.id), headers=headers)
|
||||
assert response.status_code == 200
|
||||
|
||||
page_data = response.json()
|
||||
|
@ -111,6 +126,28 @@ def test_update_cookbook(api_client: TestClient, unique_user: TestUser, cookbook
|
|||
assert page_data["slug"] == update_data["name"]
|
||||
|
||||
|
||||
def test_update_cookbook_other_household(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, cookbooks: list[TestCookbook]
|
||||
):
|
||||
cookbook = random.choice(cookbooks)
|
||||
|
||||
update_data = get_page_data(unique_user.group_id, unique_user.household_id)
|
||||
|
||||
update_data["name"] = random_string(10)
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.households_cookbooks_item_id(cookbook.id), json=update_data, headers=h2_user.token
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
response = api_client.get(api_routes.households_cookbooks_item_id(cookbook.id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
page_data = response.json()
|
||||
assert page_data["name"] != update_data["name"]
|
||||
assert page_data["slug"] != update_data["name"]
|
||||
|
||||
|
||||
def test_update_cookbooks_many(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
|
||||
pages = [x.data for x in cookbooks]
|
||||
|
||||
|
@ -135,6 +172,20 @@ def test_update_cookbooks_many(api_client: TestClient, unique_user: TestUser, co
|
|||
assert str(know) in server_ids
|
||||
|
||||
|
||||
def test_update_cookbooks_many_other_household(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, cookbooks: list[TestCookbook]
|
||||
):
|
||||
pages = [x.data for x in cookbooks]
|
||||
|
||||
reverse_order = sorted(pages, key=lambda x: x["position"], reverse=True)
|
||||
for x, page in enumerate(reverse_order):
|
||||
page["position"] = x
|
||||
page["group_id"] = str(unique_user.group_id)
|
||||
|
||||
response = api_client.put(api_routes.households_cookbooks, json=utils.jsonify(reverse_order), headers=h2_user.token)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_delete_cookbook(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
|
||||
sample = random.choice(cookbooks)
|
||||
response = api_client.delete(api_routes.households_cookbooks_item_id(sample.id), headers=unique_user.token)
|
||||
|
@ -145,6 +196,18 @@ def test_delete_cookbook(api_client: TestClient, unique_user: TestUser, cookbook
|
|||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_delete_cookbook_other_household(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, cookbooks: list[TestCookbook]
|
||||
):
|
||||
sample = random.choice(cookbooks)
|
||||
response = api_client.delete(api_routes.households_cookbooks_item_id(sample.id), headers=h2_user.token)
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
response = api_client.get(api_routes.households_cookbooks_item_id(sample.slug), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"qf_string, expected_code",
|
||||
[
|
||||
|
|
|
@ -299,3 +299,16 @@ def test_cookbook_recipes_includes_all_households(api_client: TestClient, unique
|
|||
assert recipe.id in fetched_recipe_ids
|
||||
for recipe in other_recipes:
|
||||
assert recipe.id in fetched_recipe_ids
|
||||
|
||||
|
||||
def test_cookbooks_from_other_households(api_client: TestClient, unique_user: TestUser, h2_user: TestUser):
|
||||
h2_cookbook = h2_user.repos.cookbooks.create(
|
||||
SaveCookBook(
|
||||
name=random_string(),
|
||||
group_id=h2_user.group_id,
|
||||
household_id=h2_user.household_id,
|
||||
)
|
||||
)
|
||||
|
||||
response = api_client.get(api_routes.recipes, params={"cookbook": h2_cookbook.slug}, headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from pathlib import Path
|
||||
|
||||
import ldap
|
||||
import pytest
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
from mealie.core import security
|
||||
|
@ -13,6 +14,7 @@ from mealie.core.security.providers.credentials_provider import (
|
|||
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
|
||||
|
@ -92,7 +94,7 @@ class LdapConnMock:
|
|||
pass
|
||||
|
||||
|
||||
def setup_env(monkeypatch: MonkeyPatch):
|
||||
def setup_env(monkeypatch: MonkeyPatch, **kwargs):
|
||||
user = random_string(10)
|
||||
mail = random_string(10)
|
||||
name = random_string(10)
|
||||
|
@ -140,11 +142,55 @@ def test_ldap_user_creation(monkeypatch: MonkeyPatch):
|
|||
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):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue