Skip to content

Commit 12ebaf1

Browse files
authored
Merge pull request #2040 from Kobzol/require-zulip-id
Make Zulip IDs required
2 parents 9cbd51f + 6181e3b commit 12ebaf1

File tree

8 files changed

+105
-35
lines changed

8 files changed

+105
-35
lines changed

config.toml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,32 @@ special-org-members = [
5252
"rust-log-analyzer",
5353
"rust-timer",
5454
"rustbot",
55-
5655
# Ferrous systems employees who manage the github sponsors
5756
# for rust-analyzer.
5857
"MissHolmes",
5958
"skade",
6059
]
60+
61+
members-without-zulip-id = [
62+
"arshiamufti",
63+
"bnchi",
64+
"brotzeit",
65+
"celaus",
66+
"chris-morgan",
67+
"codesections",
68+
"da-x",
69+
"ecstatic-morse",
70+
"gdr-at-ms",
71+
"kennykerr",
72+
"mathk",
73+
"nico-abram",
74+
"opeolluwa",
75+
"patchfx",
76+
"pvdrz",
77+
"reitermarkus",
78+
"ryankurte",
79+
"Stammark",
80+
"therealprof",
81+
"U007D",
82+
"zeenix"
83+
]

docs/toml-schema.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ The file structure is this:
99
name = "John Doe" # Display name of the person for the website (required)
1010
github = "johndoe" # GitHub username of the person (required)
1111
github-id = 123456 # GitHub ID of the person (required)
12-
zulip-id = 123456 # Zulip ID of the person (optional)
12+
zulip-id = 123456 # Zulip ID of the person (required)
1313
discord-id = 123456 # Discord ID of the person (optional)
1414
# You can also set `email = false` to explicitly disable the email for the user.
1515
# This will, for example, avoid adding the person to the mailing lists.

src/schema.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub(crate) struct Config {
1515
permissions_bools: HashSet<String>,
1616
// Use a BTreeSet for consistent ordering in tests
1717
special_org_members: BTreeSet<String>,
18+
members_without_zulip_id: BTreeSet<String>,
1819
}
1920

2021
impl Config {
@@ -41,6 +42,10 @@ impl Config {
4142
pub(crate) fn special_org_members(&self) -> &BTreeSet<String> {
4243
&self.special_org_members
4344
}
45+
46+
pub(crate) fn members_without_zulip_id(&self) -> &BTreeSet<String> {
47+
&self.members_without_zulip_id
48+
}
4449
}
4550

4651
// This is an enum to allow two kinds of values for the email field:

src/validate.rs

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ static CHECKS: &[Check<fn(&Data, &mut Vec<String>)>] = checks![
4949
validate_zulip_group_extra_people,
5050
validate_unique_zulip_streams,
5151
validate_unique_zulip_user_ids,
52+
validate_present_zulip_id,
53+
validate_zulip_id_allowlist,
5254
validate_zulip_stream_ids,
5355
validate_zulip_stream_extra_people,
5456
validate_repos,
@@ -715,6 +717,53 @@ fn validate_unique_zulip_user_ids(data: &Data, errors: &mut Vec<String>) {
715717
})
716718
}
717719

