コード例 #1
0
ファイル: config.py プロジェクト: w7374520/sentry
def get_filter_settings(project):
    filter_settings = {}

    for flt in get_all_filters():
        filter_id = get_filter_key(flt)
        settings = _load_filter_settings(flt, project)
        filter_settings[filter_id] = settings

    invalid_releases = project.get_option(u"sentry:{}".format(
        FilterTypes.RELEASES))
    if invalid_releases:
        filter_settings["releases"] = {"releases": invalid_releases}

    blacklisted_ips = project.get_option("sentry:blacklisted_ips")
    if blacklisted_ips:
        filter_settings["clientIps"] = {"blacklistedIps": blacklisted_ips}

    error_messages = project.get_option(u"sentry:{}".format(
        FilterTypes.ERROR_MESSAGES))
    if error_messages:
        filter_settings["errorMessages"] = {"patterns": error_messages}

    csp_disallowed_sources = []
    if bool(project.get_option("sentry:csp_ignored_sources_defaults", True)):
        csp_disallowed_sources += DEFAULT_DISALLOWED_SOURCES
    csp_disallowed_sources += project.get_option("sentry:csp_ignored_sources",
                                                 [])
    if csp_disallowed_sources:
        filter_settings["csp"] = {"disallowedSources": csp_disallowed_sources}

    return filter_settings
コード例 #2
0
ファイル: project_filters.py プロジェクト: zvrr/sentry
    def get(self, request, project):
        """
        List a project's filters

        Retrieve a list of filters for a given project.

            {method} {path}

        """
        results = []
        for flt in message_filters.get_all_filters():
            filter_spec = flt.spec
            results.append({
                "id":
                filter_spec.id,
                # 'active' will be either a boolean or list for the legacy browser filters
                # all other filters will be boolean
                "active":
                message_filters.get_filter_state(filter_spec.id, project),
                "description":
                filter_spec.description,
                "name":
                filter_spec.name,
                "hello":
                filter_spec.id + " - " + filter_spec.name,
            })
        results.sort(key=lambda x: x["name"])
        return Response(results)
コード例 #3
0
    def put(self, request, project, filter_id):
        """
        Update a filter

        Update a project's filter.

            {method} {path}

        """
        current_filter = None
        for flt in message_filters.get_all_filters():
            if flt.spec.id == filter_id:
                current_filter = flt
                break
        else:
            raise ResourceDoesNotExist  # could not find filter with the requested id

        serializer = current_filter.spec.serializer_cls(data=request.DATA,
                                                        partial=True)

        if not serializer.is_valid():
            return Response(serializer.errors, status=400)

        current_state = message_filters.get_filter_state(filter_id, project)

        new_state = message_filters.set_filter_state(filter_id, project,
                                                     serializer.object)
        audit_log_state = AuditLogEntryEvent.PROJECT_ENABLE

        if filter_id == 'legacy-browsers':
            if isinstance(current_state, bool) or new_state == 0 or isinstance(
                    new_state, six.binary_type):
                returned_state = new_state

                if isinstance(new_state, six.binary_type):
                    audit_log_state = AuditLogEntryEvent.PROJECT_DISABLE
                    returned_state = current_state

            elif current_state - new_state:
                returned_state = current_state - new_state
                audit_log_state = AuditLogEntryEvent.PROJECT_DISABLE

            elif new_state - current_state:
                returned_state = new_state - current_state

            elif new_state == current_state:
                returned_state = new_state

        if filter_id in ('browser-extensions', 'localhost', 'web-crawlers'):
            returned_state = filter_id
            removed = current_state - new_state

            if removed == 1:
                audit_log_state = AuditLogEntryEvent.PROJECT_DISABLE

        self.create_audit_entry(
            request=request,
            organization=project.organization,
            target_object=project.id,
            event=audit_log_state,
            data={"state": returned_state},
        )

        return Response(status=201)
