mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-11 20:00:29 +01:00
Render inherited auth and headers (#217)
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::error::Result;
|
||||
use KeyAndValueRef::{Ascii, Binary};
|
||||
use tauri::{Manager, Runtime, WebviewWindow};
|
||||
use yaak_grpc::{KeyAndValueRef, MetadataMap};
|
||||
use yaak_models::models::GrpcRequest;
|
||||
use yaak_models::query_manager::QueryManagerExt;
|
||||
use yaak_plugins::events::{CallHttpAuthenticationRequest, HttpHeader};
|
||||
use yaak_plugins::manager::PluginManager;
|
||||
use KeyAndValueRef::{Ascii, Binary};
|
||||
|
||||
pub(crate) fn metadata_to_map(metadata: MetadataMap) -> BTreeMap<String, String> {
|
||||
let mut entries = BTreeMap::new();
|
||||
@@ -20,6 +20,23 @@ pub(crate) fn metadata_to_map(metadata: MetadataMap) -> BTreeMap<String, String>
|
||||
entries
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_grpc_request<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
request: &GrpcRequest,
|
||||
) -> Result<GrpcRequest> {
|
||||
let mut new_request = request.clone();
|
||||
|
||||
let (authentication_type, authentication) =
|
||||
window.db().resolve_auth_for_grpc_request(request)?;
|
||||
new_request.authentication_type = authentication_type;
|
||||
new_request.authentication = authentication;
|
||||
|
||||
let metadata = window.db().resolve_metadata_for_grpc_request(request)?;
|
||||
new_request.metadata = metadata;
|
||||
|
||||
Ok(new_request)
|
||||
}
|
||||
|
||||
pub(crate) async fn build_metadata<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
request: &GrpcRequest,
|
||||
@@ -28,8 +45,7 @@ pub(crate) async fn build_metadata<R: Runtime>(
|
||||
let mut metadata = BTreeMap::new();
|
||||
|
||||
// Add the rest of metadata
|
||||
let resolved_metadata = window.db().resolve_metadata_for_grpc_request(&request)?;
|
||||
for h in resolved_metadata {
|
||||
for h in request.metadata.clone() {
|
||||
if h.name.is_empty() && h.value.is_empty() {
|
||||
continue;
|
||||
}
|
||||
@@ -41,28 +57,34 @@ pub(crate) async fn build_metadata<R: Runtime>(
|
||||
metadata.insert(h.name, h.value);
|
||||
}
|
||||
|
||||
let (authentication_type, authentication) =
|
||||
window.db().resolve_auth_for_grpc_request(&request)?;
|
||||
|
||||
if let Some(auth_name) = authentication_type.clone() {
|
||||
let auth = authentication.clone();
|
||||
let plugin_req = CallHttpAuthenticationRequest {
|
||||
context_id: format!("{:x}", md5::compute(request.id.clone())),
|
||||
values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(),
|
||||
method: "POST".to_string(),
|
||||
url: request.url.clone(),
|
||||
headers: metadata
|
||||
.iter()
|
||||
.map(|(name, value)| HttpHeader {
|
||||
name: name.to_string(),
|
||||
value: value.to_string(),
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
let plugin_result =
|
||||
plugin_manager.call_http_authentication(&window, &auth_name, plugin_req).await?;
|
||||
for header in plugin_result.set_headers {
|
||||
metadata.insert(header.name, header.value);
|
||||
match request.authentication_type.clone() {
|
||||
None => {
|
||||
// No authentication found. Not even inherited
|
||||
}
|
||||
Some(authentication_type) if authentication_type == "none" => {
|
||||
// Explicitly no authentication
|
||||
}
|
||||
Some(authentication_type) => {
|
||||
let auth = request.authentication.clone();
|
||||
let plugin_req = CallHttpAuthenticationRequest {
|
||||
context_id: format!("{:x}", md5::compute(request.id.clone())),
|
||||
values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(),
|
||||
method: "POST".to_string(),
|
||||
url: request.url.clone(),
|
||||
headers: metadata
|
||||
.iter()
|
||||
.map(|(name, value)| HttpHeader {
|
||||
name: name.to_string(),
|
||||
value: value.to_string(),
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
let plugin_result = plugin_manager
|
||||
.call_http_authentication(&window, &authentication_type, plugin_req)
|
||||
.await?;
|
||||
for header in plugin_result.set_headers {
|
||||
metadata.insert(header.name, header.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,14 +65,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
);
|
||||
let update_source = UpdateSource::from_window(window);
|
||||
|
||||
let request = match render_http_request(
|
||||
&unrendered_request,
|
||||
&base_environment,
|
||||
environment.as_ref(),
|
||||
&cb,
|
||||
)
|
||||
.await
|
||||
{
|
||||
let resolved_request = match resolve_http_request(window, unrendered_request) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Ok(response_err(
|
||||
@@ -84,6 +77,21 @@ pub async fn send_http_request<R: Runtime>(
|
||||
}
|
||||
};
|
||||
|
||||
let request =
|
||||
match render_http_request(&resolved_request, &base_environment, environment.as_ref(), &cb)
|
||||
.await
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Ok(response_err(
|
||||
&app_handle,
|
||||
&*response.lock().await,
|
||||
e.to_string(),
|
||||
&update_source,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let mut url_string = request.url.clone();
|
||||
|
||||
url_string = ensure_proto(&url_string);
|
||||
@@ -230,9 +238,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
// );
|
||||
// }
|
||||
|
||||
let resolved_headers = window.db().resolve_headers_for_http_request(&request)?;
|
||||
|
||||
for h in resolved_headers {
|
||||
for h in request.headers.clone() {
|
||||
if h.name.is_empty() && h.value.is_empty() {
|
||||
continue;
|
||||
}
|
||||
@@ -431,10 +437,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
}
|
||||
};
|
||||
|
||||
let (authentication_type, authentication) =
|
||||
window.db().resolve_auth_for_http_request(&request)?;
|
||||
|
||||
match authentication_type {
|
||||
match request.authentication_type {
|
||||
None => {
|
||||
// No authentication found. Not even inherited
|
||||
}
|
||||
@@ -444,8 +447,10 @@ pub async fn send_http_request<R: Runtime>(
|
||||
Some(authentication_type) => {
|
||||
let req = CallHttpAuthenticationRequest {
|
||||
context_id: format!("{:x}", md5::compute(request.id)),
|
||||
values: serde_json::from_value(serde_json::to_value(&authentication).unwrap())
|
||||
.unwrap(),
|
||||
values: serde_json::from_value(
|
||||
serde_json::to_value(&request.authentication).unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
url: sendable_req.url().to_string(),
|
||||
method: sendable_req.method().to_string(),
|
||||
headers: sendable_req
|
||||
@@ -676,6 +681,23 @@ pub async fn send_http_request<R: Runtime>(
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_http_request<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
request: &HttpRequest,
|
||||
) -> Result<HttpRequest> {
|
||||
let mut new_request = request.clone();
|
||||
|
||||
let (authentication_type, authentication) =
|
||||
window.db().resolve_auth_for_http_request(request)?;
|
||||
new_request.authentication_type = authentication_type;
|
||||
new_request.authentication = authentication;
|
||||
|
||||
let headers = window.db().resolve_headers_for_http_request(request)?;
|
||||
new_request.headers = headers;
|
||||
|
||||
Ok(new_request)
|
||||
}
|
||||
|
||||
fn ensure_proto(url_str: &str) -> String {
|
||||
if url_str.starts_with("http://") || url_str.starts_with("https://") {
|
||||
return url_str.to_string();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extern crate core;
|
||||
use crate::encoding::read_response_body;
|
||||
use crate::error::Error::GenericError;
|
||||
use crate::grpc::{build_metadata, metadata_to_map};
|
||||
use crate::grpc::{build_metadata, metadata_to_map, resolve_grpc_request};
|
||||
use crate::http_request::send_http_request;
|
||||
use crate::notifications::YaakNotifier;
|
||||
use crate::render::{render_grpc_request, render_template};
|
||||
@@ -151,10 +151,13 @@ async fn cmd_grpc_reflect<R: Runtime>(
|
||||
None => None,
|
||||
};
|
||||
let unrendered_request = app_handle.db().get_grpc_request(request_id)?;
|
||||
let resolved_request = resolve_grpc_request(&window, &unrendered_request)?;
|
||||
|
||||
let base_environment =
|
||||
app_handle.db().get_base_environment(&unrendered_request.workspace_id)?;
|
||||
|
||||
let req = render_grpc_request(
|
||||
&unrendered_request,
|
||||
&resolved_request,
|
||||
&base_environment,
|
||||
environment.as_ref(),
|
||||
&PluginTemplateCallback::new(
|
||||
@@ -195,10 +198,12 @@ async fn cmd_grpc_go<R: Runtime>(
|
||||
None => None,
|
||||
};
|
||||
let unrendered_request = app_handle.db().get_grpc_request(request_id)?;
|
||||
let resolved_request = resolve_grpc_request(&window, &unrendered_request)?;
|
||||
let base_environment =
|
||||
app_handle.db().get_base_environment(&unrendered_request.workspace_id)?;
|
||||
|
||||
let request = render_grpc_request(
|
||||
&unrendered_request,
|
||||
&resolved_request,
|
||||
&base_environment,
|
||||
environment.as_ref(),
|
||||
&PluginTemplateCallback::new(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::error::Result;
|
||||
use crate::manager::WebsocketManager;
|
||||
use crate::render::render_request;
|
||||
use crate::render::render_websocket_request;
|
||||
use crate::resolve::resolve_websocket_request;
|
||||
use log::{info, warn};
|
||||
use std::str::FromStr;
|
||||
use tauri::http::{HeaderMap, HeaderName};
|
||||
@@ -119,8 +120,9 @@ pub(crate) async fn send<R: Runtime>(
|
||||
};
|
||||
let base_environment =
|
||||
app_handle.db().get_base_environment(&unrendered_request.workspace_id)?;
|
||||
let request = render_request(
|
||||
&unrendered_request,
|
||||
let resolved_request = resolve_websocket_request(&window, &unrendered_request)?;
|
||||
let request = render_websocket_request(
|
||||
&resolved_request,
|
||||
&base_environment,
|
||||
environment.as_ref(),
|
||||
&PluginTemplateCallback::new(
|
||||
@@ -194,8 +196,9 @@ pub(crate) async fn connect<R: Runtime>(
|
||||
};
|
||||
let base_environment =
|
||||
app_handle.db().get_base_environment(&unrendered_request.workspace_id)?;
|
||||
let request = render_request(
|
||||
&unrendered_request,
|
||||
let resolved_request = resolve_websocket_request(&window, &unrendered_request)?;
|
||||
let request = render_websocket_request(
|
||||
&resolved_request,
|
||||
&base_environment,
|
||||
environment.as_ref(),
|
||||
&PluginTemplateCallback::new(
|
||||
@@ -206,13 +209,9 @@ pub(crate) async fn connect<R: Runtime>(
|
||||
)
|
||||
.await?;
|
||||
|
||||
let (authentication_type, authentication) =
|
||||
window.db().resolve_auth_for_websocket_request(&request)?;
|
||||
|
||||
let mut headers = HeaderMap::new();
|
||||
|
||||
let resolved_headers = window.db().resolve_headers_for_websocket_request(&request)?;
|
||||
for h in resolved_headers {
|
||||
for h in request.headers.clone() {
|
||||
if h.name.is_empty() && h.value.is_empty() {
|
||||
continue;
|
||||
}
|
||||
@@ -220,13 +219,14 @@ pub(crate) async fn connect<R: Runtime>(
|
||||
if !h.enabled {
|
||||
continue;
|
||||
}
|
||||
|
||||
headers.insert(
|
||||
HeaderName::from_str(&h.name).unwrap(),
|
||||
HeaderValue::from_str(&h.value).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
match authentication_type {
|
||||
match request.authentication_type {
|
||||
None => {
|
||||
// No authentication found. Not even inherited
|
||||
}
|
||||
@@ -234,7 +234,7 @@ pub(crate) async fn connect<R: Runtime>(
|
||||
// Explicitly no authentication
|
||||
}
|
||||
Some(authentication_type) => {
|
||||
let auth = authentication.clone();
|
||||
let auth = request.authentication.clone();
|
||||
let plugin_req = CallHttpAuthenticationRequest {
|
||||
context_id: format!("{:x}", md5::compute(request_id.to_string())),
|
||||
values: serde_json::from_value(serde_json::to_value(&auth).unwrap()).unwrap(),
|
||||
@@ -250,8 +250,9 @@ pub(crate) async fn connect<R: Runtime>(
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
let plugin_result =
|
||||
plugin_manager.call_http_authentication(&window, &authentication_type, plugin_req).await?;
|
||||
let plugin_result = plugin_manager
|
||||
.call_http_authentication(&window, &authentication_type, plugin_req)
|
||||
.await?;
|
||||
for header in plugin_result.set_headers {
|
||||
headers.insert(
|
||||
HeaderName::from_str(&header.name).unwrap(),
|
||||
|
||||
@@ -3,6 +3,7 @@ mod connect;
|
||||
pub mod error;
|
||||
mod manager;
|
||||
mod render;
|
||||
mod resolve;
|
||||
|
||||
use crate::commands::{
|
||||
close, connect, delete_connection, delete_connections, delete_request, duplicate_request,
|
||||
|
||||
@@ -4,7 +4,7 @@ use yaak_models::models::{Environment, HttpRequestHeader, WebsocketRequest};
|
||||
use yaak_models::render::make_vars_hashmap;
|
||||
use yaak_templates::{parse_and_render, render_json_value_raw, TemplateCallback};
|
||||
|
||||
pub async fn render_request<T: TemplateCallback>(
|
||||
pub async fn render_websocket_request<T: TemplateCallback>(
|
||||
r: &WebsocketRequest,
|
||||
base_environment: &Environment,
|
||||
environment: Option<&Environment>,
|
||||
|
||||
21
src-tauri/yaak-ws/src/resolve.rs
Normal file
21
src-tauri/yaak-ws/src/resolve.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
use crate::error::Result;
|
||||
use tauri::{Runtime, WebviewWindow};
|
||||
use yaak_models::models::WebsocketRequest;
|
||||
use yaak_models::query_manager::QueryManagerExt;
|
||||
|
||||
pub(crate) fn resolve_websocket_request<R: Runtime>(
|
||||
window: &WebviewWindow<R>,
|
||||
request: &WebsocketRequest,
|
||||
) -> Result<WebsocketRequest> {
|
||||
let mut new_request = request.clone();
|
||||
|
||||
let (authentication_type, authentication) =
|
||||
window.db().resolve_auth_for_websocket_request(request)?;
|
||||
new_request.authentication_type = authentication_type;
|
||||
new_request.authentication = authentication;
|
||||
|
||||
let headers = window.db().resolve_headers_for_websocket_request(request)?;
|
||||
new_request.headers = headers;
|
||||
|
||||
Ok(new_request)
|
||||
}
|
||||
Reference in New Issue
Block a user