Skip to content

Commit

Permalink
v0.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
mdecimus committed Apr 17, 2024
1 parent a48251c commit dc70104
Show file tree
Hide file tree
Showing 17 changed files with 289 additions and 63 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).

## [0.1.2] - 2024-04-17

## Added
- `DNS-01` and `HTTP-01` ACME challenge configuration.

### Changed
- Use rust stable.

### Fixed
- Properly escape URL path components.

## [0.1.1] - 2024-04-12

## Added
Expand Down
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ leptos_router = { version = "0.6.9", features = ["csr"] }
leptos-use = "0.10.2"
gloo-net = { version = "0.5", features = ["http"] }
gloo-storage = "0.3.0"
form_urlencoded = "1.1.0"
serde = { version = "1", features = ["derive", "rc"] }
serde_json = "1.0.113"
web-sys = { version = "0.3", features = ["AbortController", "AbortSignal"] }
Expand All @@ -32,6 +31,8 @@ chrono = { version = "0.4.34", features = ["serde"] }
chrono-humanize = "0.2.3"
ahash = { version = "0.8.11", features = ["serde"] }
regex = "1.10.3"
form_urlencoded = "1.1.0"
serde_urlencoded = "0.7.1"

[features]
demo = []
Expand Down
58 changes: 46 additions & 12 deletions src/core/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,47 +62,51 @@ pub enum Error {
Server(ManagementApiError),
}

pub trait IntoUrlBuilder {
fn into_url_builder(self) -> UrlBuilder;
}

pub type Result<T> = std::result::Result<T, Error>;

