Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/WalletConnect/echo-server i…
Browse files Browse the repository at this point in the history
…nto feat/fcm-v1
  • Loading branch information
chris13524 committed Apr 19, 2024
2 parents 37f019f + f5218e6 commit 63df7de
Show file tree
Hide file tree
Showing 28 changed files with 78 additions and 260 deletions.
4 changes: 0 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ TENANT_DATABASE_URL=
DEFAULT_TENANT_ID= # This has a default value and dosen't hold much impact to the running of echo-server
JWT_SECRET=

# Cloud App
CLOUD_API_URL=
CLOUD_API_KEY=

# CORS
CORS_ALLOWED_ORIGINS=*

Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ jobs:
env:
TF_VAR_grafana_auth: ${{ steps.grafana-get-key.outputs.key }}
TF_VAR_grafana_endpoint: ${{ steps.grafana-get-details.outputs.endpoint }}
TF_VAR_cloud_api_key: ${{ secrets.CLOUD_API_KEY }}
TF_VAR_jwt_secret: ${{ secrets.JWT_SECRET }}
TF_VAR_image_version: ${{ inputs.image_tag }}
TF_VAR_relay_public_key: ${{ secrets.RELAY_PUBLIC_KEY }}
Expand Down Expand Up @@ -154,7 +153,6 @@ jobs:
env:
TF_VAR_grafana_auth: ${{ steps.grafana-get-key.outputs.key }}
TF_VAR_grafana_endpoint: ${{ steps.grafana-get-details.outputs.endpoint }}
TF_VAR_cloud_api_key: ${{ secrets.CLOUD_API_KEY }}
TF_VAR_jwt_secret: ${{ secrets.JWT_SECRET }}
TF_VAR_image_version: ${{ inputs.image_tag }}
TF_VAR_relay_public_key: ${{ secrets.RELAY_PUBLIC_KEY }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/ci_terraform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ jobs:
env:
TF_VAR_grafana_auth: ${{ steps.grafana-get-key.outputs.key }}
TF_VAR_grafana_endpoint: ${{ steps.grafana-get-details.outputs.endpoint }}
TF_VAR_cloud_api_key: ${{ secrets.CLOUD_API_KEY }}
TF_VAR_jwt_secret: ${{ secrets.JWT_SECRET }}
TF_VAR_relay_public_key: ${{ secrets.RELAY_PUBLIC_KEY }}
with:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.

- - -
## v0.38.0 - 2024-04-17
#### Features
- refactored cloud auth (#317) - (830ad97) - Chris Smith

- - -

## v0.37.6 - 2024-03-25
#### Bug Fixes
- APNs certificate expired error (#314) - (d5347fa) - Chris Smith
Expand Down
28 changes: 1 addition & 27 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "echo-server"
version = "0.37.6"
version = "0.38.0"
edition = "2021"
authors = [
"Harry Bairstow <[email protected]>"
Expand Down Expand Up @@ -90,8 +90,6 @@ is-variant-derive = { path = "crates/is-variant-derive" }
once_cell = "1.15"
pnet_datalink = "0.31"
ipnet = "2.5"
cerberus = { git = "https://github.com/WalletConnect/cerberus.git", tag = "v0.5.0" }
async-recursion = "1.0.4"
tap = "1.0.1"
wiremock = "0.5.21"
moka = { version = "0.12", features = ["future"] }
Expand Down
6 changes: 0 additions & 6 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,6 @@ pub struct Config {

#[cfg(feature = "geoblock")]
pub blocked_countries: Vec<String>,

// Cloud
#[cfg(feature = "cloud")]
pub cloud_api_url: String,
#[cfg(feature = "cloud")]
pub cloud_api_key: String,
}

impl Config {
Expand Down
9 changes: 0 additions & 9 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,6 @@ pub enum Error {
#[error("BatchCollector Error: {0}")]
BatchCollector(String),

#[error(transparent)]
Registry(#[from] cerberus::registry::RegistryError),

#[error("Invalid Project ID: {0}")]
InvalidProjectId(String),

Expand Down Expand Up @@ -534,12 +531,6 @@ impl IntoResponse for Error {
message: "Internal error monitoring the request".to_string(),
},
], vec![]),
Error::Registry(_) => crate::handlers::Response::new_failure(StatusCode::INTERNAL_SERVER_ERROR, vec![
ResponseError {
name: "internal_api_failed".to_string(),
message: "Please check https://status.walletconnect.com as an internal API failed to resolve this request".to_string(),
},
], vec![]),
Error::JWT(_) => crate::handlers::Response::new_failure(StatusCode::UNAUTHORIZED, vec![
ResponseError {
name: "invalid_auth".to_string(),
Expand Down
63 changes: 12 additions & 51 deletions src/handlers/create_tenant.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
#[cfg(feature = "cloud")]
use cerberus::registry::RegistryClient;
use {
crate::{
error::{Error, Error::InvalidProjectId},
handlers::validate_tenant_request,
increment_counter,
log::prelude::*,
state::AppState,
stores::tenant::TenantUpdateParams,
error::Error, handlers::validate_tenant_request, increment_counter, log::prelude::*,
state::AppState, stores::tenant::TenantUpdateParams,
},
axum::{extract::State, http::HeaderMap, Json},
serde::{Deserialize, Serialize},
Expand All @@ -34,52 +28,19 @@ pub async fn handler(
Json(body): Json<TenantRegisterBody>,
) -> Result<Json<TenantRegisterResponse>, Error> {
#[cfg(feature = "cloud")]
let (valid_id, project) = {
let project_id = body.id.clone();

let response = state.registry_client.project_data(&project_id).await?;

if let Some(project) = response {
// TODO potentially more validation in future
// Project passed forwards for JWT verification later
(project.is_enabled, Some(project))
} else {
(false, None)
}
};

// When not using the cloud app all Ids are valid
#[cfg(not(feature = "cloud"))]
let valid_id = true;

if !valid_id {
return Err(InvalidProjectId(body.id));
}

#[cfg(feature = "cloud")]
if let Some(project) = project {
if let Err(e) = validate_tenant_request(
&state.registry_client,
&state.gotrue_client,
&headers,
body.id.clone(),
Some(project),
)
.await
{
error!(
tenant_id = %body.id,
err = ?e,
"JWT verification failed"
);
return Err(e);
}
} else {
return Err(InvalidProjectId(body.id));
if let Err(e) =
validate_tenant_request(&state.jwt_validation_client, &headers, body.id.clone()).await
{
error!(
tenant_id = %body.id,
err = ?e,
"JWT verification failed"
);
return Err(e);
}

#[cfg(not(feature = "cloud"))]
if let Err(e) = validate_tenant_request(&state.gotrue_client, &headers) {
if let Err(e) = validate_tenant_request(&state.jwt_validation_client, &headers) {
error!(
tenant_id = %body.id,
err = ?e,
Expand Down
12 changes: 3 additions & 9 deletions src/handlers/delete_tenant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,11 @@ pub async fn handler(
headers: HeaderMap,
) -> Result<Json<DeleteTenantResponse>, Error> {
#[cfg(feature = "cloud")]
let verification_res = validate_tenant_request(
&state.registry_client,
&state.gotrue_client,
&headers,
id.clone(),
None,
)
.await;
let verification_res =
validate_tenant_request(&state.jwt_validation_client, &headers, id.clone()).await;

#[cfg(not(feature = "cloud"))]
let verification_res = validate_tenant_request(&state.gotrue_client, &headers);
let verification_res = validate_tenant_request(&state.jwt_validation_client, &headers);

if let Err(e) = verification_res {
error!(
Expand Down
12 changes: 3 additions & 9 deletions src/handlers/get_tenant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,11 @@ pub async fn handler(
headers: HeaderMap,
) -> Result<Json<GetTenantResponse>, Error> {
#[cfg(feature = "cloud")]
let verification_res = validate_tenant_request(
&state.registry_client,
&state.gotrue_client,
&headers,
id.clone(),
None,
)
.await;
let verification_res =
validate_tenant_request(&state.jwt_validation_client, &headers, id.clone()).await;

#[cfg(not(feature = "cloud"))]
let verification_res = validate_tenant_request(&state.gotrue_client, &headers);
let verification_res = validate_tenant_request(&state.jwt_validation_client, &headers);

if let Err(e) = verification_res {
error!(
Expand Down
76 changes: 27 additions & 49 deletions src/handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
#[cfg(feature = "cloud")]
use {
crate::error::Error::InvalidProjectId,
async_recursion::async_recursion,
cerberus::{
project::ProjectData,
registry::{RegistryClient, RegistryHttpClient},
},
};
use {
crate::{
error::{Error::InvalidAuthentication, Result},
supabase::GoTrueClient,
jwt_validation::JwtValidationClient,
},
axum::{
http::{header::AUTHORIZATION, HeaderMap},
Expand Down Expand Up @@ -164,58 +155,45 @@ impl Default for Response {
}
}

#[async_recursion]
#[cfg(feature = "cloud")]
#[instrument(skip_all, fields(project_id = %project_id, project = ?project))]
#[instrument(skip_all, fields(project_id = %project_id))]
pub async fn validate_tenant_request(
registry_client: &RegistryHttpClient,
gotrue_client: &GoTrueClient,
jwt_validation_client: &JwtValidationClient,
headers: &HeaderMap,
project_id: String,
project: Option<ProjectData>,
) -> Result<bool> {
if let Some(project) = project {
if let Some(token_value) = headers.get(AUTHORIZATION) {
Ok(match gotrue_client
.is_valid_token(token_value.to_str()?.to_string().replace("Bearer ", ""))
{
Ok(token_data) => {
#[cfg(feature = "cloud")]
let valid_token = token_data.claims.sub == project.creator;

#[cfg(not(feature = "cloud"))]
let valid_token = true;

if !valid_token {
Err(InvalidAuthentication)
} else {
Ok(true)
}
if let Some(token_value) = headers.get(AUTHORIZATION) {
Ok(match jwt_validation_client
.is_valid_token(token_value.to_str()?.to_string().replace("Bearer ", ""))
{
Ok(token_data) => {
#[cfg(feature = "cloud")]
let valid_token = token_data.claims.sub == project_id;

#[cfg(not(feature = "cloud"))]
let valid_token = true;

if !valid_token {
Err(InvalidAuthentication)
} else {
Ok(true)
}
Err(_) => Err(InvalidAuthentication),
}?)
} else {
Err(InvalidAuthentication)
}
} else if let Some(project_fetched) = registry_client.project_data(&project_id).await? {
validate_tenant_request(
registry_client,
gotrue_client,
headers,
project_id,
Some(project_fetched),
)
.await
}
Err(_) => Err(InvalidAuthentication),
}?)
} else {
Err(InvalidProjectId(project_id.to_string()))
Err(InvalidAuthentication)
}
}

#[cfg(not(feature = "cloud"))]
#[instrument(skip_all)]
pub fn validate_tenant_request(gotrue_client: &GoTrueClient, headers: &HeaderMap) -> Result<bool> {
pub fn validate_tenant_request(
jwt_validation_client: &JwtValidationClient,
headers: &HeaderMap,
) -> Result<bool> {
if let Some(token_data) = headers.get(AUTHORIZATION) {
if gotrue_client
if jwt_validation_client
.is_valid_token(token_data.to_str()?.to_string().replace("Bearer ", ""))
.is_ok()
{
Expand Down
Loading

0 comments on commit 63df7de

Please sign in to comment.