Skip to content

Commit

Permalink
fix: enable opt_auth for regions & enable service tokens for upgradin…
Browse files Browse the repository at this point in the history
…g actors (#1618)

<!-- Please make sure there is an issue that this PR is correlated to. -->

## Changes

<!-- If there are frontend changes, please include screenshots. -->
  • Loading branch information
NathanFlurry committed Dec 13, 2024
1 parent 33ede46 commit 12ecaf3
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 27 deletions.
18 changes: 14 additions & 4 deletions packages/api/actor/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ pub struct Auth {
claims: Option<Claims>,
}

pub struct CheckOpts<'a> {
pub query: &'a GlobalQuery,
pub allow_service_token: bool,
pub opt_auth: bool,
}

pub struct CheckOutput {
pub game_id: Uuid,
pub env_id: Uuid,
Expand Down Expand Up @@ -65,13 +71,12 @@ impl Auth {
pub async fn check(
&self,
ctx: &OperationContext<()>,
query: &GlobalQuery,
allow_service: bool,
opts: CheckOpts<'_>,
) -> GlobalResult<CheckOutput> {
let is_development = ctx.config().server()?.rivet.auth.access_kind
== rivet_config::config::rivet::AccessKind::Development;

let (project_query, environment_query) = query.project_and_env()?;
let (project_query, environment_query) = opts.query.project_and_env()?;

// Lookup project name ID
let project = if is_development {
Expand Down Expand Up @@ -121,6 +126,11 @@ impl Auth {
return Ok(output);
}

// Skip auth if not needed
if self.claims.is_none() && opts.opt_auth {
return Ok(output);
}

// Validate claims
let claims = self.claims()?;

Expand All @@ -134,7 +144,7 @@ impl Auth {
Ok(output)
} else if let Ok(service_ent) = claims.as_env_service() {
ensure_with!(
allow_service,
opts.allow_service_token,
API_FORBIDDEN,
reason = "Cannot use service token for this endpoint."
);
Expand Down
75 changes: 65 additions & 10 deletions packages/api/actor/src/route/actors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use serde_json::json;

use crate::{
assert,
auth::{Auth, CheckOutput},
auth::{Auth, CheckOpts, CheckOutput},
utils::build_global_query_compat,
};

Expand Down Expand Up @@ -40,7 +40,17 @@ async fn get_inner(
_watch_index: WatchIndexQuery,
query: GlobalEndpointTypeQuery,
) -> GlobalResult<models::ActorGetActorResponse> {
let CheckOutput { env_id, .. } = ctx.auth().check(ctx.op_ctx(), &query.global, true).await?;
let CheckOutput { env_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query.global,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

// Get the server
let servers_res = ctx
Expand Down Expand Up @@ -119,8 +129,17 @@ pub async fn create(
body: models::ActorCreateActorRequest,
query: GlobalEndpointTypeQuery,
) -> GlobalResult<models::ActorCreateActorResponse> {
let CheckOutput { game_id, env_id } =
ctx.auth().check(ctx.op_ctx(), &query.global, true).await?;
let CheckOutput { game_id, env_id } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query.global,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

let (clusters_res, game_configs_res, build) = tokio::try_join!(
ctx.op(cluster::ops::get_for_game::Input {
Expand Down Expand Up @@ -408,8 +427,17 @@ pub async fn destroy(
actor_id: Uuid,
query: DeleteQuery,
) -> GlobalResult<serde_json::Value> {
let CheckOutput { game_id, env_id } =
ctx.auth().check(ctx.op_ctx(), &query.global, true).await?;
let CheckOutput { game_id, env_id } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query.global,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

ensure_with!(
query.override_kill_timeout.unwrap_or(0) >= 0,
Expand Down Expand Up @@ -474,7 +502,17 @@ pub async fn upgrade(
body: models::ActorUpgradeActorRequest,
query: GlobalQuery,
) -> GlobalResult<serde_json::Value> {
let CheckOutput { game_id, env_id } = ctx.auth().check(ctx.op_ctx(), &query, false).await?;
let CheckOutput { game_id, env_id } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

assert::server_for_env(&ctx, actor_id, game_id, env_id, None).await?;

Expand Down Expand Up @@ -502,7 +540,17 @@ pub async fn upgrade_all(
body: models::ActorUpgradeAllActorsRequest,
query: GlobalQuery,
) -> GlobalResult<models::ActorUpgradeAllActorsResponse> {
let CheckOutput { game_id, env_id } = ctx.auth().check(ctx.op_ctx(), &query, false).await?;
let CheckOutput { game_id, env_id } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

let tags = unwrap_with!(body.tags, API_BAD_BODY, error = "missing property `tags`");

Expand Down Expand Up @@ -622,9 +670,16 @@ async fn list_actors_inner(
_watch_index: WatchIndexQuery,
query: ListQuery,
) -> GlobalResult<models::ActorListActorsResponse> {
let CheckOutput { env_id, .. } = ctx
let CheckOutput { game_id, env_id } = ctx
.auth()
.check(ctx.op_ctx(), &query.global_endpoint_type.global, true)
.check(
ctx.op_ctx(),
CheckOpts {
query: &query.global_endpoint_type.global,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

let include_destroyed = query.include_destroyed.unwrap_or(false);
Expand Down
62 changes: 56 additions & 6 deletions packages/api/actor/src/route/builds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde_json::json;
use util::timestamp;

use crate::{
auth::{Auth, CheckOutput},
auth::{Auth, CheckOpts, CheckOutput},
utils::build_global_query_compat,
};

Expand All @@ -22,7 +22,17 @@ pub async fn get(
_watch_index: WatchIndexQuery,
query: GlobalQuery,
) -> GlobalResult<models::ActorGetBuildResponse> {
let CheckOutput { env_id, .. } = ctx.auth().check(ctx.op_ctx(), &query, true).await?;
let CheckOutput { env_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

let builds_res = op!([ctx] build_get {
build_ids: vec![build_id.into()],
Expand Down Expand Up @@ -87,7 +97,17 @@ pub async fn list(
_watch_index: WatchIndexQuery,
query: ListQuery,
) -> GlobalResult<models::ActorListBuildsResponse> {
let CheckOutput { env_id, .. } = ctx.auth().check(ctx.op_ctx(), &query.global, true).await?;
let CheckOutput { env_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query.global,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

let list_res = op!([ctx] build_list_for_env {
env_id: Some(env_id.into()),
Expand Down Expand Up @@ -183,7 +203,17 @@ pub async fn patch_tags(
body: models::ActorPatchBuildTagsRequest,
query: GlobalQuery,
) -> GlobalResult<serde_json::Value> {
let CheckOutput { env_id, .. } = ctx.auth().check(ctx.op_ctx(), &query, true).await?;
let CheckOutput { env_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

let tags = unwrap_with!(body.tags, API_BAD_BODY, error = "missing field `tags`");

Expand Down Expand Up @@ -268,7 +298,17 @@ pub async fn create_build(
body: models::ActorPrepareBuildRequest,
query: GlobalQuery,
) -> GlobalResult<models::ActorPrepareBuildResponse> {
let CheckOutput { env_id, .. } = ctx.auth().check(ctx.op_ctx(), &query, true).await?;
let CheckOutput { env_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

let (kind, image_tag) = match body.kind {
Option::None | Some(models::ActorBuildKind::DockerImage) => (
Expand Down Expand Up @@ -372,7 +412,17 @@ pub async fn complete_build(
_body: serde_json::Value,
query: GlobalQuery,
) -> GlobalResult<serde_json::Value> {
let CheckOutput { env_id, .. } = ctx.auth().check(ctx.op_ctx(), &query, true).await?;
let CheckOutput { env_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query,
allow_service_token: true,
opt_auth: false,
},
)
.await?;

let build_res = op!([ctx] build_get {
build_ids: vec![build_id.into()],
Expand Down
15 changes: 12 additions & 3 deletions packages/api/actor/src/route/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::time::Duration;

use crate::{
assert,
auth::{Auth, CheckOutput},
auth::{Auth, CheckOpts, CheckOutput},
utils::build_global_query_compat,
};

Expand All @@ -30,8 +30,17 @@ pub async fn get_logs(
watch_index: WatchIndexQuery,
query: GetActorLogsQuery,
) -> GlobalResult<models::ActorGetActorLogsResponse> {
let CheckOutput { game_id, env_id } =
ctx.auth().check(ctx.op_ctx(), &query.global, false).await?;
let CheckOutput { game_id, env_id } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query.global,
allow_service_token: false,
opt_auth: false,
},
)
.await?;

// Validate server belongs to game
assert::server_for_env(&ctx, server_id, game_id, env_id, None).await?;
Expand Down
38 changes: 34 additions & 4 deletions packages/api/actor/src/route/regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rivet_operation::prelude::*;
use serde::Deserialize;

use crate::{
auth::{Auth, CheckOutput},
auth::{Auth, CheckOpts, CheckOutput},
utils::build_global_query_compat,
};

Expand All @@ -17,7 +17,17 @@ pub async fn list(
_watch_index: WatchIndexQuery,
query: GlobalQuery,
) -> GlobalResult<models::ActorListRegionsResponse> {
let CheckOutput { game_id, .. } = ctx.auth().check(ctx.op_ctx(), &query, true).await?;
let CheckOutput { game_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query,
allow_service_token: true,
opt_auth: true,
},
)
.await?;

let cluster_res = ctx
.op(cluster::ops::get_for_game::Input {
Expand Down Expand Up @@ -61,7 +71,17 @@ pub async fn list_deprecated(
_watch_index: WatchIndexQuery,
) -> GlobalResult<models::ServersListDatacentersResponse> {
let query = build_global_query_compat(&ctx, game_id, env_id).await?;
let CheckOutput { game_id, .. } = ctx.auth().check(ctx.op_ctx(), &query, true).await?;
let CheckOutput { game_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query,
allow_service_token: true,
opt_auth: true,
},
)
.await?;

let cluster_res = ctx
.op(cluster::ops::get_for_game::Input {
Expand Down Expand Up @@ -113,7 +133,17 @@ pub async fn resolve(
_watch_index: WatchIndexQuery,
query: ResolveQuery,
) -> GlobalResult<models::ActorResolveRegionResponse> {
let CheckOutput { game_id, .. } = ctx.auth().check(ctx.op_ctx(), &query.global, true).await?;
let CheckOutput { game_id, .. } = ctx
.auth()
.check(
ctx.op_ctx(),
CheckOpts {
query: &query.global,
allow_service_token: true,
opt_auth: true,
},
)
.await?;

// Resolve coords
let coords = match (query.lat, query.long) {
Expand Down

0 comments on commit 12ecaf3

Please sign in to comment.