Skip to content

Commit

Permalink
Agama CLI auth login command fully transformed to use new http client
Browse files Browse the repository at this point in the history
  • Loading branch information
mchf committed Aug 1, 2024
1 parent 895b819 commit fb7cc60
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 25 deletions.
27 changes: 8 additions & 19 deletions rust/agama-cli/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<String> {
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::<std::collections::HashMap<String, String>>()
.json::<HashMap<String, String>>()
.await?;
let value = body.get("token");

Expand Down Expand Up @@ -84,6 +72,7 @@ pub async fn run(client: BaseHTTPClient, subcommand: AuthCommands) -> anyhow::Re
/// user.
fn read_password() -> Result<String, CliError> {
let stdin = io::stdin();

let password = if stdin.is_terminal() {
ask_password()?
} else {
Expand Down
11 changes: 7 additions & 4 deletions rust/agama-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -132,8 +132,8 @@ async fn build_manager<'a>() -> anyhow::Result<ManagerClient<'a>> {
}

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?;
Expand All @@ -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(())
Expand Down
9 changes: 9 additions & 0 deletions rust/agama-lib/src/base_http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self, ServiceError> {
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<Self, ServiceError> {
let token = AuthToken::find().ok_or(ServiceError::NotAuthenticated)?;
Expand Down
4 changes: 2 additions & 2 deletions service/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -75,4 +75,4 @@ DEPENDENCIES
yard (~> 0.9.0)

BUNDLED WITH
2.4.22
2.5.3

0 comments on commit fb7cc60

Please sign in to comment.