Exemple #1
0
def post_index_creation(raw_repodata: dict, channel_name, subdir):
    """Use available online keys to sign packages"""

    with get_db_manager() as db:
        query = (
            db.query(db_models.SigningKey)
            .join(db_models.RoleDelegation.keys)
            .filter(
                db_models.RoleDelegation.channel == channel_name,
                db_models.RoleDelegation.type == "pkg_mgr",
                db_models.SigningKey.private_key is not None,
            )
            .order_by(desc('time_created'))
            .all()
        )

        if query:
            import json

            from libmambapy import bindings as libmamba_api

            signatures = {}
            for name, metadata in raw_repodata["packages"].items():
                sig = libmamba_api.sign(
                    json.dumps(metadata, indent=2, sort_keys=True), query[0].private_key
                )
                if name not in signatures:
                    signatures[name] = {}

                signatures[name][query[0].public_key] = dict(signature=sig)

        logger.info(f"Signed {Path(channel_name) / subdir}")
        raw_repodata["signatures"] = signatures
Exemple #2
0
def post_package_indexing(tempdir: Path, channel_name, subdirs, files,
                          packages):
    with get_db_manager() as db:

        query = (
            db.query(PackageVersion).filter(
                PackageVersion.channel_name == channel_name,
                PackageVersion.package_name ==
                f"{channel_name}-repodata-patches",
                PackageVersion.version_order == 0,  # newest patch package
            ).order_by(PackageVersion.version.desc()))
        patches_pkg = query.one_or_none()

    if patches_pkg:
        filename = patches_pkg.filename
        fs = pkgstore.serve_path(channel_name, "noarch/" + filename)
        package_format = patches_pkg.package_format

        if package_format == PackageFormatEnum.tarbz2:
            extract_ = extract_from_tarfile
        else:
            extract_ = extract_from_conda

        with extract_(fs) as tar:

            for subdir in subdirs:
                packages[subdir] = {}
                path = f"{subdir}/patch_instructions.json"

                patch_instructions = _load_instructions(tar, path)

                with open(tempdir / channel_name / subdir /
                          "repodata.json") as fs:
                    repodata_str = fs.read()
                    repodata = json.loads(repodata_str)

                add_temp_static_file(
                    repodata_str,
                    channel_name,
                    subdir,
                    "repodata_from_packages.json",
                    tempdir,
                    files,
                )

                patch_repodata(repodata, patch_instructions)

                packages[subdir].update(repodata["packages"])
                packages[subdir].update(repodata["packages.conda"])

                patched_repodata_str = json.dumps(repodata)
                add_temp_static_file(
                    patched_repodata_str,
                    channel_name,
                    subdir,
                    "repodata.json",
                    tempdir,
                    files,
                )
Exemple #3
0
def get_role(
        channel: str,
        type: str = None,
        auth: authorization.Rules = Depends(get_rules),
):
    auth.assert_channel_roles(channel, ["owner", "maintainer", "member"])

    with get_db_manager() as db:
        query = (db.query(db_models.ContentTrustRole).filter(
            db_models.ContentTrustRole.channel == channel).all())

    return {q.delegation.keys for q in query}
Exemple #4
0
def post_add_package_version(version, condainfo):
    run_exports = json.dumps(condainfo.run_exports)

    with get_db_manager() as db:

        if not version.runexports:
            metadata = db_models.PackageVersionMetadata(version_id=version.id,
                                                        data=run_exports)
            db.add(metadata)
        else:
            metadata = db.query(db_models.PackageVersionMetadata).get(
                version.id)
            metadata.data = run_exports
        db.commit()
Exemple #5
0
def post_pkg_mgr_private_key(
        repodata_signing_key: SigningKey,
        auth: authorization.Rules = Depends(get_rules),
):
    user_id = auth.assert_user()
    channel_name = repodata_signing_key.channel
    private_key = repodata_signing_key.private_key

    with get_db_manager() as db:
        pkg_mgr_key = db_models.RepodataSigningKey(private_key=private_key,
                                                   user_id=user_id,
                                                   channel_name=channel_name)
        db.add(pkg_mgr_key)
        db.commit()
Exemple #6
0
def get_new_key(secret: bool = False):
    public_key, private_key = libmamba_api.generate_ed25519_keypair()
    key = db_models.SigningKey(
        public_key=public_key,
        private_key=private_key,
    )

    mamba_key = libmamba_api.Key.from_ed25519(key.public_key)
    private_key = key.private_key

    with get_db_manager() as db:
        db.add(key)
        db.commit()

    res = json.loads(mamba_key.json_str)
    if secret:
        res["secret"] = private_key

    return res
Exemple #7
0
def post_add_package_version(version, condainfo):
    suggest_map = {}
    subdir = condainfo.info["subdir"]

    for each_file in condainfo.files:
        if each_file.startswith(b"bin/"):
            command = each_file.split(b"bin/")[1].strip().decode("utf-8").split("/")[0]
            package = condainfo.info["name"]
            if command not in suggest_map:
                suggest_map[command] = package

    with get_db_manager() as db:
        if not version.binfiles:
            metadata = db_models.CondaSuggestMetadata(
                version_id=version.id, data=json.dumps(suggest_map)
            )
            db.add(metadata)
        else:
            metadata = db.query(db_models.CondaSuggestMetadata).get(version.id)
            metadata.data = json.dumps(suggest_map)
        db.commit()
        generate_channel_suggest_map(db, version.channel_name, subdir)
Exemple #8
0
def post_role(
        channel: str,
        type: str,
        file: UploadFile = File(...),
        force: bool = False,
        auth: authorization.Rules = Depends(get_rules),
):
    auth.assert_channel_roles(channel, ["owner"])

    with get_db_manager() as db:
        existing_role_count = (db.query(db_models.ContentTrustRole).filter(
            db_models.ContentTrustRole.channel == channel,
            db_models.ContentTrustRole.type == type,
        ).count())
        if not force and existing_role_count:
            raise HTTPException(
                status_code=status.HTTP_409_CONFLICT,
                detail=f"Content trust role '{type}' already exists "
                f"for channel '{channel}'",
            )

        def get_self_delegation(nullable: bool = False):

            query = (db.query(db_models.RoleDelegation).filter(
                db_models.RoleDelegation.type == type,
                db_models.RoleDelegation.channel == channel,
            ).one_or_none())

            if not query and not nullable:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=f"'{type}' keys not yet delegated",
                )
            return query

        self_delegation = get_self_delegation(nullable=type == "root")

        ct_role = post_role_file(file, channel,
                                 role_builder(channel, type, self_delegation))

        db_role = db_models.ContentTrustRole(
            type=ct_role.type,
            channel=channel,
            version=ct_role.version,
            timestamp=ct_role.timestamp,
            expiration=ct_role.expires,
        )

        # add delegations
        for role_type, role_keys in ct_role.all_keys().items():
            keys = [
                db.merge(db_models.SigningKey(public_key=key_id))
                for key_id in role_keys.keys
            ]

            delegated_db_role = db_models.RoleDelegation(
                type=role_type,
                channel=channel,
                threshold=role_keys.threshold,
                keys=keys,
            )

            db_role.delegations.append(delegated_db_role)

        # set self_delegation if the role is 'root'
        if type == "root":
            # Error handling (missing 'root' delegation, etc.) is done by
            # mamba API when loading the root role from file
            self_delegation = [
                r for r in db_role.delegations if r.type == "root"
            ][0]

        # db_role.delegation = self_delegation
        self_delegation.consumers.append(db_role)

        db.add(db_role)

        db.commit()