From: Marcel van der Veldt Date: Mon, 8 Dec 2025 20:00:51 +0000 (+0100) Subject: allow auto setup without password through ingress X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=4089975cb0683ddd6c0a93c021d25e0cb559b8d3;p=music-assistant-server.git allow auto setup without password through ingress --- diff --git a/music_assistant/controllers/webserver/controller.py b/music_assistant/controllers/webserver/controller.py index 6baa5426..b9f2fd26 100644 --- a/music_assistant/controllers/webserver/controller.py +++ b/music_assistant/controllers/webserver/controller.py @@ -999,77 +999,61 @@ class WebserverController(CoreController): from_ingress = body.get("from_ingress", False) display_name = body.get("display_name") + # Check if this is a valid ingress request (from_ingress flag + actual ingress headers) + is_valid_ingress = from_ingress and is_request_from_ingress(request) + # Validation if not username or len(username) < 2: return web.json_response( {"success": False, "error": "Username must be at least 2 characters"}, status=400 ) - if not password or len(password) < 8: + # Password is only required for non-ingress users + if not is_valid_ingress and (not password or len(password) < 8): return web.json_response( {"success": False, "error": "Password must be at least 8 characters"}, status=400 ) try: - # Get built-in provider - builtin_provider = self.auth.login_providers.get("builtin") - if not builtin_provider: - return web.json_response( - {"success": False, "error": "Built-in auth provider not available"}, status=500 - ) + if is_valid_ingress: + # Ingress setup: Create user with HA provider link only (no password required) + ha_user_id = request.headers.get("X-Remote-User-ID") + if not ha_user_id: + return web.json_response( + {"success": False, "error": "Missing Home Assistant user ID"}, status=400 + ) - if not isinstance(builtin_provider, BuiltinLoginProvider): - return web.json_response( - {"success": False, "error": "Built-in provider configuration error"}, status=500 + # Create admin user without password + user = await self.auth.create_user( + username=username, + role=UserRole.ADMIN, + display_name=display_name, ) - # Check if this is an Ingress setup where user already exists - user = None - if from_ingress and is_request_from_ingress(request): - ha_user_id = request.headers.get("X-Remote-User-ID") - if ha_user_id: - # Try to find existing auto-created Ingress user - user = await self.auth.get_user_by_provider_link( - AuthProviderType.HOME_ASSISTANT, ha_user_id + # Link to Home Assistant provider + await self.auth.link_user_to_provider( + user, AuthProviderType.HOME_ASSISTANT, ha_user_id + ) + else: + # Non-ingress setup: Create user with password + builtin_provider = self.auth.login_providers.get("builtin") + if not builtin_provider: + return web.json_response( + {"success": False, "error": "Built-in auth provider not available"}, + status=500, ) - if user: - # User already exists (auto-created from Ingress), update and add password - updates = {} - if display_name and not user.display_name: - updates["display_name"] = display_name - user.display_name = display_name - - # Make user admin if not already - if user.role != UserRole.ADMIN: - updates["role"] = UserRole.ADMIN.value - user.role = UserRole.ADMIN - - # Apply updates if any - if updates: - await self.auth.database.update( - "users", - {"user_id": user.user_id}, - updates, + + if not isinstance(builtin_provider, BuiltinLoginProvider): + return web.json_response( + {"success": False, "error": "Built-in provider configuration error"}, + status=500, ) - # Add password authentication to existing user - password_hash = builtin_provider._hash_password(password, user.user_id) - await self.auth.link_user_to_provider(user, AuthProviderType.BUILTIN, password_hash) - else: - # Create new admin user with password + # Create admin user with password user = await builtin_provider.create_user_with_password( username, password, role=UserRole.ADMIN, display_name=display_name ) - # If from Ingress, also link to HA provider - if from_ingress and is_request_from_ingress(request): - ha_user_id = request.headers.get("X-Remote-User-ID") - if ha_user_id: - # Link user to Home Assistant provider - await self.auth.link_user_to_provider( - user, AuthProviderType.HOME_ASSISTANT, ha_user_id - ) - # Create token for the new admin device_name = body.get( "device_name", f"Setup ({request.headers.get('User-Agent', 'Unknown')[:50]})" diff --git a/music_assistant/helpers/resources/setup.html b/music_assistant/helpers/resources/setup.html index 034c7a51..d849dcbd 100644 --- a/music_assistant/helpers/resources/setup.html +++ b/music_assistant/helpers/resources/setup.html @@ -329,13 +329,8 @@
@@ -446,6 +441,22 @@ const usernameField = document.getElementById('username'); usernameField.value = ingressUsername; usernameField.disabled = true; + + // Hide password fields for ingress users (they don't need to set a password) + document.querySelector('.form-group:has(#password)').style.display = 'none'; + document.querySelector('.form-group:has(#confirmPassword)').style.display = 'none'; + + // Remove required attribute from password fields for HTML5 validation + document.getElementById('password').removeAttribute('required'); + document.getElementById('confirmPassword').removeAttribute('required'); + + // Update step header for ingress users + const stepHeader = document.querySelector('.step[data-step="1"] .step-header'); + stepHeader.querySelector('h2').textContent = 'Confirm Your Account'; + stepHeader.querySelector('p').textContent = 'Your account will be linked to your Home Assistant user.'; + + // Update button text for ingress users + document.getElementById('createAccountBtn').textContent = 'Complete Setup'; } function updateStepIndicator() { @@ -523,14 +534,17 @@ return; } - if (password.length < 8) { - showError('Password must be at least 8 characters long'); - return; - } + // Password validation only for non-ingress users + if (!isIngressSetup) { + if (password.length < 8) { + showError('Password must be at least 8 characters long'); + return; + } - if (password !== confirmPassword) { - showError('Passwords do not match'); - return; + if (password !== confirmPassword) { + showError('Passwords do not match'); + return; + } } setLoading(true);