720+
/// Ensure that every active member except a few remaining people on an allowlist have a Zulip ID.
721+
fn validate_present_zulip_id(data: &Data, errors: &mut Vec<String>) {
722+
wrapper(
723+
data.active_members().unwrap().iter(),
724+
errors,
725+
|person, _| {
726+
let person = data.person(person).expect("Person not found");
727+
if person.zulip_id().is_none()
728+
&& !data
729+
.config()
730+
.members_without_zulip_id()
731+
.contains(person.github())
732+
{
733+
return Err(anyhow::anyhow!(
734+
"User {} does not have a Zulip ID",
735+
person.github()
736+
));
737+
}
738+
Ok(())
739+
},
740+
)
741+
}
742+
743+
/// Ensure people in the missing Zulip ID allowlist do not actually have Zulip ID configured.
744+
fn validate_zulip_id_allowlist(data: &Data, errors: &mut Vec<String>) {
745+
// Sort for deterministic output
746+
let mut members = data
747+
.config()
748+
.members_without_zulip_id()
749+
.iter()
750+
.collect::<Vec<_>>();
751+
members.sort();
752+
for member in members {
753+
let Some(person) = data.person(member) else {
754+
errors.push(format!(
755+
"Person {member} in Zulip ID allowlist does not exist"
756+
));
757+
continue;
758+
};
759+
if person.zulip_id().is_some() {
760+
errors.push(format!(
761+
"Person {member} in Zulip ID allowlist has Zulip ID configured. Please remove them from the `members-without-zulip-id` list in `config.toml`"
762+
));
763+
}
764+
}
765+
}
766+
718767
/// Ensure team members in Zulip groups have a Zulip id
719768
fn validate_zulip_group_ids(data: &Data, errors: &mut Vec<String>) {
720769
wrapper(data.teams(), errors, |team, errors| {
@@ -731,15 +780,17 @@ fn validate_zulip_group_ids(data: &Data, errors: &mut Vec<String>) {
731780
// Okay, have zulip IDs.
732781
}
733782
ZulipMember::MemberWithoutId { github } => {
734-
// Bad, only github handle, no zulip ID, even though included in zulip user
735-
// group
736-
bail!(
737-
"person `{}` in '{}' is a member of a Zulip user group '{}' but has no \
738-
Zulip id",
739-
github,
740-
team.name(),
741-
group.name()
742-
);
783+
if !data.config().members_without_zulip_id().contains(github) {
784+
// Bad, only github handle, no zulip ID, even though included in zulip user
785+
// group
786+
bail!(
787+
"person `{}` in '{}' is a member of a Zulip user group '{}' but has no \
788+
Zulip id",
789+
github,
790+
team.name(),
791+
group.name()
792+
);
793+
}
743794
}
744795
}
745796
Ok(())
@@ -764,11 +815,13 @@ fn validate_zulip_stream_ids(data: &Data, errors: &mut Vec<String>) {
764815
match member {
765816
ZulipMember::MemberWithId { .. } | ZulipMember::JustId(_) => {}
766817
ZulipMember::MemberWithoutId { github } => {
767-
bail!(
768-
"person `{github}` is a member of a Zulip stream `{}` defined in team `{}`, but has no Zulip id",
769-
stream.name(),
770-
team.name()
771-
);
818+
if !data.config().members_without_zulip_id().contains(github) {
819+
bail!(
820+
"person `{github}` is a member of a Zulip stream `{}` defined in team `{}`, but has no Zulip id",
821+
stream.name(),
822+
team.name()
823+
);
824+
}
772825
}
773826
}
774827
Ok(())

teams/all.toml

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,7 @@ extra-emails = [
3131

3232
[[zulip-groups]]
3333
name = "T-all"
34-
# Exclude the following people from the Zulip group for grandfathering purposes,
35-
# where previously we didn't require all project team members to have Zulip IDs
36-
# (since there wasn't a `T-all` Zulip group previously).
37-
excluded-people = [
38-
"U007D",
39-
"andrewpollack",
40-
"bnchi",
41-
"celaus",
42-
"opeolluwa",
43-
]
4434

4535
# Private channel with all team members, so that we can have an easy way of reaching them.
4636
[[zulip-streams]]
4737
name = "all/private"
48-
# Exclude the following people from the Zulip stream for grandfathering purposes,
49-
# where previously we didn't require all project team members to have Zulip IDs.
50-
excluded-people = [
51-
"U007D",
52-
"andrewpollack",
53-
"bnchi",
54-
"celaus",
55-
"opeolluwa",
56-
]

tests/static-api/_expected/v1/zulip-map.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"users": {
33
"2": 2,
4+
"6": 6,
45
"1234": 0,
56
"4321": 0
67
}

tests/static-api/config.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ permissions-bools = [
2222
special-org-members = [
2323
"test-bot",
2424
]
25+
26+
members-without-zulip-id = [
27+
"test-admin",
28+
"user-3",
29+
"user-4"
30+
]

tests/static-api/people/user-6.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ name = 'Sixth user'
22
github = 'user-6'
33
github-id = 6
44
5+
zulip-id = 6

0 commit comments

Comments
 (0)