Commit Graph

372 Commits

Author SHA1 Message Date
Zixuan James Li 95394de186 decorator: Refactor require_server_admin_api with ParamSpec.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-30 18:15:33 -07:00
Zixuan James Li b02779c005 request: Refactor remote_server into RequestNotes.
This eliminates the possibility of having `request.user` as
`RemoteZulipServer` by refactoring it as an attribute of `RequestNotes`.

So we can effectively narrow the type of `request.user` by testing
`user.is_authenticated` in most cases (except that of `SCIMClient`) in
code paths that require access to `.format_requestor_for_logs` where we
previously expect either `UserProfile` or `RemoteZulipServer` backed by
the implied polymorphism.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-28 09:38:40 -07:00
Zixuan James Li 3bc78d2473 decorator: Do not set remote_server.rate_limits.
In b46af40bd3,
we set this attribute because back then we might call `rate_limit_user`
on `RemoteZulipServer`.

This is no longer the case as `RemoteZulipServer` now has its own rate
limiting and we never call `rate_limit_user` without an `isinstance` check
for `UserProfile`.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-28 09:38:40 -07:00
Zixuan James Li 789b66ff3b decorator: Remove unnecessary flag for process_client.
We can express the same idea more simply by not passing `user` in
cases where it isn't valid for UserActivity.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-28 09:38:21 -07:00
Zixuan James Li 06d3f3cf64 2fa: Refactor is_2fa_verified to require type narrowing.
This makes it mandatory to narrow the type of the user to `UserProfile`
before calling this helper.

This effectively removes the `request.user` check. We do not call login_page
anywhere else without getting through the authentication middleware.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-27 14:28:31 -07:00
Zixuan James Li 159449b448 response: Replace json_unauthorized with UnauthorizedError.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-18 18:01:42 -07:00
Tim Abbott 05b70ba74a decorator: Explicitly require req_secret in internal_notify_view.
It's hard to come up with a realistic story where this would matter:
SHARED_SECRET is generated automatically during server setup at the
same time as SECRET_KEY, which is a required setting, but it seems
preferable to be explicit that this is a required parameter for the
internal_notify authentication model.
2022-07-15 09:20:37 -07:00
Lauryn Menard 855e14272a backend: Migrate `secret` parameter to REQ framework.
Instead of using request.POST to get any potential `secret`
parameter used in `authenticate_notify` for `internal_notify_view`
decorator, moves it to the REQ framework parameters as `req_secret`.

Updates existing tests to explicitly test for a request without
`secret` parameter, which defaults to `None`; this is also tested
in `test_event_system.py`.
2022-07-15 09:20:37 -07:00
Zixuan James Li 74f59bd8d0 2fa: Rename zulip_otp_required for clarity.
The name does not really comply with the actual behavior of
the decorator since it returns True for an unauthenticated user.
This makes it clear that the 2fa check only applies to users that
are already logged in.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-13 14:49:41 -07:00
Zixuan James Li 00bd7513f2 2fa: Verify 2FA authentication status with is_2fa_verified.
This replaces user.is_verified with is_2fa_verified.

The helper does extra checks such that the user being checked for 2fa
authentication status is valid.

`request.user.is_verified` is functionally the same as `is_verified`
from `django_otp.middleware`, except that the former is monkey-patched
onto the user object by the 2FA middleware. We use the latter wrapped
in `is_2fa_verified` instead to avoid accessing the patched attribute.

See also: 6b24d56e59/docs/source/overview.rst (authentication-and-verification)

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-13 14:49:41 -07:00
Zixuan James Li 3367839839 decorator: Add test case for unauthenticated 2fa.
This simulates the situation in which the user is not
authenticated (as an AnonymousUser) and have 2FA enabled.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-07-13 14:49:41 -07:00
Zixuan James Li e11013fc00 decorator: Remove unused Union.
The other variant of possible return type was removed in
7c9e8a5071, but the return type is not
accurately reflecting that.
2022-07-06 17:20:57 -07:00
Zixuan James Li a3a0545aac typing: Populate POST and _files with `cast` and `setattr`.
`POST` is an immutable attribute and `_files` is an internal attribute
of `HttpRequest`. With type annotations provided by `django-stubs`, mypy
stops us from modifying these attributes. This uses `cast` and `setattr`
to avoid typing issues.

This is a part of django-stubs refactorings.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-06-28 16:07:18 -07:00
Anders Kaseorg 5033beb99c request: Replace tornado_handler weak reference with tornado_handler_id.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-06-25 08:42:23 -07:00
Anders Kaseorg c1a54f4567 decorator: Only URL-decode application/x-www-form-urlencoded requests.
We previously parsed any request with method other than {GET, POST} and
Content-Type other than multipart/form-data as if it were
application/x-www-form-urlencoded.

