Commit Graph

175 Commits

Author SHA1 Message Date
Sahil Batra
1b35ad3094 message: Use set instead of list when checking DM permission.
When checking DM permissions, instead of using list of
users, we now use set of users to check if any user is
in direct_message_permission_group because there can be
case when sender can also be one of the recipients.
2025-04-08 12:32:33 -07:00
Sahil Batra
f29166dbba settings: Do not pre-fetch DM permission group settings.
This commit updates code to not pre-fetch DM permission
group settings using select_related and instead just
fetch the required data from DB when checking permission.

This will increase one query but will help in pre-fetching
the settings for all users and for all type of messages.

Fixes part of #33677.
2025-04-07 15:34:30 -07:00
Sahil Batra
179782eaba user_groups: Refactor is_user_in_group and is_any_user_in_group.
This commit updates is_user_in_group and is_any_user_in_group
to accept group ID as parameter instead of UserGroup object.

This is a prep commit for updating code to not prefetch
direct message permissions group.
2025-04-07 15:34:30 -07:00
Shubham Padia
139679cdb1 user_groups: Add get_recursive_supergroups_union_for_groups.
This function will be useful in finding out affected groups when
sending events for users gaining or losing metadata access when the
members of a user group change in any way.
2025-03-25 13:20:06 -07:00
Shubham Padia
b3862c5008 user_groups: Use UserGroupMembersDict in initial state data.
On the event side, orjson does the work of converting
UserGroupMembersData to json. But when fetching intial state data,
UserGroupMembersData was being returned which is not
json-serializable. This was causing a mismatch in the `verify_action`
workflow of test_events related to stream group settings where
apply_events resulted in a state with `direct_members` and
`direct_subgroups` as part of an ordinary dict, while fetching initial
state data was giving us a UserGroupMembersData class.
This commit uses UserGroupMembersDict where appropriate. It will
still be good to keep around the dataclass class since it has the added
benefit of storing the relevant value when needed.
2025-03-18 11:53:48 -07:00
Tim Abbott
e18a87ce6c lint: Fix ruff-format violations.
Apparently these were masked by commits after
ac9b7b5fa1 in the PR fixing them.
2025-03-17 14:28:02 -07:00
Shubham Padia
ac9b7b5fa1 user_groups: Rename UserGroupMembersDict to UserGroupMembersData.
UserGroupMembersData is not serializable by orjson. We will be
introducing a TypedDict (which is serializable) in the next commit
called UserGroupMembersDict. This rename will help us distinguish
between the two.
2025-03-17 14:21:37 -07:00
Sahil Batra
5915b85c5a register: Optimize computing stream group setting values.
Fetch all anonymous groups data once which can be used
for computing group setting values for realm, streams
and user groups.

Fixes #32561.
2025-03-14 18:31:18 -07:00
Sahil Batra
0053c64f37 groups: Anonymous group member and subgroup IDs should be sorted.
We now return the members and subgroups ID list sorted for
settings that are set to anonymous groups. This is needed to
make sure we do not show save discard buttons when only pill
order is changed.
2025-03-12 17:18:05 -07:00
Shubham Padia
8481dcedc4 stream: Do not pass user group object when changing group setting.
Passing the user group object in case of named user group is fine for
`do_change_stream_group_based_setting`. But for anonymous groups, if the
code path calling that function is not creating a new anonymous user
group, it has to modify the user group by itself before calling that
function. In that case, if `old_setting_api_value` is not provided,
`old_user_group` is calculated false, since the group id has not changed
for the stream, but the group membership has changed.
old_setting_api_value will be the same as new_setting_api_value in such
a case.
It is better to accept the new setting value as either an int or
UserGroupMembersDict, so that `do_change_stream_group_based_setting` can
decide what to do with that argument.
2025-03-04 11:34:59 -08:00
Sahil Batra
c2f1b3673e register: Optimize computing realm group setting values.
We do not fetch all the realm group settings using
select_related for register data now since it takes a
lot of time in planning phase. This commit updates
the code to fetch all the members and subgroups data
in user_groups_in_realm_serialized so that we do not
need to access each setting group individually.

user_groups_in_realm_serialized is updated to send the
required data accordingly.

