Skip to content

Commit 5950988

Browse files
gws: add diff for google accounts
1 parent 53f8283 commit 5950988

8 files changed

Lines changed: 361 additions & 10 deletions

File tree

rust_team_data/src/v1.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ pub struct Team {
2626
pub github: Option<TeamGitHub>,
2727
pub website_data: Option<TeamWebsite>,
2828
pub roles: Vec<MemberRole>,
29+
#[serde(skip_serializing_if = "Option::is_none")]
30+
pub google_workspace_saml_group: Option<bool>,
31+
}
32+
33+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
34+
pub struct GoogleWorkspace {
35+
pub first_name: String,
36+
pub last_name: String,
37+
pub account_handle: String,
2938
}
3039

3140
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@@ -36,6 +45,8 @@ pub struct TeamMember {
3645
pub is_lead: bool,
3746
#[serde(skip_serializing_if = "Vec::is_empty", default)]
3847
pub roles: Vec<String>,
48+
#[serde(skip_serializing_if = "Option::is_none")]
49+
pub google_workspace: Option<GoogleWorkspace>,
3950
}
4051

4152
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]

src/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ mod static_api;
1010
mod sync;
1111
mod validate;
1212

13-
const AVAILABLE_SERVICES: &[&str] = &["github", "mailgun", "zulip", "crates-io"];
13+
const AVAILABLE_SERVICES: &[&str] = &[
14+
"github",
15+
"google-workspace",
16+
"mailgun",
17+
"zulip",
18+
"crates-io",
19+
];
1420

1521
const USER_AGENT: &str = "https://github.com/rust-lang/team (infra@rust-lang.org)";
1622

src/schema.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,22 @@ pub(crate) struct Funding {
7676
github_sponsors: bool,
7777
}
7878

79-
#[allow(dead_code)]
80-
#[derive(serde::Deserialize, Debug)]
79+
#[derive(serde::Deserialize, Debug, Clone)]
8180
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
8281
pub(crate) struct GoogleWorkspace {
83-
first_name: String,
84-
last_name: String,
85-
account_handle: String,
82+
pub first_name: String,
83+
pub last_name: String,
84+
pub account_handle: String,
85+
}
86+
87+
impl From<&GoogleWorkspace> for rust_team_data::v1::GoogleWorkspace {
88+
fn from(gws: &GoogleWorkspace) -> Self {
89+
rust_team_data::v1::GoogleWorkspace {
90+
first_name: gws.first_name.clone(),
91+
last_name: gws.last_name.clone(),
92+
account_handle: gws.account_handle.clone(),
93+
}
94+
}
8695
}
8796

8897
#[allow(dead_code)]
@@ -157,8 +166,8 @@ impl Person {
157166
&self.permissions
158167
}
159168

160-
pub(crate) fn google_workspace(&self) -> &Option<GoogleWorkspace> {
161-
&self.google_workspace
169+
pub(crate) fn google_workspace(&self) -> Option<&GoogleWorkspace> {
170+
self.google_workspace.as_ref()
162171
}
163172

164173
pub(crate) fn validate(&self) -> Result<(), Error> {
@@ -194,7 +203,6 @@ impl std::fmt::Display for TeamKind {
194203
}
195204
}
196205

197-
#[allow(dead_code)]
198206
#[derive(serde::Deserialize, Debug)]
199207
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
200208
pub(crate) struct Team {

src/static_api.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use anyhow::{Context as _, Error, ensure};
77
use indexmap::IndexMap;
88
use log::info;
99
use rust_team_data::v1;
10-
use rust_team_data::v1::{BranchProtectionMode, Crate, CrateTeamOwner, RepoMember};
10+
use rust_team_data::v1::{
11+
BranchProtectionMode, Crate, CrateTeamOwner, GoogleWorkspace, RepoMember,
12+
};
1113
use std::collections::HashMap;
1214
use std::path::Path;
1315

@@ -539,6 +541,7 @@ fn convert_teams<'a>(
539541
github_id: person.github_id(),
540542
is_lead: leads.contains(github_name),
541543
roles: website_roles.get(*github_name).cloned().unwrap_or_default(),
544+
google_workspace: person.google_workspace().map(GoogleWorkspace::from),
542545
});
543546
}
544547
}
@@ -557,6 +560,7 @@ fn convert_teams<'a>(
557560
.get(alum.github.as_str())
558561
.cloned()
559562
.unwrap_or_default(),
563+
google_workspace: person.google_workspace().map(GoogleWorkspace::from),
560564
});
561565
}
562566
}
@@ -606,6 +610,7 @@ fn convert_teams<'a>(
606610
description: role.description.clone(),
607611
})
608612
.collect(),
613+
google_workspace_saml_group: team.google_workspace_saml_group(),
609614
};
610615
team_map.insert(team.name().into(), team_data);
611616
}

src/sync/github/tests/test_utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ impl From<TeamData> for v1::Team {
287287
github: (!gh_teams.is_empty()).then_some(TeamGitHub { teams: gh_teams }),
288288
website_data: None,
289289
roles: vec![],
290+
google_workspace_saml_group: None,
290291
}
291292
}
292293
}

src/sync/gws/api.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use crate::sync::gws::RUST_LANG_GWS_DOMAIN;
2+
use async_trait::async_trait;
3+
use rust_team_data::v1::GoogleWorkspace;
4+
5+
/// https://developers.google.com/workspace/admin/directory/reference/rest/v1/groups
6+
#[derive(Clone, Debug, PartialEq)]
7+
pub(crate) struct Group {
8+
pub name: String,
9+
pub email: String,
10+
}
11+
12+
/// https://developers.google.com/workspace/admin/directory/reference/rest/v1/users#UserName
13+
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
14+
pub(crate) struct UserName {
15+
pub given_name: String,
16+
pub family_name: String,
17+
}
18+
19+
///https://developers.google.com/workspace/admin/directory/reference/rest/v1/users
20+
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
21+
pub(crate) struct User {
22+
pub name: UserName,
23+
pub primary_email: String,
24+
}
25+
26+
impl From<&GoogleWorkspace> for User {
27+
fn from(gws: &GoogleWorkspace) -> Self {
28+
Self {
29+
primary_email: format!("{}@{}", gws.account_handle, RUST_LANG_GWS_DOMAIN),
30+
name: UserName {
31+
given_name: gws.first_name.to_string(),
32+
family_name: gws.last_name.to_string(),
33+
},
34+
}
35+
}
36+
}
37+
38+
#[async_trait]
39+
pub(crate) trait GoogleWorkspaceApiClient {
40+
async fn get_users(&self) -> anyhow::Result<Vec<User>>;
41+
}

0 commit comments

Comments
 (0)