Example #1
0
    def test_change_subscription_property(self) -> None:
        user = self.example_user('hamlet')
        # Fetch the Denmark stream for testing
        stream = get_stream("Denmark", user.realm)
        sub = Subscription.objects.get(user_profile=user, recipient__type=Recipient.STREAM,
                                       recipient__type_id=stream.id)
        properties = {"color": True,
                      "is_muted": True,
                      "desktop_notifications": False,
                      "audible_notifications": False,
                      "push_notifications": True,
                      "email_notifications": True,
                      "pin_to_top": True,
                      "wildcard_mentions_notify": False}

        for property, value in properties.items():
            now = timezone_now()

            old_value = getattr(sub, property)
            self.assertNotEqual(old_value, value)
            do_change_subscription_property(user, sub, stream, property, value, acting_user=user)
            expected_extra_data = {RealmAuditLog.OLD_VALUE: {'property': property, 'value': old_value},
                                   RealmAuditLog.NEW_VALUE: {'property': property, 'value': value}}
            self.assertEqual(RealmAuditLog.objects.filter(
                realm=user.realm, event_type=RealmAuditLog.SUBSCRIPTION_PROPERTY_CHANGED,
                event_time__gte=now, acting_user=user, modified_user=user,
                extra_data=ujson.dumps(expected_extra_data)).count(), 1)
            self.assertEqual(getattr(sub, property), value)
Example #2
0
def update_subscription_properties_backend(
    request: HttpRequest,
    user_profile: UserProfile,
    subscription_data: List[Dict[str, Any]] = REQ(validator=check_list(
        check_dict([("stream_id", check_int), ("property", check_string),
                    ("value", check_union([check_string, check_bool]))]), ), ),
) -> HttpResponse:
    """
    This is the entry point to changing subscription properties. This
    is a bulk endpoint: requestors always provide a subscription_data
    list containing dictionaries for each stream of interest.

    Requests are of the form:

    [{"stream_id": "1", "property": "is_muted", "value": False},
     {"stream_id": "1", "property": "color", "value": "#c2c2c2"}]
    """
    property_converters = {
        "color": check_color,
        "in_home_view": check_bool,
        "is_muted": check_bool,
        "desktop_notifications": check_bool,
        "audible_notifications": check_bool,
        "push_notifications": check_bool,
        "email_notifications": check_bool,
        "pin_to_top": check_bool,
        "wildcard_mentions_notify": check_bool
    }
    response_data = []

    for change in subscription_data:
        stream_id = change["stream_id"]
        property = change["property"]
        value = change["value"]

        if property not in property_converters:
            return json_error(
                _("Unknown subscription property: {}").format(property))

        (stream, recipient, sub) = access_stream_by_id(user_profile, stream_id)
        if sub is None:
            return json_error(
                _("Not subscribed to stream id {}").format(stream_id))

        try:
            value = property_converters[property](property, value)
        except ValidationError as error:
            return json_error(error.message)

        do_change_subscription_property(user_profile, sub, stream, property,
                                        value)

        response_data.append({
            'stream_id': stream_id,
            'property': property,
            'value': value
        })

    return json_success({"subscription_data": response_data})
Example #3
0
def json_subscription_property(
    request,
    user_profile,
    subscription_data=REQ(validator=check_list(
        check_dict([("stream", check_string), ("property", check_string),
                    ("value",
                     check_variable_type([check_string, check_bool]))])))):
    # type: (HttpRequest, UserProfile, List[Dict[str, Any]]) -> HttpResponse
    """
    This is the entry point to changing subscription properties. This
    is a bulk endpoint: requestors always provide a subscription_data
    list containing dictionaries for each stream of interest.

    Requests are of the form:

    [{"stream": "devel", "property": "in_home_view", "value": False},
     {"stream": "devel", "property": "color", "value": "#c2c2c2"}]
    """
    if request.method != "POST":
        return json_error(_("Invalid verb"))

    property_converters = {
        "color": check_string,
        "in_home_view": check_bool,
        "desktop_notifications": check_bool,
        "audible_notifications": check_bool,
        "pin_to_top": check_bool
    }
    response_data = []

    for change in subscription_data:
        stream_name = change["stream"]
        property = change["property"]
        value = change["value"]

        if property not in property_converters:
            return json_error(
                _("Unknown subscription property: %s") % (property, ))

        (stream, recipient,
         sub) = access_stream_by_name(user_profile, stream_name)
        if sub is None:
            return json_error(
                _("Not subscribed to stream %s") % (stream_name, ))

        property_conversion = property_converters[property](property, value)
        if property_conversion:
            return json_error(property_conversion)

        do_change_subscription_property(user_profile, sub, stream, property,
                                        value)

        response_data.append({
            'stream': stream_name,
            'property': property,
            'value': value
        })

    return json_success({"subscription_data": response_data})
