Esempio n. 1
0
def load_krb_user_from_request(request):
    """Load Kerberos user from current request

    REMOTE_USER needs to be set in environment variable, that is set by
    frontend Apache authentication module.
    """
    remote_user = request.environ.get('REMOTE_USER')
    if not remote_user:
        raise Unauthorized('REMOTE_USER is not present in request.')

    username, realm = remote_user.split('@')

    user = User.find_user_by_name(username)
    if not user:
        user = User.create_user(username=username)

    try:
        groups = query_ldap_groups(username)
    except ldap.SERVER_DOWN as e:
        log.error('Cannot query groups of %s from LDAP. Error: %s', username,
                  e.args[0]['desc'])
        groups = []

    g.groups = groups
    g.user = user
    return user
    def rebuild_if_not_exists(self, event, errata_id):
        """
        Initiates rebuild of artifacts based on Errata advisory with
        `errata_id` id.

        :rtype: List of ErrataAdvisoryRPMsSignedEvent instances.
        :return: List of extra events generated to initiate the rebuild.
        """

        db_event = db.session.query(Event).filter_by(
            event_type_id=EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent],
            search_key=str(errata_id)).first()
        if (db_event and db_event.state != EventState.FAILED.value and
                not event.manual):
            log.debug("Ignoring Errata advisory %d - it already exists in "
                      "Freshmaker db.", errata_id)
            return []

        # Get additional info from Errata to fill in the needed data.
        errata = Errata()
        advisories = errata.advisories_from_event(event)
        if not advisories:
            log.error("Unknown Errata advisory %d" % errata_id)
            return []

        log.info("Generating ErrataAdvisoryRPMsSignedEvent for Errata "
                 "advisory %d, because its state changed to %s.", errata_id,
                 event.advisory.state)
        advisory = advisories[0]
        new_event = ErrataAdvisoryRPMsSignedEvent(
            event.msg_id + "." + str(advisory.name), advisory)
        new_event.dry_run = event.dry_run
        new_event.manual = event.manual
        return [new_event]
Esempio n. 3
0
def require_oidc_scope(scope):
    """Check if required scopes is in OIDC scopes within request"""
    full_scope = '{0}{1}'.format(conf.oidc_base_namespace, scope)
    if conf.auth_backend == "openidc" and full_scope not in g.oidc_scopes:
        message = 'Request does not have required scope %s' % scope
        log.error(message)
        raise Forbidden(message)
    def _filter_bundles_by_pinned_related_images(self, bundle_image_nvrs):
        """
        If the digests were not pinned by OSBS, the bundle image nvr
        will be filtered out.

        There is no need in checking pinning for every of related images,
        because we already know that digest points to the manifest list,
        because of previous filtering.

        :param set bundle_image_nvrs: NVRs of operator bundles
        :return: list of NVRs of bundle images that have at least one
            original related image that was rebuilt
        """
        ret_bundle_images_nvrs = set()
        with koji_service(conf.koji_profile,
                          log,
                          dry_run=self.dry_run,
                          login=False) as session:
            for nvr in bundle_image_nvrs:
                build = session.get_build(nvr)
                if not build:
                    log.error("Could not find the build %s in Koji", nvr)
                    continue
                related_images = (build.get("build", {}).get("extra", {}).get(
                    "image", {}).get("operator_manifests",
                                     {}).get("related_images", {}))

                # Skip the bundle if the related images section was not populated by OSBS
                if related_images.get("created_by_osbs") is not True:
                    continue
                ret_bundle_images_nvrs.add(nvr)
        return ret_bundle_images_nvrs
Esempio n. 5
0
    def load_cg_metadata(self, buildinfo):
        """
        Fetch CG metadata.json and load the json.

        buildinfo may be either a int ID, a string NVR, or a map containing
        'name', 'version' and 'release.
        """
        cg_metadata_url = None
        try:
            cg_metadata_url = self.get_cg_metadata_url(buildinfo)
            resp = requests.get(cg_metadata_url)
            # url is redirected
            if resp.history:
                cg_metadata_url = resp.url
            return requests.get(cg_metadata_url).json()
        except requests.ConnectionError:
            raise
        except Exception as e:
            if cg_metadata_url:
                log.error(
                    "Unable to load CG metadata for build (%r) from url (%s): %s",
                    buildinfo, cg_metadata_url, str(e))
            else:
                log.error("Unable to load CG metadata for build (%r): %s",
                          str(e))
            raise
