From 8e249a2afe125c55e07b623859ea055648d1b766 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 3 Feb 2025 10:09:42 -0300 Subject: [PATCH 1/4] feat: add option to disable automatic superuser creation --- src/backend/base/langflow/services/settings/auth.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backend/base/langflow/services/settings/auth.py b/src/backend/base/langflow/services/settings/auth.py index 25dd338ab895..8d1cb8779ca2 100644 --- a/src/backend/base/langflow/services/settings/auth.py +++ b/src/backend/base/langflow/services/settings/auth.py @@ -54,6 +54,9 @@ class AuthSettings(BaseSettings): model_config = SettingsConfigDict(validate_assignment=True, extra="ignore", env_prefix="LANGFLOW_") + disable_superuser_creation: bool = False + """If True, the superuser will not be created automatically.""" + def reset_credentials(self) -> None: self.SUPERUSER = DEFAULT_SUPERUSER self.SUPERUSER_PASSWORD = DEFAULT_SUPERUSER_PASSWORD From 6936452ef59d58c9cae6343d6959af6357054294 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 3 Feb 2025 10:09:53 -0300 Subject: [PATCH 2/4] fix: remove superuser initialization from main flow --- src/backend/base/langflow/main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/backend/base/langflow/main.py b/src/backend/base/langflow/main.py index 172837b4c817..e6557fc063e6 100644 --- a/src/backend/base/langflow/main.py +++ b/src/backend/base/langflow/main.py @@ -26,7 +26,6 @@ from langflow.api import health_check_router, log_router, router from langflow.initial_setup.setup import ( create_or_update_starter_projects, - initialize_super_user_if_needed, load_bundles_from_urls, load_flows_from_directory, ) @@ -120,7 +119,6 @@ async def lifespan(_app: FastAPI): try: await initialize_services(fix_migration=fix_migration) setup_llm_caching() - await initialize_super_user_if_needed() temp_dirs, bundles_components_paths = await load_bundles_with_error_handling() get_settings_service().settings.components_path.extend(bundles_components_paths) all_types_dict = await get_and_cache_all_types_dict(get_settings_service()) From 98e4c4139882c98bf76d51ae0ec0065ae1502a00 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 3 Feb 2025 10:10:12 -0300 Subject: [PATCH 3/4] refactor: streamline superuser initialization process and update related tests --- .../base/langflow/initial_setup/setup.py | 30 ++--------------- src/backend/base/langflow/services/utils.py | 33 ++++++++++++++++--- .../tests/performance/test_server_init.py | 3 +- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/backend/base/langflow/initial_setup/setup.py b/src/backend/base/langflow/initial_setup/setup.py index 481f3169d6f1..eddc8fada5c1 100644 --- a/src/backend/base/langflow/initial_setup/setup.py +++ b/src/backend/base/langflow/initial_setup/setup.py @@ -27,20 +27,11 @@ from langflow.base.constants import FIELD_FORMAT_ATTRIBUTES, NODE_FORMAT_ATTRIBUTES, ORJSON_OPTIONS from langflow.initial_setup.constants import STARTER_FOLDER_DESCRIPTION, STARTER_FOLDER_NAME -from langflow.services.auth.utils import create_super_user from langflow.services.database.models.flow.model import Flow, FlowCreate from langflow.services.database.models.folder.model import Folder, FolderCreate -from langflow.services.database.models.folder.utils import ( - create_default_folder_if_it_doesnt_exist, - get_default_folder_id, -) +from langflow.services.database.models.folder.utils import get_default_folder_id from langflow.services.database.models.user.crud import get_user_by_username -from langflow.services.deps import ( - get_settings_service, - get_storage_service, - get_variable_service, - session_scope, -) +from langflow.services.deps import get_settings_service, get_storage_service, session_scope from langflow.template.field.prompt import DEFAULT_PROMPT_INTUT_TYPES from langflow.utils.util import escape_json_dump @@ -763,20 +754,3 @@ async def create_or_update_starter_projects(all_types_dict: dict, *, do_create: project_tags=project_tags, new_folder_id=new_folder.id, ) - - -async def initialize_super_user_if_needed() -> None: - settings_service = get_settings_service() - if not settings_service.auth_settings.AUTO_LOGIN: - return - username = settings_service.auth_settings.SUPERUSER - password = settings_service.auth_settings.SUPERUSER_PASSWORD - if not username or not password: - msg = "SUPERUSER and SUPERUSER_PASSWORD must be set in the settings if AUTO_LOGIN is true." - raise ValueError(msg) - - async with session_scope() as async_session: - super_user = await create_super_user(db=async_session, username=username, password=password) - await get_variable_service().initialize_user_variables(super_user.id, async_session) - await create_default_folder_if_it_doesnt_exist(async_session, super_user.id) - logger.info("Super user initialized") diff --git a/src/backend/base/langflow/services/utils.py b/src/backend/base/langflow/services/utils.py index d207e3c5322e..750597c1e18d 100644 --- a/src/backend/base/langflow/services/utils.py +++ b/src/backend/base/langflow/services/utils.py @@ -7,20 +7,24 @@ from sqlalchemy import delete from sqlalchemy import exc as sqlalchemy_exc from sqlmodel import col, select +from sqlmodel.ext.asyncio.session import AsyncSession from langflow.services.auth.utils import create_super_user, verify_password from langflow.services.cache.factory import CacheServiceFactory +from langflow.services.database.models.folder.utils import create_default_folder_if_it_doesnt_exist from langflow.services.database.models.transactions.model import TransactionTable from langflow.services.database.models.vertex_builds.model import VertexBuildTable from langflow.services.database.utils import initialize_database from langflow.services.schema import ServiceType from langflow.services.settings.constants import DEFAULT_SUPERUSER, DEFAULT_SUPERUSER_PASSWORD +from langflow.services.settings.manager import SettingsService -from .deps import get_db_service, get_service, get_settings_service +from .deps import get_db_service, get_service, get_settings_service, get_variable_service if TYPE_CHECKING: from sqlmodel.ext.asyncio.session import AsyncSession + from langflow.services.database.models.user.model import User from langflow.services.settings.manager import SettingsService @@ -75,7 +79,7 @@ async def get_or_create_super_user(session: AsyncSession, username, password, is logger.opt(exception=True).debug("Error creating superuser.") -async def setup_superuser(settings_service, session: AsyncSession) -> None: +async def setup_superuser(settings_service, session: AsyncSession) -> User: if settings_service.auth_settings.AUTO_LOGIN: logger.debug("AUTO_LOGIN is set to True. Creating default superuser.") else: @@ -86,7 +90,7 @@ async def setup_superuser(settings_service, session: AsyncSession) -> None: password = settings_service.auth_settings.SUPERUSER_PASSWORD is_default = (username == DEFAULT_SUPERUSER) and (password == DEFAULT_SUPERUSER_PASSWORD) - + user = None try: user = await get_or_create_super_user( session=session, username=username, password=password, is_default=is_default @@ -99,6 +103,7 @@ async def setup_superuser(settings_service, session: AsyncSession) -> None: raise RuntimeError(msg) from exc finally: settings_service.auth_settings.reset_credentials() + return user async def teardown_superuser(settings_service, session: AsyncSession) -> None: @@ -226,6 +231,26 @@ async def clean_vertex_builds(settings_service: SettingsService, session: AsyncS # Don't re-raise since this is a cleanup task +async def initialize_super_user_if_needed( + settings_service: SettingsService | None = None, session: AsyncSession | None = None +) -> None: + if settings_service is None: + settings_service = get_settings_service() + if not settings_service.auth_settings.AUTO_LOGIN or settings_service.auth_settings.DISABLE_SUPERUSER_CREATION: + return + username = settings_service.auth_settings.SUPERUSER + password = settings_service.auth_settings.SUPERUSER_PASSWORD + if not username or not password: + msg = "SUPERUSER and SUPERUSER_PASSWORD must be set in the settings if AUTO_LOGIN is true." + raise ValueError(msg) + user = await setup_superuser(settings_service, session) + if user is None: + return + await get_variable_service().initialize_user_variables(user.id, session) + await create_default_folder_if_it_doesnt_exist(session, user.id) + logger.info("Super user initialized") + + async def initialize_services(*, fix_migration: bool = False) -> None: """Initialize all the services needed.""" # Test cache connection @@ -236,7 +261,7 @@ async def initialize_services(*, fix_migration: bool = False) -> None: await db_service.initialize_alembic_log_file() async with db_service.with_session() as session: settings_service = get_service(ServiceType.SETTINGS_SERVICE) - await setup_superuser(settings_service, session) + await initialize_super_user_if_needed(settings_service, session) try: await get_db_service().assign_orphaned_flows_to_superuser() except sqlalchemy_exc.IntegrityError as exc: diff --git a/src/backend/tests/performance/test_server_init.py b/src/backend/tests/performance/test_server_init.py index b3e7a3975a2a..6101173d792f 100644 --- a/src/backend/tests/performance/test_server_init.py +++ b/src/backend/tests/performance/test_server_init.py @@ -43,8 +43,7 @@ def test_setup_llm_caching(): async def test_initialize_super_user(): """Benchmark super user initialization.""" - from langflow.initial_setup.setup import initialize_super_user_if_needed - from langflow.services.utils import initialize_services + from langflow.services.utils import initialize_services, initialize_super_user_if_needed await initialize_services(fix_migration=False) await initialize_super_user_if_needed() From e52a97bcda128dc07cd8677c52b6673dfb0f887f Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 3 Feb 2025 10:39:31 -0300 Subject: [PATCH 4/4] fix: correct casing for disable_superuser_creation setting --- src/backend/base/langflow/services/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/base/langflow/services/utils.py b/src/backend/base/langflow/services/utils.py index 750597c1e18d..331e9bda7654 100644 --- a/src/backend/base/langflow/services/utils.py +++ b/src/backend/base/langflow/services/utils.py @@ -236,7 +236,7 @@ async def initialize_super_user_if_needed( ) -> None: if settings_service is None: settings_service = get_settings_service() - if not settings_service.auth_settings.AUTO_LOGIN or settings_service.auth_settings.DISABLE_SUPERUSER_CREATION: + if not settings_service.auth_settings.AUTO_LOGIN or settings_service.auth_settings.disable_superuser_creation: return username = settings_service.auth_settings.SUPERUSER password = settings_service.auth_settings.SUPERUSER_PASSWORD