Skip to content

Commit

Permalink
Add support to authentication with access token
Browse files Browse the repository at this point in the history
Closes #5
  • Loading branch information
yukibtc committed Sep 14, 2024
1 parent c98a4c6 commit d4e80cb
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 15 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use ntfy::prelude::*;
#[tokio::main]
async fn main() -> Result<(), NtfyError> {
let dispatcher = Dispatcher::builder("https://ntfy.sh")
.credentials(Auth::new("username", "password")) // Add optional credentials
.credentials(Auth::credentials("username", "password")) // Add optional credentials
.proxy("socks5h://127.0.0.1:9050") // Add optional proxy
.build()?; // Build dispatcher
Expand Down Expand Up @@ -61,4 +61,4 @@ This project is distributed under the MIT software license - see the [LICENSE](L

⚡ Tips: <https://getalby.com/p/yuki>

⚡ Lightning Address: [email protected]
⚡ Lightning Address: [email protected]
4 changes: 2 additions & 2 deletions examples/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ntfy::prelude::*;

fn main() -> Result<(), NtfyError> {
let dispatcher = Dispatcher::builder("https://ntfy.sh")
.credentials(Auth::new("username", "password")) // Add optional credentials
.credentials(Auth::credentials("username", "password")) // Add optional credentials
.proxy("socks5h://127.0.0.1:9050") // Add optional proxy
.build()?; // Build dispatcher

Expand All @@ -26,7 +26,7 @@ fn main() -> Result<(), NtfyError> {
.delay(1639194738) // Add optional delay
.markdown(true); // Use markdown

dispatcher.send(&payload).unwrap();
dispatcher.send(&payload)?;

Ok(())
}
4 changes: 2 additions & 2 deletions examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use ntfy::prelude::*;
#[tokio::main]
async fn main() -> Result<(), NtfyError> {
let dispatcher = Dispatcher::builder("https://ntfy.sh")
.credentials(Auth::new("username", "password")) // Add optional credentials
.credentials(Auth::credentials("username", "password")) // Add optional credentials
.proxy("socks5h://127.0.0.1:9050") // Add optional proxy
.build()?; // Build dispatcher

Expand All @@ -27,7 +27,7 @@ async fn main() -> Result<(), NtfyError> {
.delay(1639194738) // Add optional delay
.markdown(true); // Use markdown

dispatcher.send(&payload).await.unwrap();
dispatcher.send(&payload).await?;

Ok(())
}
6 changes: 4 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#!/usr/bin/env just --justfile

precommit:
cargo fmt
cargo fmt --all -- --config format_code_in_doc_comments=true
cargo test
cargo clippy
cargo clippy --features blocking

check:
cargo fmt --all -- --config format_code_in_doc_comments=true
cargo check
cargo test
cargo clippy -- -D warnings
cargo clippy --features blocking -- -D warnings
cargo clippy --features blocking -- -D warnings
72 changes: 66 additions & 6 deletions src/dispatcher/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ use std::fmt;
use base64::engine::{general_purpose, Engine};

#[derive(Clone)]
pub struct Auth {
username: String,
password: String,
pub enum Auth {
/// Authentication with credential
Credentials {
/// Username
username: String,
/// Password
password: String,
},
/// Authentication with access token
Token(String),
}

impl fmt::Debug for Auth {
Expand All @@ -18,18 +25,71 @@ impl fmt::Debug for Auth {
}

impl Auth {
#[deprecated(since = "0.6.0", note = "Use `Auth::credentials` instead.")]
pub fn new<S>(username: S, password: S) -> Self
where
S: Into<String>,
{
Self {
Self::credentials(username, password)
}

/// Authentication with credential (username + password)
///
/// <https://docs.ntfy.sh/publish/#username-password>
#[inline]
pub fn credentials<U, P>(username: U, password: P) -> Self
where
U: Into<String>,
P: Into<String>,
{
Self::Credentials {
username: username.into(),
password: password.into(),
}
}

/// Authentication with access token
///
/// <https://docs.ntfy.sh/publish/#access-tokens>
#[inline]
pub(crate) fn as_base64(&self) -> String {
general_purpose::STANDARD.encode(format!("{}:{}", self.username, self.password))
pub fn token<S>(token: S) -> Self
where
S: Into<String>,
{
Self::Token(token.into())
}

#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_header_value(self) -> String {
match self {
Self::Credentials { username, password } => {
let b64: String =
general_purpose::STANDARD.encode(format!("{username}:{password}"));
format!("Basic {b64}")
}
Self::Token(token) => {
format!("Bearer {token}")
}
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_auth_credentials() {
let auth = Auth::credentials("username", "password");
assert_eq!(auth.to_header_value(), "Basic dXNlcm5hbWU6cGFzc3dvcmQ=");
}

#[test]
fn test_auth_token() {
let auth = Auth::token("tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2");
assert_eq!(
auth.to_header_value(),
"Bearer tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2"
);
}
}
2 changes: 1 addition & 1 deletion src/dispatcher/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl DispatcherBuilder {

if let Some(auth) = self.auth {
let mut headers = HeaderMap::new();
let mut auth_value = HeaderValue::from_str(&format!("Basic {}", auth.as_base64()))?;
let mut auth_value = HeaderValue::from_str(&auth.to_header_value())?;
auth_value.set_sensitive(true);
headers.insert("Authorization", auth_value);
client = client.default_headers(headers);
Expand Down

0 comments on commit d4e80cb

Please sign in to comment.