@@ -33,59 +33,65 @@ class SupportedPermissionSettings {
3333 /// TODO(server): Stabilize [InitialSnapshot.serverSupportedPermissionSettings]
3434 /// or a similar API, and switch to using that. See thread:
3535 /// https://chat.zulip.org/#narrow/channel/378-api-design/topic/server_supported_permission_settings/near/2247549
36+ // TODO: When we get this data from the server, it will sometimes be missing
37+ // items that appear here, because they're for newer permissions that the
38+ // server doesn't know about. We'll want reasonable fallback behavior for
39+ // those missing items, and as a source for that, we can still record
40+ // current-server data somewhere in our codebase. Discussion:
41+ // https://github.com/zulip/zulip-flutter/pull/1842#discussion_r2331337006
3642 static SupportedPermissionSettings fixture = SupportedPermissionSettings (
3743 realm: {
3844 // From the server's Realm.REALM_PERMISSION_GROUP_SETTINGS,
3945 // in zerver/models/realms.py. Current as of 6ab30fcce, 2025-08.
4046 'create_multiuse_invite_group' : PermissionSettingsItem (
4147 // allow_nobody_group=True,
4248 allowEveryoneGroup: false ,
43- // default_group_name=SystemGroups.ADMINISTRATORS ,
49+ defaultGroupName : SystemGroupName .administrators ,
4450 ),
4551 'can_access_all_users_group' : PermissionSettingsItem (
4652 // require_system_group=True,
4753 // allow_nobody_group=False,
4854 allowEveryoneGroup: true ,
49- // default_group_name=SystemGroups.EVERYONE ,
55+ defaultGroupName : SystemGroupName .everyone ,
5056 // # Note that user_can_access_all_other_users in the web
5157 // # app is relying on members always have access.
5258 // allowed_system_groups=[SystemGroups.EVERYONE, SystemGroups.MEMBERS],
5359 ),
5460 'can_add_subscribers_group' : PermissionSettingsItem (
5561 // allow_nobody_group=True,
5662 allowEveryoneGroup: false ,
57- // default_group_name=SystemGroups.MEMBERS ,
63+ defaultGroupName : SystemGroupName .members ,
5864 ),
5965 'can_add_custom_emoji_group' : PermissionSettingsItem (
6066 // allow_nobody_group=True,
6167 allowEveryoneGroup: false ,
62- // default_group_name=SystemGroups.MEMBERS ,
68+ defaultGroupName : SystemGroupName .members ,
6369 ),
6470 'can_create_bots_group' : PermissionSettingsItem (
6571 // allow_nobody_group=True,
6672 allowEveryoneGroup: false ,
67- // default_group_name=SystemGroups.MEMBERS ,
73+ defaultGroupName : SystemGroupName .members ,
6874 ),
6975 'can_create_groups' : PermissionSettingsItem (
7076 // allow_nobody_group=True,
7177 allowEveryoneGroup: false ,
72- // default_group_name=SystemGroups.MEMBERS ,
78+ defaultGroupName : SystemGroupName .members ,
7379 ),
7480 'can_create_public_channel_group' : PermissionSettingsItem (
7581 // allow_nobody_group=True,
7682 allowEveryoneGroup: false ,
77- // default_group_name=SystemGroups.MEMBERS ,
83+ defaultGroupName : SystemGroupName .members ,
7884 ),
7985 'can_create_private_channel_group' : PermissionSettingsItem (
8086 // allow_nobody_group=True,
8187 allowEveryoneGroup: false ,
82- // default_group_name=SystemGroups.MEMBERS ,
88+ defaultGroupName : SystemGroupName .members ,
8389 ),
8490 'can_create_web_public_channel_group' : PermissionSettingsItem (
8591 // require_system_group=True,
8692 // allow_nobody_group=True,
8793 allowEveryoneGroup: false ,
88- // default_group_name=SystemGroups.OWNERS ,
94+ defaultGroupName : SystemGroupName .owners ,
8995 // allowed_system_groups=[
9096 // SystemGroups.MODERATORS,
9197 // SystemGroups.ADMINISTRATORS,
@@ -96,77 +102,77 @@ class SupportedPermissionSettings {
96102 'can_create_write_only_bots_group' : PermissionSettingsItem (
97103 // allow_nobody_group=True,
98104 allowEveryoneGroup: false ,
99- // default_group_name=SystemGroups.MEMBERS ,
105+ defaultGroupName : SystemGroupName .members ,
100106 ),
101107 'can_delete_any_message_group' : PermissionSettingsItem (
102108 // allow_nobody_group=True,
103109 allowEveryoneGroup: false ,
104- // default_group_name=SystemGroups.ADMINISTRATORS ,
110+ defaultGroupName : SystemGroupName .administrators ,
105111 ),
106112 'can_delete_own_message_group' : PermissionSettingsItem (
107113 // allow_nobody_group=True,
108114 allowEveryoneGroup: true ,
109- // default_group_name=SystemGroups.EVERYONE ,
115+ defaultGroupName : SystemGroupName .everyone ,
110116 ),
111117 'can_invite_users_group' : PermissionSettingsItem (
112118 // allow_nobody_group=True,
113119 allowEveryoneGroup: false ,
114- // default_group_name=SystemGroups.MEMBERS ,
120+ defaultGroupName : SystemGroupName .members ,
115121 ),
116122 'can_manage_all_groups' : PermissionSettingsItem (
117123 // allow_nobody_group=False,
118124 allowEveryoneGroup: false ,
119- // default_group_name=SystemGroups.OWNERS ,
125+ defaultGroupName : SystemGroupName .owners ,
120126 ),
121127 'can_manage_billing_group' : PermissionSettingsItem (
122128 // allow_nobody_group=False,
123129 allowEveryoneGroup: false ,
124- // default_group_name=SystemGroups.ADMINISTRATORS ,
130+ defaultGroupName : SystemGroupName .administrators ,
125131 ),
126132 'can_mention_many_users_group' : PermissionSettingsItem (
127133 // allow_nobody_group=True,
128134 allowEveryoneGroup: true ,
129- // default_group_name=SystemGroups.ADMINISTRATORS ,
135+ defaultGroupName : SystemGroupName .administrators ,
130136 ),
131137 'can_move_messages_between_channels_group' : PermissionSettingsItem (
132138 // allow_nobody_group=True,
133139 allowEveryoneGroup: false ,
134- // default_group_name=SystemGroups.MEMBERS ,
140+ defaultGroupName : SystemGroupName .members ,
135141 ),
136142 'can_move_messages_between_topics_group' : PermissionSettingsItem (
137143 // allow_nobody_group=True,
138144 allowEveryoneGroup: true ,
139- // default_group_name=SystemGroups.EVERYONE ,
145+ defaultGroupName : SystemGroupName .everyone ,
140146 ),
141147 'can_resolve_topics_group' : PermissionSettingsItem (
142148 // allow_nobody_group=True,
143149 allowEveryoneGroup: true ,
144- // default_group_name=SystemGroups.EVERYONE ,
150+ defaultGroupName : SystemGroupName .everyone ,
145151 ),
146152 'can_set_delete_message_policy_group' : PermissionSettingsItem (
147153 // allow_nobody_group=True,
148154 allowEveryoneGroup: false ,
149- // default_group_name=SystemGroups.MODERATORS ,
155+ defaultGroupName : SystemGroupName .moderators ,
150156 ),
151157 'can_set_topics_policy_group' : PermissionSettingsItem (
152158 // allow_nobody_group=True,
153159 allowEveryoneGroup: true ,
154- // default_group_name=SystemGroups.MEMBERS ,
160+ defaultGroupName : SystemGroupName .members ,
155161 ),
156162 'can_summarize_topics_group' : PermissionSettingsItem (
157163 // allow_nobody_group=True,
158164 allowEveryoneGroup: true ,
159- // default_group_name=SystemGroups.EVERYONE ,
165+ defaultGroupName : SystemGroupName .everyone ,
160166 ),
161167 'direct_message_initiator_group' : PermissionSettingsItem (
162168 // allow_nobody_group=True,
163169 allowEveryoneGroup: true ,
164- // default_group_name=SystemGroups.EVERYONE ,
170+ defaultGroupName : SystemGroupName .everyone ,
165171 ),
166172 'direct_message_permission_group' : PermissionSettingsItem (
167173 // allow_nobody_group=True,
168174 allowEveryoneGroup: true ,
169- // default_group_name=SystemGroups.EVERYONE ,
175+ defaultGroupName : SystemGroupName .everyone ,
170176 ),
171177 },
172178 group: {}, // Please go ahead and fill this in when we come to need it.
@@ -176,52 +182,52 @@ class SupportedPermissionSettings {
176182 "can_add_subscribers_group" : PermissionSettingsItem (
177183 // allow_nobody_group=True,
178184 allowEveryoneGroup: false ,
179- // default_group_name=SystemGroups.NOBODY ,
185+ defaultGroupName : SystemGroupName .nobody ,
180186 ),
181187 "can_administer_channel_group" : PermissionSettingsItem (
182188 // allow_nobody_group=True,
183189 allowEveryoneGroup: false ,
184- // default_group_name="stream_creator_or_nobody" ,
190+ defaultGroupName : PseudoSystemGroupName .streamCreatorOrNobody ,
185191 ),
186192 "can_delete_any_message_group" : PermissionSettingsItem (
187193 // allow_nobody_group=True,
188194 allowEveryoneGroup: true ,
189- // default_group_name=SystemGroups.NOBODY ,
195+ defaultGroupName : SystemGroupName .nobody ,
190196 ),
191197 "can_delete_own_message_group" : PermissionSettingsItem (
192198 // allow_nobody_group=True,
193199 allowEveryoneGroup: true ,
194- // default_group_name=SystemGroups.NOBODY ,
200+ defaultGroupName : SystemGroupName .nobody ,
195201 ),
196202 "can_move_messages_out_of_channel_group" : PermissionSettingsItem (
197203 // allow_nobody_group=True,
198204 allowEveryoneGroup: true ,
199- // default_group_name=SystemGroups.NOBODY ,
205+ defaultGroupName : SystemGroupName .nobody ,
200206 ),
201207 "can_move_messages_within_channel_group" : PermissionSettingsItem (
202208 // allow_nobody_group=True,
203209 allowEveryoneGroup: true ,
204- // default_group_name=SystemGroups.NOBODY ,
210+ defaultGroupName : SystemGroupName .nobody ,
205211 ),
206212 "can_remove_subscribers_group" : PermissionSettingsItem (
207213 // allow_nobody_group=True,
208214 allowEveryoneGroup: true ,
209- // default_group_name=SystemGroups.ADMINISTRATORS ,
215+ defaultGroupName : SystemGroupName .administrators ,
210216 ),
211217 "can_send_message_group" : PermissionSettingsItem (
212218 // allow_nobody_group=True,
213219 allowEveryoneGroup: true ,
214- // default_group_name=SystemGroups.EVERYONE ,
220+ defaultGroupName : SystemGroupName .everyone ,
215221 ),
216222 "can_subscribe_group" : PermissionSettingsItem (
217223 // allow_nobody_group=True,
218224 allowEveryoneGroup: false ,
219- // default_group_name=SystemGroups.NOBODY ,
225+ defaultGroupName : SystemGroupName .nobody ,
220226 ),
221227 "can_resolve_topics_group" : PermissionSettingsItem (
222228 // allow_nobody_group=True,
223229 allowEveryoneGroup: true ,
224- // default_group_name=SystemGroups.NOBODY ,
230+ defaultGroupName : SystemGroupName .nobody ,
225231 ),
226232 },
227233 );
@@ -237,12 +243,112 @@ class SupportedPermissionSettings {
237243@JsonSerializable (fieldRename: FieldRename .snake)
238244class PermissionSettingsItem {
239245 final bool allowEveryoneGroup;
246+
247+ final DefaultGroupName defaultGroupName;
248+
240249 // also other fields not yet used
241250
242- PermissionSettingsItem ({required this .allowEveryoneGroup});
251+ PermissionSettingsItem ({
252+ required this .allowEveryoneGroup,
253+ required this .defaultGroupName,
254+ });
243255
244256 factory PermissionSettingsItem .fromJson (Map <String , dynamic > json) =>
245257 _$PermissionSettingsItemFromJson (json);
246258
247259 Map <String , dynamic > toJson () => _$PermissionSettingsItemToJson (this );
248260}
261+
262+ /// A value of [PermissionSettingsItem.defaultGroupName] .
263+ ///
264+ /// Can be any of these:
265+ /// - a known system group [SystemGroupName]
266+ /// - a known special string [PseudoSystemGroupName]
267+ /// - an unknown system group or special string [DefaultGroupNameUnknown]
268+ sealed class DefaultGroupName {
269+ DefaultGroupName ();
270+
271+ factory DefaultGroupName .fromJson (String json) {
272+ final DefaultGroupName ? maybeResult = json.startsWith ('role:' )
273+ ? SystemGroupName .fromJson (json)
274+ : PseudoSystemGroupName .fromJson (json);
275+ return maybeResult ?? DefaultGroupNameUnknown (json);
276+ }
277+
278+ String toJson ();
279+ }
280+
281+ class DefaultGroupNameUnknown extends DefaultGroupName {
282+ DefaultGroupNameUnknown (this .apiValue);
283+ final String apiValue;
284+
285+ @override
286+ String toJson () => apiValue;
287+ }
288+
289+ /// A known special string
290+ /// that [PermissionSettingsItem.defaultGroupName] might be.
291+ ///
292+ /// See server implementation, e.g.
293+ /// `can_administer_channel_group` in zerver/models/streams.py.
294+ @JsonEnum (valueField: 'apiValue' , alwaysCreate: true )
295+ enum PseudoSystemGroupName implements DefaultGroupName {
296+ // Discussion on this; it looks like it might get renamed:
297+ // https://chat.zulip.org/#narrow/channel/378-api-design/topic/stream_creator_or_nobody/near/2258637
298+ streamCreatorOrNobody (apiValue: 'stream_creator_or_nobody' ),
299+ ;
300+
301+ const PseudoSystemGroupName ({required this .apiValue});
302+
303+ final String apiValue;
304+
305+ /// Get a [PseudoSystemGroupName] from an [apiValue] ,
306+ /// or null if it's not recognized.
307+ ///
308+ /// Example:
309+ /// 'stream_creator_or_nobody' -> PseudoSystemGroupName.streamCreatorOrNobody
310+ static PseudoSystemGroupName ? fromJson (String json) => _byApiValue[json];
311+
312+ // _$…EnumMap is thanks to `alwaysCreate: true`
313+ static final _byApiValue = _$PseudoSystemGroupNameEnumMap
314+ .map ((key, value) => MapEntry (value, key));
315+
316+ @override
317+ String toJson () => _$PseudoSystemGroupNameEnumMap [this ]! ;
318+ }
319+
320+ /// A known canonical name for a system group.
321+ ///
322+ /// Doc: https://zulip.com/api/group-setting-values#system-groups
323+ @JsonEnum (valueField: 'apiValue' , alwaysCreate: true )
324+ enum SystemGroupName implements DefaultGroupName {
325+ // TODO(#1096) audit all references when implementing public-access option
326+ everyoneOnInternet (apiValue: 'role:internet' ),
327+
328+ everyone (apiValue: 'role:everyone' ),
329+ members (apiValue: 'role:members' ),
330+ fullMembers (apiValue: 'role:fullmembers' ),
331+ moderators (apiValue: 'role:moderators' ),
332+ administrators (apiValue: 'role:administrators' ),
333+ owners (apiValue: 'role:owners' ),
334+ nobody (apiValue: 'role:nobody' ),
335+ ;
336+
337+ const SystemGroupName ({required this .apiValue});
338+
339+ final String apiValue;
340+
341+ /// Get a [SystemGroupName] from an [apiValue] ,
342+ /// or null if it's not recognized.
343+ ///
344+ /// Example:
345+ /// 'role:administrators' -> SystemGroupName.administrators
346+ static SystemGroupName ? fromJson (String json) => _byApiValue[json];
347+
348+ // _$…EnumMap is thanks to `alwaysCreate: true`
349+ static final _byApiValue = _$SystemGroupNameEnumMap
350+ .map ((key, value) => MapEntry (value, key));
351+
352+ @override
353+ String toJson () => _$SystemGroupNameEnumMap [this ]! ;
354+ }
0 commit comments