Skip to content

Commit

Permalink
Merge pull request #33 from sablier-labs/feat/add-bearer-authentication
Browse files Browse the repository at this point in the history
Feat: add bearer token authorization
  • Loading branch information
gavriliumircea authored Jul 5, 2024
2 parents 1ac14d3 + 64125ba commit 892db95
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 15 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export PINATA_ACCESS_TOKEN=
export PINATA_API_KEY=
export PINATA_API_SERVER=
export PINATA_SECRET_API_KEY=
export IPFS_GATEWAY=
export IPFS_GATEWAY=
export MERKLE_API_BEARER_TOKEN=
41 changes: 31 additions & 10 deletions src/controller/eligibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ use url::Url;
use vercel_runtime as Vercel;
use warp::Filter;

/// Bearer token guard
fn is_authorized(req: &Vercel::Request) -> bool {
let headers = req.headers();
let expected_token = std::env::var("MERKLE_API_BEARER_TOKEN").expect("MERKLE_API_BEARER_TOKEN must be set");

if let Some(auth_header) = headers.get("Authorization") {
if let Ok(auth_str) = auth_header.to_str() {
return auth_str == format!("Bearer {}", expected_token);
}
}

false
}

/// Eligibility request common handler. It downloads data from IPFS and determines if an address is eligible for an
/// airstream campaign.
pub async fn handler(eligibility: Eligibility) -> response::R {
Expand Down Expand Up @@ -71,19 +85,26 @@ pub async fn handler_to_vercel(req: Vercel::Request) -> Result<Vercel::Response<
let url = Url::parse(&req.uri().to_string()).unwrap();
let query: HashMap<String, String> = url.query_pairs().into_owned().collect();

// ------------------------------------------------------------
//Format arguments for the generic handler
// ------------------------------------------------------------
if is_authorized(&req) {
// ------------------------------------------------------------
//Format arguments for the generic handler
// ------------------------------------------------------------

let fallback = String::from("");
let params = Eligibility {
address: query.get("address").unwrap_or(&fallback).clone(),
cid: query.get("cid").unwrap_or(&fallback).clone(),
};

let fallback = String::from("");
let params = Eligibility {
address: query.get("address").unwrap_or(&fallback).clone(),
cid: query.get("cid").unwrap_or(&fallback).clone(),
};
let result = handler(params).await;

let result = handler(params).await;
response::to_vercel(result)
} else {
let response_json =
json!(GeneralErrorResponse { message: String::from("Bad authentication process provided.") });

response::to_vercel(result)
response::to_vercel(response::unauthorized(response_json))
}
}

/// Bind the route with the handler for the Warp handler.
Expand Down
5 changes: 5 additions & 0 deletions src/data_objects/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ pub fn bad_request(json_response: Json) -> R {
R { status: warp::http::StatusCode::BAD_REQUEST.as_u16(), message: json_response }
}

/// Create a UNAUTHORIZED type of response
pub fn unauthorized(json_response: Json) -> R {
R { status: warp::http::StatusCode::UNAUTHORIZED.as_u16(), message: json_response }
}

/// Create an Ok type of response
pub fn ok(json_response: Json) -> R {
R { status: warp::http::StatusCode::OK.as_u16(), message: json_response }
Expand Down
4 changes: 0 additions & 4 deletions src/services/ipfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ use serde::{de::DeserializeOwned, Deserialize};
pub struct PinataSuccess {
#[serde(rename = "IpfsHash")]
pub ipfs_hash: String,
#[serde(rename = "PinSize")]
pub pin_size: usize,
#[serde(rename = "Timestamp")]
pub timestamp: String,
}

/// Deserialize the text response returned by Pinata API into PinataSuccess
Expand Down

0 comments on commit 892db95

Please sign in to comment.