Ejemplo n.º 1
0
def remove_members_from_group_backend(request: HttpRequest, user_profile: UserProfile,
                                      user_group_id: int, members: List[int]) -> HttpResponse:
    if not members:
        return json_success()

    user_profiles = user_ids_to_users(members, user_profile.realm)
    user_group = access_user_group_by_id(user_group_id, user_profile.realm)
    remove_members_from_user_group(user_group, user_profiles)
    return json_success()
Ejemplo n.º 2
0
def remove_members_from_group_backend(request: HttpRequest, user_profile: UserProfile,
                                      user_group_id: int, members: List[int]) -> HttpResponse:
    if not members:
        return json_success()

    user_profiles = user_ids_to_users(members, user_profile.realm)
    user_group = access_user_group_by_id(user_group_id, user_profile)
    group_member_ids = get_user_group_members(user_group)
    for member in members:
        if (member not in group_member_ids):
            raise JsonableError(_("There is no member '%s' in this user group" % (member,)))

    remove_members_from_user_group(user_group, user_profiles)
    return json_success()
Ejemplo n.º 3
0
def add_members_to_group_backend(request: HttpRequest, user_profile: UserProfile,
                                 user_group_id: int, members: List[int]) -> HttpResponse:
    if not members:
        return json_success()

    user_group = access_user_group_by_id(user_group_id, user_profile)
    user_profiles = user_ids_to_users(members, user_profile.realm)
    existing_member_ids = set(get_memberships_of_users(user_group, user_profiles))

    for user_profile in user_profiles:
        if user_profile.id in existing_member_ids:
            raise JsonableError(_("User %s is already a member of this group" % (user_profile.id,)))

    bulk_add_members_to_user_group(user_group, user_profiles)
    return json_success()
Ejemplo n.º 4
0
def edit_user_group(request: HttpRequest, user_profile: UserProfile,
                    user_group_id: int=REQ(validator=check_int),
                    name: str=REQ(default=""), description: str=REQ(default="")
                    ) -> HttpResponse:
    if not (name or description):
        return json_error(_("No new data supplied"))

    user_group = access_user_group_by_id(user_group_id, user_profile)

    result = {}
    if name != user_group.name:
        do_update_user_group_name(user_group, name)
        result['name'] = _("Name successfully updated.")

    if description != user_group.description:
        do_update_user_group_description(user_group, description)
        result['description'] = _("Description successfully updated.")

    return json_success(result)
Ejemplo n.º 5
0
def add_members_to_group_backend(request: HttpRequest,
                                 user_profile: UserProfile, user_group_id: int,
                                 members: List[int]) -> HttpResponse:
    if not members:
        return json_success()

    user_group = access_user_group_by_id(user_group_id, user_profile)
    user_profiles = user_ids_to_users(members, user_profile.realm)
    existing_member_ids = set(
        get_memberships_of_users(user_group, user_profiles))

    for user_profile in user_profiles:
        if user_profile.id in existing_member_ids:
            raise JsonableError(
                _("User {user_id} is already a member of this group").format(
                    user_id=user_profile.id, ))

    bulk_add_members_to_user_group(user_group, user_profiles)
    return json_success()
Ejemplo n.º 6
0
def edit_user_group(
        request: HttpRequest,
        user_profile: UserProfile,
        user_group_id: int = REQ(validator=check_int, path_only=True),
        name: str = REQ(default=""),
        description: str = REQ(default=""),
) -> HttpResponse:
    if not (name or description):
        return json_error(_("No new data supplied"))

    user_group = access_user_group_by_id(user_group_id, user_profile)

    if name != user_group.name:
        do_update_user_group_name(user_group, name)

    if description != user_group.description:
        do_update_user_group_description(user_group, description)

    return json_success()
Ejemplo n.º 7
0
def get_is_user_group_member(
    request: HttpRequest,
    user_profile: UserProfile,
    user_group_id: int = REQ(json_validator=check_int, path_only=True),
    user_id: int = REQ(json_validator=check_int, path_only=True),
    direct_member_only: bool = REQ(json_validator=check_bool, default=False),
) -> HttpResponse:
    user_group = access_user_group_by_id(user_group_id,
                                         user_profile,
                                         for_read=True)
    target_user = access_user_by_id(user_profile, user_id, for_admin=False)

    return json_success(
        request,
        data={
            "is_user_group_member":
            is_user_in_group(user_group,
                             target_user,
                             direct_member_only=direct_member_only)
        },
    )
Ejemplo n.º 8
0
def edit_user_group(
    request: HttpRequest,
    user_profile: UserProfile,
    user_group_id: int = REQ(validator=check_int),
    name: str = REQ(default=""),
    description: str = REQ(default="")
) -> HttpResponse:
    if not (name or description):
        return json_error(_("No new data supplied"))

    user_group = access_user_group_by_id(user_group_id, user_profile)

    result = {}
    if name != user_group.name:
        do_update_user_group_name(user_group, name)
        result['name'] = _("Name successfully updated.")

    if description != user_group.description:
        do_update_user_group_description(user_group, description)
        result['description'] = _("Description successfully updated.")

    return json_success(result)
