diff --git a/src/models/team.rs b/src/models/team.rs index c843c4e189a..d8606b93271 100644 --- a/src/models/team.rs +++ b/src/models/team.rs @@ -138,7 +138,7 @@ impl Team { let org_id = team.organization.id; - if !can_add_team(gh_client, org_id, team.id, req_user).await? { + if !can_add_team(gh_client, org_id, team.id, &req_user.gh_login, &token).await? { return Err(custom( StatusCode::FORBIDDEN, "only members of a team or organization owners can add it as an owner", @@ -166,11 +166,13 @@ impl Team { pub async fn contains_user( &self, gh_client: &dyn GitHubClient, - user: &User, + gh_login: &str, + token: &AccessToken, ) -> Result { match self.org_id { Some(org_id) => { - team_with_gh_id_contains_user(gh_client, org_id, self.github_id, user).await + team_with_gh_id_contains_user(gh_client, org_id, self.github_id, gh_login, token) + .await } // This means we don't have an org_id on file for the `self` team. It much // probably was deleted from github by the time we backfilled the database. @@ -199,24 +201,22 @@ async fn can_add_team( gh_client: &dyn GitHubClient, org_id: i32, team_id: i32, - user: &User, + gh_login: &str, + token: &AccessToken, ) -> Result { Ok( - team_with_gh_id_contains_user(gh_client, org_id, team_id, user).await? - || is_gh_org_owner(gh_client, org_id, user).await?, + team_with_gh_id_contains_user(gh_client, org_id, team_id, gh_login, token).await? + || is_gh_org_owner(gh_client, org_id, gh_login, token).await?, ) } async fn is_gh_org_owner( gh_client: &dyn GitHubClient, org_id: i32, - user: &User, + gh_login: &str, + token: &AccessToken, ) -> Result { - let token = AccessToken::new(user.gh_access_token.expose_secret().to_string()); - let membership = gh_client - .org_membership(org_id, &user.gh_login, &token) - .await?; - + let membership = gh_client.org_membership(org_id, gh_login, token).await?; Ok(membership.is_some_and(|m| m.state == "active" && m.role == "admin")) } @@ -224,14 +224,14 @@ async fn team_with_gh_id_contains_user( gh_client: &dyn GitHubClient, github_org_id: i32, github_team_id: i32, - user: &User, + gh_login: &str, + token: &AccessToken, ) -> Result { // GET /organizations/:org_id/team/:team_id/memberships/:username // check that "state": "active" - let token = AccessToken::new(user.gh_access_token.expose_secret().to_string()); let membership = gh_client - .team_membership(github_org_id, github_team_id, &user.gh_login, &token) + .team_membership(github_org_id, github_team_id, gh_login, token) .await?; // There is also `state: pending` for which we could possibly give diff --git a/src/models/user.rs b/src/models/user.rs index 2852cd3afe8..1d3932b6a63 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -5,7 +5,8 @@ use diesel::prelude::*; use diesel::sql_types::Integer; use diesel::upsert::excluded; use diesel_async::{AsyncPgConnection, RunQueryDsl}; -use secrecy::SecretString; +use oauth2::AccessToken; +use secrecy::{ExposeSecret, SecretString}; use crate::models::{Crate, CrateOwner, Email, Owner, OwnerKind, Rights}; use crate::schema::{crate_owners, emails, users}; @@ -68,6 +69,8 @@ impl User { gh_client: &dyn GitHubClient, owners: &[Owner], ) -> Result { + let token = AccessToken::new(self.gh_access_token.expose_secret().to_string()); + let mut best = Rights::None; for owner in owners { match *owner { @@ -77,7 +80,8 @@ impl User { } } Owner::Team(ref team) => { - if team.contains_user(gh_client, self).await? { + let gh_login = &self.gh_login; + if team.contains_user(gh_client, gh_login, &token).await? { best = Rights::Publish; } }