Пример #1
0
def transform_to_notification_settings_by_recipient(
    notification_settings: Iterable[NotificationSetting],
    recipients: Iterable[Team | User],
) -> Mapping[
    Team | User,
    Mapping[NotificationScopeType, Mapping[ExternalProviders, NotificationSettingOptionValues]],
]:
    """
    Given an unsorted list of notification settings, create a mapping of users
    to a map of notification scopes to setting values.
    """
    actor_mapping = {recipient.actor_id: recipient for recipient in recipients}
    notification_settings_by_recipient: MutableMapping[
        Team | User,
        MutableMapping[
            NotificationScopeType,
            MutableMapping[ExternalProviders, NotificationSettingOptionValues],
        ],
    ] = defaultdict(lambda: defaultdict(dict))
    for notification_setting in notification_settings:
        recipient = actor_mapping.get(notification_setting.target_id)
        scope_type = NotificationScopeType(notification_setting.scope_type)
        value = NotificationSettingOptionValues(notification_setting.value)
        provider = ExternalProviders(notification_setting.provider)
        notification_settings_by_recipient[recipient][scope_type][provider] = value
    return notification_settings_by_recipient
Пример #2
0
def transform_to_notification_settings_by_parent_id(
    notification_settings: Iterable[Any],
    user_default: Optional[NotificationSettingOptionValues] = None,
) -> Tuple[Mapping[ExternalProviders, Mapping[
        int, NotificationSettingOptionValues]], Mapping[
            ExternalProviders, Optional[NotificationSettingOptionValues]], ]:
    """
    Given a unorganized list of notification settings, create a mapping of
    providers to a mapping parents (projects or organizations) to setting
    values. Return this mapping as a tuple with a mapping of provider to the
    user's parent-independent notification preference.
    """
    notification_settings_by_parent_id: Dict[ExternalProviders, Dict[
        int, NotificationSettingOptionValues]] = defaultdict(dict)

    # This is the user's default value for any projects or organizations that
    # don't have the option value specifically recorded.
    notification_setting_user_default: Dict[
        ExternalProviders,
        Optional[NotificationSettingOptionValues]] = defaultdict(
            lambda: user_default)
    for notification_setting in notification_settings:
        scope_type = NotificationScopeType(notification_setting.scope_type)
        provider = ExternalProviders(notification_setting.provider)
        value = NotificationSettingOptionValues(notification_setting.value)

        if scope_type == NotificationScopeType.USER:
            notification_setting_user_default[provider] = value
        else:
            key = int(notification_setting.scope_identifier)
            notification_settings_by_parent_id[provider][key] = value
    return notification_settings_by_parent_id, notification_setting_user_default
Пример #3
0
def get_send_to_member(
    project: Project, target_identifier: Optional[Union[int, str]]
) -> Mapping[ExternalProviders, Set[User]]:
    """
    No checking for disabled users is done. If a user explicitly specifies a
    member as a target to send to, it should overwrite the user's personal mail
    settings.
    :param project:
    :param target_identifier: Optional. String or int representation of a user_id.
    :returns: Mapping[ExternalProvider, Iterable[User]] A mapping of provider to
        member that a notification should be sent to as a set.
    """
    if target_identifier is None:
        return {}
    try:
        user = (User.objects.filter(
            id=int(target_identifier),
            sentry_orgmember_set__teams__projectteam__project=project,
        ).distinct().get())
    except User.DoesNotExist:
        return {}
    notification_settings = NotificationSetting.objects.get_for_users_by_parent(
        NotificationSettingTypes.ISSUE_ALERTS, parent=project, users=[user])
    if notification_settings:
        return {
            ExternalProviders(notification_setting.provider): {user}
            for notification_setting in notification_settings
        }
    # Fall back to email if there are no settings.
    return {ExternalProviders.EMAIL: {user}}
Пример #4
0
    def get_send_to_member(self, project, target_identifier):
        """
        No checking for disabled users is done. If a user explicitly specifies a member
        as a target to send to, it should overwrite the user's personal notification settings.
        :param target_identifier:
        :return: Mapping[ExternalProvider, Iterable[int]]
        Mapping of provider to id of member that a notification should be sent to as a list.
        """
        if target_identifier is None:
            return {}
        try:
            user = (User.objects.filter(
                id=int(target_identifier),
                sentry_orgmember_set__teams__projectteam__project=project,
            ).distinct().get())
        except User.DoesNotExist:
            return {}

        notification_settings = NotificationSetting.objects.get_for_users_by_parent(
            NotificationSettingTypes.ISSUE_ALERTS,
            parent=project,
            users=[user])
        if notification_settings:
            return {
                ExternalProviders(notification_setting.provider): [user.id]
                for notification_setting in notification_settings
            }
        # fall back to email if there are no settings
        return {ExternalProviders.EMAIL: [user.id]}
