feat: Login with OAuth via OpenID Connect (OIDC) (#3280)

* initial oidc implementation

* add dynamic scheme

* e2e test setup

* add caching

* fix

* try this

* add libldap-2.5 to runtime dependencies (#2849)

* New translations en-us.json (Norwegian) (#2851)

* New Crowdin updates (#2855)

* New translations en-us.json (Italian)

* New translations en-us.json (Norwegian)

* New translations en-us.json (Portuguese)

* fix

* remove cache

* cache yarn deps

* cache docker image

* cleanup action

* lint

* fix tests

* remove not needed variables

* run code gen

* fix tests

* add docs

* move code into custom scheme

* remove unneeded type

* fix oidc admin

* add more tests

* add better spacing on login page

* create auth providers

* clean up testing stuff

* type fixes

* add OIDC auth method to postgres enum

* add option to bypass login screen and go directly to iDP

* remove check so we can fallback to another auth method oauth fails

* Add provider name to be shown at the login screen

* add new properties to admin about api

* fix spec

* add a prompt to change auth method when changing password

* Create new auth section. Add more info on auth methods

* update docs

* run ruff

* update docs

* format

* docs gen

* formatting

* initialize logger in class

* mypy type fixes

* docs gen

* add models to get proper fields in docs and fix serialization

* validate id token before using it

* only request a mealie token on initial callback

* remove unused method

* fix unit tests

* docs gen

* check for valid idToken before getting token

* add iss to mealie token

* check to see if we already have a mealie token before getting one

* fix lock file

* update authlib

* update lock file

* add remember me environment variable

* add user group setting to allow only certain groups to log in

---------

Co-authored-by: Carter Mintey <cmintey8@gmail.com>
Co-authored-by: Carter <35710697+cmintey@users.noreply.github.com>
This commit is contained in:
Hayden
2024-03-10 13:51:36 -05:00
committed by GitHub
parent bea1a592d7
commit 5f6844eceb
53 changed files with 1533 additions and 400 deletions

View File

@@ -10,6 +10,7 @@ from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from sqlalchemy.orm.session import Session
from mealie.core import root_logger
from mealie.core.config import get_app_dirs, get_app_settings
from mealie.db.db_setup import generate_session
from mealie.repos.all_repositories import get_repositories
@@ -21,6 +22,13 @@ oauth2_scheme_soft_fail = OAuth2PasswordBearer(tokenUrl="/api/auth/token", auto_
ALGORITHM = "HS256"
app_dirs = get_app_dirs()
settings = get_app_settings()
logger = root_logger.get_logger("dependencies")
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
async def is_logged_in(token: str = Depends(oauth2_scheme_soft_fail), session=Depends(generate_session)) -> bool:
@@ -76,13 +84,10 @@ async def try_get_current_user(
async def get_current_user(
request: Request, token: str | None = Depends(oauth2_scheme_soft_fail), session=Depends(generate_session)
request: Request,
token: str | None = Depends(oauth2_scheme_soft_fail),
session=Depends(generate_session),
) -> PrivateUser:
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
if token is None and "mealie.access_token" in request.cookies:
# Try extract from cookie
token = request.cookies.get("mealie.access_token", "")
@@ -117,12 +122,6 @@ async def get_current_user(
async def get_integration_id(token: str = Depends(oauth2_scheme)) -> str:
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
decoded_token = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
return decoded_token.get("integration_id", DEFAULT_INTEGRATION_ID)