コード例 #4
0
def get_project_config(project_id, full_config=True, for_store=False):
    """
    Constructs the ProjectConfig information.

    :param project_id: the project id as int or string
    :param full_config: True if only the full config is required, False
        if only the restricted (for external relays) is required
        (default True, i.e. full configuration)
    :param for_store: If set to true, this omits all parameters that are not
        needed for store normalization. This is a temporary flag that should
        be removed once store has been moved to Relay. Most importantly, this
        avoids database accesses.

    :return: a ProjectConfig object for the given project
    """
    project = _get_project_from_id(six.text_type(project_id))

    if project is None:
        raise APIError("Invalid project id:{}".format(project_id))

    with configure_scope() as scope:
        scope.set_tag("project", project.id)

    if for_store:
        project_keys = []
    else:
        project_keys = ProjectKey.objects \
            .filter(project=project) \
            .all()

    public_keys = {}
    for project_key in project_keys:
        public_keys[project_key.public_key] = project_key.status == 0

    now = datetime.utcnow().replace(tzinfo=utc)

    org_options = OrganizationOption.objects.get_all_values(
        project.organization_id)

    cfg = {
        'disabled': project.status > 0,
        'slug': project.slug,
        'lastFetch': now,
        'lastChange': project.get_option('sentry:relay-rev-lastchange', now),
        'rev': project.get_option('sentry:relay-rev', uuid.uuid4().hex),
        'publicKeys': public_keys,
        'config': {
            'allowedDomains': project.get_option('sentry:origins', ['*']),
            'trustedRelays': org_options.get('sentry:trusted-relays', []),
            'piiConfig': _get_pii_config(project, org_options),
        },
        'project_id': project.id,
    }

    if not full_config:
        # This is all we need for external Relay processors
        return ProjectConfig(project, **cfg)

    # The organization id is only required for reporting when processing events
    # internally. Do not expose it to external Relays.
    cfg['organization_id'] = project.organization_id

    # Explicitly bind Organization so we don't implicitly query it later
    # this just allows us to comfortably assure that `project.organization` is safe.
    # This also allows us to pull the object from cache, instead of being
    # implicitly fetched from database.
    project.organization = Organization.objects.get_from_cache(
        id=project.organization_id)

    if project.organization is not None:
        org_options = OrganizationOption.objects.get_all_values(
            project.organization_id)
    else:
        org_options = {}

    project_cfg = cfg['config']

    # get the filter settings for this project
    filter_settings = {}
    project_cfg['filter_settings'] = filter_settings

    for flt in get_all_filters():
        filter_id = get_filter_key(flt)
        settings = _load_filter_settings(flt, project)
        filter_settings[filter_id] = settings

    invalid_releases = project.get_option(u'sentry:{}'.format(FilterTypes.RELEASES))
    if invalid_releases:
        filter_settings[FilterTypes.RELEASES] = {'releases': invalid_releases}

    blacklisted_ips = project.get_option('sentry:blacklisted_ips')
    if blacklisted_ips:
        filter_settings['client_ips'] = {'blacklisted_ips': blacklisted_ips}

    error_messages = project.get_option(u'sentry:{}'.format(FilterTypes.ERROR_MESSAGES))
    if error_messages:
        filter_settings[FilterTypes.ERROR_MESSAGES] = {'patterns': error_messages}

    csp_disallowed_sources = []
    if bool(project.get_option('sentry:csp_ignored_sources_defaults', True)):
        csp_disallowed_sources += DEFAULT_DISALLOWED_SOURCES
    csp_disallowed_sources += project.get_option('sentry:csp_ignored_sources', [])
    if csp_disallowed_sources:
        filter_settings['csp'] = {'disallowed_sources': csp_disallowed_sources}

    scrub_ip_address = (org_options.get('sentry:require_scrub_ip_address', False) or
                        project.get_option('sentry:scrub_ip_address', False))

    project_cfg['scrub_ip_addresses'] = scrub_ip_address

    scrub_data = (org_options.get('sentry:require_scrub_data', False) or
                  project.get_option('sentry:scrub_data', True))

    project_cfg['scrub_data'] = scrub_data
    project_cfg['grouping_config'] = get_grouping_config_dict_for_project(project)
    project_cfg['allowed_domains'] = list(get_origins(project))

    if scrub_data:
        # We filter data immediately before it ever gets into the queue
        sensitive_fields_key = 'sentry:sensitive_fields'
        sensitive_fields = (
            org_options.get(sensitive_fields_key, []) +
            project.get_option(sensitive_fields_key, [])
        )
        project_cfg['sensitive_fields'] = sensitive_fields

        exclude_fields_key = 'sentry:safe_fields'
        exclude_fields = (
            org_options.get(exclude_fields_key, []) +
            project.get_option(exclude_fields_key, [])
        )
        project_cfg['exclude_fields'] = exclude_fields

        scrub_defaults = (org_options.get('sentry:require_scrub_defaults', False) or
                          project.get_option('sentry:scrub_defaults', True))
        project_cfg['scrub_defaults'] = scrub_defaults

    return ProjectConfig(project, **cfg)