Fixes #33656.
2025-02-27 10:03:28 -08:00
Sahil Batra
643182ce42 user_groups: Refactor code in user_groups_in_realm_serialized.
Following improvments are done in user_groups_in_realm_serialized-
- Members and subgroups are fetched using a single query using
union.
- Query to fetch groups now does not fetch setting fields since
we already have the members and subgroups of all the setting
groups and we can check if setting group was a named group
or not directly without checking named_user_group field of
UserGroup object as we have IDs of all named groups of the realm.
2025-02-27 10:03:28 -08:00
Sahil Batra
75b5d43a91 groups: Rename AnonymousSettingGroupDict to UserGroupMembersDict.
This change is done because we would use the same data structure
for named user groups as well in future commits.
2025-02-27 10:03:28 -08:00
Shubham Padia
f6bb990b91 user_group: Move UserGroupMembershipDetails from lib/streams.py. 2025-02-21 15:36:07 -08:00
Sahil Batra
cf3315bd18 settings: Correctly handle passing empty anonymous group.
If empty anonymous group is passed for a setting value in
an API request, the setting is set to "Nobody" group.
2025-02-18 10:40:28 -08:00
Sahil Batra
a1ac49582b streams: Optimize computing users with metadata access.
This commit updates code to optimize computing users who have
metadata access via permission groups so that we do not have
to do DB query for each stream to get recursive members for
the groups having permissions.
2025-02-14 12:00:37 -08:00
Shubham Padia
33ea2b366e user_groups: Add function to get union of members of two groups.
This helps us important database queries when we want to perform a union
on the members of multiple user groups.
2025-02-11 15:09:16 -08:00
Shubham Padia
121af1c815 stream: Pass group id to get recursive group members.
Previously, we needed to pass the group to the function, which sometimes
meant having 1 extra query to fetch the user group when we just needed
the group id for this function.
2025-02-11 15:09:16 -08:00
Sahil Batra
8b068cf244 groups: Remove unused parameter from parse_group_setting_value.
setting_name parameter was not being used in
parse_group_setting_value function.
2025-02-06 17:20:01 -08:00
bedo
f9f6e6d7e6 mention: Optimize query when mentioning several groups.
Fixes: #32934

context:
Fetching all users who are members (directly or via sub-groups)
of groups mentioned in one message.

Reduce O(n) queries, where n is the number
of mentioned groups, to a constant of 1 query.

Extend "get_recursive_subgroups_for_groups" functionality to
"get_root_id_annotated_recursive_subgroups_for_groups"
which is the same but keeps track of each group root_id and
annotates it to each group.

Then in init_user_group_data(), we only fetch
each group's root_id along with
active direct members.
2025-01-28 10:29:40 -08:00
Sahil Batra
121df45cc4 groups: Remove allow_owners_group field from GroupPermissionSetting.
As we now allow anonymous groups and settings can be set to any
set of users, there is no benefit in not allowing a setting to
be set to "Owners" group.
2024-12-04 11:12:28 -08:00
Sahil Batra
7e6a02b82d user_groups: Add setting to control who can remove members.
This commit adds a new setting to control who can remove
members from the group.
2024-12-02 17:38:44 -08:00
Shubham Padia
343741f621 stream: Fetch system groups in one query for group setting defaults.
Right now, the number of queries has remained the same, but when we add
more settings in the future, we won't be increasing the number of
queries when iterating over stream permission group settings.
2024-12-01 19:32:22 -08:00
Sahil Batra
b78ca79ccf user_groups: Define AnonymousSettingGroupDict in types.py.
AnonymousSettingGroupDict is now defined in types.py instead
of user_groups.py to avoid import cycles in future commits.
2024-11-15 16:36:37 -08:00
Sahil Batra
e5043b991a user_groups: Add API support to add subgroups during group creation.
This commit adds support to add subgroups to a group while
creating it.

User can add the subgroups to group irrespective of permissions
like user can add members during creating it.
2024-10-17 14:27:21 -07:00
Sahil Batra
47a611f989 user_groups: Check permission when adding subgroups.
This commit updates code to allow users with permission
to add members to add subgroups as well. And only users
with permission to manage the group can remove subgroups.

Also updated tests to check permissions in separate tests
and removed them from the existing test.
2024-10-17 14:27:21 -07:00
Sahil Batra
f24f1bfd14 user_groups: Refactor code to check permission for updating groups.
Users with permission to manage the group have all the permissions
including joining/leaving the group, adding others group which also
have a separate setting to control them.