Check that Content-Type is application/x-www-form-urlencoded before
parsing the body that way.  Restrict this logic to {DELETE, PATCH,
PUT} (having a body at all doesn’t make sense for {CONNECT, HEAD,
OPTIONS, TRACE}).

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-06-25 08:36:16 -07:00
Zixuan James Li a86ba33087 webhooks: Use setattr when assigning _all_event_types.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2022-06-23 19:25:48 -07:00
Alex Vandiver 814841c9ec puppet: Remove typo'd cron job.
54b6a83412 fixed the typo introduced in 49ad188449, but that does
not clean up existing installs which had the file with the wrong name
already.

Remove the file with the typo'd name, so two jobs do not race, and fix
the typo in the comment.
2022-05-16 14:57:21 -07:00
Anders Kaseorg 0043c0b6b2 django: Use HttpRequest.headers.
Fixes #14769.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-05-13 20:42:20 -07:00
Anders Kaseorg 110f7a379a beanstalk: Move %40 kludge into authenticated_rest_api_view.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-05-13 20:42:20 -07:00
Zixuan James Li e632a4ced2 decorator: Strengthen decorator types using ParamSpec.
Signed-off-by: Zixuan James Li <359101898@qq.com>
2022-04-14 12:44:35 -07:00
Zixuan James Li 9d448e73d2 decorator: Remove cachify in favor of lru_cache.
`cachify` is essentially caching the return value of a function using only
the non-keyword-only arguments as the key.

The use case of the function in the backend can be sufficiently covered by
`functools.lru_cache` as an unbound cache. There is no signficant difference
apart from `cachify` overlooking keyword-only arguments, and
`functools.lru_cache` being conveniently typed.

Signed-off-by: Zixuan James Li <359101898@qq.com>
2022-04-14 12:44:35 -07:00
Anders Kaseorg 5f92078d07 request: Add a var_name parameter to converter.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-03-15 13:02:02 -07:00
Aman Agrawal 7c9e8a5071 decorator: Enable web-public view for production. 2022-02-16 13:25:53 -08:00
Lauryn Menard 3be622ffa7 backend: Add request as parameter to json_success.
Adds request as a parameter to json_success as a refactor towards
making `ignored_parameters_unsupported` functionality available
for all API endpoints.

Also, removes any data parameters that are an empty dict or
a dict with the generic success response values.
2022-02-04 15:16:56 -08:00
Anders Kaseorg 2caeb38e9e python: Replace IOError with OSError.
IOError is an alias for OSError in Python ≥ 3.3.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-01-23 22:17:02 -08:00
Eeshan Garg 94d00ca942 zilencer: Stop serving requests from deactivated remote servers. 2022-01-21 14:56:04 -08:00
Eeshan Garg 2393342e03 webhooks/jira: Handle anomalous payloads properly.
We recently ran into a payload in production that didn't contain
an event type at all. A payload where we can't figure out the event
type is quite rare. Instead of letting these payloads run amok, we
should raise a more informative exception for such unusual payloads.
If we encounter too many of these, then we can choose to conduct a
deeper investigation on a case-by-case basis.

With some changes by Tim Abbott.
2021-12-28 10:56:25 -08:00
Alex Vandiver 49ad188449 rate_limit: Add a flag to lump all TOR exit node IPs together.
TOR users are legitimate users of the system; however, that system can
also be used for abuse -- specifically, by evading IP-based
rate-limiting.

For the purposes of IP-based rate-limiting, add a
RATE_LIMIT_TOR_TOGETHER flag, defaulting to false, which lumps all
requests from TOR exit nodes into the same bucket.  This may allow a
TOR user to deny other TOR users access to the find-my-account and
new-realm endpoints, but this is a low cost for cutting off a
significant potential abuse vector.

If enabled, the list of TOR exit nodes is fetched from their public
endpoint once per hour, via a cron job, and cached on disk.  Django
processes load this data from disk, and cache it in memcached.
Requests are spared from the burden of checking disk on failure via a
circuitbreaker, which trips of there are two failures in a row, and
only begins trying again after 10 minutes.
2021-11-16 11:42:00 -08:00
Alex Vandiver cbbd4b128d push_notifications: Provide a hint when the server is not registered. 2021-10-19 12:17:30 -07:00
Aman Agrawal 3b29c61409 auth: Add login buttons for web public access.
For users who are not logged in and for those who don't have
'prefers_web_public_view' set in session, we redirect them
to the default login page where they can choose to login
as spectator or authenticated user.
2021-10-05 16:30:40 -07:00
Aman Agrawal 5a2a787b76 user_passes_test: Extract zulip_redirect_to_login from it.
This function will be re-used to
setup redirect logic in home view.
2021-09-14 10:33:53 -07:00
PIG208 53888e5a26 request: Refactor ZulipRequestNotes to RequestNotes.
This utilizes the generic `BaseNotes` we added for multipurpose
patching. With this migration as an example, we can further support
more types of notes to replace the monkey-patching approach we have used
throughout the codebase for type safety.
2021-09-03 08:48:45 -07:00
Anders Kaseorg ad5f0c05b5 python: Remove default "utf8" argument for encode(), decode().
Partially generated by pyupgrade.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-08-02 15:53:52 -07:00
PIG208 e517f967b8 typing: Amend inaccurate type annotations.
This amend some type annotations that turn out to be inaccurate with
django-stubs.
2021-07-27 12:17:00 -07:00
PIG208 8121d2d58d typing: Fix misuse of HttpResponse.
Amend usage of HttpResponse when appropriate.
2021-07-27 14:31:19 +08:00
PIG208 f280ebe4b5 decorator: Type zulip_login_required with overload.
As we only return the actual decorator as-is only if `function` is
`None`, we can use `@overload` to accurately annotate the return type
for the decorator.
2021-07-26 15:09:07 -07:00
Mateusz Mandera 4418aefde4 decorators: Extract rate_limit_request_by_ip function. 2021-07-24 15:52:06 -07:00
Tim Abbott 01ce58319d mypy: Fix most AnonymousUser type errors.
This commit fixes several mypy errors with Django stubs, by telling
mypy that we know in a given code path that the user is authenticated.
2021-07-24 14:55:46 -07:00
Anders Kaseorg fb3ddf50d4 python: Fix mypy no_implicit_reexport errors.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-07-16 14:02:31 -07:00
sahil839 50240ca71b models: Use COMMON_POLICY_TYPES for user_group_edit_policy.
This commit adds moderators and full members options for
user_group_edit_policy by using COMMON_POLICY_TYPES.

