Skip to content
Closed
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
13 changes: 13 additions & 0 deletions lib/claims/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ pub trait ClaimsDecode {
fn as_access_token(&self) -> GlobalResult<ent::AccessToken>;
fn as_provisioned_server(&self) -> GlobalResult<ent::ProvisionedServer>;
fn as_game_namespace_service(&self) -> GlobalResult<ent::GameNamespaceService>;
fn as_game_namespace_service_option(&self) -> GlobalResult<Option<ent::GameNamespaceService>>;
}

impl ClaimsDecode for schema::Claims {
Expand Down Expand Up @@ -679,6 +680,18 @@ impl ClaimsDecode for schema::Claims {
))
.and_then(std::convert::identity)
}

fn as_game_namespace_service_option(&self) -> GlobalResult<Option<ent::GameNamespaceService>> {
self.entitlements
.iter()
.find_map(|ent| match &ent.kind {
Some(schema::entitlement::Kind::GameNamespaceService(ent)) => {
Some(ent::GameNamespaceService::try_from(ent))
}
_ => None,
})
.transpose()
}
}

pub trait EntitlementTag {
Expand Down
6 changes: 3 additions & 3 deletions svc/api/cloud/src/route/games/namespaces/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ pub async fn create_token_service(
ctx: Ctx<Auth>,
game_id: Uuid,
namespace_id: Uuid,
body: models::CreateGameNamespaceTokenServiceRequest,
) -> GlobalResult<models::CreateGameNamespaceTokenServiceResponse> {
body: models::CloudGamesNamespacesCreateGameNamespaceTokenServiceRequest,
) -> GlobalResult<models::CloudGamesNamespacesCreateGameNamespaceTokenServiceResponse> {
ctx.auth()
.check_game_write_or_admin(ctx.op_ctx(), game_id)
.await?;
Expand Down Expand Up @@ -309,7 +309,7 @@ pub async fn create_token_service(
}).await?;

Ok(
models::CloudGamesNamespacesCreateGameNamespaceTokenPublicResponse {
models::CloudGamesNamespacesCreateGameNamespaceTokenServiceResponse {
token: unwrap!(token_res.token).token,
},
)
Expand Down
2 changes: 1 addition & 1 deletion svc/api/cloud/src/route/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ define_router! {
},
"games" / Uuid / "namespaces" / Uuid / "tokens" / "service": {
POST: games::namespaces::create_token_service(
body: models::CreateGameNamespaceTokenServiceRequest
body: models::CloudGamesNamespacesCreateGameNamespaceTokenServiceRequest
),
},
"games" / Uuid / "namespaces" / Uuid / "tokens" / "development": {
Expand Down
58 changes: 48 additions & 10 deletions svc/api/matchmaker/src/auth.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use api_helper::{
auth::{ApiAuth, AuthRateLimitCtx},
ctx::Ctx,
util::{as_auth_expired, basic_rate_limit},
util::{as_auth_expired, basic_rate_limit, basic_rate_limit_with_config},
};
use proto::claims::Claims;
use rivet_cache::{RateLimitBucketConfig, RateLimitConfig};
use rivet_claims::ClaimsDecode;
use rivet_operation::prelude::*;

Expand All @@ -18,15 +19,43 @@ impl ApiAuth for Auth {
api_token: Option<String>,
rate_limit_ctx: AuthRateLimitCtx<'_>,
) -> GlobalResult<Auth> {
Self::rate_limit(rate_limit_ctx).await?;

Ok(Auth {
claims: if let Some(api_token) = api_token {
Some(as_auth_expired(rivet_claims::decode(&api_token)?)?)
} else {
None
},
})
// Decode claims
let claims = if let Some(api_token) = api_token {
Some(as_auth_expired(rivet_claims::decode(&api_token)?)?)
} else {
None
};

// Customize rate limit
if claims
.as_ref()
.and_then(|x| x.as_game_namespace_service_option().transpose())
.transpose()?
.is_some()
{
// TODO: Configure by route & by game ID
basic_rate_limit_with_config(
rate_limit_ctx,
Some(RateLimitConfig {
key: "service".into(),
buckets: vec![
RateLimitBucketConfig {
count: 256,
bucket_duration_ms: util::duration::minutes(1),
},
RateLimitBucketConfig {
count: 10_000,
bucket_duration_ms: util::duration::hours(1),
},
],
}),
)
.await?;
} else {
Self::rate_limit(rate_limit_ctx).await?;
}

Ok(Auth { claims })
}

async fn rate_limit(rate_limit_ctx: AuthRateLimitCtx<'_>) -> GlobalResult<()> {
Expand Down Expand Up @@ -54,6 +83,15 @@ impl Auth {
.transpose()?
{
return Ok(game_ns);
} else if let Some(ns_service) = self
.claims
.as_ref()
.and_then(|x| x.as_game_namespace_service_option().transpose())
.transpose()?
{
return Ok(rivet_claims::ent::GameNamespacePublic {
namespace_id: ns_service.namespace_id,
});
} else {
tracing::info!("no ns claims");
}
Expand Down