So, it makes sense to just check managing permissions first in
access_user_group_for_update and then check the specific permission.
There is no behavioral change in this commit, it only changes the
order of checking permissions.
2024-10-16 09:40:07 -07:00
Tim Abbott
7e7113ad84 groups: Enable group-settings value on groups in production.
The main change is redefining ALLOW_GROUP_VALUED_SETTINGS to not
control code, but instead to instead control the configuration for
whether settings that have not been converted to use our modern UI
patterns should require system groups.

Fundamentally, it's the same for the realm/stream group-valued
settings, which don't have the new UI patterns yet.

We remove the visual hiding of the "can manage group" setting, which
was hidden only due to transitions being incomplete.
2024-10-15 15:58:54 -07:00
Shubham Padia
060156fca4 user_groups: Add can_leave_group setting for user group.
This field will be used to control permission for who can
leave a user group.
2024-10-14 11:44:27 -07:00
Shubham Padia
c9d5276031 user_groups: Set can_manage_all_groups to administrator group.
Earlier we use to restrict admins, moderators or members of a group to
manage that group if they were part of the realm wide
`can_manage_all_groups`. We will not do that anymore and even
non-members of a group regardless of role can manage a group if they are
part of `can_manage_all_groups`.

See
https://chat.zulip.org/#narrow/stream/101-design/topic/Group.20add.20members.20dropdown/near/1952902
to check more about the migration plan for which this is the last step.
2024-10-11 16:31:18 -07:00
Shubham Padia
f134662312 user_groups: Check can_add_members_group before adding members.
Removing members will be controlled by `can_manage_group` until we add
`can_remove_members_group` in the future.

Users with permission to manage a group can add members to that group by
default without being present in `can_add_members_group`.
2024-10-11 16:31:18 -07:00
Shubham Padia
b305ca14dd user_groups: Add add_can_members_group to user group.
The default value for this field that we wanted to have was that group
itlself. But we are deferring that to later in order to reach the point
of switching over to the groups system sooner. Till then, we will use
`group_creator` as the default. See
https://chat.zulip.org/#narrow/stream/101-design/topic/Group.20add.20members.20dropdown/near/1952904
for more details.

For migration plan details, see
https://chat.zulip.org/#narrow/stream/101-design/topic/Group.20add.20members.20dropdown/near/1952902

The increase in query count from 7 to 9 in the query count test for
creating a user group is because of group_creator being the default for
the new field.
2024-10-11 16:31:18 -07:00
Sahil Batra
4784c71bf9 user_groups: Do not allow updating memberships of deactivated users.
This commit updates backend code to not allow adding deactivated
users to groups including when creating groups and also to not
allow removing deactivated users from groups.
2024-10-10 11:37:44 -07:00
Sahil Batra
0b58820294 user_groups: Do not include deactivated users in anonymous group settings.
This commit updates code to not include deactivated users in the
anonymous group settings data sent to clients, where the setting
value is sent as a dict containing members and subgroups of the
anonymous group.
2024-10-10 11:37:44 -07:00
Sahil Batra
9292ad8186 user_groups: Do not include deactivated users in members list.
This commit updates code to not include deactivated users in
members list in the user groups object sent in "/register"
and "GET /user_groups" response and also in the response
returned by endpoint like "GET /user_groups/{group_id}/members".

The events code is also update to handle this -
- We expect clients to update the members list on receiving
"realm_user/update" event on deactivation. But for guests
who cannot access the user, "user_group/remove_members"
event is sent to update the group members list on deactivation.
- "user_group/add_members" event is sent to all the users on
reactivating the user.
2024-10-10 11:37:44 -07:00
Sahil Batra
1033230b52 user_groups: Include "can_join_group" field in user group objects.
Fixes part of #25938.
2024-10-08 12:18:13 -07:00
Sahil Batra
e1d7f57da7 user_groups: Add can_join_group setting for user group.
This field will be used to control permission for who can
join a user group.

