Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
186 commits
Select commit Hold shift + click to select a range
1e82662
feat: Introduce service registration decorator and enhance ServiceMan…
ogabrielluiz Oct 3, 2025
31c1026
feat: Implement VariableService for managing environment variables
ogabrielluiz Oct 3, 2025
6c4e77b
feat: Enhance LocalStorageService with Service integration and async …
ogabrielluiz Oct 3, 2025
99a09a7
feat: Implement telemetry service with abstract base class and minima…
ogabrielluiz Oct 3, 2025
85f1bd3
feat: Introduce BaseTracingService and implement minimal TracingService
ogabrielluiz Oct 3, 2025
4523ab6
feat: Add unit tests for service registration decorators
ogabrielluiz Oct 3, 2025
4828597
feat: Add comprehensive unit and integration tests for ServiceManager
ogabrielluiz Oct 3, 2025
2e1748e
feat: Add unit and integration tests for minimal service implementations
ogabrielluiz Oct 3, 2025
d7985c3
docs: Add detailed documentation for pluggable services architecture …
ogabrielluiz Oct 3, 2025
64b81d3
feat: Add example configuration file for Langflow services
ogabrielluiz Oct 3, 2025
114bc8a
docs: Update PLUGGABLE_SERVICES.md to enhance architecture benefits s…
ogabrielluiz Oct 3, 2025
b537b88
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 30, 2025
5deb7d0
test(services): improve variable service teardown test with public AP…
ogabrielluiz Oct 30, 2025
3153dc7
docs(pluggable-service-layer): add docstrings for service manager and…
ogabrielluiz Oct 30, 2025
c66bac6
fix: remove duplicate teardown method from LocalStorageService
mpawlow Dec 17, 2025
af26cdc
fix(tests): update service tests for LocalStorageService constructor …
mpawlow Dec 17, 2025
6960fb0
fix(services): Harden service lifecycle methods
mpawlow Jan 13, 2026
a6b8dce
docs: Update discovery order for pluggable services
mpawlow Jan 13, 2026
cea85e6
fix(lfx): replace aiofile with aiofiles for CI compatibility
mpawlow Jan 14, 2026
a202a8b
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 15, 2026
4bf0d4a
fix(lfx): prevent race condition in plugin discovery
mpawlow Jan 15, 2026
2bff47e
Merge branch 'main' into pluggable-service-layer
HimavarshaVS Jan 16, 2026
4b2e19f
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 16, 2026
af29156
feat: Introduce service registration decorator and enhance ServiceMan…
ogabrielluiz Oct 3, 2025
926d776
feat: Enhance LocalStorageService with Service integration and async …
ogabrielluiz Oct 3, 2025
8e540c3
docs(pluggable-service-layer): add docstrings for service manager and…
ogabrielluiz Oct 30, 2025
0e9e2a7
feat(auth): implement abstract base class for authentication services…
ogabrielluiz Nov 24, 2025
8cfd393
refactor(auth): move authentication logic from utils to AuthService
ogabrielluiz Nov 24, 2025
96a8271
refactor(auth): update authentication methods and remove settings_ser…
ogabrielluiz Nov 24, 2025
ca12040
test(auth): add unit tests for AuthService and pluggable authentication
ogabrielluiz Nov 24, 2025
9645f99
fix(tests): update test cases to use AuthService and correct user ret…
ogabrielluiz Nov 24, 2025
7471bd7
docs(pluggable-services): add auth_service to ServiceType enum docume…
ogabrielluiz Nov 24, 2025
08e96ef
fix(auth): Add missing type hints and abstract methods to AuthService…
Copilot Nov 25, 2025
0b46428
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 25, 2025
f18875c
fix(auth): refactor api_key_security method to accept optional databa…
ogabrielluiz Nov 27, 2025
ed4660c
feat(auth): enhance AuthServiceBase with detailed design principles a…
ogabrielluiz Nov 27, 2025
e09db9b
fix(auth): remove settings_service from encrypt/decrypt_api_key calls
ogabrielluiz Nov 27, 2025
1755c11
fix(auth): resolve type errors and duplicate definitions in pluggable…
mpawlow Jan 15, 2026
09c16b7
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 15, 2026
77320af
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Jan 15, 2026
96b6ece
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Jan 16, 2026
f65bd6c
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Jan 19, 2026
f513600
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 19, 2026
3f686a2
replace jose with pyjwt
HimavarshaVS Jan 20, 2026
cc4c2d2
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 20, 2026
dd0b8f2
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Jan 20, 2026
cd653f8
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 20, 2026
02d0bf2
starter projects
HimavarshaVS Jan 20, 2026
78f0cc9
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 20, 2026
b2eea5f
fix BE mcp tests
HimavarshaVS Jan 20, 2026
b8d0ebe
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 20, 2026
e4351f2
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Jan 20, 2026
1241a29
remive legacy usage of session
HimavarshaVS Jan 20, 2026
712133f
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 20, 2026
f27c8a6
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Jan 20, 2026
33eca67
fix user tests
HimavarshaVS Jan 21, 2026
cee558e
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 21, 2026
0fc1b2a
fix lfx tests
HimavarshaVS Jan 21, 2026
c767d34
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 21, 2026
0774aec
starter project update
HimavarshaVS Jan 21, 2026
ba83b87
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 21, 2026
932fee3
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Jan 21, 2026
c92be1b
fix mypy errors
HimavarshaVS Jan 21, 2026
4c6dc3c
fix mypy errors on tests
HimavarshaVS Jan 21, 2026
d70c9c5
fix tests for decrypt_api_key
HimavarshaVS Jan 21, 2026
08c6cd9
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Jan 21, 2026
6efb8e1
resolve conflicts in auth utils
HimavarshaVS Jan 21, 2026
29bba6a
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 21, 2026
dc4f9fe
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Jan 21, 2026
2077da4
Merge branch 'main' of https://github.com/langflow-ai/langflow into p…
deon-sanchez Jan 21, 2026
ec7888b
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 21, 2026
28d702c
Add pluggable authentication factory with provider enum
HimavarshaVS Jan 21, 2026
cfa64c7
Add SSO feature flags to AuthSettings
HimavarshaVS Jan 21, 2026
73199a0
Add SSO fields to User model
HimavarshaVS Jan 21, 2026
911e0bd
Add SSO configuration loader with YAML support
HimavarshaVS Jan 21, 2026
283110d
Add unit tests for SSO configuration loader
HimavarshaVS Jan 21, 2026
254b6cc
Add SSO configuration database model and CRUD operations
HimavarshaVS Jan 21, 2026
4d93536
Add CRUD operations for SSO configuration management
HimavarshaVS Jan 21, 2026
22309cd
Add SSO configuration service supporting both file and database configs
HimavarshaVS Jan 21, 2026
fe5ae54
Add example SSO configuration file with W3ID and other providers
HimavarshaVS Jan 21, 2026
ae4b6b9
Implement OIDC authentication service with discovery and JIT provisio…
HimavarshaVS Jan 21, 2026
b718486
Update AuthServiceFactory to instantiate OIDC service when SSO enabled
HimavarshaVS Jan 21, 2026
629b97e
Improve JWT token validation and API key decryption error handling
HimavarshaVS Jan 21, 2026
de6e7f4
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 21, 2026
8e01b35
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 21, 2026
bd103a0
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 22, 2026
92f5290
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 22, 2026
7315a45
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 22, 2026
71e10fb
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 22, 2026
21beb66
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 22, 2026
efc044b
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 23, 2026
9ca4e48
fix: resolve ruff linting errors in auth services and add sso-config.…
HimavarshaVS Jan 23, 2026
ca80827
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 23, 2026
fee36b5
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 23, 2026
f849e5d
fix: use correct function name get_current_user_from_access_token in …
HimavarshaVS Jan 23, 2026
08a8f13
fix: remove incorrect settings_service parameter from decrypt_api_key…
HimavarshaVS Jan 23, 2026
3e91f82
fix: correct encryption logic to properly detect plaintext vs encrypt…
HimavarshaVS Jan 23, 2026
36b369d
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 23, 2026
33bd533
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Jan 30, 2026
0f07712
fix tests
HimavarshaVS Jan 30, 2026
e6be23e
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 30, 2026
23815a8
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 30, 2026
5beb52b
fix mypy errors
HimavarshaVS Jan 30, 2026
367366c
fix tests
HimavarshaVS Jan 30, 2026
2297df2
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 30, 2026
646c004
fix ruff errors
HimavarshaVS Jan 30, 2026
364d591
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 30, 2026
9e8d4be
fix tests in service
HimavarshaVS Jan 30, 2026
22731b7
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 30, 2026
e1ea988
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 30, 2026
f29061b
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 30, 2026
f9fd699
fix test security cors
HimavarshaVS Jan 30, 2026
2bd9644
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 30, 2026
5d6e188
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 30, 2026
421b5ee
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 30, 2026
cf6d41b
fix webhook issues
HimavarshaVS Jan 30, 2026
fe74901
modify component index
HimavarshaVS Jan 30, 2026
a230293
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Jan 30, 2026
b95461e
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 30, 2026
165e2f8
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Jan 30, 2026
12f5240
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Jan 30, 2026
c550ea1
fix webhook tests
HimavarshaVS Jan 30, 2026
2b0dd21
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 30, 2026
5974e64
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 30, 2026
fea2293
build component index
HimavarshaVS Jan 30, 2026
87ca961
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 30, 2026
61a166d
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 30, 2026
1d79e2d
remove SSO functionality
HimavarshaVS Jan 30, 2026
7d627ce
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Jan 30, 2026
a96530a
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 31, 2026
557b268
fix variable creation
HimavarshaVS Jan 31, 2026
09829f8
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Jan 31, 2026
b5bfe00
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 31, 2026
a3018c2
refactor: move MCPServerConfig schema to a separate file and update m…
ogabrielluiz Feb 2, 2026
0d9300c
refactor: streamline AuthServiceFactory to use service_class for inst…
ogabrielluiz Feb 2, 2026
132c062
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Feb 2, 2026
cadd58a
handle access token type
HimavarshaVS Feb 2, 2026
c0ebf00
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 2, 2026
4829cd5
remove SSO fields from user model
HimavarshaVS Feb 2, 2026
682f05a
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 2, 2026
5e937bb
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 2, 2026
e1b71e8
replace is_encrypted back
HimavarshaVS Feb 2, 2026
b202dd8
fix mypy errors
HimavarshaVS Feb 2, 2026
22be2b4
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 2, 2026
204cdfe
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 3, 2026
9e4a26b
remove sso config example
HimavarshaVS Feb 3, 2026
11c1db2
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 3, 2026
35c0ab5
feat: Refactor framework agnostic auth service (#11565)
HimavarshaVS Feb 4, 2026
8deb8cb
move base to lfx
HimavarshaVS Feb 5, 2026
10d0e63
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Feb 5, 2026
007b436
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 5, 2026
ced24d7
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 5, 2026
86ad571
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 5, 2026
71ea7b2
resolve review comments
HimavarshaVS Feb 5, 2026
51e4f43
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 5, 2026
e3b36a5
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 5, 2026
b06ad93
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Feb 5, 2026
4b086b1
add auth protocol
HimavarshaVS Feb 5, 2026
846fcce
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 5, 2026
9383eb8
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 5, 2026
ae5a243
revert models.py execption handling
HimavarshaVS Feb 5, 2026
4c9a411
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 5, 2026
f964e7e
revert wrappers to ensure backwards compatibility
HimavarshaVS Feb 5, 2026
69a3a12
fix http error code
HimavarshaVS Feb 5, 2026
3b822ef
fix FE tests
HimavarshaVS Feb 5, 2026
20f9cf5
fix test_variables.py
HimavarshaVS Feb 5, 2026
8f93ac2
Merge remote-tracking branch 'origin' into pluggable-auth-service
HimavarshaVS Feb 5, 2026
cc8b735
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 5, 2026
7b45a53
fix ruff errors
HimavarshaVS Feb 5, 2026
ebe448d
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 5, 2026
3b5f097
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 6, 2026
4f60adf
fix tests
HimavarshaVS Feb 6, 2026
55da26d
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 6, 2026
afb7095
add wrappers for create token methods
HimavarshaVS Feb 6, 2026
f7ef6d8
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 6, 2026
7741c26
fix ruff errors
HimavarshaVS Feb 6, 2026
f2ec420
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 6, 2026
36acfee
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 6, 2026
f0bae8a
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 6, 2026
0557f58
update error message
HimavarshaVS Feb 6, 2026
8025404
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 6, 2026
3375e1e
Merge branch 'main' into pluggable-auth-service
HimavarshaVS Feb 6, 2026
883cf24
modify status code for inactive user
HimavarshaVS Feb 6, 2026
fe6b714
Merge branch 'pluggable-auth-service' of https://github.com/langflow-…
HimavarshaVS Feb 6, 2026
8488d76
fix ruff errors
HimavarshaVS Feb 6, 2026
e6a34b3
Optimize _auth_error_to_http
codeflash-ai[bot] Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,4 @@ member_servers.json
# data files used for desktop registration
data/user

sso-config.yaml
2 changes: 1 addition & 1 deletion .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@
"filename": "src/backend/tests/unit/test_setup_superuser.py",
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
"is_verified": false,
"line_number": 56,
"line_number": 60,
"is_secret": false
}
],
Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ external = ["RUF027"]
"src/lfx/src/lfx/base/curl/parse.py" = [
"S105", # False positive: 'token' variable name, not a password
]
"src/lfx/src/lfx/services/auth/service.py" = [
"ARG002", # No-op impl: unused args required by interface
"EM101", # NotImplementedError messages as literals
"TC003", # Type-only imports used in signatures
]
"src/lfx/src/lfx/base/mcp/util.py" = [
"SLF001", # MCP library private member access
]
Expand Down
10 changes: 6 additions & 4 deletions src/backend/base/langflow/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
from langflow.cli.progress import create_langflow_progress
from langflow.initial_setup.setup import get_or_create_default_folder
from langflow.main import setup_app
from langflow.services.auth.utils import check_key, get_current_user_by_jwt
from langflow.services.auth.utils import get_current_user_from_access_token
from langflow.services.database.models.api_key.crud import check_key
from langflow.services.deps import get_db_service, get_settings_service, is_settings_service_initialized, session_scope
from langflow.services.utils import initialize_services
from langflow.utils.version import fetch_latest_version, get_version_info
Expand Down Expand Up @@ -735,7 +736,7 @@ async def _create_superuser(username: str, password: str, auth_token: str | None
# Try JWT first
user = None
try:
user = await get_current_user_by_jwt(auth_token, session)
user = await get_current_user_from_access_token(auth_token, session)
except (InvalidTokenError, HTTPException):
# Try API key
api_key_result = await check_key(session, auth_token)
Expand All @@ -756,9 +757,10 @@ async def _create_superuser(username: str, password: str, auth_token: str | None

# Auth complete, create the superuser
async with session_scope() as session:
from langflow.services.auth.utils import create_super_user
from langflow.services.deps import get_auth_service

if await create_super_user(db=session, username=username, password=password):
auth = get_auth_service()
if await auth.create_super_user(username, password, db=session):
# Verify that the superuser was created
from langflow.services.database.models.user.model import User

Expand Down
2 changes: 1 addition & 1 deletion src/backend/base/langflow/api/v1/api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ async def save_store_api_key(
api_key = api_key_request.api_key

# Encrypt the API key
encrypted = auth_utils.encrypt_api_key(api_key, settings_service=settings_service)
encrypted = auth_utils.encrypt_api_key(api_key)
current_user.store_api_key = encrypted
db.add(current_user)
await db.commit()
Expand Down
5 changes: 2 additions & 3 deletions src/backend/base/langflow/api/v1/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,12 @@
api_key_security,
get_current_active_user,
get_current_user_for_sse,
get_webhook_user,
)
from langflow.services.cache.utils import save_uploaded_file
from langflow.services.database.models.flow.model import Flow, FlowRead
from langflow.services.database.models.flow.utils import get_all_webhook_components_in_flow
from langflow.services.database.models.user.model import User, UserRead
from langflow.services.deps import get_session_service, get_settings_service, get_telemetry_service
from langflow.services.deps import get_auth_service, get_session_service, get_settings_service, get_telemetry_service
from langflow.services.event_manager import create_webhook_event_manager, webhook_event_manager
from langflow.services.telemetry.schema import RunPayload
from langflow.utils.compression import compress_response
Expand Down Expand Up @@ -752,7 +751,7 @@ async def webhook_run_flow(
error_msg = ""

# Get the appropriate user for webhook execution based on auth settings
webhook_user = await get_webhook_user(flow_id_or_name, request)
webhook_user = await get_auth_service().get_webhook_user(flow_id_or_name, request)

try:
data = await request.body()
Expand Down
23 changes: 10 additions & 13 deletions src/backend/base/langflow/api/v1/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,9 @@
from langflow.api.utils import DbSession
from langflow.api.v1.schemas import Token
from langflow.initial_setup.setup import get_or_create_default_folder
from langflow.services.auth.utils import (
authenticate_user,
create_refresh_token,
create_user_longterm_token,
create_user_tokens,
)
from langflow.services.database.models.user.crud import get_user_by_id
from langflow.services.database.models.user.model import UserRead
from langflow.services.deps import get_settings_service, get_variable_service
from langflow.services.deps import get_auth_service, get_settings_service, get_variable_service

router = APIRouter(tags=["Login"])

Expand All @@ -38,7 +32,8 @@ async def login_to_get_access_token(
):
auth_settings = get_settings_service().auth_settings
try:
user = await authenticate_user(form_data.username, form_data.password, db)
auth = get_auth_service()
user = await auth.authenticate_user(form_data.username, form_data.password, db)
except Exception as exc:
if isinstance(exc, HTTPException):
raise
Expand All @@ -52,7 +47,7 @@ async def login_to_get_access_token(
) from exc

if user:
tokens = await create_user_tokens(user_id=user.id, db=db, update_last_login=True)
tokens = await auth.create_user_tokens(user_id=user.id, db=db, update_last_login=True)
response.set_cookie(
"refresh_token_lf",
tokens["refresh_token"],
Expand Down Expand Up @@ -103,7 +98,8 @@ async def auto_login(response: Response, db: DbSession):
auth_settings = get_settings_service().auth_settings

if auth_settings.AUTO_LOGIN:
user_id, tokens = await create_user_longterm_token(db)
auth = get_auth_service()
user_id, tokens = await auth.create_user_longterm_token(db)
response.set_cookie(
"access_token_lf",
tokens["access_token"],
Expand Down Expand Up @@ -157,7 +153,8 @@ async def refresh_token(
token = request.cookies.get("refresh_token_lf")

if token:
tokens = await create_refresh_token(token, db)
auth = get_auth_service()
tokens = await auth.create_refresh_token(token, db)
response.set_cookie(
"refresh_token_lf",
tokens["refresh_token"],
Expand Down Expand Up @@ -195,7 +192,7 @@ async def get_session(
It does not raise an error if unauthenticated, allowing the frontend to gracefully
handle the session state.
"""
from langflow.services.auth.utils import get_current_user_by_jwt, oauth2_login
from langflow.services.auth.utils import oauth2_login

# Try to get the token from the request (cookie or Authorization header)
try:
Expand All @@ -204,7 +201,7 @@ async def get_session(
return SessionResponse(authenticated=False)

# Validate the token and get user
user = await get_current_user_by_jwt(token, db)
user = await get_auth_service().get_current_user_from_access_token(token, db)
if not user or not user.is_active:
return SessionResponse(authenticated=False)

Expand Down
2 changes: 1 addition & 1 deletion src/backend/base/langflow/api/v1/mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ async def handle_messages(request: Request):
# Streamable HTTP Transport
################################################################################
class StreamableHTTP:
def __init__(self):
def __init__(self) -> None:
self.session_manager: StreamableHTTPSessionManager | None = None
self._started = False
self._start_stop_lock = asyncio.Lock()
Expand Down
6 changes: 3 additions & 3 deletions src/backend/base/langflow/api/v1/mcp_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
MCPProjectUpdateRequest,
MCPSettings,
)
from langflow.services.auth.constants import AUTO_LOGIN_WARNING
from langflow.services.auth.mcp_encryption import decrypt_auth_settings, encrypt_auth_settings
from langflow.services.auth.utils import AUTO_LOGIN_WARNING
from langflow.services.database.models import Flow, Folder
from langflow.services.database.models.api_key.crud import check_key, create_api_key
from langflow.services.database.models.api_key.model import ApiKey, ApiKeyCreate
Expand Down Expand Up @@ -135,7 +135,7 @@ async def verify_project_auth(
# For MCP endpoints, always fall back to username lookup when no API key is provided
result = await get_user_by_username(db, settings_service.auth_settings.SUPERUSER)
if result:
await logger.awarning(AUTO_LOGIN_WARNING)
logger.warning(AUTO_LOGIN_WARNING)
return result
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
Expand Down Expand Up @@ -1297,7 +1297,7 @@ class ProjectTaskGroup:
otherwise Asyncio will raise a RuntimeError.
"""

def __init__(self):
def __init__(self) -> None:
self._started = False
self._start_stop_lock = anyio.Lock()
self._task_group: TaskGroup | None = None
Expand Down
10 changes: 6 additions & 4 deletions src/backend/base/langflow/api/v1/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ async def _get_disabled_models(session: DbSession, current_user: CurrentActiveUs
var = await variable_service.get_variable_object(
user_id=current_user.id, name=DISABLED_MODELS_VAR, session=session
)
if var.value is not None:
if var.value: # This checks for both None and empty string
try:
parsed_value = json.loads(var.value)
# Validate it's a list of strings
Expand Down Expand Up @@ -306,17 +306,19 @@ async def _get_enabled_models(session: DbSession, current_user: CurrentActiveUse
var = await variable_service.get_variable_object(
user_id=current_user.id, name=ENABLED_MODELS_VAR, session=session
)
if var.value is not None:
# Strip whitespace and check if value is non-empty
if var.value and (value_stripped := var.value.strip()):
try:
parsed_value = json.loads(var.value)
parsed_value = json.loads(value_stripped)
# Validate it's a list of strings
if not isinstance(parsed_value, list):
logger.warning("Invalid enabled models format for user %s: not a list", current_user.id)
return set()
# Ensure all items are strings
return {str(item) for item in parsed_value if isinstance(item, str)}
except (json.JSONDecodeError, TypeError):
logger.warning("Failed to parse enabled models for user %s", current_user.id, exc_info=True)
# Log at debug level to avoid flooding logs with expected edge cases
logger.debug("Failed to parse enabled models for user %s: %s", current_user.id, var.value)
return set()
except ValueError:
# Variable not found, return empty set
Expand Down
4 changes: 2 additions & 2 deletions src/backend/base/langflow/api/v1/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def get_user_store_api_key(user: CurrentActiveUser):
if not user.store_api_key:
raise HTTPException(status_code=400, detail="You must have a store API key set.")
try:
return auth_utils.decrypt_api_key(user.store_api_key, get_settings_service())
return auth_utils.decrypt_api_key(user.store_api_key)
except Exception as e:
raise HTTPException(status_code=500, detail="Failed to decrypt API key. Please set a new one.") from e

Expand All @@ -33,7 +33,7 @@ def get_optional_user_store_api_key(user: CurrentActiveUser):
if not user.store_api_key:
return None
try:
return auth_utils.decrypt_api_key(user.store_api_key, get_settings_service())
return auth_utils.decrypt_api_key(user.store_api_key)
except Exception: # noqa: BLE001
logger.exception("Failed to decrypt API key")
return user.store_api_key
Expand Down
22 changes: 11 additions & 11 deletions src/backend/base/langflow/api/v1/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@
from langflow.api.utils import CurrentActiveUser, DbSession
from langflow.api.v1.schemas import UsersResponse
from langflow.initial_setup.setup import get_or_create_default_folder
from langflow.services.auth.utils import (
get_current_active_superuser,
get_password_hash,
verify_password,
)
from langflow.services.auth.utils import get_current_active_superuser
from langflow.services.database.models.user.crud import get_user_by_id, update_user
from langflow.services.database.models.user.model import User, UserCreate, UserRead, UserUpdate
from langflow.services.deps import get_settings_service
from langflow.services.deps import get_auth_service, get_settings_service

router = APIRouter(tags=["Users"], prefix="/users")

Expand All @@ -36,7 +32,7 @@ async def add_user(

new_user = User.model_validate(user, from_attributes=True)
try:
new_user.password = get_password_hash(user.password)
new_user.password = get_auth_service().get_password_hash(user.password)
new_user.is_active = settings_service.auth_settings.NEW_USER_IS_ACTIVE
session.add(new_user)
await session.flush()
Expand Down Expand Up @@ -96,7 +92,7 @@ async def patch_user(
if update_password:
if not user.is_superuser:
raise HTTPException(status_code=400, detail="You can't change your password here")
user_update.password = get_password_hash(user_update.password)
user_update.password = get_auth_service().get_password_hash(user_update.password)

if user_db := await get_user_by_id(session, user_id):
if not update_password:
Expand All @@ -114,15 +110,19 @@ async def reset_password(
) -> User:
"""Reset a user's password."""
if user_id != user.id:
raise HTTPException(status_code=400, detail="You can't change another user's password")
raise HTTPException(status_code=404, detail="You can't change another user's password")

if not user:
raise HTTPException(status_code=404, detail="User not found")

if verify_password(user_update.password, user.password):
if user_update.password is None:
raise HTTPException(status_code=400, detail="Password is required for password reset")

auth = get_auth_service()
if auth.verify_password(user_update.password, user.password):
raise HTTPException(status_code=400, detail="You can't use your current password")

new_password = get_password_hash(user_update.password)
new_password = auth.get_password_hash(user_update.password)
user.password = new_password

await session.flush()
Expand Down
20 changes: 9 additions & 11 deletions src/backend/base/langflow/api/v2/mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from io import BytesIO
from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, UploadFile
from fastapi import APIRouter, Body, Depends, HTTPException, UploadFile
from lfx.base.agents.utils import safe_cache_get, safe_cache_set
from lfx.base.mcp.util import update_tools

Expand All @@ -17,6 +17,7 @@
get_mcp_file,
upload_user_file,
)
from langflow.api.v2.schemas import MCPServerConfig
from langflow.logging import logger
from langflow.services.deps import get_settings_service, get_shared_component_cache_service, get_storage_service
from langflow.services.settings.service import SettingsService
Expand Down Expand Up @@ -163,9 +164,6 @@ async def check_server(server_name: str) -> dict:

from langflow.services.auth import utils as auth_utils
from langflow.services.database.models.variable.model import Variable
from langflow.services.deps import get_settings_service

settings_service = get_settings_service()

# Load variables directly from database and decrypt ALL types (including CREDENTIAL)
stmt = select(Variable).where(Variable.user_id == current_user.id)
Expand All @@ -177,9 +175,7 @@ async def check_server(server_name: str) -> dict:
# Prior to v1.8, both Generic and Credential variables were encrypted.
# As such, must attempt to decrypt both types to ensure backwards-compatibility.
try:
decrypted_value = auth_utils.decrypt_api_key(
variable.value, settings_service=settings_service
)
decrypted_value = auth_utils.decrypt_api_key(variable.value)
request_variables[variable.name] = decrypted_value
except Exception as e: # noqa: BLE001
await logger.aerror(
Expand Down Expand Up @@ -324,15 +320,16 @@ async def update_server(
@router.post("/servers/{server_name}")
async def add_server(
server_name: str,
server_config: dict,
*,
server_config: Annotated[MCPServerConfig, Body()],
current_user: CurrentActiveUser,
session: DbSession,
storage_service: Annotated[StorageService, Depends(get_storage_service)],
settings_service: Annotated[SettingsService, Depends(get_settings_service)],
):
return await update_server(
server_name,
server_config,
server_config.model_dump(exclude_unset=True),
current_user,
session,
storage_service,
Expand All @@ -344,15 +341,16 @@ async def add_server(
@router.patch("/servers/{server_name}")
async def update_server_endpoint(
server_name: str,
server_config: dict,
*,
server_config: Annotated[MCPServerConfig, Body()],
current_user: CurrentActiveUser,
session: DbSession,
storage_service: Annotated[StorageService, Depends(get_storage_service)],
settings_service: Annotated[SettingsService, Depends(get_settings_service)],
):
return await update_server(
server_name,
server_config,
server_config.model_dump(exclude_unset=True),
current_user,
session,
storage_service,
Expand Down
Loading
Loading