Example #4
0
 def change_subscription_properties(
     user_profile: UserProfile,
     stream: Stream,
     sub: Subscription,
     properties: Dict[str, bool],
 ) -> None:
     for property_name, value in properties.items():
         do_change_subscription_property(user_profile, sub, stream, property_name, value)
Example #5
0
def json_subscription_property(
    request,
    user_profile,
    subscription_data=REQ(
        validator=check_list(
            check_dict(
                [
                    ("stream", check_string),
                    ("property", check_string),
                    ("value", check_variable_type([check_string, check_bool])),
                ]
            )
        )
    ),
):
    # type: (HttpRequest, UserProfile, List[Dict[str, Any]]) -> HttpResponse
    """
    This is the entry point to changing subscription properties. This
    is a bulk endpoint: requestors always provide a subscription_data
    list containing dictionaries for each stream of interest.

    Requests are of the form:

    [{"stream": "devel", "property": "in_home_view", "value": False},
     {"stream": "devel", "property": "color", "value": "#c2c2c2"}]
    """
    if request.method != "POST":
        return json_error(_("Invalid verb"))

    property_converters = {
        "color": check_string,
        "in_home_view": check_bool,
        "desktop_notifications": check_bool,
        "audible_notifications": check_bool,
        "pin_to_top": check_bool,
    }
    response_data = []

    for change in subscription_data:
        stream_name = change["stream"]
        property = change["property"]
        value = change["value"]

        if property not in property_converters:
            return json_error(_("Unknown subscription property: %s") % (property,))

        sub = get_subscription_or_die(stream_name, user_profile)[0]

        property_conversion = property_converters[property](property, value)
        if property_conversion:
            return json_error(property_conversion)

        do_change_subscription_property(user_profile, sub, stream_name, property, value)

        response_data.append({"stream": stream_name, "property": property, "value": value})

    return json_success({"subscription_data": response_data})
Example #6
0
def json_subscription_property(
    request,
    user_profile,
    subscription_data=REQ(validator=check_list(
        check_dict([["stream", check_string], ["property", check_string],
                    ["value",
                     check_variable_type([check_string, check_bool])]])))):
    """
    This is the entry point to changing subscription properties. This
    is a bulk endpoint: requestors always provide a subscription_data
    list containing dictionaries for each stream of interest.

    Requests are of the form:

    [{"stream": "devel", "property": "in_home_view", "value": False},
     {"stream": "devel", "property": "color", "value": "#c2c2c2"}]
    """
    if request.method != "POST":
        return json_error("Invalid verb")

    property_converters = {
        "color": check_string,
        "in_home_view": check_bool,
        "desktop_notifications": check_bool,
        "audible_notifications": check_bool
    }
    response_data = []

    for change in subscription_data:
        stream_name = change["stream"]
        property = change["property"]
        value = change["value"]

        if property not in property_converters:
            return json_error("Unknown subscription property: %s" %
                              (property, ))

        sub = get_subscription_or_die(stream_name, user_profile)[0]

        property_conversion = property_converters[property](property, value)
        if property_conversion:
            return json_error(property_conversion)

        do_change_subscription_property(user_profile, sub, stream_name,
                                        property, value)

        response_data.append({
            'stream': stream_name,
            'property': property,
            'value': value
        })

    return json_success({"subscription_data": response_data})
