Beispiel #1
0
def delete_package_version(
        platform: str,
        filename: str,
        channel_name: str,
        package_name: str,
        dao: Dao = Depends(get_dao),
        db=Depends(get_db),
        auth: authorization.Rules = Depends(get_rules),
):

    version = dao.get_package_version_by_filename(channel_name, package_name,
                                                  filename, platform)

    auth.assert_package_delete(version.package)

    if not version:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"package version {platform}/{filename} not found",
        )

    db.delete(version)
    db.commit()

    path = os.path.join(platform, filename)
    pkgstore.delete_file(channel_name, path)

    dao.update_channel_size(channel_name)
Beispiel #2
0
def get_job(
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
        job: job_db_models.Job = Depends(get_job_or_fail),
):
    auth.assert_jobs()
    return job
Beispiel #3
0
def patch_channel(
        channel_data: rest_models.Channel,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
        channel: db_models.Channel = Depends(get_channel_or_fail),
        db=Depends(get_db),
):

    auth.assert_update_channel_info(channel.name)

    user_attrs = channel_data.dict(exclude_unset=True)

    if "size_limit" in user_attrs:
        auth.assert_set_channel_size_limit()

    changeable_attrs = ["private", "size_limit", "metadata"]

    for attr_ in user_attrs.keys():
        if attr_ not in changeable_attrs:
            raise HTTPException(
                status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                detail=f"attribute '{attr_}' of channel can not be changed",
            )

    for attr_, value_ in user_attrs.items():
        if attr_ == "metadata":
            metadata = channel.load_channel_metadata()
            metadata.update(value_)
            setattr(channel, "channel_metadata", json.dumps(metadata))
        else:
            setattr(channel, attr_, value_)
    db.commit()

    return channel
Beispiel #4
0
def delete_user(
        username: str,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):
    user = dao.get_user_by_username(username)

    auth.assert_delete_user(user.id)
    dao.delete_user(user.id)
Beispiel #5
0
def delete_channel_mirror(
        channel_name: str,
        mirror_id: str,
        channel: db_models.Channel = Depends(get_channel_or_fail),
        auth: authorization.Rules = Depends(get_rules),
        dao: Dao = Depends(get_dao),
):
    auth.assert_unregister_mirror(channel_name)
    dao.delete_channel_mirror(channel_name, mirror_id)
Beispiel #6
0
def post_api_key(api_key: rest_models.BaseApiKey,
                 dao: Dao = Depends(get_dao),
                 auth: authorization.Rules = Depends(get_rules)):

    auth.assert_create_api_key_roles(api_key.roles)

    user_id = auth.assert_user()

    key = secrets.token_urlsafe(32)
    dao.create_api_key(user_id, api_key, key)
Beispiel #7
0
def create_job(
        job: JobBase,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):
    """create a new job"""
    user = auth.assert_user()
    auth.assert_jobs()
    new_job = dao.create_job(user, job.manifest, job.items_spec)
    return new_job
Beispiel #8
0
def get_channel_members(
        channel: db_models.Channel = Depends(get_channel_or_fail),
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):

    auth.assert_list_channel_members(channel.name)
    member_list = dao.get_channel_members(channel.name)

    return member_list
Beispiel #9
0
def post_api_key(
        api_key: rest_models.BaseApiKey,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):

    auth.assert_create_api_key_roles(api_key.roles)

    user_id = auth.assert_user()

    key = generate_random_key(32)
    dao.create_api_key(user_id, api_key, key)

    user_role_keys, custom_role_keys = dao.get_api_keys_with_members(
        user_id, key)

    if len(user_role_keys) > 0:
        key = user_role_keys[0]
        return rest_models.ApiKey(
            key=key.key,
            description=key.description,
            time_created=key.time_created,
            expire_at=key.expire_at,
            roles=None,
        )

    else:
        key = custom_role_keys[0][0]
        package_member = custom_role_keys[0][1]
        channel_member = custom_role_keys[0][2]
        roles = []
        if package_member:
            roles.append(
                CPRole(
                    channel=package_member.channel_name,
                    package=package_member.package_name,
                    role=package_member.role,
                ))

        if channel_member:
            roles.append(
                CPRole(
                    channel=channel_member.channel_name,
                    package=None,
                    role=channel_member.role,
                ))

        return rest_models.ApiKey(
            key=key.key,
            description=key.description,
            time_created=key.time_created,
            expire_at=key.expire_at,
            roles=roles,
        )
