Exemplo n.º 1
0
 def filter_to_accepting_recipients(
     self,
     project: "Project",
     recipients: Iterable[Union["Team", "User"]],
 ) -> Mapping[ExternalProviders, Iterable[Union["Team", "User"]]]:
     """
     Filters a list of teams or users down to the recipients by provider who
     are subscribed to alerts. We check both the project level settings and
     global default settings.
     """
     notification_settings = self.get_for_recipient_by_parent(
         NotificationSettingTypes.ISSUE_ALERTS, parent=project, recipients=recipients
     )
     notification_settings_by_recipient = transform_to_notification_settings_by_recipient(
         notification_settings, recipients
     )
     mapping = defaultdict(set)
     should_use_slack_automatic = features.has(
         "organizations:notification-slack-automatic", project.organization
     )
     for recipient in recipients:
         providers = where_should_recipient_be_notified(
             notification_settings_by_recipient, recipient, should_use_slack_automatic
         )
         for provider in providers:
             mapping[provider].add(recipient)
     return mapping
Exemplo n.º 2
0
def disabled_users_from_project(
        project: Project) -> Mapping[ExternalProviders, set[User]]:
    """Get a set of users that have disabled Issue Alert notifications for a given project."""
    user_ids = project.member_set.values_list("user", flat=True)
    users = User.objects.filter(id__in=user_ids)
    notification_settings = NotificationSetting.objects.get_for_recipient_by_parent(
        type=NotificationSettingTypes.ISSUE_ALERTS,
        parent=project,
        recipients=users,
    )
    notification_settings_by_recipient = transform_to_notification_settings_by_recipient(
        notification_settings, users)
    # Although this can be done with dict comprehension, looping for clarity.
    output = defaultdict(set)
    for user in users:
        settings = notification_settings_by_recipient.get(user)
        if settings:
            settings_by_provider = get_settings_by_provider(settings)
            for provider, settings_value_by_scope in settings_by_provider.items(
            ):
                project_setting = settings_value_by_scope.get(
                    NotificationScopeType.PROJECT)
                user_setting = settings_value_by_scope.get(
                    NotificationScopeType.USER) or settings_value_by_scope.get(
                        NotificationScopeType.TEAM)
                if project_setting == NotificationSettingOptionValues.NEVER or (
                        not project_setting and user_setting
                        == NotificationSettingOptionValues.NEVER):
                    output[provider].add(user)
    return output
Exemplo n.º 3
0
 def test_transform_to_notification_settings_by_recipient(self):
     assert transform_to_notification_settings_by_recipient(
         notification_settings=self.notification_settings,
         recipients=[self.user]) == {
             self.user: {
                 NotificationScopeType.USER: {
                     ExternalProviders.SLACK:
                     NotificationSettingOptionValues.ALWAYS
                 },
                 NotificationScopeType.PROJECT: {
                     ExternalProviders.SLACK:
                     NotificationSettingOptionValues.ALWAYS
                 },
             }
         }
Exemplo n.º 4
0
    def get_participants(
            self, group: "Group"
    ) -> Mapping[ExternalProviders, Mapping["User", int]]:
        """
        Identify all users who are participating with a given issue.
        :param group: Group object
        """
        from sentry.models import NotificationSetting, User

        all_possible_users = User.objects.get_from_group(group)
        active_and_disabled_subscriptions = self.filter(
            group=group, user__in=all_possible_users)
        notification_settings = NotificationSetting.objects.get_for_recipient_by_parent(
            NotificationSettingTypes.WORKFLOW,
            recipients=all_possible_users,
            parent=group.project,
        )
        subscriptions_by_user_id = {
            subscription.user_id: subscription
            for subscription in active_and_disabled_subscriptions
        }
        notification_settings_by_recipient = transform_to_notification_settings_by_recipient(
            notification_settings, all_possible_users)

        should_use_slack_automatic = features.has(
            "organizations:notification-slack-automatic", group.organization)

        result: MutableMapping[ExternalProviders,
                               MutableMapping["User", int]] = defaultdict(dict)
        for user in all_possible_users:
            subscription_option = subscriptions_by_user_id.get(user.id)
            providers = where_should_be_participating(
                user,
                subscription_option,
                notification_settings_by_recipient,
                should_use_slack_automatic=should_use_slack_automatic,
            )
            for provider in providers:
                result[provider][user] = (subscription_option
                                          and subscription_option.reason
                                          or GroupSubscriptionReason.implicit)

        return result
Exemplo n.º 5
0
 def filter_to_accepting_recipients(
     self,
     parent: Project,
     recipients: Iterable[Team | User],
     type: NotificationSettingTypes = NotificationSettingTypes.ISSUE_ALERTS,
 ) -> Mapping[ExternalProviders, Iterable[Team | User]]:
     """
     Filters a list of teams or users down to the recipients by provider who
     are subscribed to alerts. We check both the project level settings and
     global default settings.
     """
     notification_settings = self.get_for_recipient_by_parent(
         type, parent, recipients)
     notification_settings_by_recipient = transform_to_notification_settings_by_recipient(
         notification_settings, recipients)
     mapping = defaultdict(set)
     for recipient in recipients:
         providers = where_should_recipient_be_notified(
             notification_settings_by_recipient, recipient, type)
         for provider in providers:
             mapping[provider].add(recipient)
     return mapping
Exemplo n.º 6
0
def get_participants_for_release(
    projects: Iterable[Project], organization: Organization, user_ids: Set[int]
) -> Mapping[ExternalProviders, Mapping[User, int]]:
    # Collect all users with verified emails on a team in the related projects.
    users = set(User.objects.get_team_members_with_verified_email_for_projects(projects))

    # Get all the involved users' settings for deploy-emails (including
    # users' organization-independent settings.)
    notification_settings = NotificationSetting.objects.get_for_recipient_by_parent(
        NotificationSettingTypes.DEPLOY,
        recipients=users,
        parent=organization,
    )
    notification_settings_by_recipient = transform_to_notification_settings_by_recipient(
        notification_settings, users
    )

    should_use_slack_automatic = features.has(
        "organizations:notification-slack-automatic", organization
    )

    # Map users to their setting value. Prioritize user/org specific, then
    # user default, then product default.
    users_to_reasons_by_provider: MutableMapping[
        ExternalProviders, MutableMapping[User, int]
    ] = defaultdict(dict)
    for user in users:
        notification_settings_by_scope = notification_settings_by_recipient.get(user, {})
        values_by_provider = get_values_by_provider_by_type(
            notification_settings_by_scope,
            notification_providers(),
            NotificationSettingTypes.DEPLOY,
            should_use_slack_automatic=should_use_slack_automatic,
        )
        for provider, value in values_by_provider.items():
            reason_option = get_reason(user, value, user_ids)
            if reason_option:
                users_to_reasons_by_provider[provider][user] = reason_option
    return users_to_reasons_by_provider
Exemplo n.º 7
0
    def test_transform_to_notification_settings_by_recipient_empty(self):
        assert (transform_to_notification_settings_by_recipient(
            notification_settings=[], recipients=[]) == {})

        assert (transform_to_notification_settings_by_recipient(
            notification_settings=[], recipients=[self.user]) == {})