コード例 #5
0
def get_project_config(project,
                       org_options=None,
                       full_config=True,
                       for_store=False):
    """
    Constructs the ProjectConfig information.

    :param project: The project to load configuration for. Ensure that
        organization is bound on this object; otherwise it will be loaded from
        the database.
    :param org_options: Inject preloaded organization options for faster loading.
        If ``None``, options are lazy-loaded from the database.
    :param full_config: True if only the full config is required, False
        if only the restricted (for external relays) is required
        (default True, i.e. full configuration)
    :param for_store: If set to true, this omits all parameters that are not
        needed for Relay. This is a temporary flag that should be removed once
        store has been moved to Relay. Most importantly, this avoids database
        accesses.

    :return: a ProjectConfig object for the given project
    """
    with configure_scope() as scope:
        scope.set_tag("project", project.id)

    if for_store:
        project_keys = []
    else:
        project_keys = ProjectKey.objects.filter(project=project).all()

    public_keys = []

    for project_key in project_keys:
        key = {
            "publicKey": project_key.public_key,
            "isEnabled": project_key.status == 0
        }
        if full_config:
            key["numericId"] = project_key.id

            key["quotas"] = [
                quota.to_json()
                for quota in quotas.get_quotas(project, key=project_key)
            ]
        public_keys.append(key)

    now = datetime.utcnow().replace(tzinfo=utc)

    if org_options is None:
        org_options = OrganizationOption.objects.get_all_values(
            project.organization_id)

    cfg = {
        "disabled": project.status > 0,
        "slug": project.slug,
        "lastFetch": now,
        "lastChange": project.get_option("sentry:relay-rev-lastchange", now),
        "rev": project.get_option("sentry:relay-rev",
                                  uuid.uuid4().hex),
        "publicKeys": public_keys,
        "config": {
            "allowedDomains":
            project.get_option("sentry:origins", ["*"]),
            "trustedRelays":
            org_options.get("sentry:trusted-relays", []),
            "piiConfig":
            _get_pii_config(project),
            "datascrubbingSettings":
            _get_datascrubbing_settings(project, org_options),
        },
        "project_id": project.id,
    }

    if not full_config:
        # This is all we need for external Relay processors
        return ProjectConfig(project, **cfg)

    # The organization id is only required for reporting when processing events
    # internally. Do not expose it to external Relays.
    cfg["organization_id"] = project.organization_id

    project_cfg = cfg["config"]

    # get the filter settings for this project
    filter_settings = {}
    project_cfg["filter_settings"] = filter_settings

    for flt in get_all_filters():
        filter_id = get_filter_key(flt)
        settings = _load_filter_settings(flt, project)
        filter_settings[filter_id] = settings

    invalid_releases = project.get_option(u"sentry:{}".format(
        FilterTypes.RELEASES))
    if invalid_releases:
        filter_settings[FilterTypes.RELEASES] = {"releases": invalid_releases}

    blacklisted_ips = project.get_option("sentry:blacklisted_ips")
    if blacklisted_ips:
        filter_settings["client_ips"] = {"blacklisted_ips": blacklisted_ips}

    error_messages = project.get_option(u"sentry:{}".format(
        FilterTypes.ERROR_MESSAGES))
    if error_messages:
        filter_settings[FilterTypes.ERROR_MESSAGES] = {
            "patterns": error_messages
        }

    csp_disallowed_sources = []
    if bool(project.get_option("sentry:csp_ignored_sources_defaults", True)):
        csp_disallowed_sources += DEFAULT_DISALLOWED_SOURCES
    csp_disallowed_sources += project.get_option("sentry:csp_ignored_sources",
                                                 [])
    if csp_disallowed_sources:
        filter_settings["csp"] = {"disallowed_sources": csp_disallowed_sources}

    scrub_ip_address = org_options.get("sentry:require_scrub_ip_address",
                                       False) or project.get_option(
                                           "sentry:scrub_ip_address", False)

    project_cfg["scrub_ip_addresses"] = scrub_ip_address

    project_cfg["grouping_config"] = get_grouping_config_dict_for_project(
        project)
    project_cfg["allowed_domains"] = list(get_origins(project))

    return ProjectConfig(project, **cfg)
