From ae5b3767639f88d86104cce112e6188abaff69e4 Mon Sep 17 00:00:00 2001 From: morrieinmaas Date: Mon, 3 Jan 2022 11:21:10 +0100 Subject: [PATCH] feat: apikey from cli arg or config Signed-off-by: morrieinmaas --- cli.yaml | 5 +++ src/agent/agents.rs | 2 +- src/agent/http_agent.rs | 32 +++++++------- src/cli/register.rs | 28 +++++++++---- src/utils/http.rs | 92 +++++++++++++++++++++++++---------------- 5 files changed, 99 insertions(+), 60 deletions(-) diff --git a/cli.yaml b/cli.yaml index a0dfcc00..4b8f05b1 100644 --- a/cli.yaml +++ b/cli.yaml @@ -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: diff --git a/src/agent/agents.rs b/src/agent/agents.rs index a11d16a8..756d60eb 100644 --- a/src/agent/agents.rs +++ b/src/agent/agents.rs @@ -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) -> Self; /// Check if the endpoint is valid async fn check_endpoint(&self) -> (); diff --git a/src/agent/http_agent.rs b/src/agent/http_agent.rs index 50fb3408..744ebbcb 100644 --- a/src/agent/http_agent.rs +++ b/src/agent/http_agent.rs @@ -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}; @@ -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, } /// All the available endpoints @@ -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) -> Self { + HttpAgent { url: endpoint, api_key } } /// Check if the endpoint is valid async fn check_endpoint(&self) -> () { - http::get::(Endpoint::connections(&self.url), None).await; + self.get::(Endpoint::connections(&self.url), None).await; } } @@ -111,12 +113,12 @@ impl Agent for HttpAgent { query.push(("alias", alias)); } - http::get::(Endpoint::connections(&self.url), Some(query)).await + self.get::(Endpoint::connections(&self.url), Some(query)).await } /// Get a connection by id async fn get_connection_by_id(&self, id: String) -> Connection { - http::get::(Endpoint::get_connection_by_id(&self.url, &id), None).await + self.get::(Endpoint::get_connection_by_id(&self.url, &id), None).await } /// Prints an invitation, as url or qr, in stdout @@ -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::(Endpoint::discover_features(&self.url), None).await + self.get::(Endpoint::discover_features(&self.url), None).await } /// Send a basic message to another agent @@ -160,7 +162,7 @@ impl Agent for HttpAgent { "content": config.message, }); - http::post::( + self.post::( Endpoint::basic_message(&self.url, &config.connection_id), None, Some(body), @@ -178,9 +180,7 @@ impl Agent for HttpAgent { } }); - Log::log_pretty(config); - - http::post::(Endpoint::credential_offer(&self.url), None, Some(body)).await; + self.post::(Endpoint::credential_offer(&self.url), None, Some(body)).await; } async fn schema(&self, config: &SchemaConfig) -> Schema { @@ -190,7 +190,7 @@ impl Agent for HttpAgent { "schema_version": config.version }); - http::post::(Endpoint::schema(&self.url), None, Some(body)).await + self.post::(Endpoint::schema(&self.url), None, Some(body)).await } async fn credential_definition( @@ -203,7 +203,7 @@ impl Agent for HttpAgent { "tag": config.tag }); - http::post::( + self.post::( Endpoint::credential_definition(&self.url), None, Some(body), diff --git a/src/cli/register.rs b/src/cli/register.rs index 64750bb1..ec77b343 100644 --- a/src/cli/register.rs +++ b/src/cli/register.rs @@ -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 diff --git a/src/utils/http.rs b/src/utils/http.rs index 6d79dd4e..0b143540 100644 --- a/src/utils/http.rs +++ b/src/utils/http.rs @@ -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(url: Url, query: Option>) -> T { - let client = match query { - Some(q) => Client::new().get(url).query(&q), - None => Client::new().get(url), - }; - - send::(client).await +/// Interface providing HTTP call methods +#[async_trait] +pub trait HttpCalls { + /// GET method + async fn get(&self, url: Url, query: Option>) -> T; + /// POST method + async fn post(&self, url: Url, query: Option>, body: Option) -> T; + /// SEND - general method for GET and POST + async fn send(&self, client: RequestBuilder) -> T; } -/// Builds a post request and calls the sender -pub async fn post( - url: Url, - query: Option>, - body: Option, -) -> 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(&self, url: Url, query: Option>) -> T { + let client = match query { + Some(q) => Client::new().get(url).query(&q), + None => Client::new().get(url), + }; + + self.send::(client).await + } - let client = match body { - Some(b) => client.json(&b), - None => client, - }; + /// Builds a post request and calls the sender + async fn post( + &self, + url: Url, + query: Option>, + body: Option, + ) -> T { + let client = Client::new().post(url).query(&query); - send::(client).await -} + let client = match body { + Some(b) => client.json(&b), + None => client, + }; + + self.send::(client).await + } + + /// Sends any request + async fn send(&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(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), } }