Moderators do not require to be a member of user group in
order to edit or remove the user group if they are allowed
to do so according to user_group_edit_policy.
But full members need to be a member of user group to edit
or remove the user group.
2021-07-14 14:38:44 -07:00
PIG208 c03b9c95ad request: Store client information using ZulipRequestNotes.
This concludes the HttpRequest migration to eliminate arbitrary
attributes (except private ones that are belong to django) attached
to the request object during runtime and migrated them to a
separate data structure dedicated for the purpose of adding
information (so called notes) to a HttpRequest.
2021-07-14 12:01:07 -07:00
PIG208 5167a93229 request: Move tornado_handler to ZulipRequestNotes. 2021-07-14 12:01:07 -07:00
PIG208 742c17399e request: Move miscellaneous attributes to ZulipRequestNotes.
This includes the migration of fields that require trivial changes
to be migrated to be stored with ZulipRequestNotes.

Specifically _requestor_for_logs, _set_language, _query, error_format,
placeholder_open_graph_description, saveed_response, which were all
previously set on the HttpRequest object at some point. This migration
allows them to be typed.
2021-07-14 12:01:07 -07:00
PIG208 5475334b16 request: Refactor to store requestor_for_logs in ZulipRequestNotes. 2021-07-14 12:01:07 -07:00
Mateusz Mandera 093ca7a574 zilencer: Log warning when a remote server hits rate limits.
We don't want this rate limit to affect legitimate users so it being hit
should be abnormal - thus worth logging so that we can spot if we're
rate limiting legitimate users and can know to increase the limit.
2021-07-08 15:55:03 -07:00
Mateusz Mandera 85cbdc8904 rate_limit: Add rate limiting of ZulipRemoteServer. 2021-07-08 15:55:02 -07:00
Mateusz Mandera b9056d193d rate_limit: Implement IP-based rate limiting.
If the user is logged in, we'll stick to rate limiting by the
UserProfile. In case of requests without authentication, we'll apply the
same limits but to the IP address.
2021-07-08 15:46:52 -07:00
Mateusz Mandera 5e8e843613 rate_limit: Remove domain arg to the rate_limit decorator.
This option of specifying a different domain isn't used anywhere as of
now and we don't have a concrete way it could be used in the near
future. It's also getting in the way of how we want to do rate limiting
by IP, for which we'll want to apply a new domain 'api_by_ip'. That's
incompatible with how this decorator wants to determine the domain based
on the argument it receives when called to decorate a view function.

If in the future we want to have more granular control over API domains,
this can be refactored to be more general, but as of now it's just
imposing restrictions on how we can write the rate limiting code inside
it.
2021-07-08 15:35:12 -07:00
PIG208 2f9c586af5 webhooks: Allow event registration using webhook_view decorator.
In addition to event filtering, we add support for registering supported
events for a webhook integration using the webhook_view decorator.

The event types are stored in the view function directly as a function
attribute, and can be later accessed via the module path and the view
function name are given (which is already specified the integrations.py)

Note that the WebhookTestCase doesn't know the name of the view function
and the module of the webhook. WEBHOOK_DIR_NAME needs to be overridden
if we want exceptions to raised when one of our test functions triggered
a unspecified event, but this practice is not enforced.

all_event_type does not need to be given even if event filters are used
in the webhook. But if a list of event types is given, it will be possible
for us to include it in the documentation while ensuring that all the
tested events are included (but not vice versa at the current stage, as
we yet not required all the events included in the list to be tested)

This guarantees that we can always access the list of all the tested
events of a webhook. This feature will be later plumbed to marcos to
display all event types dynamically in doc.md.
2021-07-05 19:10:31 -07:00
PIG208 a6e88a5a76 exceptions: Add AccessDeniedError. 2021-07-05 11:02:09 -07:00