def test_load_json(string, is_path, exception, raises, result): if raises: with pytest.raises(exception): utils.load_json(string, is_path=is_path, exception=exception) else: assert result == utils.load_json(string, is_path=is_path, exception=exception)
async def verify_decision_task(chain, link): """Verify the decision task Link. Args: chain (ChainOfTrust): the chain we're operating on. link (LinkOfTrust): the task link we're checking. Raises: CoTError: on chain of trust verification error. """ errors = [] worker_type = get_worker_type(link.task) if worker_type not in chain.context.config['valid_decision_worker_types']: errors.append( "{} is not a valid decision workerType!".format(worker_type)) # make sure all tasks generated from this decision task match the published task-graph.json path = link.get_artifact_full_path('public/task-graph.json') if not os.path.exists(path): errors.append("{} {}: {} doesn't exist!".format( link.name, link.task_id, path)) raise_on_errors(errors) link.task_graph = load_json(path, is_path=True, exception=CoTError, message="Can't load {}! %(exc)s".format(path)) for target_link in [chain] + chain.links: # Verify the target's task is in the decision task's task graph, unless # it's this task or another decision task. # https://github.com/mozilla-releng/scriptworker/issues/77 if target_link.decision_task_id == link.task_id and \ target_link.task_id != link.task_id and \ target_link.task_type != 'decision': verify_link_in_task_graph(chain, link, target_link) verify_firefox_decision_command(link) raise_on_errors(errors)
def read_worker_creds(key="credentials"): """Get credentials from CREDS_FILES or the environment. This looks at the CREDS_FILES in order, and falls back to the environment. Args: key (str, optional): each CREDS_FILE is a json dict. This key's value contains the credentials. Defaults to 'credentials'. Returns: dict: the credentials found. None if no credentials found. """ for path in CREDS_FILES: if not os.path.exists(path): continue contents = load_json(path, is_path=True, exception=None) if contents.get(key): return contents[key] else: if key == "credentials" and os.environ.get("TASKCLUSTER_ACCESS_TOKEN") and \ os.environ.get("TASKCLUSTER_CLIENT_ID"): credentials = { "accessToken": os.environ["TASKCLUSTER_ACCESS_TOKEN"], "clientId": os.environ["TASKCLUSTER_CLIENT_ID"], } if os.environ.get("TASKCLUSTER_CERTIFICATE"): credentials['certificate'] = os.environ[ 'TASKCLUSTER_CERTIFICATE'] return credentials
def parse_azure_message(message): """Parse a single Azure message from the xml. Args: message (Element): xml element containing a single Azure message Returns: dict: the relevant message info Raises: ScriptWorkerException: on load_json failure """ message_info = {} interesting_keys = { "MessageId": "messageId", "PopReceipt": "popReceipt", "MessageText": "messageText", } for element in message: if element.tag in interesting_keys: message_info[interesting_keys[element.tag]] = element.text message_info['popReceipt'] = urllib.parse.quote(message_info['popReceipt']) message_text = base64.b64decode( message_info['messageText']).decode('utf-8') message_info['task_info'] = load_json( message_text, exception=ScriptWorkerException, message="Can't load azure json! %(exc)s\n{}".format(message_text)) return message_info
def generate_cot(context, path=None): """Format and sign the cot body, and write to disk. Args: context (scriptworker.context.Context): the scriptworker context. path (str, optional): The path to write the chain of trust artifact to. If None, this is artifact_dir/public/chainOfTrust.json.asc. Defaults to None. Returns: str: the contents of the chain of trust artifact. Raises: ScriptWorkerException: on schema error. """ body = generate_cot_body(context) schema = load_json( context.config['cot_schema_path'], is_path=True, exception=ScriptWorkerException, message="Can't read schema file {}: %(exc)s".format(context.config['cot_schema_path']) ) validate_json_schema(body, schema, name="chain of trust") body = format_json(body) path = path or os.path.join(context.config['artifact_dir'], "public", "chainOfTrust.json.asc") if context.config['sign_chain_of_trust']: body = sign(GPG(context), body) with open(path, "w") as fh: print(body, file=fh, end="") return body
def get_task(config): """Read the task.json from work_dir. Args: config (dict): the running config, to find work_dir. Returns: dict: the contents of task.json Raises: ScriptWorkerTaskException: on error. """ path = os.path.join(config['work_dir'], "task.json") message = "Can't read task from {}!\n%(exc)s".format(path) contents = load_json(path, is_path=True, message=message) return contents
def verify_cot_signatures(chain): """Verify the signatures of the chain of trust artifacts populated in ``download_cot``. Populate each link.cot with the chain of trust json body. Args: chain (ChainOfTrust): the chain of trust to add to. Raises: CoTError: on failure. """ for link in chain.links: path = link.get_artifact_full_path('public/chainOfTrust.json.asc') gpg_home = os.path.join(chain.context.config['base_gpg_home_dir'], link.worker_impl) gpg = GPG(chain.context, gpg_home=gpg_home) log.debug( "Verifying the {} {} chain of trust signature against {}".format( link.name, link.task_id, gpg_home)) try: with open(path, "r") as fh: contents = fh.read() except OSError as exc: raise CoTError("Can't read {}: {}!".format(path, str(exc))) try: # TODO remove verify_sig pref and kwarg when git repo pubkey # verification works reliably! body = get_body( gpg, contents, verify_sig=chain.context.config['verify_cot_signature']) except ScriptWorkerGPGException as exc: raise CoTError( "GPG Error verifying chain of trust for {}: {}!".format( path, str(exc))) link.cot = load_json( body, exception=CoTError, message="{} {}: Invalid cot json body! %(exc)s".format( link.name, link.task_id)) unsigned_path = link.get_artifact_full_path('chainOfTrust.json') log.debug("Good. Writing json contents to {}".format(unsigned_path)) with open(unsigned_path, "w") as fh: fh.write(format_json(link.cot))