Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: apikey from cli arg or config #37

Merged
merged 1 commit into from
Jan 3, 2022
Merged
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
5 changes: 5 additions & 0 deletions cli.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ args:
short: e
long: endpoint
takes_value: true
- apikey:
help: The admin apikey
short: k
long: apikey
takes_value: true

# Subcommands
subcommands:
Expand Down
2 changes: 1 addition & 1 deletion src/agent/agents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub trait Agent {
#[async_trait]
pub trait HttpAgentExtended {
/// New http agent instance
fn new(endpoint: String) -> Self;
fn new(endpoint: String, api_key: Option<String>) -> Self;

/// Check if the endpoint is valid
async fn check_endpoint(&self) -> ();
Expand Down
32 changes: 16 additions & 16 deletions src/agent/http_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use crate::typing::{
Connection, Connections, CredentialDefinition, CredentialDefinitionConfig, Features,
Invitation, InvitationConfig, IssueCredentialConfig, MessageConfig, Schema, SchemaConfig,
};
use crate::utils::http;
use crate::utils::logger::Log;
use crate::utils::http::HttpCalls;
use async_trait::async_trait;
use reqwest::Url;
use serde_json::{json, Value};
Expand All @@ -13,7 +12,10 @@ use serde_json::{json, Value};
#[derive(Debug, Clone)]
pub struct HttpAgent {
/// base url of the cloudagent
url: String,
pub url: String,

/// admin Api key for the cloudagent
pub api_key: Option<String>,
}

/// All the available endpoints
Expand Down Expand Up @@ -91,13 +93,13 @@ impl Endpoint {

#[async_trait]
impl HttpAgentExtended for HttpAgent {
fn new(endpoint: String) -> Self {
HttpAgent { url: endpoint }
fn new(endpoint: String, api_key: Option<String>) -> Self {
HttpAgent { url: endpoint, api_key }
}

/// Check if the endpoint is valid
async fn check_endpoint(&self) -> () {
http::get::<Connections>(Endpoint::connections(&self.url), None).await;
self.get::<Connections>(Endpoint::connections(&self.url), None).await;
}
}

Expand All @@ -111,12 +113,12 @@ impl Agent for HttpAgent {
query.push(("alias", alias));
}

http::get::<Connections>(Endpoint::connections(&self.url), Some(query)).await
self.get::<Connections>(Endpoint::connections(&self.url), Some(query)).await
}

/// Get a connection by id
async fn get_connection_by_id(&self, id: String) -> Connection {
http::get::<Connection>(Endpoint::get_connection_by_id(&self.url, &id), None).await
self.get::<Connection>(Endpoint::get_connection_by_id(&self.url, &id), None).await
}

/// Prints an invitation, as url or qr, in stdout
Expand Down Expand Up @@ -146,12 +148,12 @@ impl Agent for HttpAgent {
}
}

http::post(Endpoint::create_invitation(&self.url), Some(query), body).await
self.post(Endpoint::create_invitation(&self.url), Some(query), body).await
}

/// Requests all the features from the cloudagent
async fn discover_features(&self) -> Features {
http::get::<Features>(Endpoint::discover_features(&self.url), None).await
self.get::<Features>(Endpoint::discover_features(&self.url), None).await
}

/// Send a basic message to another agent
Expand All @@ -160,7 +162,7 @@ impl Agent for HttpAgent {
"content": config.message,
});

http::post::<serde_json::Value>(
self.post::<serde_json::Value>(
Endpoint::basic_message(&self.url, &config.connection_id),
None,
Some(body),
Expand All @@ -178,9 +180,7 @@ impl Agent for HttpAgent {
}
});

Log::log_pretty(config);

http::post::<Value>(Endpoint::credential_offer(&self.url), None, Some(body)).await;
self.post::<Value>(Endpoint::credential_offer(&self.url), None, Some(body)).await;
}

async fn schema(&self, config: &SchemaConfig) -> Schema {
Expand All @@ -190,7 +190,7 @@ impl Agent for HttpAgent {
"schema_version": config.version
});

http::post::<Schema>(Endpoint::schema(&self.url), None, Some(body)).await
self.post::<Schema>(Endpoint::schema(&self.url), None, Some(body)).await
}

async fn credential_definition(
Expand All @@ -203,7 +203,7 @@ impl Agent for HttpAgent {
"tag": config.tag
});

