@@ -456,59 +456,65 @@ class SupportedPermissionSettings {
456456 /// TODO(server): Stabilize [InitialSnapshot.serverSupportedPermissionSettings]
457457 /// or a similar API, and switch to using that. See thread:
458458 /// https://chat.zulip.org/#narrow/channel/378-api-design/topic/server_supported_permission_settings/near/2247549
459+ // TODO: When we get this data from the server, it will sometimes be missing
460+ // items that appear here, because they're for newer permissions that the
461+ // server doesn't know about. We'll want reasonable fallback behavior for
462+ // those missing items, and as a source for that, we can still record
463+ // current-server data somewhere in our codebase. Discussion:
464+ // https://github.com/zulip/zulip-flutter/pull/1842#discussion_r2331337006
459465 static SupportedPermissionSettings fixture = SupportedPermissionSettings (
460466 realm: {
461467 // From the server's Realm.REALM_PERMISSION_GROUP_SETTINGS,
462468 // in zerver/models/realms.py. Current as of 6ab30fcce, 2025-08.
463469 'create_multiuse_invite_group' : PermissionSettingsItem (
464470 // allow_nobody_group=True,
465471 allowEveryoneGroup: false ,
466- // default_group_name=SystemGroups.ADMINISTRATORS ,
472+ defaultGroupName : SystemGroupName .administrators ,
467473 ),
468474 'can_access_all_users_group' : PermissionSettingsItem (
469475 // require_system_group=True,
470476 // allow_nobody_group=False,
471477 allowEveryoneGroup: true ,
472- // default_group_name=SystemGroups.EVERYONE ,
478+ defaultGroupName : SystemGroupName .everyone ,
473479 // # Note that user_can_access_all_other_users in the web
474480 // # app is relying on members always have access.
475481 // allowed_system_groups=[SystemGroups.EVERYONE, SystemGroups.MEMBERS],
476482 ),
477483 'can_add_subscribers_group' : PermissionSettingsItem (
478484 // allow_nobody_group=True,
479485 allowEveryoneGroup: false ,
480- // default_group_name=SystemGroups.MEMBERS ,
486+ defaultGroupName : SystemGroupName .members ,
481487 ),
482488 'can_add_custom_emoji_group' : PermissionSettingsItem (
483489 // allow_nobody_group=True,
484490 allowEveryoneGroup: false ,
485- // default_group_name=SystemGroups.MEMBERS ,
491+ defaultGroupName : SystemGroupName .members ,
486492 ),
487493 'can_create_bots_group' : PermissionSettingsItem (
488494 // allow_nobody_group=True,
489495 allowEveryoneGroup: false ,
490- // default_group_name=SystemGroups.MEMBERS ,
496+ defaultGroupName : SystemGroupName .members ,
491497 ),
492498 'can_create_groups' : PermissionSettingsItem (
493499 // allow_nobody_group=True,
494500 allowEveryoneGroup: false ,
495- // default_group_name=SystemGroups.MEMBERS ,
501+ defaultGroupName : SystemGroupName .members ,
496502 ),
497503 'can_create_public_channel_group' : PermissionSettingsItem (
498504 // allow_nobody_group=True,
499505 allowEveryoneGroup: false ,
500- // default_group_name=SystemGroups.MEMBERS ,
506+ defaultGroupName : SystemGroupName .members ,
501507 ),
502508 'can_create_private_channel_group' : PermissionSettingsItem (
503509 // allow_nobody_group=True,
504510 allowEveryoneGroup: false ,
505- // default_group_name=SystemGroups.MEMBERS ,
511+ defaultGroupName : SystemGroupName .members ,
506512 ),
507513 'can_create_web_public_channel_group' : PermissionSettingsItem (
508514 // require_system_group=True,
509515 // allow_nobody_group=True,
510516 allowEveryoneGroup: false ,
511- // default_group_name=SystemGroups.OWNERS ,
517+ defaultGroupName : SystemGroupName .owners ,
512518 // allowed_system_groups=[
513519 // SystemGroups.MODERATORS,
514520 // SystemGroups.ADMINISTRATORS,
@@ -519,77 +525,77 @@ class SupportedPermissionSettings {
519525 'can_create_write_only_bots_group' : PermissionSettingsItem (
520526 // allow_nobody_group=True,
521527 allowEveryoneGroup: false ,
522- // default_group_name=SystemGroups.MEMBERS ,
528+ defaultGroupName : SystemGroupName .members ,
523529 ),
524530 'can_delete_any_message_group' : PermissionSettingsItem (
525531 // allow_nobody_group=True,
526532 allowEveryoneGroup: false ,
527- // default_group_name=SystemGroups.ADMINISTRATORS ,
533+ defaultGroupName : SystemGroupName .administrators ,
528534 ),
529535 'can_delete_own_message_group' : PermissionSettingsItem (
530536 // allow_nobody_group=True,
531537 allowEveryoneGroup: true ,
532- // default_group_name=SystemGroups.EVERYONE ,
538+ defaultGroupName : SystemGroupName .everyone ,
533539 ),
534540 'can_invite_users_group' : PermissionSettingsItem (
535541 // allow_nobody_group=True,
536542 allowEveryoneGroup: false ,
537- // default_group_name=SystemGroups.MEMBERS ,
543+ defaultGroupName : SystemGroupName .members ,
538544 ),
539545 'can_manage_all_groups' : PermissionSettingsItem (
540546 // allow_nobody_group=False,
541547 allowEveryoneGroup: false ,
542- // default_group_name=SystemGroups.OWNERS ,
548+ defaultGroupName : SystemGroupName .owners ,
543549 ),
544550 'can_manage_billing_group' : PermissionSettingsItem (
545551 // allow_nobody_group=False,
546552 allowEveryoneGroup: false ,
547- // default_group_name=SystemGroups.ADMINISTRATORS ,
553+ defaultGroupName : SystemGroupName .administrators ,
548554 ),
549555 'can_mention_many_users_group' : PermissionSettingsItem (
550556 // allow_nobody_group=True,
551557 allowEveryoneGroup: true ,
552- // default_group_name=SystemGroups.ADMINISTRATORS ,
558+ defaultGroupName : SystemGroupName .administrators ,
553559 ),
554560 'can_move_messages_between_channels_group' : PermissionSettingsItem (
555561 // allow_nobody_group=True,
556562 allowEveryoneGroup: false ,
557- // default_group_name=SystemGroups.MEMBERS ,
563+ defaultGroupName : SystemGroupName .members ,
558564 ),
559565 'can_move_messages_between_topics_group' : PermissionSettingsItem (
560566 // allow_nobody_group=True,
561567 allowEveryoneGroup: true ,
562- // default_group_name=SystemGroups.EVERYONE ,
568+ defaultGroupName : SystemGroupName .everyone ,
563569 ),
564570 'can_resolve_topics_group' : PermissionSettingsItem (
565571 // allow_nobody_group=True,
566572 allowEveryoneGroup: true ,
567- // default_group_name=SystemGroups.EVERYONE ,
573+ defaultGroupName : SystemGroupName .everyone ,
568574 ),
569575 'can_set_delete_message_policy_group' : PermissionSettingsItem (
570576 // allow_nobody_group=True,
571577 allowEveryoneGroup: false ,
572- // default_group_name=SystemGroups.MODERATORS ,
578+ defaultGroupName : SystemGroupName .moderators ,
573579 ),
574580 'can_set_topics_policy_group' : PermissionSettingsItem (
575581 // allow_nobody_group=True,
576582 allowEveryoneGroup: true ,
577- // default_group_name=SystemGroups.MEMBERS ,
583+ defaultGroupName : SystemGroupName .members ,
578584 ),
579585 'can_summarize_topics_group' : PermissionSettingsItem (
580586 // allow_nobody_group=True,
581587 allowEveryoneGroup: true ,
582- // default_group_name=SystemGroups.EVERYONE ,
588+ defaultGroupName : SystemGroupName .everyone ,
583589 ),
584590 'direct_message_initiator_group' : PermissionSettingsItem (
585591 // allow_nobody_group=True,
586592 allowEveryoneGroup: true ,
587- // default_group_name=SystemGroups.EVERYONE ,
593+ defaultGroupName : SystemGroupName .everyone ,
588594 ),
589595 'direct_message_permission_group' : PermissionSettingsItem (
590596 // allow_nobody_group=True,
591597 allowEveryoneGroup: true ,
592- // default_group_name=SystemGroups.EVERYONE ,
598+ defaultGroupName : SystemGroupName .everyone ,
593599 ),
594600 },
595601 group: {}, // Please go ahead and fill this in when we come to need it.
@@ -599,52 +605,52 @@ class SupportedPermissionSettings {
599605 "can_add_subscribers_group" : PermissionSettingsItem (
600606 // allow_nobody_group=True,
601607 allowEveryoneGroup: false ,
602- // default_group_name=SystemGroups.NOBODY ,
608+ defaultGroupName : SystemGroupName .nobody ,
603609 ),
604610 "can_administer_channel_group" : PermissionSettingsItem (
605611 // allow_nobody_group=True,
606612 allowEveryoneGroup: false ,
607- // default_group_name="stream_creator_or_nobody" ,
613+ defaultGroupName : PseudoSystemGroupName .streamCreatorOrNobody ,
608614 ),
609615 "can_delete_any_message_group" : PermissionSettingsItem (
610616 // allow_nobody_group=True,
611617 allowEveryoneGroup: true ,
612- // default_group_name=SystemGroups.NOBODY ,
618+ defaultGroupName : SystemGroupName .nobody ,
613619 ),
614620 "can_delete_own_message_group" : PermissionSettingsItem (
615621 // allow_nobody_group=True,
616622 allowEveryoneGroup: true ,
617- // default_group_name=SystemGroups.NOBODY ,
623+ defaultGroupName : SystemGroupName .nobody ,
618624 ),
619625 "can_move_messages_out_of_channel_group" : PermissionSettingsItem (
620626 // allow_nobody_group=True,
621627 allowEveryoneGroup: true ,
622- // default_group_name=SystemGroups.NOBODY ,
628+ defaultGroupName : SystemGroupName .nobody ,
623629 ),
624630 "can_move_messages_within_channel_group" : PermissionSettingsItem (
625631 // allow_nobody_group=True,
626632 allowEveryoneGroup: true ,
627- // default_group_name=SystemGroups.NOBODY ,
633+ defaultGroupName : SystemGroupName .nobody ,
628634 ),
629635 "can_remove_subscribers_group" : PermissionSettingsItem (
630636 // allow_nobody_group=True,
631637 allowEveryoneGroup: true ,
632- // default_group_name=SystemGroups.ADMINISTRATORS ,
638+ defaultGroupName : SystemGroupName .administrators ,
633639 ),
634640 "can_send_message_group" : PermissionSettingsItem (
635641 // allow_nobody_group=True,
636642 allowEveryoneGroup: true ,
637- // default_group_name=SystemGroups.EVERYONE ,
643+ defaultGroupName : SystemGroupName .everyone ,
638644 ),
639645 "can_subscribe_group" : PermissionSettingsItem (
640646 // allow_nobody_group=True,
641647 allowEveryoneGroup: false ,
642- // default_group_name=SystemGroups.NOBODY ,
648+ defaultGroupName : SystemGroupName .nobody ,
643649 ),
644650 "can_resolve_topics_group" : PermissionSettingsItem (
645651 // allow_nobody_group=True,
646652 allowEveryoneGroup: true ,
647- // default_group_name=SystemGroups.NOBODY ,
653+ defaultGroupName : SystemGroupName .nobody ,
648654 ),
649655 },
650656 );
@@ -660,12 +666,115 @@ class SupportedPermissionSettings {
660666@JsonSerializable (fieldRename: FieldRename .snake)
661667class PermissionSettingsItem {
662668 final bool allowEveryoneGroup;
669+
670+ @DefaultGroupNameConverter ()
671+ final SettableAsDefaultGroupName defaultGroupName;
672+
663673 // also other fields not yet used
664674
665- PermissionSettingsItem ({required this .allowEveryoneGroup});
675+ PermissionSettingsItem ({
676+ required this .allowEveryoneGroup,
677+ required this .defaultGroupName,
678+ });
666679
667680 factory PermissionSettingsItem .fromJson (Map <String , dynamic > json) =>
668681 _$PermissionSettingsItemFromJson (json);
669682
670683 Map <String , dynamic > toJson () => _$PermissionSettingsItemToJson (this );
671684}
685+
686+ /// A value of [PermissionSettingsItem.defaultGroupName] .
687+ ///
688+ /// Can be any of these:
689+ /// - a known system group [SystemGroupName]
690+ /// - a known special string [PseudoSystemGroupName]
691+ /// - an unknown system group or special string [DefaultGroupNameUnknown]
692+ sealed class SettableAsDefaultGroupName {
693+ String toJson ();
694+ }
695+
696+ class DefaultGroupNameConverter extends JsonConverter <SettableAsDefaultGroupName , String > {
697+ const DefaultGroupNameConverter ();
698+
699+ @override
700+ SettableAsDefaultGroupName fromJson (String json) {
701+ final SettableAsDefaultGroupName ? maybeResult = json.startsWith ('role:' )
702+ ? SystemGroupName .fromJson (json)
703+ : PseudoSystemGroupName .fromJson (json);
704+ return maybeResult ?? DefaultGroupNameUnknown (json);
705+ }
706+
707+ @override
708+ String toJson (SettableAsDefaultGroupName object) => object.toJson ();
709+ }
710+
711+ class DefaultGroupNameUnknown extends SettableAsDefaultGroupName {
712+ DefaultGroupNameUnknown (this .apiValue);
713+ final String apiValue;
714+
715+ @override
716+ String toJson () => apiValue;
717+ }
718+
719+ /// A known special string
720+ /// that [PermissionSettingsItem.defaultGroupName] might be.
721+ ///
722+ /// See server implementation, e.g.
723+ /// `can_administer_channel_group` in zerver/models/streams.py.
724+ @JsonEnum (valueField: 'apiValue' , alwaysCreate: true )
725+ enum PseudoSystemGroupName implements SettableAsDefaultGroupName {
726+ streamCreatorOrNobody (apiValue: 'stream_creator_or_nobody' ),
727+ ;
728+
729+ const PseudoSystemGroupName ({required this .apiValue});
730+
731+ final String apiValue;
732+
733+ /// Get a [PseudoSystemGroupName] from an [apiValue] ,
734+ /// or null if it's not recognized.
735+ ///
736+ /// Example:
737+ /// 'stream_creator_or_nobody' -> PseudoSystemGroupName.streamCreatorOrNobody
738+ static PseudoSystemGroupName ? fromJson (String json) => _byApiValue[json];
739+
740+ // _$…EnumMap is thanks to `alwaysCreate: true`
741+ static final _byApiValue = _$PseudoSystemGroupNameEnumMap
742+ .map ((key, value) => MapEntry (value, key));
743+
744+ @override
745+ String toJson () => _$PseudoSystemGroupNameEnumMap [this ]! ;
746+ }
747+
748+ /// A known canonical name for a system group.
749+ ///
750+ /// Doc: https://zulip.com/api/group-setting-values#system-groups
751+ @JsonEnum (valueField: 'apiValue' , alwaysCreate: true )
752+ enum SystemGroupName implements SettableAsDefaultGroupName {
753+ everyoneOnInternet (apiValue: 'role:internet' ),
754+ everyone (apiValue: 'role:everyone' ),
755+ members (apiValue: 'role:members' ),
756+ fullMembers (apiValue: 'role:fullmembers' ),
757+ moderators (apiValue: 'role:moderators' ),
758+ administrators (apiValue: 'role:administrators' ),
759+ owners (apiValue: 'role:owners' ),
760+ nobody (apiValue: 'role:nobody' ),
761+ ;
762+
763+ const SystemGroupName ({required this .apiValue});
764+
765+ final String apiValue;
766+
767+ /// Get a [SystemGroupName] from an [apiValue] ,
768+ /// or null if it's not recognized.
769+ ///
770+ /// Example:
771+ /// 'role:administrators' -> SystemGroupName.administrators
772+ static SystemGroupName ? fromJson (String json) => _byApiValue[json];
773+
774+ // _$…EnumMap is thanks to `alwaysCreate: true`
775+ static final _byApiValue = _$SystemGroupNameEnumMap
776+ .map ((key, value) => MapEntry (value, key));
777+
778+ @override
779+ String toJson () => _$SystemGroupNameEnumMap [this ]! ;
780+ }
0 commit comments