impl<'x> HttpRequest {
pub fn new(method: Method, url: impl AsRef<str>) -> Self {
pub fn new(method: Method, url: impl IntoUrlBuilder) -> Self {
Self {
method,
url: UrlBuilder::new(url),
url: url.into_url_builder(),
headers: Headers::new(),
body: None,
}
}

pub fn get(url: impl AsRef<str>) -> Self {
pub fn get(url: impl IntoUrlBuilder) -> Self {
Self::new(Method::GET, url)
}

pub fn post(url: impl AsRef<str>) -> Self {
pub fn post(url: impl IntoUrlBuilder) -> Self {
Self::new(Method::POST, url)
}

pub fn put(url: impl AsRef<str>) -> Self {
pub fn put(url: impl IntoUrlBuilder) -> Self {
Self::new(Method::PUT, url)
}

pub fn delete(url: impl AsRef<str>) -> Self {
pub fn delete(url: impl IntoUrlBuilder) -> Self {
Self::new(Method::DELETE, url)
}

pub fn patch(url: impl AsRef<str>) -> Self {
pub fn patch(url: impl IntoUrlBuilder) -> Self {
Self::new(Method::PATCH, url)
}

pub fn with_parameter(mut self, key: impl AsRef<str>, value: impl AsRef<str>) -> Self {
pub fn with_parameter(mut self, key: &'static str, value: impl Into<String>) -> Self {
self.url = self.url.with_parameter(key, value);
self
}

pub fn with_optional_parameter(
mut self,
key: impl AsRef<str>,
value: Option<impl AsRef<str>>,
key: &'static str,
value: Option<impl Into<String>>,
) -> Self {
self.url = self.url.with_optional_parameter(key, value);
self
Expand All @@ -115,15 +119,15 @@ impl<'x> HttpRequest {
format!("Bearer {}", auth_token.access_token),
);
if !auth_token.base_url.is_empty() {
result.url = UrlBuilder::new(format!("{}{}", auth_token.base_url, result.url.finish()));
result.url.prepend_path(auth_token.base_url.as_str());
}
result
}

pub fn with_base_url(mut self, auth_token: impl AsRef<AuthToken>) -> Self {
let auth_token = auth_token.as_ref();
if !auth_token.base_url.is_empty() {
self.url = UrlBuilder::new(format!("{}{}", auth_token.base_url, self.url.finish()));
self.url.prepend_path(auth_token.base_url.as_str());
}
self
}
Expand Down Expand Up @@ -225,6 +229,36 @@ impl<'x> HttpRequest {
}
}

impl IntoUrlBuilder for String {
fn into_url_builder(self) -> UrlBuilder {
UrlBuilder::new(self)
}
}

impl IntoUrlBuilder for &str {
fn into_url_builder(self) -> UrlBuilder {
UrlBuilder::new(self)
}
}

impl IntoUrlBuilder for (&str, &str) {
fn into_url_builder(self) -> UrlBuilder {
UrlBuilder::new(self.0).with_subpath(self.1)
}
}

impl IntoUrlBuilder for (&str, String) {
fn into_url_builder(self) -> UrlBuilder {
UrlBuilder::new(self.0).with_subpath(self.1)
}
}

impl IntoUrlBuilder for (&str, &String) {
fn into_url_builder(self) -> UrlBuilder {
UrlBuilder::new(self.0).with_subpath(self.1)
}
}

impl From<gloo_net::Error> for Error {
fn from(err: gloo_net::Error) -> Self {
Error::Network(format!("HTTP request failed: {err}"))
Expand Down
20 changes: 10 additions & 10 deletions src/core/oauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ pub async fn oauth_authenticate(
let is_admin = response.is_admin;
match HttpRequest::post(format!("{base_url}/auth/token"))
.with_raw_body(
form_urlencoded::Serializer::new(String::with_capacity(response.code.len() + 64))
.append_pair("grant_type", "authorization_code")
.append_pair("client_id", "webadmin")
.append_pair("code", &response.code)
.append_pair("redirect_uri", "")
.finish(),
serde_urlencoded::to_string([
("grant_type", "authorization_code"),
("client_id", "webadmin"),
("code", &response.code),
("redirect_uri", ""),
]).unwrap(),
)
.send_raw()
.await
Expand Down Expand Up @@ -190,10 +190,10 @@ pub async fn oauth_refresh_token(base_url: &str, refresh_token: &str) -> Option<

match HttpRequest::post(format!("{base_url}/auth/token"))
.with_raw_body(
form_urlencoded::Serializer::new(String::with_capacity(refresh_token.len() + 64))
.append_pair("grant_type", "refresh_token")
.append_pair("refresh_token", refresh_token)
.finish(),
serde_urlencoded::to_string([
("grant_type", "refresh_token"),
("refresh_token", refresh_token),
]).unwrap(),
)
.send_raw()
.await
Expand Down
53 changes: 36 additions & 17 deletions src/core/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,60 @@
* for more details.
*/

use ahash::AHashMap;

pub struct UrlBuilder {
pub url: form_urlencoded::Serializer<'static, String>,
pub path: String,
pub params: AHashMap<&'static str, String>,
}

impl UrlBuilder {
pub fn new(url: impl AsRef<str>) -> Self {
let url = url.as_ref();
let url = if !url.ends_with('?') {
format!("{url}?")
} else {
url.to_string()
};
let url_len = url.len();
pub fn new(path: impl Into<String>) -> Self {
Self {
url: form_urlencoded::Serializer::for_suffix(url, url_len),
path: path.into(),
params: AHashMap::new(),
}
}

pub fn with_parameter(mut self, key: impl AsRef<str>, value: impl AsRef<str>) -> Self {
self.url.append_pair(key.as_ref(), value.as_ref());
pub fn prepend_path(&mut self, path: impl AsRef<str>) {
self.path.insert_str(0, path.as_ref());
}

pub fn with_subpath(mut self, subpath: impl AsRef<str>) -> Self {
self.path.push('/');
self.path.push_str(
&form_urlencoded::Serializer::new(String::new())
.append_key_only(subpath.as_ref())
.finish(),
);
self
}

pub fn with_parameter(mut self, key: &'static str, value: impl Into<String>) -> Self {
self.params.insert(key, value.into());
self
}

pub fn with_optional_parameter(
mut self,
key: impl AsRef<str>,
value: Option<impl AsRef<str>>,
key: &'static str,
value: Option<impl Into<String>>,
) -> Self {
if let Some(value) = value {
self.url.append_pair(key.as_ref(), value.as_ref());
self.params.insert(key, value.into());
}
self
}

pub fn finish(mut self) -> String {
self.url.finish()
pub fn finish(self) -> String {
if self.params.is_empty() {
self.path
} else {
format!(
"{}?{}",
self.path,
serde_urlencoded::to_string(&self.params).unwrap()
)
}
}
}
6 changes: 4 additions & 2 deletions src/pages/config/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ pub fn SettingsList() -> impl IntoView {
value=filter
on_search=move |value| {
use_navigate()(
&UrlBuilder::new(format!("/settings/{}", current_schema.get().id))
&UrlBuilder::new("/settings")
.with_subpath(current_schema.get().id)
.with_parameter("filter", value)
.finish(),
Default::default(),
Expand Down Expand Up @@ -377,7 +378,8 @@ pub fn SettingsList() -> impl IntoView {
page_size=Signal::derive(move || current_schema.get().list.page_size)
on_page_change=move |page: u32| {
use_navigate()(
&UrlBuilder::new(format!("/settings/{}", current_schema.get().id))
&UrlBuilder::new("/settings")
.with_subpath(current_schema.get().id)
.with_parameter("page", page.to_string())
.with_optional_parameter("filter", filter.get())
.finish(),
Expand Down
Loading

0 comments on commit dc70104

Please sign in to comment.