Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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))