コード例 #6
0
def get_project_config(project_id, full_config=True, for_store=False):
    """
    Constructs the ProjectConfig information.

    :param project_id: the project id as int or string
    :param full_config: True if only the full config is required, False
        if only the restricted (for external relays) is required
        (default True, i.e. full configuration)
    :param for_store: If set to true, this omits all parameters that are not
        needed for store normalization. This is a temporary flag that should
        be removed once store has been moved to Relay. Most importantly, this
        avoids database accesses.

    :return: a ProjectConfig object for the given project
    """
    project = _get_project_from_id(six.text_type(project_id))

    if project is None:
        raise APIError("Invalid project id:{}".format(project_id))

    with configure_scope() as scope:
        scope.set_tag("project", project.id)

    if for_store:
        project_keys = []
    else:
        project_keys = ProjectKey.objects.filter(project=project).all()

    public_keys = {}
    for project_key in project_keys:
        public_keys[project_key.public_key] = project_key.status == 0

    now = datetime.utcnow().replace(tzinfo=utc)

    org_options = OrganizationOption.objects.get_all_values(
        project.organization_id)

    cfg = {
        "disabled": project.status > 0,
        "slug": project.slug,
        "lastFetch": now,
        "lastChange": project.get_option("sentry:relay-rev-lastchange", now),
        "rev": project.get_option("sentry:relay-rev",
                                  uuid.uuid4().hex),
        "publicKeys": public_keys,
        "config": {
            "allowedDomains":
            project.get_option("sentry:origins", ["*"]),
            "trustedRelays":
            org_options.get("sentry:trusted-relays", []),
            "piiConfig":
            _get_pii_config(project),
            "datascrubbingSettings":
            _get_datascrubbing_settings(project, org_options),
        },
        "project_id": project.id,
    }

    if not full_config:
        # This is all we need for external Relay processors
        return ProjectConfig(project, **cfg)

    # The organization id is only required for reporting when processing events
    # internally. Do not expose it to external Relays.
    cfg["organization_id"] = project.organization_id

    # Explicitly bind Organization so we don't implicitly query it later
    # this just allows us to comfortably assure that `project.organization` is safe.
    # This also allows us to pull the object from cache, instead of being
    # implicitly fetched from database.
    project.organization = Organization.objects.get_from_cache(
        id=project.organization_id)

    if project.organization is not None:
        org_options = OrganizationOption.objects.get_all_values(
            project.organization_id)
    else:
        org_options = {}

    project_cfg = cfg["config"]

    # get the filter settings for this project
    filter_settings = {}
    project_cfg["filter_settings"] = filter_settings

    for flt in get_all_filters():
        filter_id = get_filter_key(flt)
        settings = _load_filter_settings(flt, project)
        filter_settings[filter_id] = settings

    invalid_releases = project.get_option(u"sentry:{}".format(
        FilterTypes.RELEASES))
    if invalid_releases:
        filter_settings[FilterTypes.RELEASES] = {"releases": invalid_releases}

    blacklisted_ips = project.get_option("sentry:blacklisted_ips")
    if blacklisted_ips:
        filter_settings["client_ips"] = {"blacklisted_ips": blacklisted_ips}

    error_messages = project.get_option(u"sentry:{}".format(
        FilterTypes.ERROR_MESSAGES))
    if error_messages:
        filter_settings[FilterTypes.ERROR_MESSAGES] = {
            "patterns": error_messages
        }

    csp_disallowed_sources = []
    if bool(project.get_option("sentry:csp_ignored_sources_defaults", True)):
        csp_disallowed_sources += DEFAULT_DISALLOWED_SOURCES
    csp_disallowed_sources += project.get_option("sentry:csp_ignored_sources",
                                                 [])
    if csp_disallowed_sources:
        filter_settings["csp"] = {"disallowed_sources": csp_disallowed_sources}

    scrub_ip_address = org_options.get("sentry:require_scrub_ip_address",
                                       False) or project.get_option(
                                           "sentry:scrub_ip_address", False)

    project_cfg["scrub_ip_addresses"] = scrub_ip_address

    project_cfg["grouping_config"] = get_grouping_config_dict_for_project(
        project)
    project_cfg["allowed_domains"] = list(get_origins(project))

    return ProjectConfig(project, **cfg)
