Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ PROJECTS_NO_OBFUSCATION = "exliquid;dktk_supervisors;exporter;ehds2" # Projects
QUERIES_TO_CACHE = "queries_to_cache.conf" # The path to a file containing base64 encoded queries whose results are to be cached. If not set, no results are cached
PROVIDER = "name" #EUCAIM provider name
PROVIDER_ICON = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=" # Base64 encoded EUCAIM provider icon
AUTH_HEADER = "ApiKey XXXX" #Authorization header; if the endpoint type is Blaze or BlazeAndSql, this header is used for the Exporter target application, and the syntax is AUTH_HEADER = "XXXX" where "XXXX" is the API key
AUTH_HEADER = "ApiKey: XXXX" #Authorization header, in the format "Key: Value"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would advise agains this. The current format AUTHORIZATION: ApiKey XXX follows the RFC 9110 with authorization method ApiKey. Additionally,, this is how Mainzelliste and MainSEL implements it.
If you want to use a non-standard-header, I would advise for x-api-key as recommended by OpenAPI.

```

In order to use Postgres querying, a Docker image built with the feature "dktk" needs to be used and this optional variable set:
Expand Down
27 changes: 23 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::fmt;
use std::{fmt, str::FromStr};
use std::path::PathBuf;

use beam_lib::AppId;
use clap::Parser;
use reqwest::{header::HeaderValue, Url};
use reqwest::{header::{HeaderName, HeaderValue}, Url};
use once_cell::sync::Lazy;
use reqwest::{Certificate, Client, Proxy};
use tracing::{debug, info, warn};
Expand Down Expand Up @@ -197,7 +197,7 @@ pub(crate) struct Config {
pub client: Client,
pub provider: Option<String>,
pub provider_icon: Option<String>,
pub auth_header: Option<String>,
pub auth_header: Option<(HeaderName, HeaderValue)>,
#[cfg(feature = "query-sql")]
pub postgres_connection_string: Option<String>,
#[cfg(feature = "query-sql")]
Expand All @@ -219,6 +219,25 @@ impl Config {
let client = prepare_reqwest_client(&tls_ca_certificates)?;
dbg!(cli_args.endpoint_url.clone());
dbg!(cli_args.blaze_url.clone());

let auth_header = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not an auth header anymore, but an arbitrary header field, right? We should rename it then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additinally, this imposes a security risk to be able to send an arbitrary header, potentially overriding exsisting headers if they are already present.

if let Some(auth_header) = cli_args.auth_header {
if let Some((header_name, header_value)) = auth_header.split_once(':') {
let header_name = HeaderName::from_str(header_name)
.map_err(|e| FocusError::ConfigurationError(format!("Invalid key \"{}\" in auth header \"{}\": {}", header_name, auth_header, e)))?;

let header_value = HeaderValue::from_str(header_value.trim_start())
.map_err(|e| FocusError::ConfigurationError(format!("Invalid value \"{}\" in auth header \"{}\": {}", header_value, auth_header, e)))?;

Some((header_name, header_value))
} else {
return Err(FocusError::ConfigurationError(format!("Missing ':' in auth header value \"{}\"", auth_header)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a description of the error logic is more useful? Something in the line of "Missing header key (the part before the colon)"?

}
} else {
None
}
};

let config = Config {
beam_proxy_url: cli_args.beam_proxy_url,
beam_app_id_long: AppId::new_unchecked(cli_args.beam_app_id_long),
Expand All @@ -242,7 +261,7 @@ impl Config {
queries_to_cache: cli_args.queries_to_cache,
provider: cli_args.provider,
provider_icon: cli_args.provider_icon,
auth_header: cli_args.auth_header,
auth_header,
#[cfg(feature = "query-sql")]
postgres_connection_string: cli_args.postgres_connection_string,
#[cfg(feature = "query-sql")]
Expand Down
10 changes: 3 additions & 7 deletions src/exporter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use reqwest::{header::{self, HeaderMap, HeaderValue}, StatusCode};
use reqwest::{header::{self, HeaderMap, HeaderName, HeaderValue}, StatusCode};
use serde::Deserialize;
use serde::Serialize;
use serde_json::Value;
Expand Down Expand Up @@ -42,12 +42,8 @@ pub async fn post_exporter_query(body: &String, task_type: TaskType) -> Result<S

let mut headers = HeaderMap::new();

if let Some(auth_header_value) = CONFIG.auth_header.clone() {
headers.insert(
"x-api-key",
HeaderValue::from_str(auth_header_value.as_str())
.map_err(FocusError::InvalidHeaderValue)?,
);
if let Some(auth_header) = CONFIG.auth_header.clone() {
headers.insert(auth_header.0, auth_header.1);
}

if task_type == TaskType::Status {
Expand Down
8 changes: 2 additions & 6 deletions src/intermediate_rep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,8 @@ pub async fn post_ast(ast: ast::Ast) -> Result<String, FocusError> {
HeaderValue::from_static("application/json"),
);

if let Some(auth_header_value) = CONFIG.auth_header.clone() {
headers.insert(
header::AUTHORIZATION,
HeaderValue::from_str(auth_header_value.as_str())
.map_err(FocusError::InvalidHeaderValue)?,
);
if let Some(auth_header) = CONFIG.auth_header.clone() {
headers.insert(auth_header.0, auth_header.1);
}

let resp = CONFIG
Expand Down