Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions svc/api/cloud/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use api_helper::{
auth::{ApiAuth, AuthRateLimitCtx},
util::{as_auth_expired, basic_rate_limit},
};
use proto::claims::Claims;
use proto::{backend, claims::Claims};
use rivet_claims::ClaimsDecode;
use rivet_operation::prelude::*;

Expand Down Expand Up @@ -44,7 +44,10 @@ impl Auth {
.ok_or_else(|| err_code!(API_UNAUTHORIZED, reason = "No bearer token provided."))
}

pub async fn user(&self, ctx: &OperationContext<()>) -> GlobalResult<rivet_claims::ent::User> {
pub async fn user(
&self,
ctx: &OperationContext<()>,
) -> GlobalResult<(backend::user::User, rivet_claims::ent::User)> {
let claims = self.claims()?;
let user_ent = claims.as_user()?;

Expand All @@ -65,7 +68,7 @@ impl Auth {
bail_with!(TOKEN_REVOKED);
}

Ok(user_ent)
Ok((user.clone(), user_ent))
}

/// Validates that the agent can read a list of teams.
Expand All @@ -77,16 +80,16 @@ impl Auth {
let claims = self.claims()?;

if claims.as_user().is_ok() {
let user_ent = self.user(ctx).await?;
let (user, user_ent) = self.user(ctx).await?;
assert::user_registered(ctx, user_ent.user_id).await?;

let team_list_res = op!([ctx] user_team_list {
user_ids: vec![user_ent.user_id.into()],
})
.await?;

let user = unwrap!(team_list_res.users.first());
let user_team_ids = user
let user_teams = unwrap!(team_list_res.users.first());
let user_team_ids = user_teams
.teams
.iter()
.map(|t| Ok(unwrap_ref!(t.team_id).as_uuid()))
Expand All @@ -95,7 +98,7 @@ impl Auth {
.iter()
.all(|team_id| user_team_ids.contains(team_id));

ensure_with!(has_teams, GROUP_NOT_MEMBER);
ensure_with!(has_teams || user.is_admin, GROUP_NOT_MEMBER);

Ok(())
} else if claims.as_game_cloud().is_ok() {
Expand Down Expand Up @@ -140,7 +143,7 @@ impl Auth {
let claims = self.claims()?;

if claims.as_user().is_ok() {
let user_ent = self.user(ctx).await?;
let (user, user_ent) = self.user(ctx).await?;

assert::user_registered(ctx, user_ent.user_id).await?;

Expand Down Expand Up @@ -195,7 +198,7 @@ impl Auth {
let claims = self.claims()?;

if claims.as_user().is_ok() {
let user_ent = self.user(ctx).await?;
let (user, user_ent) = self.user(ctx).await?;

assert::user_registered(ctx, user_ent.user_id).await?;

Expand Down Expand Up @@ -254,7 +257,7 @@ impl Auth {
let claims = self.claims()?;

let (user_id, team_ids, game_ids) = if claims.as_user().is_ok() {
let user_ent = self.user(ctx).await?;
let (_, user_ent) = self.user(ctx).await?;

// Fetch teams associated with user
let teams_res = op!([ctx] user_team_list {
Expand Down Expand Up @@ -369,15 +372,8 @@ impl Auth {
let claims = self.claims()?;

if claims.as_user().is_ok() {
let user_ent = self.user(ctx).await?;

// Get user
let user_res = op!([ctx] user_get {
user_ids: vec![user_ent.user_id.into()]
})
.await?;
let (user, _) = self.user(ctx).await?;

let user = unwrap!(user_res.users.first(), "user not found");
ensure_with!(user.is_admin, IDENTITY_NOT_ADMIN);

Ok(())
Expand Down
11 changes: 7 additions & 4 deletions svc/api/group/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use api_helper::{
auth::{ApiAuth, AuthRateLimitCtx},
util::{as_auth_expired, basic_rate_limit},
};
use proto::claims::Claims;
use proto::{backend, claims::Claims};
use rivet_claims::ClaimsDecode;
use rivet_operation::prelude::*;

Expand Down Expand Up @@ -40,7 +40,10 @@ impl Auth {
.ok_or_else(|| err_code!(API_UNAUTHORIZED, reason = "No bearer token provided."))
}

pub async fn user(&self, ctx: &OperationContext<()>) -> GlobalResult<rivet_claims::ent::User> {
pub async fn user(
&self,
ctx: &OperationContext<()>,
) -> GlobalResult<(backend::user::User, rivet_claims::ent::User)> {
let claims = self.claims()?;
let user_ent = claims.as_user()?;

Expand All @@ -61,15 +64,15 @@ impl Auth {
bail_with!(TOKEN_REVOKED);
}

Ok(user_ent)
Ok((user.clone(), user_ent))
}

/// Validates that the given agent is an admin user.
pub async fn admin(&self, ctx: &OperationContext<()>) -> GlobalResult<()> {
let claims = self.claims()?;

if claims.as_user().is_ok() {
let user_ent = self.user(ctx).await?;
let (_, user_ent) = self.user(ctx).await?;

// Get user
let user_res = op!([ctx] user_get {
Expand Down
52 changes: 26 additions & 26 deletions svc/api/group/src/route/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub async fn profile(
group_id: Uuid,
watch_index: WatchIndexQuery,
) -> GlobalResult<models::GetGroupProfileResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Fetch team data
let teams = op!([ctx] team_get {
Expand Down Expand Up @@ -190,23 +190,23 @@ pub async fn members(
watch_index: WatchIndexQuery,
query: ListMembersQuery,
) -> GlobalResult<models::GetGroupMembersResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (user, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Check if user is a member of this team
let team_list_res = op!([ctx] user_team_list {
user_ids: vec![user_ent.user_id.into()],
})
.await?;

let user = unwrap!(team_list_res.users.first());
let user_team_ids = user
let user_team = unwrap!(team_list_res.users.first());
let user_team_ids = user_team
.teams
.iter()
.map(|t| Ok(unwrap_ref!(t.team_id).as_uuid()))
.collect::<GlobalResult<Vec<_>>>()?;
let has_team = user_team_ids.iter().any(|team_id| &group_id == team_id);

ensure_with!(has_team, GROUP_NOT_MEMBER);
ensure_with!(has_team || user.is_admin, GROUP_NOT_MEMBER);

let team_members_res = op!([ctx] team_member_list {
team_ids: vec![group_id.into()],
Expand Down Expand Up @@ -353,7 +353,7 @@ pub async fn join_requests(
watch_index: WatchIndexQuery,
_query: ListJoinRequestsQuery,
) -> GlobalResult<models::GetGroupJoinRequestsResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Verify the team exists
let (teams_res, team_join_requests_res) = tokio::try_join!(
Expand Down Expand Up @@ -518,7 +518,7 @@ pub async fn update_profile(
group_id: Uuid,
body: models::UpdateGroupProfileRequest,
) -> GlobalResult<models::UpdateGroupProfileResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

let res = op!([ctx] team_get {
team_ids: vec![group_id.into()],
Expand Down Expand Up @@ -564,7 +564,7 @@ pub async fn get_suggested_groups(
ctx: Ctx<Auth>,
_watch_index: WatchIndexQuery,
) -> GlobalResult<models::ListSuggestedGroupsResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Fetch recommendations
let recommend_res = op!([ctx] team_recommend { count: 64 }).await?;
Expand Down Expand Up @@ -593,7 +593,7 @@ pub async fn leave(
group_id: Uuid,
_body: models::LeaveGroupRequest,
) -> GlobalResult<models::LeaveGroupResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Validate the team exists
let teams_res = op!([ctx] team_get {
Expand All @@ -618,7 +618,7 @@ pub async fn create(
ctx: Ctx<Auth>,
body: models::CreateGroupRequest,
) -> GlobalResult<models::CreateGroupResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

let publicity = unwrap!(std::env::var("RIVET_ACCESS_KIND").ok());
match publicity.as_str() {
Expand Down Expand Up @@ -661,7 +661,7 @@ pub async fn request_join(
group_id: Uuid,
_body: models::CreateGroupJoinRequestRequest,
) -> GlobalResult<models::CreateGroupJoinRequestResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Validate the team exists
let teams_res = op!([ctx] team_get {
Expand Down Expand Up @@ -724,7 +724,7 @@ pub async fn resolve_join_request(
identity_id: Uuid,
body: models::ResolveGroupJoinRequestRequest,
) -> GlobalResult<models::ResolveGroupJoinRequestResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Validate the team exists
let teams_res = op!([ctx] team_get {
Expand Down Expand Up @@ -765,7 +765,7 @@ pub async fn search(
_watch_index: WatchIndexQuery,
query: SearchQuery,
) -> GlobalResult<models::SearchGroupsResponse> {
let _user_ent = ctx.auth().user(ctx.op_ctx()).await?;
ctx.auth().user(ctx.op_ctx()).await?;

ensure_with!(
query.limit.map(|v| v != 0).unwrap_or(true),
Expand Down Expand Up @@ -805,7 +805,7 @@ pub async fn validate_profile(
ctx: Ctx<Auth>,
body: models::ValidateGroupProfileRequest,
) -> GlobalResult<models::ValidateGroupProfileResponse> {
let _user_ent = ctx.auth().user(ctx.op_ctx()).await?;
ctx.auth().user(ctx.op_ctx()).await?;

let res = op!([ctx] team_profile_validate {
display_name: body.display_name.clone(),
Expand All @@ -828,7 +828,7 @@ pub async fn transfer_owner(
group_id: Uuid,
body: models::TransferGroupOwnershipRequest,
) -> GlobalResult<models::TransferGroupOwnershipResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (user, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

let new_owner_user_id = Uuid::from_str(body.new_owner_identity_id.as_str())?;

Expand Down Expand Up @@ -856,7 +856,7 @@ pub async fn transfer_owner(

// Verify that new owner is a group member
ensure_with!(
utils::group_member(&ctx, group_id, new_owner_user_id).await?,
utils::group_member(&ctx, group_id, new_owner_user_id).await? || user.is_admin,
GROUP_NOT_MEMBER
);

Expand All @@ -878,7 +878,7 @@ pub async fn prepare_avatar_upload(
ctx: Ctx<Auth>,
body: new_models::GroupPrepareAvatarUploadRequest,
) -> GlobalResult<new_models::GroupPrepareAvatarUploadResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;
assert::user_registered(&ctx, user_ent.user_id).await?;

ensure!(body.content_length >= 0, "Upload invalid");
Expand Down Expand Up @@ -927,7 +927,7 @@ pub async fn complete_avatar_upload(
upload_id: Uuid,
_body: models::CompleteGroupAvatarUploadRequest,
) -> GlobalResult<models::CompleteGroupAvatarUploadResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Validate the team exists
let teams_res = op!([ctx] team_get {
Expand Down Expand Up @@ -959,7 +959,7 @@ pub async fn create_invite(
group_id: Uuid,
body: models::CreateGroupInviteRequest,
) -> GlobalResult<models::CreateGroupInviteResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Validate the team exists
let teams_res = op!([ctx] team_get {
Expand Down Expand Up @@ -999,7 +999,7 @@ pub async fn consume_invite(
code: String,
_body: models::ConsumeGroupInviteRequest,
) -> GlobalResult<models::ConsumeGroupInviteResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

ensure_eq!(code.len(), 8, "invalid code");

Expand Down Expand Up @@ -1078,7 +1078,7 @@ pub async fn get_invite(
code: String,
_watch_index: WatchIndexQuery,
) -> GlobalResult<models::GetGroupInviteResponse> {
let _user_ent = ctx.auth().user(ctx.op_ctx()).await?;
ctx.auth().user(ctx.op_ctx()).await?;

ensure_eq!(code.len(), 8, "invalid code");

Expand Down Expand Up @@ -1121,7 +1121,7 @@ pub async fn kick_member(
identity_id: Uuid,
_body: models::KickGroupMemberRequest,
) -> GlobalResult<models::KickGroupMemberResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (user, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Verify user is not self
ensure_with!(
Expand All @@ -1147,7 +1147,7 @@ pub async fn kick_member(

// Verify that user is a group member
ensure_with!(
utils::group_member(&ctx, group_id, identity_id).await?,
utils::group_member(&ctx, group_id, identity_id).await? || user.is_admin,
GROUP_NOT_MEMBER
);

Expand All @@ -1169,7 +1169,7 @@ pub async fn ban(
identity_id: Uuid,
_body: models::BanGroupIdentityRequest,
) -> GlobalResult<models::BanGroupIdentityResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Verify user is not self
ensure_with!(
Expand Down Expand Up @@ -1210,7 +1210,7 @@ pub async fn unban(
group_id: Uuid,
identity_id: Uuid,
) -> GlobalResult<models::UnbanGroupIdentityResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Verify user is not self
ensure_with!(
Expand Down Expand Up @@ -1263,7 +1263,7 @@ pub async fn bans(
watch_index: WatchIndexQuery,
_query: ListBansQuery,
) -> GlobalResult<models::GetGroupBansResponse> {
let user_ent = ctx.auth().user(ctx.op_ctx()).await?;
let (_, user_ent) = ctx.auth().user(ctx.op_ctx()).await?;

// Verify the team exists
let (teams_res, team_bans_res) = tokio::try_join!(
Expand Down