Beispiel #1
0
    def remove_legacy_option(type: Optional[NotificationSettingTypes] = None,
                             **kwargs: Any) -> None:
        from sentry.models.useroption import UserOption

        if type:
            kwargs["key"] = get_legacy_key(type)
        else:
            kwargs["key__in"] = KEYS_TO_LEGACY_KEYS.values()

        UserOption.objects.filter(**kwargs).delete()
Beispiel #2
0
 def remove_settings_for_user(self,
                              user,
                              type: NotificationSettingTypes = None):
     if type:
         # We don't need a transaction because this is only used in tests.
         UserOption.objects.filter(user=user,
                                   key=get_legacy_key(type)).delete()
         self.filter(target=user.actor, type=type.value).delete()
     else:
         UserOption.objects.filter(
             user=user, key__in=KEYS_TO_LEGACY_KEYS.values()).delete()
         self.filter(target=user.actor).delete()
Beispiel #3
0
    def get_settings(
        self,
        provider: ExternalProviders,
        type: NotificationSettingTypes,
        user=None,
        team=None,
        project=None,
        organization=None,
    ):
        """
        In this temporary implementation, always read EMAIL settings from
        UserOptions. One and only one of (user, team, project, or organization)
        must not be null. This function automatically translates a missing DB
        row to NotificationSettingOptionValues.DEFAULT.
        :param provider: ExternalProviders enum
        :param type: NotificationSetting.type enum
        :param user: (optional) A User object
        :param team: (optional) A Team object
        :param project: (optional) A Project object
        :param organization: (optional) An Organization object
        :return: NotificationSettingOptionValues enum
        """
        user_id_option = getattr(user, "id", None)
        scope_type, scope_identifier = _get_scope(user_id_option,
                                                  project=project,
                                                  organization=organization)
        target = _get_target(user, team)

        value = (  # NOQA
            self.filter(
                provider=provider.value,
                type=type.value,
                scope_type=scope_type,
                scope_identifier=scope_identifier,
                target=target,
            ).first() or NotificationSettingOptionValues.DEFAULT)

        legacy_value = UserOption.objects.get_value(user,
                                                    get_legacy_key(type),
                                                    project=project,
                                                    organization=organization)

        # TODO(mgaeta): This line will be valid after the "copy migration".
        # assert value == legacy_value

        return legacy_value
Beispiel #4
0
    def remove_settings(
        self,
        provider: ExternalProviders,
        type: NotificationSettingTypes,
        user: Optional[Any] = None,
        team: Optional[Any] = None,
        project: Optional[Any] = None,
        organization: Optional[Any] = None,
    ) -> None:
        """
        We don't anticipate this function will be used by the API but is useful
        for tests. This can also be called by `update_settings` when attempting
        to set a notification preference to DEFAULT.
        """
        from sentry.models.useroption import UserOption

        with transaction.atomic():
            self.find_settings(provider, type, user, team, project,
                               organization).delete()
            UserOption.objects.unset_value(user, project, get_legacy_key(type))
Beispiel #5
0
    def get_settings(
        self,
        provider: ExternalProviders,
        type: NotificationSettingTypes,
        user: Optional[Any] = None,
        team: Optional[Any] = None,
        project: Optional[Any] = None,
        organization: Optional[Any] = None,
    ) -> NotificationSettingOptionValues:
        """
        In this temporary implementation, always read EMAIL settings from
        UserOptions. One and only one of (user, team, project, or organization)
        must not be null. This function automatically translates a missing DB
        row to NotificationSettingOptionValues.DEFAULT.
        """
        from sentry.models.useroption import UserOption

        # The `unique_together` constraint should guarantee 0 or 1 rows, but
        # using `list()` rather than `.first()` to prevent Django from adding an
        # ordering that could make the query slow.
        settings = list(
            self.find_settings(provider, type, user, team, project,
                               organization))[:1]
        value = (NotificationSettingOptionValues(settings[0].value)
                 if settings else NotificationSettingOptionValues.DEFAULT)

        legacy_value = UserOption.objects.get_value(user,
                                                    get_legacy_key(type),
                                                    project=project,
                                                    organization=organization)

        expected_legacy_value = get_legacy_value(type, value)
        assert expected_legacy_value == str(legacy_value), (
            expected_legacy_value, legacy_value)

        return value
Beispiel #6
0
    def remove_settings(
        self,
        provider: ExternalProviders,
        type: NotificationSettingTypes,
        user=None,
        team=None,
        project=None,
        organization=None,
    ):
        """
        We don't anticipate this function will be used by the API but is useful
        for tests. This can also be called by `update_settings` when attempting
        to set a notification preference to DEFAULT.
        :param provider: ExternalProviders enum
        :param type: NotificationSettingTypes enum
        :param user: (Optional) User object
        :param team: (Optional) Team object
        :param project: (Optional) Project object
        :param organization: (Optional) Organization object
        """
        user_id_option = getattr(user, "id", None)
        scope_type, scope_identifier = _get_scope(user_id_option,
                                                  project=project,
                                                  organization=organization)
        target = _get_target(user, team)

        with transaction.atomic():
            self.filter(
                provider=provider.value,
                type=type.value,
                scope_type=scope_type,
                scope_identifier=scope_identifier,
                target=target,
            ).delete()

            UserOption.objects.unset_value(user, project, get_legacy_key(type))
Beispiel #7
0
    def update_settings(
        self,
        provider: ExternalProviders,
        type: NotificationSettingTypes,
        value: NotificationSettingOptionValues,
        user: Optional[Any] = None,
        team: Optional[Any] = None,
        project: Optional[Any] = None,
        organization: Optional[Any] = None,
    ) -> None:
        """
        Save a target's notification preferences.
        Examples:
          * Updating a user's org-independent preferences
          * Updating a user's per-project preferences
          * Updating a user's per-organization preferences
        """
        from sentry.models.useroption import UserOption

        # A missing DB row is equivalent to DEFAULT.
        if value == NotificationSettingOptionValues.DEFAULT:
            return self.remove_settings(
                provider,
                type,
                user=user,
                team=team,
                project=project,
                organization=organization,
            )

        if not validate(type, value):
            raise Exception(f"value '{value}' is not valid for type '{type}'")

        user_id_option = getattr(user, "id", None)
        scope_type, scope_identifier = get_scope(user_id_option,
                                                 project=project,
                                                 organization=organization)
        target_id = get_target_id(user, team)

        key = get_legacy_key(type)
        legacy_value: Union[str, int] = get_legacy_value(type, value)

        # Annoying HACK to translate "subscribe_by_default"
        if type == NotificationSettingTypes.ISSUE_ALERTS:
            legacy_value = int(legacy_value)
            if project is None:
                key = "subscribe_by_default"

        with transaction.atomic():
            setting, created = self.get_or_create(
                provider=provider.value,
                type=type.value,
                scope_type=scope_type.value,
                scope_identifier=scope_identifier,
                target_id=target_id,
                defaults={"value": value.value},
            )
            if not created and setting.value != value.value:
                setting.update(value=value.value)

            if not team:
                UserOption.objects.set_value(user,
                                             key=key,
                                             value=legacy_value,
                                             project=project,
                                             organization=organization)