Skip to content

Commit

Permalink
Added basic auth
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien-cpsn committed Feb 10, 2024
1 parent 0009d15 commit 6234283
Show file tree
Hide file tree
Showing 16 changed files with 402 additions and 52 deletions.
43 changes: 28 additions & 15 deletions src/app/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::request::request::{Request};
use crate::utils::stateful_list::StatefulList;
use crate::utils::stateful_scrollbar::StatefulScrollbar;
use crate::utils::text_input::TextInput;
use crate::utils::text_input_selection::TextInputSelection;

pub struct App<'a> {
pub should_quit: bool,
Expand All @@ -23,7 +24,14 @@ pub struct App<'a> {
pub request_result_tab: RequestResultTabs,

pub new_request_input: TextInput,

pub url_text_input: TextInput,

pub auth_text_input_selection: TextInputSelection,
pub auth_basic_username_text_input: TextInput,
pub auth_basic_password_text_input: TextInput,
pub auth_bearer_token_text_input: TextInput,

pub body_text_area: TextArea<'a>,

pub result_scrollbar: StatefulScrollbar
Expand All @@ -36,9 +44,11 @@ impl App<'_> {
name: "Check headers",
url: "https://httpbin.org/headers",
method: Method::GET,
body: JSON(String::from(r#"{
body: JSON(String::from(
r#"{
"json": 32
}"#)),
}"#
)),
..Default::default()
},
Request {
Expand All @@ -63,30 +73,33 @@ impl App<'_> {

App {
should_quit: false,

state: AppState::Normal,

collection: StatefulList {
state: Default::default(),
items,
selected: None,
last_selected: None,
},

request_view: RequestView::Normal,

request_param_tab: RequestParamsTabs::Params,
request_result_tab: RequestResultTabs::Body,
new_request_input: TextInput {
text: String::new(),
cursor_position: 0,
},
url_text_input: TextInput {
text: String::new(),
cursor_position: 0,
},

new_request_input: TextInput::default(),

url_text_input: TextInput::default(),

auth_text_input_selection: TextInputSelection::default(),
auth_basic_username_text_input: TextInput::default(),
auth_basic_password_text_input: TextInput::default(),
auth_bearer_token_text_input: TextInput::default(),

body_text_area: TextArea::default(),
result_scrollbar: StatefulScrollbar {
scroll: 0,
max_scroll: 0,
state: Default::default(),
}

result_scrollbar: StatefulScrollbar::default()
}
}

Expand Down
35 changes: 35 additions & 0 deletions src/app/app_logic/change_app_state.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::app::app::App;
use crate::app::app_states::AppState;
use crate::app::request_ui::param_tabs::RequestParamsTabs;
use crate::request::auth::Auth;
use crate::request::body::ContentType;

impl App<'_> {
Expand All @@ -14,12 +15,46 @@ impl App<'_> {

pub fn select_request_state(&mut self) {
self.state = AppState::SelectedRequest;
self.update_inputs();
}

pub fn edit_request_url_state(&mut self) {
self.state = AppState::EditingRequestUrl;
}

pub fn edit_request_auth_state(&mut self) {
// Prevent selection reset after modifying an input
if self.state == AppState::SelectedRequest {
self.auth_text_input_selection.selected = 0;
}

self.update_inputs();
self.request_param_tab = RequestParamsTabs::Auth;

let selected_request_index = self.collection.selected.unwrap();
let selected_request = &self.collection.items[selected_request_index];

match selected_request.auth {
Auth::NoAuth => self.auth_text_input_selection.max_selection = 0,
Auth::BasicAuth(_, _) => {
self.state = AppState::EditingRequestAuth;
self.auth_text_input_selection.max_selection = 2
},
Auth::BearerToken(_) => {
self.state = AppState::EditingRequestAuth;
self.auth_text_input_selection.max_selection = 1
},
}
}

pub fn edit_request_auth_username_state(&mut self) {
self.state = AppState::EditingRequestAuthUsername;
}

pub fn edit_request_auth_password_state(&mut self) {
self.state = AppState::EditingRequestAuthPassword;
}