Beispiel #10
0
def delete_channel(
    channel: db_models.Channel = Depends(get_channel_allow_proxy),
    dao: Dao = Depends(get_dao),
    auth: authorization.Rules = Depends(get_rules),
):

    auth.assert_delete_channel(channel)
    dao.delete_channel(channel.name)
    files = pkgstore.list_files(channel.name)
    for f in files:
        pkgstore.delete_file(channel.name, destination=f)
Beispiel #11
0
def get_jobs(
    dao: Dao = Depends(get_dao),
    auth: authorization.Rules = Depends(get_rules),
    status: List[JobStatus] = Query([JobStatus.pending, JobStatus.running]),
    skip: int = 0,
    limit: int = PAGINATION_LIMIT,
):
    # if this is merged https://github.com/tiangolo/fastapi/issues/2077
    # we will be able to use non-exploded list, i.e., ?state=running,pending
    auth.assert_jobs()
    return dao.get_jobs(states=status, skip=skip, limit=limit)
Beispiel #12
0
def get_tasks(
    job_id: int,
    dao: Dao = Depends(get_dao),
    status: List[TaskStatus] = Query(
        [TaskStatus.created, TaskStatus.pending, TaskStatus.running]),
    auth: authorization.Rules = Depends(get_rules),
    skip: int = 0,
    limit: int = PAGINATION_LIMIT,
):
    auth.assert_jobs()
    return dao.get_tasks(job_id, status, skip, limit)
Beispiel #13
0
def create_job(
    job: JobBase,
    dao: Dao = Depends(get_dao),
    auth: authorization.Rules = Depends(get_rules),
):
    """create a new job"""
    user = auth.assert_user()
    # only admins can create jobs through /jobs API
    auth.assert_jobs(None)
    new_job = dao.create_job(user, job)
    return new_job
Beispiel #14
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}
Beispiel #15
0
def get_tasks(
    job_id: int,
    dao: Dao = Depends(get_dao),
    status: List[TaskStatus] = Query(
        [TaskStatus.created, TaskStatus.pending, TaskStatus.running]
    ),
    auth: authorization.Rules = Depends(get_rules),
    skip: int = 0,
    limit: int = PAGINATION_LIMIT,
    job: job_db_models.Job = Depends(get_job_or_fail),
):
    auth.assert_jobs(owner_id=job.owner_id)
    return dao.get_tasks(job.id, status, skip, limit)
Beispiel #16
0
def list_user_channels(username: str, dao: Dao, auth: authorization.Rules,
                       skip: int, limit: int):
    user = dao.get_user_by_username(username)

    if not user or not user.profile:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"User {username} not found")

    auth.assert_read_user_data(user.id)

    channels = dao.get_user_channels_with_role(skip, limit, user.id)

    return channels
Beispiel #17
0
def get_user(
        username: str,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):
    user = dao.get_user_by_username(username)

    if not user or not user.profile:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"User {username} not found")

    auth.assert_read_user_data(user.id)

    return user
Beispiel #18
0
def delete_channel(
        channel: db_models.Channel = Depends(get_channel_allow_proxy),
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):

    auth.assert_delete_channel(channel)
    dao.delete_channel(channel.name)
    try:
        pkgstore.remove_channel(channel.name)
    except FileNotFoundError:
        logger.warning(
            f"trying to remove non-existent package store for channel {channel.name}"
        )
Beispiel #19
0
def post_package_member(
        new_member: rest_models.PostMember,
        package: db_models.Package = Depends(get_package_or_fail),
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules)):

    auth.assert_add_package_member(package.channel.name, package.name, new_member.role)

    channel_member = dao.get_package_member(package.channel.name, package.name, new_member.username)
    if channel_member:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f'Member {new_member.username} in {package.channel.name}/{package.name} exists')

    dao.create_package_member(package.channel.name, package.name, new_member)
Beispiel #20
0
def update_job(
        job_data: JobUpdateModel,
        db=Depends(get_db),
        job: job_db_models.Job = Depends(get_job_or_fail),
        auth: authorization.Rules = Depends(get_rules),
):
    """refresh job (re-run on new packages)"""
    auth.assert_jobs()
    job.status = job_data.status  # type: ignore

    # ignore tasks that have already been run
    if job_data.force:
        run_jobs(db, job_id=job.id, force=True)

    db.commit()