Ejemplo n.º 9
0
def get_mentioned_user_group_name(messages: List[Dict[str, Any]],
                                  user_profile: UserProfile) -> Optional[str]:
    """Returns the user group name to display in the email notification
    if user group(s) are mentioned.

    This implements the same algorithm as get_user_group_mentions_data
    in zerver/lib/notification_data.py, but we're passed a list of
    messages instead.
    """
    for message in messages:
        if message["mentioned_user_group_id"] is None and message[
                "trigger"] == "mentioned":
            # The user has also been personally mentioned, so that gets prioritized.
            return None

    # These IDs are those of the smallest user groups mentioned in each message.
    mentioned_user_group_ids = [
        message["mentioned_user_group_id"] for message in messages
        if message["mentioned_user_group_id"] is not None
    ]

    # We now want to calculate the name of the smallest user group mentioned among
    # all these messages.
    smallest_user_group_size = math.inf
    smallest_user_group_name = None
    for user_group_id in mentioned_user_group_ids:
        current_user_group = access_user_group_by_id(user_group_id,
                                                     user_profile,
                                                     for_mention=True)
        current_user_group_size = len(
            get_user_group_members(current_user_group))

        if current_user_group_size < smallest_user_group_size:
            # If multiple user groups are mentioned, we prefer the
            # user group with the least members.
            smallest_user_group_size = current_user_group_size
            smallest_user_group_name = current_user_group.name

    return smallest_user_group_name
Ejemplo n.º 10
0
def get_apns_alert_subtitle(
        user_profile: UserProfile,
        message: Message,
        mentioned_user_group_id: Optional[int] = None) -> str:
    """
    On an iOS notification, this is the second bolded line.
    """
    if message.trigger == "mentioned":
        if mentioned_user_group_id is not None:
            user_group = access_user_group_by_id(mentioned_user_group_id,
                                                 user_profile)
            return _("{full_name} mentioned @{user_group_name}:").format(
                full_name=message.sender.full_name,
                user_group_name=user_group.name)
        else:
            return _("{full_name} mentioned you:").format(
                full_name=message.sender.full_name)
    elif message.trigger == "wildcard_mentioned":
        return _("{full_name} mentioned everyone:").format(
            full_name=message.sender.full_name)
    elif message.recipient.type == Recipient.PERSONAL:
        return ""
    # For group PMs, or regular messages to a stream, just use a colon to indicate this is the sender.
    return message.sender.full_name + ":"
Ejemplo n.º 11
0
def check_delete_user_group(user_group_id: int,
                            user_profile: UserProfile) -> None:
    user_group = access_user_group_by_id(user_group_id, user_profile)
    user_group.delete()
    do_send_delete_user_group_event(user_profile.realm, user_group_id,
                                    user_profile.realm.id)
Ejemplo n.º 12
0
def handle_push_notification(user_profile_id: int,
                             missed_message: Dict[str, Any]) -> None:
    """
    missed_message is the event received by the
    zerver.worker.queue_processors.PushNotificationWorker.consume function.
    """
    if not push_notifications_enabled():
        return
    user_profile = get_user_profile_by_id(user_profile_id)

    if user_profile.is_bot:
        # BUG: Investigate why it's possible to get here.
        return  # nocoverage

    if not (user_profile.enable_offline_push_notifications
            or user_profile.enable_online_push_notifications):
        # BUG: Investigate why it's possible to get here.
        return  # nocoverage

    try:
        (message, user_message) = access_message(user_profile,
                                                 missed_message["message_id"])
    except JsonableError:
        if ArchivedMessage.objects.filter(
                id=missed_message["message_id"]).exists():
            # If the cause is a race with the message being deleted,
            # that's normal and we have no need to log an error.
            return
        logging.info(
            "Unexpected message access failure handling push notifications: %s %s",
            user_profile.id,
            missed_message["message_id"],
        )
        return

    if user_message is not None:
        # If the user has read the message already, don't push-notify.
        if user_message.flags.read or user_message.flags.active_mobile_push_notification:
            return

        # Otherwise, we mark the message as having an active mobile
        # push notification, so that we can send revocation messages
        # later.
        user_message.flags.active_mobile_push_notification = True
        user_message.save(update_fields=["flags"])
    else:
        # Users should only be getting push notifications into this
        # queue for messages they haven't received if they're
        # long-term idle; anything else is likely a bug.
        if not user_profile.long_term_idle:
            logger.error(
                "Could not find UserMessage with message_id %s and user_id %s",
                missed_message["message_id"],
                user_profile_id,
                exc_info=True,
            )
            return

    trigger = missed_message["trigger"]
    mentioned_user_group_name = None
    mentioned_user_group_id = missed_message.get("mentioned_user_group_id")

    if mentioned_user_group_id is not None:
        user_group = access_user_group_by_id(mentioned_user_group_id,
                                             user_profile,
                                             for_mention=True)
        mentioned_user_group_name = user_group.name

    apns_payload = get_message_payload_apns(user_profile, message, trigger,
                                            mentioned_user_group_id,
                                            mentioned_user_group_name)
    gcm_payload, gcm_options = get_message_payload_gcm(
        user_profile, message, trigger, mentioned_user_group_id,
        mentioned_user_group_name)
    logger.info("Sending push notifications to mobile clients for user %s",
                user_profile_id)

    if uses_notification_bouncer():
        send_notifications_to_bouncer(user_profile_id, apns_payload,
                                      gcm_payload, gcm_options)
        return

    android_devices = list(
        PushDeviceToken.objects.filter(user=user_profile,
                                       kind=PushDeviceToken.GCM))

    apple_devices = list(
        PushDeviceToken.objects.filter(user=user_profile,
                                       kind=PushDeviceToken.APNS))

    send_apple_push_notification(user_profile.id, apple_devices, apns_payload)

    send_android_push_notification(android_devices, gcm_payload, gcm_options)