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)
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
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
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)
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)
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)
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
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
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, )
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)
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)
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)
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
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}
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)
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
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
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}" )
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)
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()
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}")
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], ) ]
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)
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)
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)
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
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
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()
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)
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