Skip to content

Commit

Permalink
[CX-6356] Accept Access Token in all Backend Endpoints for `convex de…
Browse files Browse the repository at this point in the history
…ploy` (#25759)

GitOrigin-RevId: 325724c9f2dc0e851752243e6a710455686b81af
  • Loading branch information
pashabitz authored and Convex, Inc. committed May 16, 2024
1 parent 69ebba0 commit ce5f34e
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 25 deletions.
14 changes: 8 additions & 6 deletions crates/application/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,8 +728,8 @@ impl<RT: Runtime> Application<RT> {
self.database.latest_snapshot()
}

pub fn app_auth(&self) -> Arc<ApplicationAuth> {
self.app_auth.clone()
pub fn app_auth(&self) -> &Arc<ApplicationAuth> {
&self.app_auth
}

pub async fn search_with_compiled_query(
Expand Down Expand Up @@ -2097,12 +2097,14 @@ impl<RT: Runtime> Application<RT> {
) -> anyhow::Result<Identity> {
let identity = match token {
AuthenticationToken::Admin(token, acting_as) => {
let admin_identity = self.key_broker().check_admin_key(&token).context(
ErrorMetadata::unauthenticated(
let admin_identity = self
.app_auth()
.check_key(token.to_string(), self.instance_name())
.await
.context(ErrorMetadata::unauthenticated(
"BadAdminKey",
"The provided admin key was invalid for this instance",
),
)?;
))?;

match acting_as {
Some(acting_user) => {
Expand Down
13 changes: 4 additions & 9 deletions crates/authentication/src/application_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,15 @@ impl ApplicationAuth {
admin_key_or_access_token: String,
instance_name: String,
) -> anyhow::Result<Identity> {
if admin_key_or_access_token.contains('|')
|| self
.key_broker
.is_encrypted_admin_key(&admin_key_or_access_token)
if self
.key_broker
.is_encrypted_admin_key(&admin_key_or_access_token)
{
// assume this is a legacy Deploy Key
// This is either a pipe-delimited deployment specific key
// or an encrypted admin key.
// The latter is used by smoke tests.
self.key_broker.check_admin_key(&admin_key_or_access_token)
} else {
// assume this is an Access Token
// Access Tokens are base64 encoded strings and do not have pipes
// in them
// Access Tokens are base64 encoded strings
self.access_token_auth
.is_authorized(&instance_name, &admin_key_or_access_token)
.await
Expand Down
13 changes: 13 additions & 0 deletions crates/local_backend/src/admin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::Context;
use authentication::application_auth::ApplicationAuth;
use common::types::MemberId;
use errors::ErrorMetadata;
use keybroker::{
Expand All @@ -17,6 +18,18 @@ pub fn must_be_admin_from_keybroker(
Ok(identity)
}

pub async fn must_be_admin_from_key(
app_auth: &ApplicationAuth,
instance_name: String,
admin_key_or_access_token: String,
) -> anyhow::Result<Identity> {
let identity = app_auth
.check_key(admin_key_or_access_token, instance_name.clone())
.await
.context(bad_admin_key_error(Some(instance_name)))?;
Ok(identity)
}

pub fn must_be_admin(identity: &Identity) -> anyhow::Result<MemberId> {
let member_id = identity
.member_id()
Expand Down
14 changes: 9 additions & 5 deletions crates/local_backend/src/deploy_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ use serde_json::Value as JsonValue;
use value::ConvexObject;

use crate::{
admin::must_be_admin_from_keybroker,
admin::{
must_be_admin_from_key,
must_be_admin_from_keybroker,
},
parse::parse_module_path,
EmptyResponse,
LocalAppState,
Expand Down Expand Up @@ -350,11 +353,12 @@ pub async fn get_config_hashes(
State(st): State<LocalAppState>,
Json(req): Json<GetConfigRequest>,
) -> Result<impl IntoResponse, HttpResponseError> {
let identity = must_be_admin_from_keybroker(
st.application.key_broker(),
Some(st.instance_name.clone()),
let identity = must_be_admin_from_key(
st.application.app_auth(),
st.instance_name.clone(),
req.admin_key,
)?;
)
.await?;

let mut tx = st.application.begin(identity).await?;
let (config, modules, udf_config) = ConfigModel::new(&mut tx)
Expand Down
11 changes: 6 additions & 5 deletions crates/local_backend/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ use value::{
use crate::{
admin::{
must_be_admin,
must_be_admin_from_keybroker,
must_be_admin_from_key,
},
authentication::ExtractIdentity,
deploy_config::ModuleJson,
Expand Down Expand Up @@ -255,11 +255,12 @@ pub async fn prepare_schema_handler(
req: PrepareSchemaArgs,
) -> Result<(Json<PrepareSchemaResponse>, bool), HttpResponseError> {
let bundle = req.bundle.try_into()?;
let identity = must_be_admin_from_keybroker(
st.application.key_broker(),
Some(st.instance_name.clone()),
let identity = must_be_admin_from_key(
st.application.app_auth(),
st.instance_name.clone(),
req.admin_key,
)?;
)
.await?;
let schema = match st.application.evaluate_schema(bundle).await {
Ok(m) => m,
Err(e) => return Err(e.into()),
Expand Down

0 comments on commit ce5f34e

Please sign in to comment.