Esempio n. 6
0
    def fetch_cve_metadata(self, cve_list):
        """
        Fetches metadata about each CVE in `cve_list` and returns a tuple with
        the name of highest severity rate and the affected packages (a dictionary
        with product and pkg_name).
        See `SFM2API.THREAT_SEVERITIES` for list of possible severity rates.

        :param list cve_list: List of strings with CVE names.
        :rtype: str
        :return: Tuple, the first element is the name of highest severity rate occuring
        in CVEs from `cve_list`. The second element is a list of dicts, with "product"
        and "pkg_name" of the affected packages.
        """
        max_rating = -1
        affected_pkgs = []
        severity = None
        for cve in cve_list:
            try:
                elements = self.query_sfm2(cve)
            except requests.exceptions.HTTPError as e:
                if e.response.status_code == 400:
                    log.warning(
                        "The request for the CVE %s to the SFM2 API seems wrong, "
                        "impact and affected packages unknown. %s", cve, e.response.request.url)
                    continue
                if e.response.status_code == 500:
                    log.warning(
                        "Some error occurred looking forCVE %s with SFM2 API, "
                        "impact and affected packages unknown. %s", cve, e.response.request.url)
                    continue
                raise

            try:
                severity = elements['impact']
            except (IndexError, KeyError):
                log.warning("Some error occured looking for impact for CVE %s using SFM2 API", cve)

            try:
                affected_pkgs.extend([
                    {'product': item['ps_module'], 'pkg_name': item['ps_component']}
                    for item in elements['affects'] if (
                        item['affected'] != "notaffected" and
                        item['resolution'] not in ["wontfix", "ooss"])])
            except (KeyError, IndexError):
                log.exception("Some error occured looking for affected packages for CVE %s using SFM2 API", cve)

            try:
                rating = SFM2API.THREAT_SEVERITIES.index(severity)
            except ValueError:
                log.error("Unknown threat_severity '%s' for CVE %s",
                          severity, cve)
                continue

            max_rating = max(max_rating, rating)

        if max_rating == -1:
            return (None, affected_pkgs)
        return (SFM2API.THREAT_SEVERITIES[max_rating], affected_pkgs)
Esempio n. 7
0
    def poll(self):
        try:
            self.check_unfinished_koji_tasks(db.session)
        except _sa_disconnect_exceptions as ex:
            db.session.rollback()
            log.error("Invalid request, session is rolled back: %s", ex.orig)
        except Exception:
            msg = 'Error in poller execution:'
            log.exception(msg)

        log.info('Poller will now sleep for "{}" seconds'
                 .format(conf.polling_interval))
Esempio n. 8
0
def koji_service(profile=None, logger=None, login=True, dry_run=False):
    """A Koji service context manager that could be used with with

    Example::

        with KojiService() as service:
            ...

        # if you want it to log something
        with KojiService(logger=logger) as service:
            ...

        # if you want it to use alternative Koji profile rather than the default one koji
        with KojiService(koji='stg', logger=logger) as service:
            ...
    """
    service = KojiService(profile=profile, dry_run=dry_run)

    if login:
        if not conf.krb_auth_principal:
            log.error("Cannot login to Koji, krb_auth_principal not set")
        else:
            log.debug('Logging into %s with Kerberos authentication.',
                      service.server)

            service.krb_login()

            # We are not logged in in dry run mode...
            if not dry_run and not service.logged_in:
                log.error('Could not login server %s', service.server)
                yield None

    try:
        yield service
    finally:
        if service.logged_in:
            if logger:
                logger.debug('Logout Koji session')
            service.logout()