Fixes part of #25938.
2024-10-08 12:18:13 -07:00
Shubham Padia
12ebd97f1f settings: Add group_creator as default for can_manage_group.
We create an unnamed user group with just the group creator as it's
member when trying to set the default. The pattern I've followed across
most of the acting_user additions is to just put the user declared
somewhere before the check_add_user_group and see if the test passes.
If it does not, then I'll look at what kind of user it needs to be set
to `acting_user`.
2024-10-01 17:35:14 -07:00
Shubham Padia
91edf59873 settings: Rename can_edit_all_user_groups to use manage.
Having both `manage` and `edit` terminologies was confusing, so
this commit ensures that we use `manage` wherever applicable.
2024-10-01 17:35:14 -07:00
Shubham Padia
6e9d56eaf4 user_groups: Check permission to manage groups based on group setting.
We also add exception for the group creator to manage groups. See
https://chat.zulip.org/#narrow/stream/3-backend/topic/Group.20creation.20-.20who.20can.20change.20the.20setting.2E/near/1943861
for more details. For the tests, wherever possible, we've just added an
acting_user when creating a group to test.
We've also added an acting_user argument to create_user_group_for_test.
We will not remove `user_group_edit_policy` yet. That will be removed
once we have introduced this setting to the frontend.
2024-10-01 17:35:14 -07:00
Sahil Batra
b8a039ee99 user_groups: Include settings and supergroups in error response.
The error response when a user group cannot be deactivated due
to it being used as a subgroup or for a setting includes details
about the supergroups, streams, user groups as well the settings
for which it is used.
2024-10-01 09:45:33 -07:00
Sahil Batra
c1973d2263 user_groups: Add access_user_group_to_read_membership.
This commit adds access_user_group_to_read_membership function
so that we can avoid calling get_user_group_by_id_in_realm with
"for_read=True" from views functions, which is better for security
since that function does not do any access checks.
2024-10-01 09:36:01 -07:00
Tim Abbott
096fea48a0 user_groups: Add docstrings for several functions. 2024-09-30 18:42:14 -07:00
Sahil Batra
b554106e6d user_groups: Allow members of subgroups to manage group.
Previously, if the user_group_edit_policy was set to allow
members or full members to manage the group, the user had
to be the direct member of the group being managed.

This commit updates the code to allow members of the subgroups
as well to manage the group as technically members of the
subgroups are member of the group.

This also improves the code to not fetch all the group members
to check this, and instead directly call is_user_in_group
which uses "exists" to check it.
2024-09-30 18:42:14 -07:00
Sahil Batra
233775d257 user_groups: Rename has_user_group_access.
This commit renames has_user_group_access function to
has_user_group_access_for_subgroup, since the function
is only used to check access for using a group as subgroup.
2024-09-30 18:42:14 -07:00
Sahil Batra
0c89621fa6 user_groups: Refactor code to check permissions.
This commit refactors the code to check permission for
accessing user group in such a way that we can avoid
duplicate code in future when we will have different
settings controlling the permissions for editing group
details and settings, joining the group, adding others
to group, etc.
2024-09-30 18:42:14 -07:00
Sahil Batra
5c790aac72 user_groups: Rename allow_deactivated in 'GET /user_groups'.
This commit renames "allow_deactivated" parameter in
"GET /user_groups" endpoint to "include_deactivated_groups", so
that we can have consistent naming here and for client capability
used for deciding whether to send deactivated groups in register
response and how to handle the related events.
2024-09-18 13:41:13 -07:00
Sahil Batra
7a6135371e settings: Handle guests separately for group-based settings.
This commit adds code to handle guests separately for group
based settings, where guest will only have permission if
that particular setting can be set to "role:everyone" group
even if the guest user is part of the group which is used
for that setting. This is to make sure that guests do not
get permissions for actions that we generally do not want
guests to have.

Currently the guests do not have permission for most of them
except for "Who can delete any message", where guest could
delete a message if the setting was set to a user defined
group with guest being its member. But this commit still
update the code to use the new function for all the settings
as we want to have a consistent pattern of how to check whether
a user has permission for group-based settings.
2024-09-18 11:51:11 -07:00
sujal shah
614caf111e user_groups: Add creator and date_created field in user groups.
This commit introduced 'creator' and 'date_created'
fields in user groups, allowing users to view who
created the groups and when.

Both fields can be null for groups without creator data.
2024-09-13 18:44:58 -07:00
Sahil Batra
688c5ad0af groups: Allow excluding deactivated groups in 'GET /user_groups' response. 2024-09-11 09:43:56 -07:00