pub fn edit_request_body_state(&mut self) {
self.request_param_tab = RequestParamsTabs::Body;

Expand Down
39 changes: 30 additions & 9 deletions src/app/app_logic/collection.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,48 @@
use crate::app::app::App;
use crate::app::app_states::AppState;
use crate::request::auth::Auth;
use crate::request::request::{Request};

impl<'a> App<'a> {
pub fn select_request(&mut self) {
pub fn reset_inputs(&mut self) {
self.url_text_input.reset_input();
self.collection.select();
self.result_scrollbar.set_scroll(0);
self.auth_basic_username_text_input.reset_input();
self.auth_basic_password_text_input.reset_input();
}

if let Some(selected_request_index) = self.collection.selected {
let selected_request = &self.collection.items[selected_request_index];
self.url_text_input.enter_str(selected_request.url);
pub fn update_inputs(&mut self) {
self.reset_inputs();

let body = selected_request.body.get_body_as_string();
let selected_request_index = self.collection.selected.unwrap();
let selected_request = &self.collection.items[selected_request_index];

self.refresh_body_textarea(body);
self.url_text_input.enter_str(selected_request.url);

match &selected_request.auth {
Auth::NoAuth => {}
Auth::BasicAuth(username, password) => {
self.auth_basic_username_text_input.enter_str(username);
self.auth_basic_password_text_input.enter_str(password);
}
Auth::BearerToken(_token) => {}
}

let body = selected_request.body.get_body_as_string();
self.refresh_body_textarea(body);
}

pub fn select_request(&mut self) {
self.collection.select();
self.result_scrollbar.set_scroll(0);

if self.collection.selected.is_some() {
self.update_inputs();
self.state = AppState::SelectedRequest;
}
}

pub fn unselect_request(&mut self) {
self.url_text_input.reset_input();
self.reset_inputs();
self.collection.unselect();
}

Expand Down
83 changes: 82 additions & 1 deletion src/app/app_logic/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ use reqwest::Client;
use reqwest::header::CONTENT_TYPE;
use tui_textarea::TextArea;
use crate::app::app::App;
use crate::request::auth::{Auth, next_auth};
use crate::request::auth::Auth::BasicAuth;
use crate::request::body::{ContentType, next_content_type};
use crate::request::method::next_method;

impl App<'_> {
/* URL */
pub fn modify_request_url(&mut self) {
let input_text = self.url_text_input.text.clone();
let selected_request_index = self.collection.selected.unwrap();
Expand All @@ -15,12 +18,68 @@ impl App<'_> {
self.select_request_state();
}

/* METHOD */

pub fn modify_request_method(&mut self) {
let selected_request_index = self.collection.selected.unwrap();
let next_method = next_method(&self.collection.items[selected_request_index].method);

self.collection.items[selected_request_index].method = next_method;
}

/* AUTH */

pub fn modify_request_auth(&mut self) {
let selected_request_index = self.collection.selected.unwrap();
let selected_request = &self.collection.items[selected_request_index];

self.collection.items[selected_request_index].auth = next_auth(&selected_request.auth);

self.update_inputs();
}

pub fn select_request_auth_input_text(&mut self) {
match self.auth_text_input_selection.selected {
0 => self.edit_request_auth_username_state(),
1 => self.edit_request_auth_password_state(),
_ => {}
}
}

pub fn modify_request_auth_basic_username(&mut self) {
let input_text = self.auth_basic_username_text_input.text.clone();

let selected_request_index = self.collection.selected.unwrap();
let selected_request = &self.collection.items[selected_request_index];

match &selected_request.auth {
BasicAuth(_, password) => {
self.collection.items[selected_request_index].auth = BasicAuth(input_text, password.to_string());
}
_ => {}
}

self.edit_request_auth_state();
}

pub fn modify_request_auth_basic_password(&mut self) {
let input_text = self.auth_basic_password_text_input.text.clone();

let selected_request_index = self.collection.selected.unwrap();
let selected_request = &self.collection.items[selected_request_index];

match &selected_request.auth {
BasicAuth(username, _) => {
self.collection.items[selected_request_index].auth = BasicAuth(username.to_string(), input_text);
}
_ => {}
}

self.edit_request_auth_state();
}

/* BODY */

pub fn refresh_body_textarea(&mut self, text: String) {
let lines: Vec<String> = text
.lines()
Expand All @@ -34,7 +93,7 @@ impl App<'_> {
let selected_request_index = self.collection.selected.unwrap();
let selected_request = &self.collection.items[selected_request_index];

let body: String = self.body_text_area.lines().join("\n");
let body = self.body_text_area.lines().join("\n");

let new_body = match selected_request.body {
ContentType::NoBody => ContentType::NoBody,
Expand Down Expand Up @@ -71,6 +130,8 @@ impl App<'_> {
self.select_request_state();
}

/* REQUEST */

pub async fn send_request(&mut self) {
let selected_request_index = self.collection.selected.unwrap();
let selected_request = &mut self.collection.items[selected_request_index];
Expand All @@ -82,6 +143,14 @@ impl App<'_> {
selected_request.url
);

match &selected_request.auth {
Auth::NoAuth => {}
BasicAuth(username, password) => {
request = request.basic_auth(username, Some(password));
}
Auth::BearerToken(_token) => {}
}

match &selected_request.body {
ContentType::NoBody => {},
ContentType::Raw(body) | ContentType::JSON(body) | ContentType::XML(body) | ContentType::HTML(body) => {
Expand All @@ -93,6 +162,8 @@ impl App<'_> {

match request.send().await {
Ok(response) => {
let status_code = response.status().as_u16();

let headers = response.headers().clone()
.iter()
.map(|(header_name, header_value)| {
Expand All @@ -110,13 +181,23 @@ impl App<'_> {

let result_body = response.text().await.unwrap();

selected_request.result.status_code = Some(status_code);
selected_request.result.body = Some(result_body);
selected_request.result.cookies = Some(cookies);
selected_request.result.headers = Some(headers);
},
Err(error) => {
let response_status_code;

if let Some(status_code) = error.status() {
response_status_code = Some(status_code.as_u16());
}
else {
response_status_code = None;
}
let result_body = error.to_string();

selected_request.result.status_code = response_status_code;
selected_request.result.body = Some(result_body);
selected_request.result.cookies = None;
selected_request.result.headers = None;
Expand Down
31 changes: 26 additions & 5 deletions src/app/app_states.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
use strum::Display;
use crate::app::app_states::AppState::*;

#[derive(Copy, Clone, PartialEq, Default, Display)]
pub enum AppState {
#[default]
#[strum(to_string = "Main menu")]
Normal,

#[strum(to_string = "Request menu")]
SelectedRequest,

#[strum(to_string = "Editing request URL")]
EditingRequestUrl,

#[strum(to_string = "Creating new request")]
CreatingNewRequest,

#[strum(to_string = "Editing request auth")]
EditingRequestAuth,

#[strum(to_string = "Editing request auth username")]
EditingRequestAuthUsername,

#[strum(to_string = "Editing request auth password")]
EditingRequestAuthPassword,

#[strum(to_string = "Editing request body")]
EditingRequestBody
}

pub fn get_available_keys(app_state: AppState) -> String {
match app_state {
AppState::Normal => String::from("q ↑ ↓ ← → n d"),
AppState::SelectedRequest => String::from("Esc Tab ^(U)rl ^(B)ody"),
AppState::EditingRequestUrl => String::from("Esc Enter ← → copy paste"),
AppState::CreatingNewRequest => String::from("Esc Enter ← → copy paste"),
AppState::EditingRequestBody => String::from("Esc Enter Tab ^(s)ave ↑ ↓ ← → copy paste")
Normal => String::from("q or ^c ↑ ↓ ← → n d"),

SelectedRequest => String::from("Esc Tab ^(U)rl ^(B)ody"),
CreatingNewRequest => String::from("Esc Enter ← → copy paste"),

EditingRequestUrl => String::from("Esc Enter ← → copy paste"),

EditingRequestAuth =>String::from("Esc Enter ↑ ↓"),
EditingRequestAuthUsername => String::from("Esc Enter ← → copy paste"),
EditingRequestAuthPassword => String::from("Esc Enter ← → copy paste"),

EditingRequestBody => String::from("Esc Enter Tab ^(s)ave ↑ ↓ ← → copy paste"),
}
}
Loading

0 comments on commit 6234283

Please sign in to comment.