http::post::<CredentialDefinition>(
self.post::<CredentialDefinition>(
Endpoint::credential_definition(&self.url),
None,
Some(body),
Expand Down
28 changes: 20 additions & 8 deletions src/cli/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,30 @@ pub async fn register_cli() {
// Takes a path, but prepends the home directory... kinda sketchy
let endpoint_from_config = config::get_value("/.config/accf/ex.ini", "Default", "endpoint");

// create an httpAgent when you supply an endpoint
let agent = match matches.value_of("endpoint") {
Some(endpoint) => HttpAgent::new(endpoint.to_string()),
// Takes a path, but prepends the home directory... kinda sketchy
let api_key_from_config = config::get_value("/.config/accf/ex.ini", "Default", "api_key");

// Get the endpoint when you supply an endpoint
let endpoint = match matches.value_of("endpoint") {
Some(endpoint) => endpoint.to_string(),
None => match endpoint_from_config {
Some(e) => HttpAgent::new(e),
None => match endpoint_from_config {
Some(e) => HttpAgent::new(e),
None => throw(Error::NoSuppliedEndpoint),
},
Some(e) => e,
None => throw(Error::NoSuppliedEndpoint),
},
};

// TODO: Check if this can be refactored
// Get the endpoint when you supply an endpoint
let api_key = match matches.value_of("apikey") {
Some(api_key) => Some(api_key.to_string()),
None => api_key_from_config
};

let agent = HttpAgent {
url: endpoint,
api_key
};

agent.check_endpoint().await;

// Registering the subcommands and their modules
Expand Down
92 changes: 57 additions & 35 deletions src/utils/http.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,71 @@
use reqwest::{Client, RequestBuilder, Url};
use serde::de::DeserializeOwned;
use serde_json::Value;

use async_trait::async_trait;
use crate::agent::http_agent::HttpAgent;
use crate::error::{throw, Error};

/// Builds a get request and calls the sender
pub async fn get<T: DeserializeOwned>(url: Url, query: Option<Vec<(&str, String)>>) -> T {
let client = match query {
Some(q) => Client::new().get(url).query(&q),
None => Client::new().get(url),
};

send::<T>(client).await
/// Interface providing HTTP call methods
#[async_trait]
pub trait HttpCalls {
/// GET method
async fn get<T: DeserializeOwned>(&self, url: Url, query: Option<Vec<(&str, String)>>) -> T;
/// POST method
async fn post<T: DeserializeOwned>(&self, url: Url, query: Option<Vec<(&str, String)>>, body: Option<Value>) -> T;
/// SEND - general method for GET and POST
async fn send<T: DeserializeOwned>(&self, client: RequestBuilder) -> T;
}

/// Builds a post request and calls the sender
pub async fn post<T: DeserializeOwned>(
url: Url,
query: Option<Vec<(&str, String)>>,
body: Option<Value>,
) -> T {
let client = Client::new().post(url).query(&query);
/// Call logic for http calls
#[async_trait]
impl HttpCalls for HttpAgent {
/// Builds a get request and calls the sender
async fn get<T: DeserializeOwned>(&self, url: Url, query: Option<Vec<(&str, String)>>) -> T {
let client = match query {
Some(q) => Client::new().get(url).query(&q),
None => Client::new().get(url),
};

self.send::<T>(client).await
}

let client = match body {
Some(b) => client.json(&b),
None => client,
};
/// Builds a post request and calls the sender
async fn post<T: DeserializeOwned>(
&self,
url: Url,
query: Option<Vec<(&str, String)>>,
body: Option<Value>,
) -> T {
let client = Client::new().post(url).query(&query);

send::<T>(client).await
}
let client = match body {
Some(b) => client.json(&b),
None => client,
};

self.send::<T>(client).await
}

/// Sends any request
async fn send<T: DeserializeOwned>(&self, client: RequestBuilder) -> T {
let client = match &self.api_key {
Some(a) => client.header("X-API-KEY", a),
None => client,
};

let response = client.send().await;

/// Sends any request
async fn send<T: DeserializeOwned>(client: RequestBuilder) -> T {
let response = client.send().await;

match response {
Ok(res) => {
if res.status().is_success() {
return match res.json().await {
Ok(parsed) => parsed,
Err(_) => throw(Error::ServerResponseParseError),
};
match response {
Ok(res) => {
if res.status().is_success() {
return match res.json().await {
Ok(parsed) => parsed,
Err(_) => throw(Error::ServerResponseParseError),
};
}
throw(Error::InternalServerError)
}
throw(Error::InternalServerError)
Err(_) => throw(Error::InternalServerError),
}
Err(_) => throw(Error::InternalServerError),
}
}