From 2b868f96059992b5a515e1f2246664097b0e5096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nero=20Blackstone=E2=80=8B?= Date: Wed, 11 Dec 2024 19:48:37 +0800 Subject: [PATCH 1/4] Update README.md Add scope variable hint. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b97b603..72d7976 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,8 @@ OIDC_DISCOVERY_URL = 'https://.okta.com/.well-known/openid-configur OIDC_CLIENT_SECRET ='' OIDC_CLIENT_ID ='' OIDC_PROVIDER_DISPLAY_NAME = "Login with Okta" +# Please note that for some OAuth2 providers like GitLab, use spaces instead of commas to separate scopes. +# If there is a scope-related error, please confirm the string format OIDC_SCOPE = "openid,profile,email,groups" OIDC_GROUP_NAME = "mlflow-users-group-name" OIDC_ADMIN_GROUP_NAME = "mlflow-admin-group-name" From 29239941b59c23a033d098c080527392c65b66cd Mon Sep 17 00:00:00 2001 From: NeroBlackstone Date: Thu, 12 Dec 2024 09:00:23 +0800 Subject: [PATCH 2/4] update docs --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 72d7976..e04b233 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,6 @@ OIDC_DISCOVERY_URL = 'https://.okta.com/.well-known/openid-configur OIDC_CLIENT_SECRET ='' OIDC_CLIENT_ID ='' OIDC_PROVIDER_DISPLAY_NAME = "Login with Okta" -# Please note that for some OAuth2 providers like GitLab, use spaces instead of commas to separate scopes. -# If there is a scope-related error, please confirm the string format OIDC_SCOPE = "openid,profile,email,groups" OIDC_GROUP_NAME = "mlflow-users-group-name" OIDC_ADMIN_GROUP_NAME = "mlflow-admin-group-name" @@ -83,6 +81,8 @@ OIDC_ADMIN_GROUP_NAME = "mlflow_admins_group_name" > please note, that for getting group membership information, the application should have "GroupMember.Read.All" permission +> Please note that for some OAuth2 providers like GitLab, use spaces instead of commas to separate scopes. If there is a scope-related error, please confirm the string format. + # Development Preconditions: From 60b4fa0b0a562b209e989fadb263558349606c11 Mon Sep 17 00:00:00 2001 From: NeroBlackstone Date: Thu, 12 Dec 2024 16:31:03 +0800 Subject: [PATCH 3/4] add some features --- README.md | 1 + mlflow_oidc_auth/config.py | 3 ++- mlflow_oidc_auth/string_utils.py | 13 ++++++++++ mlflow_oidc_auth/views/authentication.py | 11 +++++--- scripts/init-dev-env.sh | 33 ++++++++++++++++++++++++ web-ui/src/styles.scss | 2 +- 6 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 mlflow_oidc_auth/string_utils.py create mode 100755 scripts/init-dev-env.sh diff --git a/README.md b/README.md index e04b233..039d0ea 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ The plugin required the following environment variables but also supported `.env | OIDC_SCOPE | OIDC scope | | OIDC_GROUP_NAME | User group name to be allowed login to MLFlow, currently supported groups in OIDC claims and Microsoft Entra ID groups | | OIDC_ADMIN_GROUP_NAME | User group name to be allowed login to MLFlow manage and define permissions, currently supported groups in OIDC claims and Microsoft Entra ID groups | +| OIDC_ALLOW_ALL_USERS | Allow all users to log in, even if they are not in OIDC_ADMIN_GROUP_NAME and OIDC_GROUP_NAME | | OIDC_AUTHORIZATION_URL | OIDC Auth URL (if discovery URL is not defined) | | OIDC_TOKEN_URL | OIDC Token URL (if discovery URL is not defined) | | OIDC_USER_URL | OIDC User info URL (if discovery URL is not defined) | diff --git a/mlflow_oidc_auth/config.py b/mlflow_oidc_auth/config.py index bf8f135..691d215 100644 --- a/mlflow_oidc_auth/config.py +++ b/mlflow_oidc_auth/config.py @@ -1,11 +1,11 @@ import os import secrets -import requests import secrets import importlib from dotenv import load_dotenv from mlflow.server import app +from mlflow_oidc_auth.string_utils import strtobool load_dotenv() # take environment variables from .env. app.logger.setLevel(os.environ.get("LOG_LEVEL", "INFO")) @@ -25,6 +25,7 @@ def __init__(self): self.OIDC_REDIRECT_URI = os.environ.get("OIDC_REDIRECT_URI", None) self.OIDC_CLIENT_ID = os.environ.get("OIDC_CLIENT_ID", None) self.OIDC_CLIENT_SECRET = os.environ.get("OIDC_CLIENT_SECRET", None) + self.OIDC_ALLOW_ALL_USERS = bool(strtobool(os.environ.get("OIDC_ALLOW_ALL_USERS", "False"))) # session self.SESSION_TYPE = os.environ.get("SESSION_TYPE", "cachelib") diff --git a/mlflow_oidc_auth/string_utils.py b/mlflow_oidc_auth/string_utils.py new file mode 100644 index 0000000..ea8bfab --- /dev/null +++ b/mlflow_oidc_auth/string_utils.py @@ -0,0 +1,13 @@ +def strtobool(val): + """Convert a string representation of truth to true (1) or false (0). + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + """ + val = val.lower() + if val in ('y', 'yes', 't', 'true', 'on', '1'): + return 1 + elif val in ('n', 'no', 'f', 'false', 'off', '0'): + return 0 + else: + raise ValueError("invalid truth value %r" % (val,)) \ No newline at end of file diff --git a/mlflow_oidc_auth/views/authentication.py b/mlflow_oidc_auth/views/authentication.py index 08ab3c0..2997c3b 100644 --- a/mlflow_oidc_auth/views/authentication.py +++ b/mlflow_oidc_auth/views/authentication.py @@ -44,14 +44,19 @@ def callback(): token["access_token"] ) else: - user_groups = token["userinfo"][config.OIDC_GROUPS_ATTRIBUTE] + try: + user_groups = token["userinfo"][config.OIDC_GROUPS_ATTRIBUTE] + except KeyError: + user_groups = [] app.logger.debug(f"User groups: {user_groups}") + app.logger.debug(f"OIDC_ALLOW_ALL_USERS:{config.OIDC_ALLOW_ALL_USERS}") if config.OIDC_ADMIN_GROUP_NAME in user_groups: is_admin = True - elif not any(group in user_groups for group in config.OIDC_GROUP_NAME): - return "User is not allowed to login", 401 + elif not config.OIDC_ALLOW_ALL_USERS: + if not any(group in user_groups for group in config.OIDC_GROUP_NAME): + return "The user is not in any group that is allowed to access, so login is not allowed.", 401 create_user(username=email.lower(), display_name=display_name, is_admin=is_admin) populate_groups(group_names=user_groups) diff --git a/scripts/init-dev-env.sh b/scripts/init-dev-env.sh new file mode 100755 index 0000000..87ab9c9 --- /dev/null +++ b/scripts/init-dev-env.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Script to initialize/reset the development environment + +# Remove auth database +if [ -f "auth.db" ]; then + rm auth.db + echo "Removed auth.db" +fi + +# Remove Flask session cache +if [ -d "/tmp/flask_session" ]; then + rm -rf /tmp/flask_session/* + echo "Cleared /tmp/flask_session" +fi + +# Remove Flask session cache +if [ -d "/tmp/flask_cache/" ]; then + rm -rf /tmp/flask_cache/* + echo "Cleared /tmp/flask_cache/" +fi + +# Remove MLflow runs +if [ -d "mlruns" ]; then + rm -rf mlruns + echo "Removed mlruns directory" +fi + +# Optional: Recreate necessary directories +mkdir -p /tmp/flask_session +mkdir -p /tmp/flask_cache/ + +echo "Environment initialization complete." \ No newline at end of file diff --git a/web-ui/src/styles.scss b/web-ui/src/styles.scss index f222408..4b2aadb 100644 --- a/web-ui/src/styles.scss +++ b/web-ui/src/styles.scss @@ -4,4 +4,4 @@ html, body { height: 100%; } body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } /* Importing Bootstrap SCSS file. */ -@import '~bootstrap/scss/bootstrap'; +@import 'bootstrap/scss/bootstrap'; From 0cd237e628c92e2529ee0afca36cdf1be9245040 Mon Sep 17 00:00:00 2001 From: NeroBlackstone Date: Thu, 12 Dec 2024 16:58:41 +0800 Subject: [PATCH 4/4] add docs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 039d0ea..09deabb 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ The plugin required the following environment variables but also supported `.env | OIDC_GROUP_DETECTION_PLUGIN | OIDC plugin to detect groups | | OIDC_PROVIDER_DISPLAY_NAME | any text to display | | OIDC_SCOPE | OIDC scope | +| OIDC_GROUPS_ATTRIBUTE | If the group name field in userinfo is not `groups`, specify its json key | | OIDC_GROUP_NAME | User group name to be allowed login to MLFlow, currently supported groups in OIDC claims and Microsoft Entra ID groups | | OIDC_ADMIN_GROUP_NAME | User group name to be allowed login to MLFlow manage and define permissions, currently supported groups in OIDC claims and Microsoft Entra ID groups | | OIDC_ALLOW_ALL_USERS | Allow all users to log in, even if they are not in OIDC_ADMIN_GROUP_NAME and OIDC_GROUP_NAME |