Beispiel #21
0
def post_channel_mirror(
        request: Request,
        mirror: rest_models.ChannelMirrorBase,
        channel_name: str,
        channel: db_models.Channel = Depends(get_channel_or_fail),
        auth: authorization.Rules = Depends(get_rules),
        dao: Dao = Depends(get_dao),
        remote_session: requests.Session = Depends(get_remote_session),
):

    auth.assert_register_mirror(channel_name)

    logger.debug(f"registering mirror {mirror.url}")

    if not mirror.api_endpoint:
        mirror.api_endpoint = mirror.url.replace("get", "api/channels")

    if not mirror.metrics_endpoint:
        mirror.metrics_endpoint = mirror.url.replace("get", "metrics/channels")

    # check api response
    response = remote_session.get(mirror.api_endpoint)

    if response.status_code != 200:
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail=f"could not connect to remote repository {mirror.url}",
        )
    response_data = response.json()

    try:
        mirrored_server = response_data["mirror_channel_url"]
    except KeyError:
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail="mirror server is not quetz server",
        )

    if not mirrored_server:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"{mirror.url} is not a mirror server",
        )

    dao.create_channel_mirror(channel_name, mirror.url, mirror.api_endpoint,
                              mirror.metrics_endpoint)

    logger.info(f"successfully registered mirror {mirror.url}")
Beispiel #22
0
def get_api_keys(dao: Dao = Depends(get_dao),
                 auth: authorization.Rules = Depends(get_rules)):
    """Get API keys for current user"""

    user_id = auth.assert_user()
    api_key_list = dao.get_package_api_keys(user_id)
    api_channel_key_list = dao.get_channel_api_keys(user_id)

    from itertools import groupby

    return [
        rest_models.ApiKey(
            key=api_key.key,
            description=api_key.description,
            roles=[
                rest_models.CPRole(
                    channel=member.channel_name,
                    package=member.package_name if hasattr(
                        member, 'package_name') else None,
                    role=member.role,
                ) for member, api_key in member_key_list
            ],
        ) for api_key, member_key_list in groupby(
            [*api_key_list, *api_channel_key_list],
            lambda member_api_key: member_api_key[1],
        )
    ]
Beispiel #23
0
def search(
        query: str,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):
    user_id = auth.get_user()
    return dao.search_packages(query, user_id)
Beispiel #24
0
def set_user_role(
        username: str,
        role: rest_models.UserRole,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):

    user = dao.get_user_by_username(username)

    if not user:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"User {username} not found")

    auth.assert_assign_user_role(role.role)

    dao.set_user_role(username, role=role.role)
Beispiel #25
0
def channel_search(
        q: str,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):
    user_id = auth.get_user()
    keywords, filters = parse_query('channel', q)
    return dao.search_channels(keywords, filters, user_id)
Beispiel #26
0
def get_job_or_fail(
        job_id: int,
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
) -> job_db_models.Job:

    auth.assert_jobs()

    job = dao.get_job(job_id)

    if not job:
        raise HTTPException(
            status_code=http_status.HTTP_404_NOT_FOUND,
            detail=f"Job with id {job_id} not found",
        )

    return job
Beispiel #27
0
def get_package_or_fail(
    package_name: str,
    channel_name: str,
    dao: Dao = Depends(get_dao),
    auth: authorization.Rules = Depends(get_rules),
) -> db_models.Package:

    package = dao.get_package(channel_name.lower(), package_name)

    if not package:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Package {channel_name}/{package_name} not found",
        )

    auth.assert_package_read(package)
    return package
Beispiel #28
0
def delete_api_keys(
        key: str,
        dao: Dao = Depends(get_dao),
        db: Session = Depends(get_db),
        auth: authorization.Rules = Depends(get_rules),
):
    api_key = dao.get_api_key(key)

    if not api_key:
        raise HTTPException(status.HTTP_404_NOT_FOUND,
                            detail=f"key '{key}' does not exist")

    auth.assert_delete_api_key(api_key)

    api_key.deleted = True

    db.commit()
Beispiel #29
0
def post_channel_member(
        new_member: rest_models.PostMember,
        channel: db_models.Channel = Depends(get_channel_or_fail),
        dao: Dao = Depends(get_dao),
        auth: authorization.Rules = Depends(get_rules),
):

    auth.assert_add_channel_member(channel.name, new_member.role)

    channel_member = dao.get_channel_member(channel.name, new_member.username)
    if channel_member:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f"Member {new_member.username} in {channel.name} exists",
        )

    dao.create_channel_member(channel.name, new_member)
Beispiel #30
0
def test_authorizations_with_deleted_api_key(data: Data, db):

    auth = Rules(data.keya, {}, db)

    user_id = auth.get_user()

    assert user_id == data.usera.id

    data.keya_obj.deleted = True

    db.commit()

    user_id = auth.get_user()

    assert not user_id

    data.keya_obj.deleted = False