Example #7
0
def update_subscription_properties_backend(
        request: HttpRequest, user_profile: UserProfile,
        subscription_data: List[Dict[str, Any]]=REQ(
            validator=check_list(
                check_dict([("stream_id", check_int),
                            ("property", check_string),
                            ("value", check_variable_type([check_string, check_bool]))])
            )
        ),
) -> HttpResponse:
    """
    This is the entry point to changing subscription properties. This
    is a bulk endpoint: requestors always provide a subscription_data
    list containing dictionaries for each stream of interest.

    Requests are of the form:

    [{"stream_id": "1", "property": "in_home_view", "value": False},
     {"stream_id": "1", "property": "color", "value": "#c2c2c2"}]
    """
    property_converters = {"color": check_color, "in_home_view": check_bool,
                           "desktop_notifications": check_bool,
                           "audible_notifications": check_bool,
                           "push_notifications": check_bool,
                           "email_notifications": check_bool,
                           "pin_to_top": check_bool}
    response_data = []

    for change in subscription_data:
        stream_id = change["stream_id"]
        property = change["property"]
        value = change["value"]

        if property not in property_converters:
            return json_error(_("Unknown subscription property: %s") % (property,))

        (stream, recipient, sub) = access_stream_by_id(user_profile, stream_id)
        if sub is None:
            return json_error(_("Not subscribed to stream id %d") % (stream_id,))

        property_conversion = property_converters[property](property, value)
        if property_conversion:
            return json_error(property_conversion)

        do_change_subscription_property(user_profile, sub, stream,
                                        property, value)

        response_data.append({'stream_id': stream_id,
                              'property': property,
                              'value': value})

    return json_success({"subscription_data": response_data})
Example #8
0
def update_subscription_properties_backend(
    request: HttpRequest,
    user_profile: UserProfile,
    subscription_data: List[Dict[str, Any]] = REQ(json_validator=check_list(
        check_dict([
            ("stream_id", check_int),
            ("property", check_string),
            ("value", check_union([check_string, check_bool])),
        ]), ), ),
) -> HttpResponse:
    """
    This is the entry point to changing subscription properties. This
    is a bulk endpoint: requestors always provide a subscription_data
    list containing dictionaries for each stream of interest.

    Requests are of the form:

    [{"stream_id": "1", "property": "is_muted", "value": False},
     {"stream_id": "1", "property": "color", "value": "#c2c2c2"}]
    """
    property_converters = {
        "color": check_color,
        "in_home_view": check_bool,
        "is_muted": check_bool,
        "desktop_notifications": check_bool,
        "audible_notifications": check_bool,
        "push_notifications": check_bool,
        "email_notifications": check_bool,
        "pin_to_top": check_bool,
        "wildcard_mentions_notify": check_bool,
    }

    for change in subscription_data:
        stream_id = change["stream_id"]
        property = change["property"]
        value = change["value"]

        if property not in property_converters:
            raise JsonableError(
                _("Unknown subscription property: {}").format(property))

        (stream, sub) = access_stream_by_id(user_profile, stream_id)
        if sub is None:
            raise JsonableError(
                _("Not subscribed to stream id {}").format(stream_id))

        try:
            value = property_converters[property](property, value)
        except ValidationError as error:
            raise JsonableError(error.message)

        do_change_subscription_property(user_profile,
                                        sub,
                                        stream,
                                        property,
                                        value,
                                        acting_user=user_profile)

    # TODO: Do this more generally, see update_realm_user_settings_defaults.realm.py
    from zerver.lib.request import RequestNotes

    request_notes = RequestNotes.get_notes(request)
    for req_var in request.POST:
        if req_var not in request_notes.processed_parameters:
            request_notes.ignored_parameters.add(req_var)

    result: Dict[str, Any] = {}
    if len(request_notes.ignored_parameters) > 0:
        result["ignored_parameters_unsupported"] = list(
            request_notes.ignored_parameters)

    return json_success(request, data=result)