diff --git a/asu/routers/api.py b/asu/routers/api.py index b1d0a447..0e5c3f10 100644 --- a/asu/routers/api.py +++ b/asu/routers/api.py @@ -120,6 +120,11 @@ def valid_profile(profile: str, build_request: BuildRequest) -> bool: profiles = app.profiles[build_request.version][build_request.target] if profile in profiles: return True + else: + for supported_devices in profiles.values(): + if profile in supported_devices: + return True + if len(profiles) == 1 and "generic" in profiles: # Handles the x86, armsr and other generic variants. build_request.profile = "generic" @@ -135,9 +140,38 @@ def valid_profile(profile: str, build_request: BuildRequest) -> bool: "forums for more information." ) - build_request.profile = app.profiles[build_request.version][build_request.target][ - build_request.profile - ] + # Translate DTS compatible strings to actual profile names: + # *Only firmware-selector client is suppose to send the profile directly, + # *translate if it is not an already translated profile + if build_request.profile not in app.profiles[build_request.version][build_request.target]: + first_occurrence = 0 + profiles_appearances: dict[str, int] = dict() + for profile, supported_devices in app.profiles[build_request.version][build_request.target].items(): + if build_request.profile in supported_devices: + profiles_appearances[profile] = supported_devices.index(build_request.profile) + + if len(profiles_appearances) == 1: + build_request.profile = profiles_appearances[0] + else: + # If there are multiple profiles including the requested DTS compatible string, + # select the one where it is the first in the list of SUPPORTED_DEVICES + logging.info( + f"DTS Compatible string: {build_request.profile} appears in " + f"multiple profiles, included in: {profiles_appearances}" + ) + for profile, index in profiles_appearances.items(): + if index == 0: + first_occurrence += 1 + build_request.profile = profile + if first_occurrence != 1: + return validation_failure( + f"Identification profile problem: {build_request.profile}. " + "The requested DTS compatible string has more than one " + "profile including it as the first SUPPORTED_DEVICES. " + "Or it is not the first in the list for any profile. " + f"{profiles_appearances} Please check the forums for more information." + ) + return ({}, None) @@ -209,9 +243,6 @@ def api_v1_build_post( request: Request, user_agent: str = Header(None), ): - # Sanitize the profile in case the client did not (bug in older LuCI app). - build_request.profile = build_request.profile.replace(",", "_") - add_build_event("requests") request_hash: str = get_request_hash(build_request) diff --git a/asu/util.py b/asu/util.py index 0c17239a..905976de 100644 --- a/asu/util.py +++ b/asu/util.py @@ -168,7 +168,7 @@ def get_request_hash(build_request: BuildRequest) -> str: build_request.version, build_request.version_code, build_request.target, - build_request.profile, + build_request.profile.replace(",", "_"), get_packages_hash( build_request.packages_versions.keys() or build_request.packages ), @@ -561,9 +561,8 @@ def reload_profiles(app: FastAPI, version: str, target: str) -> bool: ) app.profiles[version][target] = { - name.replace(",", "_"): profile + profile: data.get("supported_devices", []) for profile, data in response.json()["profiles"].items() - for name in data.get("supported_devices", []) + [profile] } return True diff --git a/tests/test_api.py b/tests/test_api.py index fb62343c..42f35a35 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -537,7 +537,7 @@ def test_api_build_real_ath79(app): target="ath79/generic", version="23.05.5", packages=["tmux", "vim"], - profile="8dev,carambola2", # Test unsanitized profile. + profile="8dev_carambola2", ), )