Пример #5
0
    def delete(self, **kwargs):
        from sentry.models import NotificationSetting

        # There is no foreign key relationship so we have to manually cascade.
        NotificationSetting.objects._filter(
            target_ids=[self.actor_id], provider=ExternalProviders(self.provider)
        ).delete()

        return super().delete(**kwargs)
Пример #6
0
    def delete(self, **kwargs):
        install = self.integration.get_installation(self.organization_id)

        install.notify_remove_external_team(external_team=self, team=self.actor.resolve())
        install.remove_notification_settings(
            actor_id=self.actor_id, provider=ExternalProviders(self.provider)
        )

        return super().delete(**kwargs)
Пример #7
0
def transform_to_notification_settings_by_user(
    notification_settings: Iterable[Any],
    users: Iterable[Any],
) -> Mapping[Any, Mapping[NotificationScopeType, Mapping[
        ExternalProviders, NotificationSettingOptionValues]]]:
    """
    Given a unorganized list of notification settings, create a mapping of
    users to a map of notification scopes to setting values.
    """
    actor_mapping = {user.actor_id: user for user in users}
    notification_settings_by_user: Dict[Any, Dict[NotificationScopeType, Dict[
        ExternalProviders, NotificationSettingOptionValues]]] = defaultdict(
            lambda: defaultdict(dict))
    for notification_setting in notification_settings:
        user = actor_mapping.get(notification_setting.target_id)
        scope_type = NotificationScopeType(notification_setting.scope_type)
        value = NotificationSettingOptionValues(notification_setting.value)
        provider = ExternalProviders(notification_setting.provider)
        notification_settings_by_user[user][scope_type][provider] = value
    return notification_settings_by_user
Пример #8
0
def transform_to_notification_settings_by_scope(
    notification_settings: Iterable["NotificationSetting"],
) -> Mapping[NotificationScopeType, Mapping[int, Mapping[
        ExternalProviders, NotificationSettingOptionValues]], ]:
    """
    Given an unsorted list of notification settings, create a mapping of scopes
    (user or parent) and their IDs to a map of provider to notifications setting values.
    """
    notification_settings_by_scopes: Dict[NotificationScopeType, Dict[
        int, Dict[ExternalProviders,
                  NotificationSettingOptionValues]]] = defaultdict(
                      lambda: defaultdict(lambda: dict()))

    for notification_setting in notification_settings:
        scope_type = NotificationScopeType(notification_setting.scope_type)
        scope_id = notification_setting.scope_identifier
        provider = ExternalProviders(notification_setting.provider)
        value = NotificationSettingOptionValues(notification_setting.value)

        notification_settings_by_scopes[scope_type][scope_id][provider] = value

    return notification_settings_by_scopes
Пример #9
0
def get_send_to_team(
    project: Project, target_identifier: Optional[Union[str, int]]
) -> Mapping[ExternalProviders, Set[User]]:
    """
    Get a team's notification settings. If not present, get settings for each subscribed user in the team.
    :param project:
    :param target_identifier: Optional. String or int representation of a team_id.
    :returns: Mapping[ExternalProvider, Iterable[User]] A mapping of provider to
        member that a notification should be sent to as a set.
    """
    if target_identifier is None:
        return {}
    try:
        team = Team.objects.get(id=int(target_identifier),
                                projectteam__project=project)
    except Team.DoesNotExist:
        return {}

    team_notification_settings = NotificationSetting.objects.get_for_recipient_by_parent(
        NotificationSettingTypes.ISSUE_ALERTS,
        parent=project,
        recipients=[team])
    if team_notification_settings:
        team_mapping = {
            ExternalProviders(notification_setting.provider): {team}
            for notification_setting in team_notification_settings
        }
        return team_mapping

    # fallback to notifying each subscribed user if there aren't team notification settings
    member_list = team.member_set.values_list("user_id", flat=True)
    users = User.objects.filter(id__in=member_list)

    mapping: Mapping[
        ExternalProviders,
        Set[User]] = NotificationSetting.objects.filter_to_subscribed_users(
            project, users)
    return mapping