diff --git a/iscript/src/iscript/autograph.py b/iscript/src/iscript/autograph.py index 60d883f09..869552b67 100644 --- a/iscript/src/iscript/autograph.py +++ b/iscript/src/iscript/autograph.py @@ -65,7 +65,7 @@ # sign_widevine_dir {{{1 -async def sign_widevine_dir(config, sign_config, app_dir): +async def sign_widevine_dir(config, sign_config, app_dir, autograph_fmt): """Sign the internals of a tarfile with the widevine key. Extract the entire tarball, but only sign a handful of files (see @@ -98,7 +98,7 @@ async def sign_widevine_dir(config, sign_config, app_dir): to = _get_mac_sigpath(from_) log.debug("Adding %s to the sigfile paths...", to) makedirs(os.path.dirname(to)) - tasks.append(asyncio.ensure_future(sign_widevine_with_autograph(sign_config, from_, "blessed" in fmt, to=to))) + tasks.append(asyncio.ensure_future(sign_widevine_with_autograph(sign_config, from_, autograph_fmt, "blessed" in fmt, to=to))) all_files.append(to) await raise_future_exceptions(tasks) remove_extra_files(app_dir, all_files) @@ -361,7 +361,7 @@ def _get_omnija_signing_files(file_list): return files -async def sign_omnija_with_autograph(config, sign_config, app_path): +async def sign_omnija_with_autograph(config, sign_config, app_path, fmt): """Sign the omnija file specified using autograph. This function overwrites from_ @@ -393,7 +393,7 @@ async def sign_omnija_with_autograph(config, sign_config, app_path): await sign_file_with_autograph( sign_config, from_, - "autograph_omnija", + fmt, to=signed_out, keyid=OMNIJA_AUTOGRAPH_KEY_ID[sign_config.get("release_type", "dep")], extension_id="omni.ja@mozilla.org", @@ -439,7 +439,7 @@ async def merge_omnija_files(orig, signed, to): # sign_widevine_with_autograph {{{1 -async def sign_widevine_with_autograph(sign_config, from_, blessed, to=None): +async def sign_widevine_with_autograph(sign_config, from_, fmt, blessed, to=None): """Create a widevine signature using autograph as a backend. Args: @@ -462,7 +462,6 @@ async def sign_widevine_with_autograph(sign_config, from_, blessed, to=None): to = to or f"{from_}.sig" flags = 1 if blessed else 0 - fmt = "autograph_widevine" h = widevine.generate_widevine_hash(from_, flags) @@ -501,17 +500,10 @@ def langpack_id(app): return id -async def sign_langpacks(config, sign_config, all_paths): - """Signs langpacks that are specified in all_paths. - - Raises: - IScriptError if we don't have any valid language packs to sign in any path. - - """ +async def sign_langpacks(config, sign_config, all_paths, fmt): + """Signs langpacks that are specified in all_paths.""" for app in all_paths: - app.check_required_attrs(["orig_path", "formats", "artifact_prefix"]) - if not {"autograph_langpack"} & set(app.formats): - raise IScriptError(f"{app.formats} does not contain 'autograph_langpack'") + app.check_required_attrs(["orig_path", "artifact_prefix"]) app.target_bundle_path = "{}/{}{}".format(config["artifact_dir"], app.artifact_prefix, app.orig_path.split(app.artifact_prefix)[1]) id = langpack_id(app) @@ -520,7 +512,7 @@ async def sign_langpacks(config, sign_config, all_paths): await sign_file_with_autograph( sign_config, app.orig_path, - "autograph_langpack", + fmt, to=app.target_bundle_path, keyid=LANGPACK_AUTOGRAPH_KEY_ID[sign_config.get("release_type", "dep")], extension_id=id, diff --git a/iscript/src/iscript/data/i_task_schema.json b/iscript/src/iscript/data/i_task_schema.json index 33b685e51..d2e8200cd 100644 --- a/iscript/src/iscript/data/i_task_schema.json +++ b/iscript/src/iscript/data/i_task_schema.json @@ -45,7 +45,13 @@ "autograph_omnija", "mac_geckodriver", "mac_single_file", - "autograph_langpack" + "autograph_langpack", + "stage_autograph_widevine", + "stage_autograph_omnija", + "stage_autograph_langpack", + "gcp_prod_autograph_widevine", + "gcp_prod_autograph_omnija", + "gcp_prod_autograph_langpack" ] } }, diff --git a/iscript/src/iscript/hardened_sign.py b/iscript/src/iscript/hardened_sign.py index f0077790b..18c7ae0e3 100644 --- a/iscript/src/iscript/hardened_sign.py +++ b/iscript/src/iscript/hardened_sign.py @@ -16,8 +16,8 @@ create_pkg_files, download_requirements_plist_file, extract_all_apps, - filter_apps, get_app_paths, + get_langpack_format, set_app_path_and_name, sign_omnija_with_autograph, sign_widevine_dir, @@ -163,29 +163,32 @@ async def sign_hardened_behavior(config, task, create_pkg=False, **kwargs): hardened_sign_config = task["payload"]["hardened-sign-config"] sign_config_files = await download_signing_resources(hardened_sign_config, tempdir) - all_apps = get_app_paths(config, task) - langpack_apps = filter_apps(all_apps, fmt="autograph_langpack") - if langpack_apps: - await sign_langpacks(config, sign_config, langpack_apps) - all_apps = filter_apps(all_apps, fmt="autograph_langpack", inverted=True) - await extract_all_apps(config, all_apps) + non_langpack_apps = [] + for app in get_app_paths(config, task): + if fmt := get_langpack_format(app): + await sign_langpacks(config, sign_config, [app], fmt) + else: + non_langpack_apps.append(app) + await extract_all_apps(config, non_langpack_apps) await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - for app in all_apps: + for app in non_langpack_apps: set_app_path_and_name(app) # sign omni.ja futures = [] - for app in all_apps: - if {"autograph_omnija", "omnija"} & set(app.formats): - futures.append(asyncio.ensure_future(sign_omnija_with_autograph(config, sign_config, app.app_path))) + for app in non_langpack_apps: + fmt = next((f for f in app.formats if "omnija" in f), None) + if fmt: + futures.append(asyncio.ensure_future(sign_omnija_with_autograph(config, sign_config, app.app_path, fmt))) await raise_future_exceptions(futures) # sign widevine futures = [] - for app in all_apps: - if {"autograph_widevine", "widevine"} & set(app.formats): - futures.append(asyncio.ensure_future(sign_widevine_dir(config, sign_config, app.app_path))) + for app in non_langpack_apps: + fmt = next((f for f in app.formats if "widevine" in f), None) + if fmt: + futures.append(asyncio.ensure_future(sign_widevine_dir(config, sign_config, app.app_path, fmt))) await raise_future_exceptions(futures) await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) futures = [] @@ -196,7 +199,7 @@ async def sign_hardened_behavior(config, task, create_pkg=False, **kwargs): copy_provisioning_profile(pprofile, app.app_path, config) # sign apps concurrently - for app in all_apps: + for app in non_langpack_apps: for config_settings in hardened_sign_config: check_globs(app.app_path, config_settings["globs"]) command = build_sign_command( @@ -212,11 +215,11 @@ async def sign_hardened_behavior(config, task, create_pkg=False, **kwargs): exception=IScriptError, ) - await tar_apps(config, all_apps) + await tar_apps(config, non_langpack_apps) log.info("Done signing apps.") if create_pkg: requirements_plist_path = await download_requirements_plist_file(config, task) - await create_pkg_files(config, sign_config, all_apps, requirements_plist_path) - await copy_pkgs_to_artifact_dir(config, all_apps) + await create_pkg_files(config, sign_config, non_langpack_apps, requirements_plist_path) + await copy_pkgs_to_artifact_dir(config, non_langpack_apps) log.info("Done creating pkgs.") diff --git a/iscript/src/iscript/mac.py b/iscript/src/iscript/mac.py index 67c962ebc..b3cf6c746 100644 --- a/iscript/src/iscript/mac.py +++ b/iscript/src/iscript/mac.py @@ -488,19 +488,8 @@ def get_app_paths(config, task): return all_paths -def filter_apps(all_paths, fmt, inverted=False): - """Filter all_apps by format. - - Args: - all_paths: list of App objects - fmt: format name to filter - inverted (default: False): whether or not to invert the list. - - """ - filter_fn = filter - if inverted: - filter_fn = filterfalse - return list(filter_fn(lambda app: fmt in app.formats, all_paths)) +def get_langpack_format(app): + return next((f for f in app.formats if "langpack" in f), None) # extract_all_apps {{{1 @@ -642,14 +631,16 @@ async def sign_all_apps(config, sign_config, entitlements_path, all_paths, provi # sign omni.ja futures = [] for app in all_paths: - if {"autograph_omnija", "omnija"} & set(app.formats): - futures.append(asyncio.ensure_future(sign_omnija_with_autograph(config, sign_config, app.app_path))) + fmt = next((f for f in app.formats if "omnija" in f), None) + if fmt: + futures.append(asyncio.ensure_future(sign_omnija_with_autograph(config, sign_config, app.app_path, fmt))) await raise_future_exceptions(futures) # sign widevine futures = [] for app in all_paths: - if {"autograph_widevine", "widevine"} & set(app.formats): - futures.append(asyncio.ensure_future(sign_widevine_dir(config, sign_config, app.app_path))) + fmt = next((f for f in app.formats if "widevine" in f), None) + if fmt: + futures.append(asyncio.ensure_future(sign_widevine_dir(config, sign_config, app.app_path, fmt))) await raise_future_exceptions(futures) await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) futures = [] @@ -1200,17 +1191,18 @@ async def notarize_behavior(config, task): path_attrs = ["app_path"] - all_paths = get_app_paths(config, task) - langpack_apps = filter_apps(all_paths, fmt="autograph_langpack") - if langpack_apps: - await sign_langpacks(config, sign_config, langpack_apps) - all_paths = filter_apps(all_paths, fmt="autograph_langpack", inverted=True) + non_langpack_apps = [] + for app in get_app_paths(config, task): + if fmt := get_langpack_format(app): + await sign_langpacks(config, sign_config, [app], fmt) + else: + non_langpack_apps.append(app) # app - await extract_all_apps(config, all_paths) + await extract_all_apps(config, non_langpack_apps) await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - await sign_all_apps(config, sign_config, entitlements_path, all_paths, provisioning_profile_path) + await sign_all_apps(config, sign_config, entitlements_path, non_langpack_apps, provisioning_profile_path) # pkg if sign_config["create_pkg"]: @@ -1218,26 +1210,26 @@ async def notarize_behavior(config, task): # Unlock keychain again in case it's locked since previous unlock await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - await create_pkg_files(config, sign_config, all_paths, requirements_plist_path=requirements_plist_path) + await create_pkg_files(config, sign_config, non_langpack_apps, requirements_plist_path=requirements_plist_path) log.info("Notarizing") if sign_config["notarize_type"] == "multi_account": - await create_all_notarization_zipfiles(all_paths, path_attrs=path_attrs) - poll_uuids = await wrap_notarization_with_sudo(config, sign_config, all_paths, path_attr="zip_path") + await create_all_notarization_zipfiles(non_langpack_apps, path_attrs=path_attrs) + poll_uuids = await wrap_notarization_with_sudo(config, sign_config, non_langpack_apps, path_attr="zip_path") else: - zip_path = await create_one_notarization_zipfile(work_dir, all_paths, sign_config, path_attrs=path_attrs) + zip_path = await create_one_notarization_zipfile(work_dir, non_langpack_apps, sign_config, path_attrs=path_attrs) poll_uuids = await notarize_no_sudo(work_dir, sign_config, zip_path) await poll_all_notarization_status(sign_config, poll_uuids) # app - await staple_notarization(all_paths, path_attr="app_path") - await tar_apps(config, all_paths) + await staple_notarization(non_langpack_apps, path_attr="app_path") + await tar_apps(config, non_langpack_apps) # pkg if sign_config["create_pkg"]: - await staple_notarization(all_paths, path_attr="pkg_path") - await copy_pkgs_to_artifact_dir(config, all_paths) + await staple_notarization(non_langpack_apps, path_attr="pkg_path") + await copy_pkgs_to_artifact_dir(config, non_langpack_apps) log.info("Done signing and notarizing apps.") @@ -1265,17 +1257,18 @@ async def notarize_1_behavior(config, task): requirements_plist_path = await download_requirements_plist_file(config, task) path_attrs = ["app_path"] - all_paths = get_app_paths(config, task) - langpack_apps = filter_apps(all_paths, fmt="autograph_langpack") - if langpack_apps: - await sign_langpacks(config, sign_config, langpack_apps) - all_paths = filter_apps(all_paths, fmt="autograph_langpack", inverted=True) + non_langpack_apps = [] + for app in get_app_paths(config, task): + if fmt := get_langpack_format(app): + await sign_langpacks(config, sign_config, [app], fmt) + else: + non_langpack_apps.append(app) # app - await extract_all_apps(config, all_paths) + await extract_all_apps(config, non_langpack_apps) await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - await sign_all_apps(config, sign_config, entitlements_path, all_paths, provisioning_profile_path) + await sign_all_apps(config, sign_config, entitlements_path, non_langpack_apps, provisioning_profile_path) # pkg if sign_config["create_pkg"]: @@ -1283,14 +1276,14 @@ async def notarize_1_behavior(config, task): # Unlock keychain again in case it's locked since previous unlock await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - await create_pkg_files(config, sign_config, all_paths, requirements_plist_path=requirements_plist_path) + await create_pkg_files(config, sign_config, non_langpack_apps, requirements_plist_path=requirements_plist_path) log.info("Submitting for notarization.") if sign_config["notarize_type"] == "multi_account": - await create_all_notarization_zipfiles(all_paths, path_attrs=path_attrs) - poll_uuids = await wrap_notarization_with_sudo(config, sign_config, all_paths, path_attr="zip_path") + await create_all_notarization_zipfiles(non_langpack_apps, path_attrs=path_attrs) + poll_uuids = await wrap_notarization_with_sudo(config, sign_config, non_langpack_apps, path_attr="zip_path") else: - zip_path = await create_one_notarization_zipfile(work_dir, all_paths, sign_config, path_attrs) + zip_path = await create_one_notarization_zipfile(work_dir, non_langpack_apps, sign_config, path_attrs) poll_uuids = await notarize_no_sudo(work_dir, sign_config, zip_path) # create uuid_manifest.json @@ -1299,8 +1292,8 @@ async def notarize_1_behavior(config, task): with open(uuids_path, "w") as fh: json.dump(sorted(poll_uuids.keys()), fh) - await tar_apps(config, all_paths) - await copy_pkgs_to_artifact_dir(config, all_paths) + await tar_apps(config, non_langpack_apps) + await copy_pkgs_to_artifact_dir(config, non_langpack_apps) log.info("Done signing apps and submitting them for notarization.") @@ -1362,17 +1355,17 @@ async def sign_behavior(config, task): entitlements_path = await download_entitlements_file(config, sign_config, task) provisioning_profile_path = await download_provisioning_profile(config, task) - all_paths = get_app_paths(config, task) - all_paths = get_app_paths(config, task) - langpack_apps = filter_apps(all_paths, fmt="autograph_langpack") - if langpack_apps: - await sign_langpacks(config, sign_config, langpack_apps) - all_paths = filter_apps(all_paths, fmt="autograph_langpack", inverted=True) - await extract_all_apps(config, all_paths) + non_langpack_apps = [] + for app in get_app_paths(config, task): + if fmt := get_langpack_format(app): + await sign_langpacks(config, sign_config, [app], fmt) + else: + non_langpack_apps.append(app) + await extract_all_apps(config, non_langpack_apps) await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - await sign_all_apps(config, sign_config, entitlements_path, all_paths, provisioning_profile_path) - await tar_apps(config, all_paths) + await sign_all_apps(config, sign_config, entitlements_path, non_langpack_apps, provisioning_profile_path) + await tar_apps(config, non_langpack_apps) log.info("Done signing apps.") @@ -1393,22 +1386,23 @@ async def sign_and_pkg_behavior(config, task): provisioning_profile_path = await download_provisioning_profile(config, task) requirements_plist_path = await download_requirements_plist_file(config, task) - all_paths = get_app_paths(config, task) - langpack_apps = filter_apps(all_paths, fmt="autograph_langpack") - if langpack_apps: - await sign_langpacks(config, sign_config, langpack_apps) - all_paths = filter_apps(all_paths, fmt="autograph_langpack", inverted=True) - await extract_all_apps(config, all_paths) + non_langpack_apps = [] + for app in get_app_paths(config, task): + if fmt := get_langpack_format(app): + await sign_langpacks(config, sign_config, [app], fmt) + else: + non_langpack_apps.append(app) + await extract_all_apps(config, non_langpack_apps) await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - await sign_all_apps(config, sign_config, entitlements_path, all_paths, provisioning_profile_path) - await tar_apps(config, all_paths) + await sign_all_apps(config, sign_config, entitlements_path, non_langpack_apps, provisioning_profile_path) + await tar_apps(config, non_langpack_apps) # pkg await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - await create_pkg_files(config, sign_config, all_paths, requirements_plist_path=requirements_plist_path) - await copy_pkgs_to_artifact_dir(config, all_paths) + await create_pkg_files(config, sign_config, non_langpack_apps, requirements_plist_path=requirements_plist_path) + await copy_pkgs_to_artifact_dir(config, non_langpack_apps) log.info("Done signing apps and creating pkgs.") @@ -1427,18 +1421,19 @@ async def single_file_behavior(config, task, notarize=True): """ sign_config = get_sign_config(config, task, base_key="mac_config") - all_paths = get_app_paths(config, task) - langpack_apps = filter_apps(all_paths, fmt="autograph_langpack") - if langpack_apps: - await sign_langpacks(config, sign_config, langpack_apps) - all_paths = filter_apps(all_paths, fmt="autograph_langpack", inverted=True) - await extract_all_apps(config, all_paths) + non_langpack_apps = [] + for app in get_app_paths(config, task): + if fmt := get_langpack_format(app): + await sign_langpacks(config, sign_config, [app], fmt) + else: + non_langpack_apps.append(app) + await extract_all_apps(config, non_langpack_apps) await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"]) await update_keychain_search_path(config, sign_config["signing_keychain"]) - await sign_single_files(config, sign_config, all_paths) + await sign_single_files(config, sign_config, non_langpack_apps) if notarize: - for app in all_paths: + for app in non_langpack_apps: if app.target_bundle_path.endswith(".zip"): zip_path = app.target_bundle_path log.info("Notarizing...") @@ -1459,7 +1454,7 @@ async def single_file_behavior(config, task, notarize=True): raise IScriptError("Unexpected number of files found for notarization") app.single_path = os.path.join(app.parent_dir, single_paths[0]) path_attrs = ["single_path"] - zip_path = await create_one_notarization_zipfile(config["work_dir"], all_paths, sign_config, path_attrs) + zip_path = await create_one_notarization_zipfile(config["work_dir"], non_langpack_apps, sign_config, path_attrs) poll_uuids = await notarize_no_sudo(config["work_dir"], sign_config, zip_path) await poll_all_notarization_status(sign_config, poll_uuids) log.info(f"{zip_path} notarized") diff --git a/iscript/tests/test_autograph.py b/iscript/tests/test_autograph.py index 402fe8509..14eb3b86e 100644 --- a/iscript/tests/test_autograph.py +++ b/iscript/tests/test_autograph.py @@ -31,6 +31,29 @@ def sign_config(): "langpack_url": "https://autograph-hsm.dev.mozaws.net/langpack", "langpack_user": "langpack_user", "langpack_pass": "langpack_pass", + "omnija_url": "https://autograph-hsm.dev.mozaws.net/omnija", + "omnija_user": "omnija_user", + "omnija_pass": "omnija_pass", + "stage_widevine_url": "https://autograph-stage.dev.mozaws.net", + "stage_widevine_user": "widevine_user", + "stage_widevine_pass": "widevine_pass", + "stage_widevine_cert": "widevine_cert", + "stage_langpack_url": "https://autograph-stage.dev.mozaws.net/langpack", + "stage_langpack_user": "langpack_user", + "stage_langpack_pass": "langpack_pass", + "stage_omnija_url": "https://autograph-stage.dev.mozaws.net/omnija", + "stage_omnija_user": "omnija_user", + "stage_omnija_pass": "omnija_pass", + "gcp_prod_widevine_url": "https://autograph-gcp.dev.mozaws.net", + "gcp_prod_widevine_user": "widevine_user", + "gcp_prod_widevine_pass": "widevine_pass", + "gcp_prod_widevine_cert": "widevine_cert", + "gcp_prod_langpack_url": "https://autograph-gcp.dev.mozaws.net/langpack", + "gcp_prod_langpack_user": "langpack_user", + "gcp_prod_langpack_pass": "langpack_pass", + "gcp_prod_omnija_url": "https://autograph-gcp.dev.mozaws.net/omnija", + "gcp_prod_omnija_user": "omnija_user", + "gcp_prod_omnija_pass": "omnija_pass", } @@ -42,8 +65,16 @@ def noop_sync(*args, **kwargs): ... # sign_file_with_autograph {{{1 @pytest.mark.asyncio -@pytest.mark.parametrize("to,expected,format,options", ((None, "from", "autograph_widevine", None), ("to", "to", "autograph_widevine", None))) -async def test_sign_file_with_autograph(sign_config, mocker, to, expected, format, options): +@pytest.mark.parametrize( + "to,expected,format,url", + ( + (None, "from", "autograph_widevine", "https://autograph-hsm.dev.mozaws.net"), + ("to", "to", "autograph_widevine", "https://autograph-hsm.dev.mozaws.net"), + ("to", "to", "stage_autograph_widevine", "https://autograph-stage.dev.mozaws.net"), + ("to", "to", "gcp_prod_autograph_widevine", "https://autograph-gcp.dev.mozaws.net"), + ), +) +async def test_sign_file_with_autograph(sign_config, mocker, to, expected, format, url): open_mock = mocker.mock_open(read_data=b"0xdeadbeef") mocker.patch("builtins.open", open_mock, create=True) @@ -58,9 +89,8 @@ async def test_sign_file_with_autograph(sign_config, mocker, to, expected, forma assert await autograph.sign_file_with_autograph(sign_config, "from", format, to=to) == expected open_mock.assert_called() kwargs = {"input": "MHhkZWFkYmVlZg=="} - if options: - kwargs["options"] = options - session_mock.post.assert_called_with("https://autograph-hsm.dev.mozaws.net/sign/file", auth=mocker.ANY, json=[kwargs]) + expected_url = f"{url}/sign/file" + session_mock.post.assert_called_with(expected_url, auth=mocker.ANY, json=[kwargs]) @pytest.mark.asyncio @@ -117,19 +147,6 @@ def fake_walk(_): config = {"artifact_dir": tmp_path / "artifacts"} - async def fake_filelist(*args, **kwargs): - return files - - async def fake_sign(_, f, fmt, **kwargs): - if f.endswith("firefox"): - assert fmt == "widevine" - elif f.endswith("container"): - assert fmt == "widevine_blessed" - else: - assert False, "unexpected file and format {} {}!".format(f, fmt) - if "MacOS" in f: - assert f not in files, "We should have renamed this file!" - def fake_isfile(path): return "isdir" not in path @@ -140,7 +157,7 @@ def fake_isfile(path): mocker.patch.object(os.path, "isfile", new=fake_isfile) mocker.patch.object(os, "walk", new=fake_walk) - await autograph.sign_widevine_dir(config, sign_config, filename) + await autograph.sign_widevine_dir(config, sign_config, filename, fmt) # _get_widevine_signing_files {{{1 @@ -240,13 +257,22 @@ async def test_bad_autograph_method(): @pytest.mark.asyncio -@pytest.mark.parametrize("blessed", (True, False)) -async def test_widevine_autograph(mocker, tmp_path, blessed, sign_config): +@pytest.mark.parametrize( + "blessed,fmt,expected_url", + ( + (True, "autograph_widevine", "https://autograph-hsm.dev.mozaws.net"), + (False, "autograph_widevine", "https://autograph-hsm.dev.mozaws.net"), + (False, "stage_autograph_widevine", "https://autograph-stage.dev.mozaws.net"), + (False, "gcp_prod_autograph_widevine", "https://autograph-gcp.dev.mozaws.net"), + ), +) +async def test_widevine_autograph(mocker, tmp_path, blessed, sign_config, fmt, expected_url): wv = mocker.patch("iscript.autograph.widevine") wv.generate_widevine_hash.return_value = b"hashhashash" wv.generate_widevine_signature.return_value = b"sigwidevinesig" - async def fake_call(*args, **kwargs): + async def fake_call(url, *args, **kwargs): + assert expected_url in url return [{"signature": base64.b64encode(b"sigwidevinesig")}] mocker.patch.object(autograph, "call_autograph", fake_call) @@ -256,21 +282,90 @@ async def fake_call(*args, **kwargs): sign_config["widevine_cert"] = cert to = tmp_path / "signed.sig" - to = await autograph.sign_widevine_with_autograph(sign_config, "from", blessed, to=to) + to = await autograph.sign_widevine_with_autograph(sign_config, "from", fmt, blessed, to=to) assert b"sigwidevinesig" == to.read_bytes() @pytest.mark.asyncio -async def test_no_widevine(mocker, tmp_path): - async def fake_call(*args, **kwargs): +@pytest.mark.parametrize( + "fmt,expected_url", + ( + ("autograph_omnija", "https://autograph-hsm.dev.mozaws.net"), + ("autograph_omnija", "https://autograph-hsm.dev.mozaws.net"), + ("stage_autograph_omnija", "https://autograph-stage.dev.mozaws.net"), + ("gcp_prod_autograph_omnija", "https://autograph-gcp.dev.mozaws.net"), + ), +) +async def test_omnija_autograph(mocker, tmp_path, sign_config, fmt, expected_url): + orig = tmp_path / "omni.ja" + with open(orig, "w+") as f: + f.write("") + + merge = mocker.patch("iscript.autograph.merge_omnija_files") + merge.side_effect = lambda orig, signed, to: shutil.copy(signed, to) + + async def fake_call(url, *args, **kwargs): + assert expected_url in url + return [{"signed_file": base64.b64encode(b"sigomnijasig")}] + + mocker.patch.object(autograph, "call_autograph", fake_call) + + config = {"work_dir": tmp_path} + await autograph.sign_omnija_with_autograph(config, sign_config, tmp_path, fmt) + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "fmt,expected_url", + ( + ("autograph_langpack", "https://autograph-hsm.dev.mozaws.net"), + ("stage_autograph_langpack", "https://autograph-stage.dev.mozaws.net"), + ("gcp_prod_autograph_langpack", "https://autograph-gcp.dev.mozaws.net"), + ), +) +async def test_langpack_autograph(mocker, tmp_path, sign_config, fmt, expected_url): + dir = tmp_path / "public" / "build" + os.makedirs(dir) + orig = dir / "test.xpi" + with open(orig, "w+") as f: + f.write("") + + lid = mocker.patch("iscript.autograph.langpack_id") + lid.return_value = "test-xpi" + + async def fake_call(url, *args, **kwargs): + assert expected_url in url + return [{"signed_file": base64.b64encode(b"siglangpacksig")}] + + mocker.patch.object(autograph, "call_autograph", fake_call) + + config = {"artifact_dir": tmp_path} + app = App() + app.orig_path = orig.as_posix() + app.artifact_prefix = "public/build" + await autograph.sign_langpacks(config, sign_config, [app], fmt) + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "fmt,expected_url", + ( + ("autograph_widevine", "https://autograph-hsm.dev.mozaws.net"), + ("stage_autograph_widevine", "https://autograph-stage.dev.mozaws.net"), + ("gcp_prod_autograph_widevine", "https://autograph-gcp.dev.mozaws.net"), + ), +) +async def test_no_widevine(mocker, tmp_path, fmt, expected_url): + async def fake_call(url, *args, **kwargs): + assert expected_url in url return [{"signature": b"sigautographsig"}] mocker.patch.object(autograph, "call_autograph", fake_call) with pytest.raises(ImportError): to = tmp_path / "signed.sig" - to = await autograph.sign_widevine_with_autograph({}, "from", True, to=to) + to = await autograph.sign_widevine_with_autograph({}, "from", fmt, True, to=to) # omnija {{{1 @@ -329,7 +424,7 @@ async def mocked_autograph(sign_config, from_, fmt, to, keyid, extension_id): shutil.copyfile(os.path.join(TEST_DATA_DIR, signed), to) mocker.patch.object(autograph, "sign_file_with_autograph", mocked_autograph) - await autograph.sign_omnija_with_autograph(config, sign_config, tmpdir) + await autograph.sign_omnija_with_autograph(config, sign_config, tmpdir, "autograph_omnija") sha256_actual = sha256(open(copy_from, "rb").read()).hexdigest() assert sha256_actual == sha256_expected @@ -421,25 +516,7 @@ async def mocked_call_autograph(url, user, password, request_json): mock_obj = mocker.patch.object(autograph, "call_autograph", new=mocked_call_autograph) - await autograph.sign_langpacks(config, sign_config, [langpack_app]) + await autograph.sign_langpacks(config, sign_config, [langpack_app], "autograph_langpack") expected_hash = "7f4292927b4a26589ee912918de941f498e58ce100041ec3565a82da57a42eab" assert sha256(open(langpack_app.target_bundle_path, "rb").read()).hexdigest() == expected_hash assert mock_ever_called[0] - - -@pytest.mark.asyncio -async def test_langpack_sign_wrong_format(sign_config, mocker, tmp_path): - mock_ever_called = [False] - filename = os.path.join(TEST_DATA_DIR, "en-CA.xpi") - langpack_app = App(orig_path=filename, formats=["invalid"], artifact_prefix=TEST_DATA_DIR) - config = {"artifact_dir": tmp_path / "artifacts"} - - async def mocked_call_autograph(url, user, password, request_json): - mock_ever_called[0] = True - return [{"signed_file": base64.b64encode(open(filename, "rb").read())}] - - mock_obj = mocker.patch.object(autograph, "call_autograph", new=mocked_call_autograph) - - with pytest.raises(IScriptError): - await autograph.sign_langpacks(config, sign_config, [langpack_app]) - assert not mock_ever_called[0]