Skip to content

Commit 8756a88

Browse files
authored
Merge pull request #10586 from Turbo87/membership-options
github: Adjust `org/team_membership()` to return `Result<Option<_>, _>`
2 parents 44a7016 + 940d231 commit 8756a88

File tree

5 files changed

+36
-38
lines changed

5 files changed

+36
-38
lines changed

crates/crates_io_github/src/lib.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ pub trait GitHubClient: Send + Sync {
3333
team_id: i32,
3434
username: &str,
3535
auth: &AccessToken,
36-
) -> Result<GitHubTeamMembership>;
36+
) -> Result<Option<GitHubTeamMembership>>;
3737
async fn org_membership(
3838
&self,
3939
org_id: i32,
4040
username: &str,
4141
auth: &AccessToken,
42-
) -> Result<GitHubOrgMembership>;
42+
) -> Result<Option<GitHubOrgMembership>>;
4343
async fn public_keys(&self, username: &str, password: &str) -> Result<Vec<GitHubPublicKey>>;
4444
}
4545

@@ -120,22 +120,28 @@ impl GitHubClient for RealGitHubClient {
120120
team_id: i32,
121121
username: &str,
122122
auth: &AccessToken,
123-
) -> Result<GitHubTeamMembership> {
123+
) -> Result<Option<GitHubTeamMembership>> {
124124
let url = format!("/organizations/{org_id}/team/{team_id}/memberships/{username}");
125-
self.request(&url, auth).await
125+
match self.request(&url, auth).await {
126+
Ok(membership) => Ok(Some(membership)),
127+
// Officially how `false` is returned
128+
Err(GitHubError::NotFound(_)) => Ok(None),
129+
Err(err) => Err(err),
130+
}
126131
}
127132

128133
async fn org_membership(
129134
&self,
130135
org_id: i32,
131136
username: &str,
132137
auth: &AccessToken,
133-
) -> Result<GitHubOrgMembership> {
134-
self.request(
135-
&format!("/organizations/{org_id}/memberships/{username}"),
136-
auth,
137-
)
138-
.await
138+
) -> Result<Option<GitHubOrgMembership>> {
139+
let url = format!("/organizations/{org_id}/memberships/{username}");
140+
match self.request(&url, auth).await {
141+
Ok(membership) => Ok(Some(membership)),
142+
Err(GitHubError::NotFound(_)) => Ok(None),
143+
Err(err) => Err(err),
144+
}
139145
}
140146

141147
/// Returns the list of public keys that can be used to verify GitHub secret alert signatures

src/models/team.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,11 @@ async fn is_gh_org_owner(
213213
user: &User,
214214
) -> Result<bool, GitHubError> {
215215
let token = AccessToken::new(user.gh_access_token.expose_secret().to_string());
216-
match gh_client
216+
let membership = gh_client
217217
.org_membership(org_id, &user.gh_login, &token)
218-
.await
219-
{
220-
Ok(membership) => Ok(membership.state == "active" && membership.role == "admin"),
221-
Err(GitHubError::NotFound(_)) => Ok(false),
222-
Err(e) => Err(e),
223-
}
218+
.await?;
219+
220+
Ok(membership.is_some_and(|m| m.state == "active" && m.role == "admin"))
224221
}
225222

226223
async fn team_with_gh_id_contains_user(
@@ -233,16 +230,11 @@ async fn team_with_gh_id_contains_user(
233230
// check that "state": "active"
234231

235232
let token = AccessToken::new(user.gh_access_token.expose_secret().to_string());
236-
let membership = match gh_client
233+
let membership = gh_client
237234
.team_membership(github_org_id, github_team_id, &user.gh_login, &token)
238-
.await
239-
{
240-
// Officially how `false` is returned
241-
Err(GitHubError::NotFound(_)) => return Ok(false),
242-
x => x?,
243-
};
235+
.await?;
244236

245237
// There is also `state: pending` for which we could possibly give
246238
// some feedback, but it's not obvious how that should work.
247-
Ok(membership.state == "active")
239+
Ok(membership.is_some_and(|m| m.state == "active"))
248240
}

src/tests/issues/issue1205.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ fn github_mock() -> MockGitHubClient {
7474
github_mock
7575
.expect_team_membership()
7676
.with(eq(1), eq(2), eq("foo"), always())
77-
.returning(|_, _, _, _| Ok(active_membership()));
77+
.returning(|_, _, _, _| Ok(Some(active_membership())));
7878

7979
github_mock
8080
}

src/tests/routes/crates/owners/remove.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ async fn test_remove_uppercase_team() {
138138
.expect_team_membership()
139139
.with(eq(1), eq(2), eq("foo"), always())
140140
.returning(|_, _, _, _| {
141-
Ok(GitHubTeamMembership {
141+
Ok(Some(GitHubTeamMembership {
142142
state: "active".to_string(),
143-
})
143+
}))
144144
});
145145

146146
let (app, _, cookie) = TestApp::full().with_github(github_mock).with_user().await;

src/tests/util/github.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl MockData {
120120
org_id: i32,
121121
team_id: i32,
122122
username: &str,
123-
) -> Result<GitHubTeamMembership, GitHubError> {
123+
) -> Result<Option<GitHubTeamMembership>, GitHubError> {
124124
let team = self
125125
.orgs
126126
.iter()
@@ -131,40 +131,40 @@ impl MockData {
131131
.find(|team| team.id == team_id)
132132
.ok_or_else(not_found)?;
133133
if team.members.contains(&username) {
134-
Ok(GitHubTeamMembership {
134+
Ok(Some(GitHubTeamMembership {
135135
state: "active".into(),
136-
})
136+
}))
137137
} else {
138-
Err(not_found())
138+
Ok(None)
139139
}
140140
}
141141

142142
fn org_membership(
143143
&self,
144144
org_id: i32,
145145
username: &str,
146-
) -> Result<GitHubOrgMembership, GitHubError> {
146+
) -> Result<Option<GitHubOrgMembership>, GitHubError> {
147147
let org = self
148148
.orgs
149149
.iter()
150150
.find(|org| org.id == org_id)
151151
.ok_or_else(not_found)?;
152152
if org.owners.contains(&username) {
153-
Ok(GitHubOrgMembership {
153+
Ok(Some(GitHubOrgMembership {
154154
state: "active".into(),
155155
role: "admin".into(),
156-
})
156+
}))
157157
} else if org
158158
.teams
159159
.iter()
160160
.any(|team| team.members.contains(&username))
161161
{
162-
Ok(GitHubOrgMembership {
162+
Ok(Some(GitHubOrgMembership {
163163
state: "active".into(),
164164
role: "member".into(),
165-
})
165+
}))
166166
} else {
167-
Err(not_found())
167+
Ok(None)
168168
}
169169
}
170170
}

0 commit comments

Comments
 (0)