コード例 #7
0
def get_full_relay_config(project_id):
    """
    Constructs the internal (big) RelayConfig

    :param project_id: the project id as int or string
    :return: FullRelayConfig the relay configuration
    """

    cfg = {}
    project = _get_project_from_id(six.text_type(project_id))

    if project is None:
        raise APIError("Invalid project id:{}".format(project_id))

    cfg['project_id'] = project.id
    cfg['organization_id'] = project.organization_id

    # Explicitly bind Organization so we don't implicitly query it later
    # this just allows us to comfortably assure that `project.organization` is safe.
    # This also allows us to pull the object from cache, instead of being
    # implicitly fetched from database.
    project.organization = Organization.objects.get_from_cache(
        id=project.organization_id)

    if project.organization is not None:
        org_options = OrganizationOption.objects.get_all_values(
            project.organization_id)
    else:
        org_options = {}

    # get the project options
    project_cfg = {}
    cfg['config'] = project_cfg

    # getting kafka info
    try:
        project_cfg['kafka_max_event_size'] = options.get(
            'kafka-publisher.max-event-size')
        project_cfg['kafka_raw_event_sample_rate'] = options.get(
            'kafka-publisher.raw-event-sample-rate')
    except Exception:
        pass  # should we log ?

    invalid_releases = project.get_option(u'sentry:{}'.format(
        FilterTypes.RELEASES))
    if invalid_releases is not None:
        project_cfg['invalid_releases'] = invalid_releases

    # get the filter settings for this project
    filter_settings = {}
    project_cfg['filter_settings'] = filter_settings

    for flt in get_all_filters():
        filter_id = flt.spec.id
        settings = _load_filter_settings(flt, project)
        filter_settings[filter_id] = settings

    scrub_ip_address = (
        org_options.get('sentry:require_scrub_ip_address', False)
        or project.get_option('sentry:scrub_ip_address', False))

    project_cfg['scrub_ip_addresses'] = scrub_ip_address

    scrub_data = (org_options.get('sentry:require_scrub_data', False)
                  or project.get_option('sentry:scrub_data', True))

    project_cfg['scrub_data'] = scrub_data
    project_cfg['grouping_config'] = get_grouping_config_dict_for_project(
        project)
    project_cfg['allowed_domains'] = list(get_origins(project))

    if scrub_data:
        # We filter data immediately before it ever gets into the queue
        sensitive_fields_key = 'sentry:sensitive_fields'
        sensitive_fields = (org_options.get(sensitive_fields_key, []) +
                            project.get_option(sensitive_fields_key, []))
        project_cfg['sensitive_fields'] = sensitive_fields

        exclude_fields_key = 'sentry:safe_fields'
        exclude_fields = (org_options.get(exclude_fields_key, []) +
                          project.get_option(exclude_fields_key, []))
        project_cfg['exclude_fields'] = exclude_fields

        scrub_defaults = (org_options.get('sentry:require_scrub_defaults',
                                          False)
                          or project.get_option('sentry:scrub_defaults', True))
        project_cfg['scrub_defaults'] = scrub_defaults

    return FullRelayConfig(project, **cfg)
