Skip to content

Commit 1947b22

Browse files
committed
initial_snapshot [nfc]: Add PermissionSettingsItem.defaultGroupName
This doesn't change our parsing of server data because we don't currently look at server_supported_permission_settings in the initial snapshot, as noted in the added TODO. It just adds data to the fixture, modeled on current server code.
1 parent af8d95b commit 1947b22

File tree

2 files changed

+168
-36
lines changed

2 files changed

+168
-36
lines changed

lib/api/model/initial_snapshot.dart

Lines changed: 144 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
661667
class 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+
}

lib/api/model/initial_snapshot.g.dart

Lines changed: 24 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)