Example #1
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 = list(
        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_users_by_parent(
        NotificationSettingTypes.DEPLOY,
        users=users,
        parent=organization,
    )
    notification_settings_by_user = transform_to_notification_settings_by_user(
        notification_settings, users)

    # 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_user.get(
            user, {})
        values_by_provider = get_deploy_values_by_provider(
            notification_settings_by_scope, notification_providers())
        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
Example #2
0
    def get_participants(self, group) -> Mapping[Any, GroupSubscriptionReason]:
        """
        Identify all users who are participating with a given issue.
        :param group: Group object
        """
        from sentry.models import NotificationSetting, User

        users = User.objects.get_from_group(group)
        user_ids = [user.id for user in users]
        subscriptions = self.filter(group=group, user_id__in=user_ids)
        notification_settings = NotificationSetting.objects.get_for_users_by_parent(
            ExternalProviders.EMAIL,
            NotificationSettingTypes.WORKFLOW,
            users=users,
            parent=group.project,
        )

        subscriptions_by_user_id = {
            subscription.user_id: subscription
            for subscription in subscriptions
        }
        notification_settings_by_user = transform_to_notification_settings_by_user(
            notification_settings, users)
        return {
            user: getattr(
                subscriptions_by_user_id.get(user.id),
                "reason",
                GroupSubscriptionReason.implicit,
            )
            for user in users if should_be_participating(
                user,
                subscriptions_by_user_id,
                notification_settings_by_user,
            )
        }
Example #3
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_users_by_parent(
        type=NotificationSettingTypes.ISSUE_ALERTS,
        parent=project,
        users=users,
    )
    notification_settings_by_user = transform_to_notification_settings_by_user(
        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_user.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)
                if project_setting == NotificationSettingOptionValues.NEVER or (
                        not project_setting and user_setting
                        == NotificationSettingOptionValues.NEVER):
                    output[provider].add(user)
    return output
Example #4
0
 def filter_to_subscribed_users(
     self,
     project: "Project",
     users: List["User"],
 ) -> Mapping[ExternalProviders, Iterable["User"]]:
     """
     Filters a list of users down to the users 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=users)
     notification_settings_by_user = transform_to_notification_settings_by_user(
         notification_settings, users)
     mapping = defaultdict(set)
     should_use_slack_automatic = features.has(
         "organizations:notification-slack-automatic", project.organization)
     for user in users:
         providers = where_should_user_be_notified(
             notification_settings_by_user, user,
             should_use_slack_automatic)
         for provider in providers:
             mapping[provider].add(user)
     return mapping
Example #5
0
    def disabled_users_from_project(project: Project) -> Set[int]:
        """ 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_users_by_parent(
            type=NotificationSettingTypes.ISSUE_ALERTS,
            parent=project,
            users=users,
        )
        notification_settings_by_user = transform_to_notification_settings_by_user(
            notification_settings, users)

        # Although this can be done with dict comprehension, looping for clarity.
        output = set()
        for user in users:
            settings = notification_settings_by_user.get(user)
            if settings:
                # Check per-project settings first, fallback to project-independent settings.
                project_setting = settings.get(NotificationScopeType.PROJECT)
                if project_setting:
                    project_setting = project_setting[ExternalProviders.EMAIL]
                user_setting = settings.get(NotificationScopeType.USER)
                if user_setting:
                    user_setting = user_setting[ExternalProviders.EMAIL]
                if project_setting == NotificationSettingOptionValues.NEVER or (
                        not project_setting and user_setting
                        == NotificationSettingOptionValues.NEVER):
                    output.add(user.id)
        return output
Example #6
0
 def test_transform_to_notification_settings_by_user(self):
     assert transform_to_notification_settings_by_user(
         notification_settings=self.notification_settings,
         users=[self.user]) == {
             self.user: {
                 NotificationScopeType.USER: {
                     ExternalProviders.SLACK:
                     NotificationSettingOptionValues.ALWAYS
                 },
                 NotificationScopeType.PROJECT: {
                     ExternalProviders.SLACK:
                     NotificationSettingOptionValues.ALWAYS
                 },
             }
         }
Example #7
0
 def test_transform_to_notification_settings_by_user(self):
     notification_settings = NotificationSetting.objects.get_for_users_by_parent(
         NotificationSettingTypes.WORKFLOW,
         users=[self.user],
         parent=self.group.project,
     )
     notification_settings_by_user = transform_to_notification_settings_by_user(
         notification_settings, [self.user])
     assert notification_settings_by_user == {
         self.user: {
             NotificationScopeType.USER: {
                 ExternalProviders.SLACK:
                 NotificationSettingOptionValues.ALWAYS
             }
         }
     }
Example #8
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_user = transform_to_notification_settings_by_user(
            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_user,
                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
Example #9
0
 def filter_to_subscribed_users(
     self,
     project: Any,
     users: List[Any],
 ) -> Mapping[ExternalProviders, Iterable[Any]]:
     """
     Filters a list of users down to the users by provider who are subscribed to alerts.
     We check both the project level settings and global default settings.
     """
     notification_settings = self.get_for_users_by_parent(
         NotificationSettingTypes.ISSUE_ALERTS, parent=project, users=users)
     notification_settings_by_user = transform_to_notification_settings_by_user(
         notification_settings, users)
     mapping = defaultdict(set)
     for user in users:
         providers = where_should_user_be_notified(
             notification_settings_by_user, user)
         for provider in providers:
             mapping[provider].add(user)
     return mapping
Example #10
0
 def filter_to_subscribed_users(
     self,
     provider: ExternalProviders,
     project: Any,
     users: List[Any],
 ) -> List[Any]:
     """
     Filters a list of users down to the users who are subscribed to email
     alerts. We check both the project level settings and global default settings.
     """
     notification_settings = self.get_for_users_by_parent(
         provider,
         NotificationSettingTypes.ISSUE_ALERTS,
         parent=project,
         users=users)
     notification_settings_by_user = transform_to_notification_settings_by_user(
         notification_settings, users)
     return [
         user for user in users
         if should_user_be_notified(notification_settings_by_user, user)
     ]
Example #11
0
    def get_participants(
            self, group) -> Mapping[ExternalProviders, Mapping[Any, int]]:
        """
        Identify all users who are participating with a given issue.
        :param group: Group object
        """
        from sentry.models import NotificationSetting, User

        users = User.objects.get_from_group(group)
        user_ids = [user.id for user in users]
        subscriptions = self.filter(group=group, user_id__in=user_ids)
        notification_settings = NotificationSetting.objects.get_for_recipient_by_parent(
            NotificationSettingTypes.WORKFLOW,
            recipients=users,
            parent=group.project,
        )
        subscriptions_by_user_id = {
            subscription.user_id: subscription
            for subscription in subscriptions
        }
        notification_settings_by_user = transform_to_notification_settings_by_user(
            notification_settings, users)

        result = defaultdict(dict)
        for user in users:
            providers = where_should_be_participating(
                user,
                subscriptions_by_user_id,
                notification_settings_by_user,
            )
            for provider in providers:
                value = getattr(
                    subscriptions_by_user_id.get(user.id),
                    "reason",
                    GroupSubscriptionReason.implicit,
                )
                result[provider][user] = value

        return result
Example #12
0
    def test_transform_to_notification_settings_by_user_empty(self):
        assert transform_to_notification_settings_by_user(
            notification_settings=[], users=[]) == {}

        assert (transform_to_notification_settings_by_user(
            notification_settings=[], users=[self.user]) == {})