From fb7cc60dac17419999cdeca7946c03c489720405 Mon Sep 17 00:00:00 2001 From: Michal Filka Date: Thu, 1 Aug 2024 08:36:28 +0200 Subject: [PATCH] Agama CLI auth login command fully transformed to use new http client --- rust/agama-cli/src/auth.rs | 27 ++++++++------------------ rust/agama-cli/src/main.rs | 11 +++++++---- rust/agama-lib/src/base_http_client.rs | 9 +++++++++ service/Gemfile.lock | 4 ++-- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/rust/agama-cli/src/auth.rs b/rust/agama-cli/src/auth.rs index 23dfd62506..a93a7dba3a 100644 --- a/rust/agama-cli/src/auth.rs +++ b/rust/agama-cli/src/auth.rs @@ -4,7 +4,7 @@ use clap::Subcommand; use crate::error::CliError; use agama_lib::base_http_client::BaseHTTPClient; use inquire::Password; -use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE}; +use std::collections::HashMap; use std::io::{self, IsTerminal}; /// HTTP Client for auth queries @@ -17,31 +17,19 @@ impl AuthHTTPClient { Ok(Self { api: client }) } - /// Necessary http request header for authenticate - fn authenticate_headers() -> HeaderMap { - let mut headers = HeaderMap::new(); - - headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json")); - - headers - } - /// Query web server for JWT /// /// TODO: /// for now it doesn't use BaseHTTPClient's post and similar methods as it needs /// to update query headers pub async fn get_jwt(&self, password: String) -> anyhow::Result { - let client = reqwest::Client::new(); - let response = client - // TODO: BaseHTTPClient::url is private, so duplicate it for now. - .post(self.api.base_url.clone() + "/auth") - .headers(Self::authenticate_headers()) - .body(format!("{{\"password\": \"{}\"}}", password)) - .send() - .await?; + let mut auth_body = HashMap::new(); + + auth_body.insert("password", password); + + let response = self.api.post_response("/auth", &auth_body).await?; let body = response - .json::>() + .json::>() .await?; let value = body.get("token"); @@ -84,6 +72,7 @@ pub async fn run(client: BaseHTTPClient, subcommand: AuthCommands) -> anyhow::Re /// user. fn read_password() -> Result { let stdin = io::stdin(); + let password = if stdin.is_terminal() { ask_password()? } else { diff --git a/rust/agama-cli/src/main.rs b/rust/agama-cli/src/main.rs index ea1af986ae..ae9ce374cc 100644 --- a/rust/agama-cli/src/main.rs +++ b/rust/agama-cli/src/main.rs @@ -30,7 +30,7 @@ use std::{ /// Agama's CLI global options #[derive(Args)] struct GlobalOpts { - #[clap(long)] + #[clap(long, default_value = "http://localhost/api/")] /// uri pointing to agama's remote api. If not provided, default https://localhost/api is /// used pub uri: String, @@ -132,8 +132,8 @@ async fn build_manager<'a>() -> anyhow::Result> { } async fn run_command(cli: Cli) -> Result<(), ServiceError> { - let client = BaseHTTPClient::new()?; - + // we need to distinguish commands on those which assume that JWT is already available + // and those which not (or don't need it) match cli.command { Commands::Config(subcommand) => { let manager = build_manager().await?; @@ -152,8 +152,11 @@ async fn run_command(cli: Cli) -> Result<(), ServiceError> { } Commands::Questions(subcommand) => run_questions_cmd(subcommand).await?, Commands::Logs(subcommand) => run_logs_cmd(subcommand).await?, - Commands::Auth(subcommand) => run_auth_cmd(client, subcommand).await?, Commands::Download { url } => crate::profile::download(&url, std::io::stdout())?, + Commands::Auth(subcommand) => { + let client = BaseHTTPClient::bare()?; + run_auth_cmd(client, subcommand).await?; + } }; Ok(()) diff --git a/rust/agama-lib/src/base_http_client.rs b/rust/agama-lib/src/base_http_client.rs index 655a1ce5d7..506f06b5cf 100644 --- a/rust/agama-lib/src/base_http_client.rs +++ b/rust/agama-lib/src/base_http_client.rs @@ -28,6 +28,15 @@ pub struct BaseHTTPClient { const API_URL: &str = "http://localhost/api"; impl BaseHTTPClient { + // Provides new client with no specialities like authorization headers or so. + // If needed, there is place for helpers like "self::to_authorized" or so. + pub fn bare() -> Result { + Ok(Self { + client: reqwest::Client::new(), + base_url: API_URL.to_string(), + }) + } + // if there is need for client without authorization, create new constructor for it pub fn new() -> Result { let token = AuthToken::find().ok_or(ServiceError::NotAuthenticated)?; diff --git a/service/Gemfile.lock b/service/Gemfile.lock index eacdcece4e..2d87dea70e 100755 --- a/service/Gemfile.lock +++ b/service/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - agama-yast (9) + agama-yast (9.devel287) cfa (~> 1.0.2) cfa_grub2 (~> 2.0.0) cheetah (~> 1.0.0) @@ -75,4 +75,4 @@ DEPENDENCIES yard (~> 0.9.0) BUNDLED WITH - 2.4.22 + 2.5.3