From dcdca9eec7a75f5e177da75a1ce3fd5f3c0c94d9 Mon Sep 17 00:00:00 2001 From: hay-kot Date: Sun, 21 Mar 2021 20:27:36 -0800 Subject: [PATCH] fix/test that never really passed --- mealie/core/__init__.py | 0 mealie/core/config.py | 2 +- mealie/core/security.py | 27 +++ mealie/routes/deps.py | 44 +++-- mealie/routes/groups/crud.py | 18 +- mealie/routes/mealplans/crud.py | 10 +- mealie/routes/setting_routes.py | 4 +- mealie/routes/users/auth.py | 51 ++--- mealie/routes/users/crud.py | 38 ++-- mealie/routes/users/sign_up.py | 8 +- mealie/schema/auth.py | 10 + poetry.lock | 183 +++++++++++------- pyproject.toml | 3 +- tests/conftest.py | 8 +- tests/test_routes/test_meal_routes.py | 7 +- tests/test_routes/test_user_routes.py | 12 +- .../test_migrations/test_nextcloud.py | 7 +- 17 files changed, 256 insertions(+), 176 deletions(-) create mode 100644 mealie/core/__init__.py create mode 100644 mealie/schema/auth.py diff --git a/mealie/core/__init__.py b/mealie/core/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/mealie/core/config.py b/mealie/core/config.py index 715390815..1f99bc0e5 100644 --- a/mealie/core/config.py +++ b/mealie/core/config.py @@ -19,7 +19,7 @@ ENV = CWD.joinpath(".env") #! I'm Broken Fix Me! dotenv.load_dotenv(ENV) -SECRET = "super-secret-key" +SECRET = "test-secret-shhh" # General PRODUCTION = os.environ.get("ENV") diff --git a/mealie/core/security.py b/mealie/core/security.py index f6cc9a805..2091e024e 100644 --- a/mealie/core/security.py +++ b/mealie/core/security.py @@ -1,6 +1,33 @@ +from datetime import datetime, timedelta +from mealie.schema.user import UserInDB + +from jose import jwt +from mealie.core.config import SECRET +from mealie.db.database import db from passlib.context import CryptContext pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +ALGORITHM = "HS256" + + +def create_access_token(data: dict(), expires_delta: timedelta = None) -> str: + to_encode = data.copy() + if expires_delta: + expire = datetime.utcnow() + expires_delta + else: + expire = datetime.utcnow() + timedelta(minutes=120) + to_encode.update({"exp": expire}) + encoded_jwt = jwt.encode(to_encode, SECRET, algorithm=ALGORITHM) + return encoded_jwt + + +def authenticate_user(session, email: str, password: str) -> UserInDB: + user: UserInDB = db.users.get(session, email, "email") + if not user: + return False + if not verify_password(password, user.password): + return False + return user def verify_password(plain_password: str, hashed_password: str) -> bool: diff --git a/mealie/routes/deps.py b/mealie/routes/deps.py index e6467bfda..acf9f8e94 100644 --- a/mealie/routes/deps.py +++ b/mealie/routes/deps.py @@ -1,23 +1,35 @@ +from fastapi import Depends, HTTPException, status +from fastapi.security import OAuth2PasswordBearer +from jose import JWTError, jwt from mealie.core.config import SECRET from mealie.db.database import db -from mealie.db.db_setup import create_session -from fastapi_login import LoginManager -from sqlalchemy.orm.session import Session - +from mealie.db.db_setup import create_session, generate_session +from mealie.schema.auth import Token, TokenData from mealie.schema.user import UserInDB -manager = LoginManager(SECRET, "/api/auth/token") +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/token") +ALGORITHM = "HS256" -@manager.user_loader -def query_user(user_email: str, session: Session = None) -> UserInDB: - """ - Get a user from the db - :param user_id: E-Mail of the user - :return: None or the UserInDB object - """ - - session = session if session else create_session() - user = db.users.get(session, user_email, "email") - session.close() +async def get_current_user(token: str = Depends(oauth2_scheme), session=Depends(generate_session)) -> UserInDB: + credentials_exception = HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Could not validate credentials", + headers={"WWW-Authenticate": "Bearer"}, + ) + try: + payload = jwt.decode(token, SECRET, algorithms=[ALGORITHM]) + username: str = payload.get("sub") + if username is None: + raise credentials_exception + token_data = TokenData(username=username) + print("Login Payload", token_data) + except JWTError: + raise credentials_exception + user = db.users.get(session, token_data.username, "email") + if user is None: + raise credentials_exception return user + + + diff --git a/mealie/routes/groups/crud.py b/mealie/routes/groups/crud.py index 5b56e05e3..60456f79c 100644 --- a/mealie/routes/groups/crud.py +++ b/mealie/routes/groups/crud.py @@ -1,9 +1,9 @@ +from fastapi import APIRouter, Depends from mealie.db.database import db from mealie.db.db_setup import generate_session -from fastapi import APIRouter, Depends -from mealie.routes.deps import manager +from mealie.routes.deps import get_current_user from mealie.schema.snackbar import SnackResponse -from mealie.schema.user import GroupBase, GroupInDB, UpdateGroup, UserInDB +from mealie.schema.user import GroupBase, GroupInDB, UpdateGroup, UserIn, UserInDB from sqlalchemy.orm.session import Session router = APIRouter(prefix="/api/groups", tags=["Groups"]) @@ -11,7 +11,7 @@ router = APIRouter(prefix="/api/groups", tags=["Groups"]) @router.get("", response_model=list[GroupInDB]) async def get_all_groups( - current_user=Depends(manager), + current_user=Depends(get_current_user), session: Session = Depends(generate_session), ): """ Returns a list of all groups in the database """ @@ -21,7 +21,7 @@ async def get_all_groups( @router.get("/self", response_model=GroupInDB) async def get_current_user_group( - current_user=Depends(manager), + current_user: UserInDB =Depends(get_current_user), session: Session = Depends(generate_session), ): """ Returns the Group Data for the Current User """ @@ -33,7 +33,7 @@ async def get_current_user_group( @router.post("") async def create_group( group_data: GroupBase, - current_user=Depends(manager), + current_user=Depends(get_current_user), session: Session = Depends(generate_session), ): """ Creates a Group in the Database """ @@ -49,7 +49,7 @@ async def create_group( async def update_group_data( id: int, group_data: UpdateGroup, - current_user=Depends(manager), + current_user=Depends(get_current_user), session: Session = Depends(generate_session), ): """ Updates a User Group """ @@ -59,7 +59,9 @@ async def update_group_data( @router.delete("/{id}") -async def delete_user_group(id: int, current_user=Depends(manager), session: Session = Depends(generate_session)): +async def delete_user_group( + id: int, current_user=Depends(get_current_user), session: Session = Depends(generate_session) +): """ Removes a user group from the database """ if id == 1: diff --git a/mealie/routes/mealplans/crud.py b/mealie/routes/mealplans/crud.py index 15066c944..1c6da143f 100644 --- a/mealie/routes/mealplans/crud.py +++ b/mealie/routes/mealplans/crud.py @@ -3,7 +3,7 @@ import datetime from fastapi import APIRouter, Depends from mealie.db.database import db from mealie.db.db_setup import generate_session -from mealie.routes.deps import manager +from mealie.routes.deps import get_current_user from mealie.schema.meal import MealPlanIn, MealPlanInDB from mealie.schema.snackbar import SnackResponse from mealie.schema.user import GroupInDB, UserInDB @@ -15,7 +15,7 @@ router = APIRouter(prefix="/api/meal-plans", tags=["Meal Plan"]) @router.get("/all", response_model=list[MealPlanInDB]) def get_all_meals( - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): """ Returns a list of all available Meal Plan """ @@ -27,7 +27,7 @@ def get_all_meals( def create_meal_plan( data: MealPlanIn, session: Session = Depends(generate_session), - current_user=Depends(manager), + current_user=Depends(get_current_user), ): """ Creates a meal plan database entry """ processed_plan = process_meals(session, data) @@ -58,7 +58,7 @@ def delete_meal_plan(plan_id, session: Session = Depends(generate_session)): @router.get("/this-week", response_model=MealPlanInDB) def get_this_week( session: Session = Depends(generate_session), - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), ): """ Returns the meal plan data for this week """ @@ -68,7 +68,7 @@ def get_this_week( @router.get("/today", tags=["Meal Plan"]) def get_today( session: Session = Depends(generate_session), - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), ): """ Returns the recipe slug for the meal scheduled for today. diff --git a/mealie/routes/setting_routes.py b/mealie/routes/setting_routes.py index 2d22c0f95..81cd18d46 100644 --- a/mealie/routes/setting_routes.py +++ b/mealie/routes/setting_routes.py @@ -7,7 +7,7 @@ from mealie.schema.user import GroupInDB, UserInDB from sqlalchemy.orm.session import Session from mealie.utils.post_webhooks import post_webhooks -from mealie.routes.deps import manager +from mealie.routes.deps import get_current_user router = APIRouter(prefix="/api/site-settings", tags=["Settings"]) @@ -31,7 +31,7 @@ def update_settings(data: SiteSettings, session: Session = Depends(generate_sess @router.post("/webhooks/test") def test_webhooks( - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): """ Run the function to test your webhooks """ diff --git a/mealie/routes/users/auth.py b/mealie/routes/users/auth.py index 989c1fe60..ef8ca6456 100644 --- a/mealie/routes/users/auth.py +++ b/mealie/routes/users/auth.py @@ -1,11 +1,12 @@ from datetime import timedelta -from mealie.core.security import verify_password -from mealie.db.db_setup import generate_session -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, status +from fastapi.exceptions import HTTPException from fastapi.security import OAuth2PasswordRequestForm -from fastapi_login.exceptions import InvalidCredentialsException -from mealie.routes.deps import manager, query_user +from mealie.core import security +from mealie.core.security import authenticate_user, verify_password +from mealie.db.db_setup import generate_session +from mealie.routes.deps import get_current_user from mealie.schema.snackbar import SnackResponse from mealie.schema.user import UserInDB from sqlalchemy.orm.session import Session @@ -13,6 +14,7 @@ from sqlalchemy.orm.session import Session router = APIRouter(prefix="/api/auth", tags=["Authentication"]) +@router.post("/token/long") @router.post("/token") def get_token( data: OAuth2PasswordRequestForm = Depends(), @@ -21,35 +23,16 @@ def get_token( email = data.username password = data.password - user: UserInDB = query_user(email, session) + user = authenticate_user(session, email, password) + if not user: - raise InvalidCredentialsException # you can also use your own HTTPException - elif not verify_password(password, user.password): - raise InvalidCredentialsException + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Incorrect username or password", + headers={"WWW-Authenticate": "Bearer"}, + ) - access_token = manager.create_access_token(data=dict(sub=email), expires=timedelta(hours=2)) - return SnackResponse.success( - "User Successfully Logged In", - {"access_token": access_token, "token_type": "bearer"}, - ) - - -@router.post("/token/long") -def get_long_token( - data: OAuth2PasswordRequestForm = Depends(), - session: Session = Depends(generate_session), -): - """Get an Access Token for 1 day""" - email = data.username - password = data.password - - user: UserInDB = query_user(email, session) - if not user: - raise InvalidCredentialsException # you can also use your own HTTPException - elif not verify_password(password, user.password): - raise InvalidCredentialsException - - access_token = manager.create_access_token(data=dict(sub=email), expires=timedelta(days=1)) + access_token = security.create_access_token(dict(sub=email), timedelta(hours=2)) return SnackResponse.success( "User Successfully Logged In", {"access_token": access_token, "token_type": "bearer"}, @@ -57,7 +40,7 @@ def get_long_token( @router.get("/refresh") -async def refresh_token(current_user: UserInDB = Depends(manager)): +async def refresh_token(current_user: UserInDB = Depends(get_current_user)): """ Use a valid token to get another token""" - access_token = manager.create_access_token(data=dict(sub=current_user.email), expires=timedelta(hours=1)) + access_token = security.create_access_token(data=dict(sub=current_user.email), expires_delta=timedelta(hours=1)) return {"access_token": access_token, "token_type": "bearer"} diff --git a/mealie/routes/users/crud.py b/mealie/routes/users/crud.py index 28fe693d5..c18b06489 100644 --- a/mealie/routes/users/crud.py +++ b/mealie/routes/users/crud.py @@ -1,14 +1,14 @@ import shutil from datetime import timedelta -from os import access +from fastapi import APIRouter, Depends, File, UploadFile +from fastapi.responses import FileResponse +from mealie.core import security from mealie.core.config import USER_DIR from mealie.core.security import get_password_hash, verify_password from mealie.db.database import db from mealie.db.db_setup import generate_session -from fastapi import APIRouter, Depends, File, UploadFile -from fastapi.responses import FileResponse -from mealie.routes.deps import manager +from mealie.routes.deps import get_current_user from mealie.schema.snackbar import SnackResponse from mealie.schema.user import ChangePassword, UserBase, UserIn, UserInDB, UserOut from sqlalchemy.orm.session import Session @@ -19,7 +19,7 @@ router = APIRouter(prefix="/api/users", tags=["Users"]) @router.post("", response_model=UserOut, status_code=201) async def create_user( new_user: UserIn, - current_user=Depends(manager), + current_user=Depends(get_current_user), session: Session = Depends(generate_session), ): @@ -31,7 +31,7 @@ async def create_user( @router.get("", response_model=list[UserOut]) async def get_all_users( - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): @@ -43,7 +43,7 @@ async def get_all_users( @router.get("/self", response_model=UserOut) async def get_logged_in_user( - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): return current_user.dict() @@ -52,7 +52,7 @@ async def get_logged_in_user( @router.get("/{id}", response_model=UserOut) async def get_user_by_id( id: int, - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): return db.users.get(session, id) @@ -62,19 +62,21 @@ async def get_user_by_id( async def update_user( id: int, new_data: UserBase, - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): - access_token = None + token = None if current_user.id == id or current_user.admin: - updated_user: UserInDB = db.users.update(session, id, new_data.dict()) - email = updated_user.email + print("Current User") + db.users.update(session, id, new_data.dict()) if current_user.id == id: - access_token = manager.create_access_token(data=dict(sub=email), expires=timedelta(hours=2)) - access_token = {"access_token": access_token, "token_type": "bearer"} + print(new_data.email) + access_token = security.create_access_token(data=dict(sub=new_data.email), expires_delta=timedelta(hours=2)) + token = {"access_token": access_token, "token_type": "bearer"} - return SnackResponse.success("User Updated", access_token) + print(SnackResponse.success("User Updated", token)) + return SnackResponse.success("User Updated", token) @router.get("/{id}/image") @@ -91,7 +93,7 @@ async def get_user_image(id: str): async def update_user_image( id: str, profile_image: UploadFile = File(...), - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), ): """ Updates a User Image """ @@ -119,7 +121,7 @@ async def update_user_image( async def update_password( id: int, password_change: ChangePassword, - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): """ Resets the User Password""" @@ -138,7 +140,7 @@ async def update_password( @router.delete("/{id}") async def delete_user( id: int, - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): """ Removes a user from the database. Must be the current user or a super user""" diff --git a/mealie/routes/users/sign_up.py b/mealie/routes/users/sign_up.py index 110a8b16e..dc21f4125 100644 --- a/mealie/routes/users/sign_up.py +++ b/mealie/routes/users/sign_up.py @@ -4,7 +4,7 @@ from mealie.core.security import get_password_hash from mealie.db.database import db from mealie.db.db_setup import generate_session from fastapi import APIRouter, Depends -from mealie.routes.deps import manager +from mealie.routes.deps import get_current_user from mealie.schema.sign_up import SignUpIn, SignUpOut, SignUpToken from mealie.schema.snackbar import SnackResponse from mealie.schema.user import UserIn, UserInDB @@ -15,7 +15,7 @@ router = APIRouter(prefix="/api/users/sign-ups", tags=["User Signup"]) @router.get("", response_model=list[SignUpOut]) async def get_all_open_sign_ups( - current_user=Depends(manager), + current_user=Depends(get_current_user), session: Session = Depends(generate_session), ): """ Returns a list of open sign up links """ @@ -28,7 +28,7 @@ async def get_all_open_sign_ups( @router.post("", response_model=SignUpToken) async def create_user_sign_up_key( key_data: SignUpIn, - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): """ Generates a Random Token that a new user can sign up with """ @@ -75,7 +75,7 @@ async def create_user_with_token( @router.delete("/{token}") async def delete_token( token: str, - current_user: UserInDB = Depends(manager), + current_user: UserInDB = Depends(get_current_user), session: Session = Depends(generate_session), ): """ Removed a token from the database """ diff --git a/mealie/schema/auth.py b/mealie/schema/auth.py new file mode 100644 index 000000000..f42bcf6d2 --- /dev/null +++ b/mealie/schema/auth.py @@ -0,0 +1,10 @@ +from pydantic import BaseModel +from typing import Optional + +class Token(BaseModel): + access_token: str + token_type: str + + +class TokenData(BaseModel): + username: Optional[str] = None diff --git a/poetry.lock b/poetry.lock index c5f81c409..4f56937cb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -197,6 +197,17 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" +[[package]] +name = "ecdsa" +version = "0.14.1" +description = "ECDSA cryptographic signature library (pure python)" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[package.dependencies] +six = "*" + [[package]] name = "extruct" version = "0.12.0" @@ -249,19 +260,6 @@ python-versions = ">=3.6" pydantic = "*" pyhumps = "*" -[[package]] -name = "fastapi-login" -version = "1.5.3" -description = "" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -fastapi = "*" -passlib = "*" -pyjwt = "*" - [[package]] name = "future" version = "0.18.2" @@ -614,6 +612,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pyasn1" +version = "0.4.8" +description = "ASN.1 types and codecs" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "pycparser" version = "2.20" @@ -653,20 +659,6 @@ category = "main" optional = false python-versions = "*" -[[package]] -name = "pyjwt" -version = "2.0.1" -description = "JSON Web Token implementation in Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -crypto = ["cryptography (>=3.3.1,<4.0.0)"] -dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1,<4.0.0)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"] - [[package]] name = "pylint" version = "2.7.2" @@ -763,6 +755,25 @@ python-versions = "*" [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-jose" +version = "3.2.0" +description = "JOSE implementation in Python" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +ecdsa = "<0.15" +pyasn1 = "*" +rsa = "*" +six = "<2.0" + +[package.extras] +cryptography = ["cryptography"] +pycrypto = ["pycrypto (>=2.6.0,<2.7.0)", "pyasn1"] +pycryptodome = ["pycryptodome (>=3.3.1,<4.0.0)", "pyasn1"] + [[package]] name = "python-multipart" version = "0.0.5" @@ -860,6 +871,17 @@ urllib3 = ">=1.21.1,<1.27" security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +[[package]] +name = "rsa" +version = "4.7.2" +description = "Pure-Python RSA implementation" +category = "main" +optional = false +python-versions = ">=3.5, <4" + +[package.dependencies] +pyasn1 = ">=0.1.3" + [[package]] name = "scrape-schema-recipe" version = "0.1.3" @@ -1103,7 +1125,7 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "adf8ad8e07d1af5c231c936276b57be83dd534e0cf706042ddb26f6ff51c86ca" +content-hash = "688326ef0f3bf3b2d2d515b941dbca379f26b08ae83afab66fa0ec95dc2c57ce" [metadata.files] aiofiles = [ @@ -1264,6 +1286,10 @@ decorator = [ {file = "decorator-4.4.2-py2.py3-none-any.whl", hash = "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760"}, {file = "decorator-4.4.2.tar.gz", hash = "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"}, ] +ecdsa = [ + {file = "ecdsa-0.14.1-py2.py3-none-any.whl", hash = "sha256:e108a5fe92c67639abae3260e43561af914e7fd0d27bae6d2ec1312ae7934dfe"}, + {file = "ecdsa-0.14.1.tar.gz", hash = "sha256:64c613005f13efec6541bb0a33290d0d03c27abab5f15fbab20fb0ee162bdd8e"}, +] extruct = [ {file = "extruct-0.12.0-py2.py3-none-any.whl", hash = "sha256:42c6c9f50b00aa6c17b5c26b5f1b3a337ebc27b427fafc3714f34ce3bbb16c2f"}, {file = "extruct-0.12.0.tar.gz", hash = "sha256:d4a68bb79d1b85ff36d603a42c2666888bb480191a399a659d9daaf735358276"}, @@ -1275,10 +1301,6 @@ fastapi = [ fastapi-camelcase = [ {file = "fastapi_camelcase-1.0.2.tar.gz", hash = "sha256:1d852149f6c9e5bb8002839a1e024050af917f1944b9d108d56468d64c6da279"}, ] -fastapi-login = [ - {file = "fastapi-login-1.5.3.tar.gz", hash = "sha256:8e8ef710f1b7107e81d00e205779e73e17be35d5a91d11685ff72f323898e93b"}, - {file = "fastapi_login-1.5.3-py3-none-any.whl", hash = "sha256:6c83b74bdb45c34ec0aab22000a7951df96c5d011f02a99a46ca4b2be6b1263c"}, -] future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, ] @@ -1414,39 +1436,43 @@ lunr = [ {file = "lunr-0.5.8.tar.gz", hash = "sha256:c4fb063b98eff775dd638b3df380008ae85e6cb1d1a24d1cd81a10ef6391c26e"}, ] lxml = [ - {file = "lxml-4.6.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:df7c53783a46febb0e70f6b05df2ba104610f2fb0d27023409734a3ecbb78fb2"}, - {file = "lxml-4.6.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1b7584d421d254ab86d4f0b13ec662a9014397678a7c4265a02a6d7c2b18a75f"}, - {file = "lxml-4.6.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:079f3ae844f38982d156efce585bc540c16a926d4436712cf4baee0cce487a3d"}, - {file = "lxml-4.6.2-cp27-cp27m-win32.whl", hash = "sha256:bc4313cbeb0e7a416a488d72f9680fffffc645f8a838bd2193809881c67dd106"}, - {file = "lxml-4.6.2-cp27-cp27m-win_amd64.whl", hash = "sha256:8157dadbb09a34a6bd95a50690595e1fa0af1a99445e2744110e3dca7831c4ee"}, - {file = "lxml-4.6.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7728e05c35412ba36d3e9795ae8995e3c86958179c9770e65558ec3fdfd3724f"}, - {file = "lxml-4.6.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4bff24dfeea62f2e56f5bab929b4428ae6caba2d1eea0c2d6eb618e30a71e6d4"}, - {file = "lxml-4.6.2-cp35-cp35m-win32.whl", hash = "sha256:f2380a6376dfa090227b663f9678150ef27543483055cc327555fb592c5967e2"}, - {file = "lxml-4.6.2-cp35-cp35m-win_amd64.whl", hash = "sha256:c4f05c5a7c49d2fb70223d0d5bcfbe474cf928310ac9fa6a7c6dddc831d0b1d4"}, - {file = "lxml-4.6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d2e35d7bf1c1ac8c538f88d26b396e73dd81440d59c1ef8522e1ea77b345ede4"}, - {file = "lxml-4.6.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:289e9ca1a9287f08daaf796d96e06cb2bc2958891d7911ac7cae1c5f9e1e0ee3"}, - {file = "lxml-4.6.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bccbfc27563652de7dc9bdc595cb25e90b59c5f8e23e806ed0fd623755b6565d"}, - {file = "lxml-4.6.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:820628b7b3135403540202e60551e741f9b6d3304371712521be939470b454ec"}, - {file = "lxml-4.6.2-cp36-cp36m-win32.whl", hash = "sha256:5a0a14e264069c03e46f926be0d8919f4105c1623d620e7ec0e612a2e9bf1c04"}, - {file = "lxml-4.6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:92e821e43ad382332eade6812e298dc9701c75fe289f2a2d39c7960b43d1e92a"}, - {file = "lxml-4.6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:efd7a09678fd8b53117f6bae4fa3825e0a22b03ef0a932e070c0bdbb3a35e654"}, - {file = "lxml-4.6.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:efac139c3f0bf4f0939f9375af4b02c5ad83a622de52d6dfa8e438e8e01d0eb0"}, - {file = "lxml-4.6.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0fbcf5565ac01dff87cbfc0ff323515c823081c5777a9fc7703ff58388c258c3"}, - {file = "lxml-4.6.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:122fba10466c7bd4178b07dba427aa516286b846b2cbd6f6169141917283aae2"}, - {file = "lxml-4.6.2-cp37-cp37m-win32.whl", hash = "sha256:3439c71103ef0e904ea0a1901611863e51f50b5cd5e8654a151740fde5e1cade"}, - {file = "lxml-4.6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:4289728b5e2000a4ad4ab8da6e1db2e093c63c08bdc0414799ee776a3f78da4b"}, - {file = "lxml-4.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b007cbb845b28db4fb8b6a5cdcbf65bacb16a8bd328b53cbc0698688a68e1caa"}, - {file = "lxml-4.6.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:76fa7b1362d19f8fbd3e75fe2fb7c79359b0af8747e6f7141c338f0bee2f871a"}, - {file = "lxml-4.6.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:26e761ab5b07adf5f555ee82fb4bfc35bf93750499c6c7614bd64d12aaa67927"}, - {file = "lxml-4.6.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:66e575c62792c3f9ca47cb8b6fab9e35bab91360c783d1606f758761810c9791"}, - {file = "lxml-4.6.2-cp38-cp38-win32.whl", hash = "sha256:89b8b22a5ff72d89d48d0e62abb14340d9e99fd637d046c27b8b257a01ffbe28"}, - {file = "lxml-4.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:2a9d50e69aac3ebee695424f7dbd7b8c6d6eb7de2a2eb6b0f6c7db6aa41e02b7"}, - {file = "lxml-4.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ce256aaa50f6cc9a649c51be3cd4ff142d67295bfc4f490c9134d0f9f6d58ef0"}, - {file = "lxml-4.6.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:7610b8c31688f0b1be0ef882889817939490a36d0ee880ea562a4e1399c447a1"}, - {file = "lxml-4.6.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f8380c03e45cf09f8557bdaa41e1fa7c81f3ae22828e1db470ab2a6c96d8bc23"}, - {file = "lxml-4.6.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:884ab9b29feaca361f7f88d811b1eea9bfca36cf3da27768d28ad45c3ee6f969"}, - {file = "lxml-4.6.2-cp39-cp39-win32.whl", hash = "sha256:33bb934a044cf32157c12bfcfbb6649807da20aa92c062ef51903415c704704f"}, - {file = "lxml-4.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:542d454665a3e277f76954418124d67516c5f88e51a900365ed54a9806122b83"}, + {file = "lxml-4.6.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a9d6bc8642e2c67db33f1247a77c53476f3a166e09067c0474facb045756087f"}, + {file = "lxml-4.6.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:791394449e98243839fa822a637177dd42a95f4883ad3dec2a0ce6ac99fb0a9d"}, + {file = "lxml-4.6.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:68a5d77e440df94011214b7db907ec8f19e439507a70c958f750c18d88f995d2"}, + {file = "lxml-4.6.2-cp27-cp27m-win32.whl", hash = "sha256:fc37870d6716b137e80d19241d0e2cff7a7643b925dfa49b4c8ebd1295eb506e"}, + {file = "lxml-4.6.2-cp27-cp27m-win_amd64.whl", hash = "sha256:69a63f83e88138ab7642d8f61418cf3180a4d8cd13995df87725cb8b893e950e"}, + {file = "lxml-4.6.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:42ebca24ba2a21065fb546f3e6bd0c58c3fe9ac298f3a320147029a4850f51a2"}, + {file = "lxml-4.6.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f83d281bb2a6217cd806f4cf0ddded436790e66f393e124dfe9731f6b3fb9afe"}, + {file = "lxml-4.6.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:535f067002b0fd1a4e5296a8f1bf88193080ff992a195e66964ef2a6cfec5388"}, + {file = "lxml-4.6.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:366cb750140f221523fa062d641393092813b81e15d0e25d9f7c6025f910ee80"}, + {file = "lxml-4.6.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:97db258793d193c7b62d4e2586c6ed98d51086e93f9a3af2b2034af01450a74b"}, + {file = "lxml-4.6.2-cp35-cp35m-win32.whl", hash = "sha256:648914abafe67f11be7d93c1a546068f8eff3c5fa938e1f94509e4a5d682b2d8"}, + {file = "lxml-4.6.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4e751e77006da34643ab782e4a5cc21ea7b755551db202bc4d3a423b307db780"}, + {file = "lxml-4.6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:681d75e1a38a69f1e64ab82fe4b1ed3fd758717bed735fb9aeaa124143f051af"}, + {file = "lxml-4.6.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:127f76864468d6630e1b453d3ffbbd04b024c674f55cf0a30dc2595137892d37"}, + {file = "lxml-4.6.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4fb85c447e288df535b17ebdebf0ec1cf3a3f1a8eba7e79169f4f37af43c6b98"}, + {file = "lxml-4.6.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:5be4a2e212bb6aa045e37f7d48e3e1e4b6fd259882ed5a00786f82e8c37ce77d"}, + {file = "lxml-4.6.2-cp36-cp36m-win32.whl", hash = "sha256:8c88b599e226994ad4db29d93bc149aa1aff3dc3a4355dd5757569ba78632bdf"}, + {file = "lxml-4.6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:6e4183800f16f3679076dfa8abf2db3083919d7e30764a069fb66b2b9eff9939"}, + {file = "lxml-4.6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d8d3d4713f0c28bdc6c806a278d998546e8efc3498949e3ace6e117462ac0a5e"}, + {file = "lxml-4.6.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8246f30ca34dc712ab07e51dc34fea883c00b7ccb0e614651e49da2c49a30711"}, + {file = "lxml-4.6.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:923963e989ffbceaa210ac37afc9b906acebe945d2723e9679b643513837b089"}, + {file = "lxml-4.6.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:1471cee35eba321827d7d53d104e7b8c593ea3ad376aa2df89533ce8e1b24a01"}, + {file = "lxml-4.6.2-cp37-cp37m-win32.whl", hash = "sha256:2363c35637d2d9d6f26f60a208819e7eafc4305ce39dc1d5005eccc4593331c2"}, + {file = "lxml-4.6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:f4822c0660c3754f1a41a655e37cb4dbbc9be3d35b125a37fab6f82d47674ebc"}, + {file = "lxml-4.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0448576c148c129594d890265b1a83b9cd76fd1f0a6a04620753d9a6bcfd0a4d"}, + {file = "lxml-4.6.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:60a20bfc3bd234d54d49c388950195d23a5583d4108e1a1d47c9eef8d8c042b3"}, + {file = "lxml-4.6.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2e5cc908fe43fe1aa299e58046ad66981131a66aea3129aac7770c37f590a644"}, + {file = "lxml-4.6.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:50c348995b47b5a4e330362cf39fc503b4a43b14a91c34c83b955e1805c8e308"}, + {file = "lxml-4.6.2-cp38-cp38-win32.whl", hash = "sha256:94d55bd03d8671686e3f012577d9caa5421a07286dd351dfef64791cf7c6c505"}, + {file = "lxml-4.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:7a7669ff50f41225ca5d6ee0a1ec8413f3a0d8aa2b109f86d540887b7ec0d72a"}, + {file = "lxml-4.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e0bfe9bb028974a481410432dbe1b182e8191d5d40382e5b8ff39cdd2e5c5931"}, + {file = "lxml-4.6.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:6fd8d5903c2e53f49e99359b063df27fdf7acb89a52b6a12494208bf61345a03"}, + {file = "lxml-4.6.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7e9eac1e526386df7c70ef253b792a0a12dd86d833b1d329e038c7a235dfceb5"}, + {file = "lxml-4.6.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:7ee8af0b9f7de635c61cdd5b8534b76c52cd03536f29f51151b377f76e214a1a"}, + {file = "lxml-4.6.2-cp39-cp39-win32.whl", hash = "sha256:2e6fd1b8acd005bd71e6c94f30c055594bbd0aa02ef51a22bbfa961ab63b2d75"}, + {file = "lxml-4.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:535332fe9d00c3cd455bd3dd7d4bacab86e2d564bdf7606079160fa6251caacf"}, + {file = "lxml-4.6.2.tar.gz", hash = "sha256:cd11c7e8d21af997ee8079037fff88f16fda188a9776eb4b81c7e4c9c0a7d7fc"}, ] markdown = [ {file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"}, @@ -1552,6 +1578,21 @@ py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, ] +pyasn1 = [ + {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, + {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, + {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, + {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, + {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, + {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, + {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, + {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, + {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, + {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, + {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, + {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, +] pycparser = [ {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, @@ -1588,10 +1629,6 @@ pyhumps = [ {file = "pyhumps-1.6.1-py3-none-any.whl", hash = "sha256:58b367b73c57b64e32d211dc769addabd68ff6db07ce64b2e6565f7d5a12291f"}, {file = "pyhumps-1.6.1.tar.gz", hash = "sha256:01612603c5ad73a407299d806d30708a3935052276fdd93776953bccc0724e0a"}, ] -pyjwt = [ - {file = "PyJWT-2.0.1-py3-none-any.whl", hash = "sha256:b70b15f89dc69b993d8a8d32c299032d5355c82f9b5b7e851d1a6d706dffe847"}, - {file = "PyJWT-2.0.1.tar.gz", hash = "sha256:a5c70a06e1f33d81ef25eecd50d50bd30e34de1ca8b2b9fa3fe0daaabcf69bf7"}, -] pylint = [ {file = "pylint-2.7.2-py3-none-any.whl", hash = "sha256:d09b0b07ba06bcdff463958f53f23df25e740ecd81895f7d2699ec04bbd8dc3b"}, {file = "pylint-2.7.2.tar.gz", hash = "sha256:0e21d3b80b96740909d77206d741aa3ce0b06b41be375d92e1f3244a274c1f8a"}, @@ -1620,6 +1657,10 @@ python-dotenv = [ {file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"}, {file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"}, ] +python-jose = [ + {file = "python-jose-3.2.0.tar.gz", hash = "sha256:4e4192402e100b5fb09de5a8ea6bcc39c36ad4526341c123d401e2561720335b"}, + {file = "python_jose-3.2.0-py2.py3-none-any.whl", hash = "sha256:67d7dfff599df676b04a996520d9be90d6cdb7e6dd10b4c7cacc0c3e2e92f2be"}, +] python-multipart = [ {file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"}, ] @@ -1707,6 +1748,10 @@ requests = [ {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, ] +rsa = [ + {file = "rsa-4.7.2-py3-none-any.whl", hash = "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2"}, + {file = "rsa-4.7.2.tar.gz", hash = "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9"}, +] scrape-schema-recipe = [ {file = "scrape-schema-recipe-0.1.3.tar.gz", hash = "sha256:f5c9bdbdb254ac4ca008e4233afd38308cf9877fc9399643d03087df0d950aea"}, {file = "scrape_schema_recipe-0.1.3-py2.py3-none-any.whl", hash = "sha256:7a505d7cd94091ffdfcbac0fad21dd583cceee2d9c7ea12366e8fefac8b4da82"}, diff --git a/pyproject.toml b/pyproject.toml index 85d867cb6..bfea02674 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,9 +25,10 @@ PyYAML = "^5.3.1" extruct = "^0.12.0" scrape-schema-recipe = "^0.1.3" python-multipart = "^0.0.5" -fastapi-login = "^1.5.3" fastapi-camelcase = "^1.0.2" bcrypt = "^3.2.0" +python-jose = "^3.2.0" +passlib = "^1.7.4" [tool.poetry.dev-dependencies] pylint = "^2.6.0" diff --git a/tests/conftest.py b/tests/conftest.py index 9e4f208aa..d3f202887 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,12 +1,16 @@ import json import requests +from fastapi.testclient import TestClient from mealie.app import app from mealie.core.config import SQLITE_DIR +from mealie.db.database import db from mealie.db.db_setup import generate_session, sql_global_init from mealie.db.init_db import init_db -from fastapi.testclient import TestClient +from mealie.routes.deps import get_current_user +from mealie.schema.user import UserInDB from pytest import fixture +from sqlalchemy.orm.session import Session from tests.test_config import TEST_DATA @@ -42,7 +46,7 @@ def test_image(): return TEST_DATA.joinpath("test_image.jpg") -@fixture(scope="function") +@fixture(scope="session") def token(api_client: requests): form_data = {"username": "changeme@email.com", "password": "MyPassword"} response = api_client.post(TOKEN_URL, form_data) diff --git a/tests/test_routes/test_meal_routes.py b/tests/test_routes/test_meal_routes.py index 01d044629..f1a478cac 100644 --- a/tests/test_routes/test_meal_routes.py +++ b/tests/test_routes/test_meal_routes.py @@ -23,9 +23,6 @@ def get_meal_plan_template(first=None, second=None): } -## Meal Routes - - @pytest.fixture def slug_1(api_client): # Slug 1 @@ -50,9 +47,7 @@ def slug_2(api_client): def test_create_mealplan(api_client, slug_1, slug_2, token): - meal_plan = get_meal_plan_template() - meal_plan["meals"][0]["slug"] = slug_1 - meal_plan["meals"][1]["slug"] = slug_2 + meal_plan = get_meal_plan_template(slug_1, slug_2) response = api_client.post(MEALPLAN_CREATE, json=meal_plan, headers=token) assert response.status_code == 200 diff --git a/tests/test_routes/test_user_routes.py b/tests/test_routes/test_user_routes.py index 34eddd5ab..db3ba1c03 100644 --- a/tests/test_routes/test_user_routes.py +++ b/tests/test_routes/test_user_routes.py @@ -17,14 +17,17 @@ def new_user(): return {"id": 2, "fullName": "My New User", "email": "newuser@email.com", "group": "Home", "admin": False} -def test_superuser_login(api_client: requests): +def test_superuser_login(api_client: requests, token): form_data = {"username": "changeme@email.com", "password": "MyPassword"} response = api_client.post(TOKEN_URL, form_data) assert response.status_code == 200 - token = json.loads(response.text).get("access_token") + new_token = json.loads(response.text).get("access_token") - return {"Authorization": f"Bearer {token}"} + response = api_client.get("/api/users/self", headers=token) + assert response.status_code == 200 + + return {"Authorization": f"Bearer {new_token}"} def test_init_superuser(api_client: requests, token, default_user): @@ -59,10 +62,11 @@ def test_get_all_users(api_client: requests, token, new_user, default_user): def test_update_user(api_client: requests, token): - update_data = {"id": 1, "fullName": "Updated Name", "email": "updated@email.com", "group": "Home", "admin": True} + update_data = {"id": 1, "fullName": "Updated Name", "email": "changeme@email.com", "group": "Home", "admin": True} response = api_client.put(f"{BASE}/1", headers=token, json=update_data) assert response.status_code == 200 + print(response.text) assert json.loads(response.text).get("access_token") diff --git a/tests/test_services/test_migrations/test_nextcloud.py b/tests/test_services/test_migrations/test_nextcloud.py index 0f35b5d78..65fcdfed3 100644 --- a/tests/test_services/test_migrations/test_nextcloud.py +++ b/tests/test_services/test_migrations/test_nextcloud.py @@ -4,12 +4,7 @@ import pytest from mealie.core.config import TEMP_DIR from mealie.schema.recipe import Recipe from mealie.services.image_services import IMG_DIR -from mealie.services.migrations.nextcloud import ( - cleanup, - import_recipes, - prep, - process_selection, -) +from mealie.services.migrations.nextcloud import cleanup, import_recipes, prep, process_selection from tests.test_config import TEST_NEXTCLOUD_DIR CWD = Path(__file__).parent