コード例 #8
0
ファイル: config.py プロジェクト: yxlbeyond/sentry
def get_project_config(project,
                       org_options=None,
                       full_config=True,
                       project_keys=None):
    """
    Constructs the ProjectConfig information.

    :param project: The project to load configuration for. Ensure that
        organization is bound on this object; otherwise it will be loaded from
        the database.
    :param org_options: Inject preloaded organization options for faster loading.
        If ``None``, options are lazy-loaded from the database.
    :param full_config: True if only the full config is required, False
        if only the restricted (for external relays) is required
        (default True, i.e. full configuration)
    :param project_keys: Pre-fetched project keys for performance, similar to
        org_options. However, if no project keys are provided it is assumed
        that the config does not need to contain auth information (this is the
        case when used in python's StoreView)

    :return: a ProjectConfig object for the given project
    """
    with configure_scope() as scope:
        scope.set_tag("project", project.id)

    public_keys = []

    for project_key in project_keys or ():
        key = {
            "publicKey": project_key.public_key,
            "isEnabled": project_key.status == 0
        }
        if full_config:
            key["numericId"] = project_key.id

            key["quotas"] = [
                quota.to_json()
                for quota in quotas.get_quotas(project, key=project_key)
            ]
        public_keys.append(key)

    now = datetime.utcnow().replace(tzinfo=utc)

    if org_options is None:
        org_options = OrganizationOption.objects.get_all_values(
            project.organization_id)

    with Hub.current.start_span(op="get_public_config"):

        cfg = {
            "disabled": project.status > 0,
            "slug": project.slug,
            "lastFetch": now,
            "lastChange": project.get_option("sentry:relay-rev-lastchange",
                                             now),
            "rev": project.get_option("sentry:relay-rev",
                                      uuid.uuid4().hex),
            "publicKeys": public_keys,
            "config": {
                "allowedDomains":
                list(get_origins(project)),
                "trustedRelays":
                org_options.get("sentry:trusted-relays", []),
                "piiConfig":
                _get_pii_config(project),
                "datascrubbingSettings":
                _get_datascrubbing_settings(project, org_options),
            },
            "projectId": project.id,
        }

    if not full_config:
        # This is all we need for external Relay processors
        return ProjectConfig(project, **cfg)

    # The organization id is only required for reporting when processing events
    # internally. Do not expose it to external Relays.
    cfg["organizationId"] = project.organization_id

    project_cfg = cfg["config"]

    with Hub.current.start_span(op="get_filter_settings"):
        # get the filter settings for this project
        filter_settings = {}
        project_cfg["filterSettings"] = filter_settings

        for flt in get_all_filters():
            filter_id = get_filter_key(flt)
            settings = _load_filter_settings(flt, project)
            filter_settings[filter_id] = settings

        invalid_releases = project.get_option(u"sentry:{}".format(
            FilterTypes.RELEASES))
        if invalid_releases:
            filter_settings["releases"] = {"releases": invalid_releases}

        blacklisted_ips = project.get_option("sentry:blacklisted_ips")
        if blacklisted_ips:
            filter_settings["clientIps"] = {"blacklistedIps": blacklisted_ips}

        error_messages = project.get_option(u"sentry:{}".format(
            FilterTypes.ERROR_MESSAGES))
        if error_messages:
            filter_settings["errorMessages"] = {"patterns": error_messages}

        csp_disallowed_sources = []
        if bool(project.get_option("sentry:csp_ignored_sources_defaults",
                                   True)):
            csp_disallowed_sources += DEFAULT_DISALLOWED_SOURCES
        csp_disallowed_sources += project.get_option(
            "sentry:csp_ignored_sources", [])
        if csp_disallowed_sources:
            filter_settings["csp"] = {
                "disallowedSources": csp_disallowed_sources
            }

    with Hub.current.start_span(op="get_grouping_config_dict_for_project"):
        project_cfg["groupingConfig"] = get_grouping_config_dict_for_project(
            project)

    return ProjectConfig(project, **cfg)