Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added crate feature requirements to docs #64

Merged
merged 2 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ members = [
]

[package.metadata.docs.rs]
features = [ "qr", "serde_support", "gen_secret" ]
all-features = true
rustc-args = ["--cfg", "docsrs"]
Comment on lines +21 to +22
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll admit I've never went too far with rustdocs. This is nice to know, thank you :)


[features]
default = []
Expand All @@ -39,4 +40,4 @@ url = { version = "2.4", optional = true }
constant_time_eq = "0.2"
rand = { version = "0.8", features = ["std_rng", "std"], optional = true, default-features = false }
zeroize = { version = "1.6", features = ["alloc", "derive"], optional = true }
qrcodegen-image = { version = "1.0", features = ["base64"], optional = true, path = "qrcodegen-image" }
qrcodegen-image = { version = "1.0", features = ["base64"], optional = true, path = "qrcodegen-image" }
5 changes: 5 additions & 0 deletions src/custom_providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
use crate::{Algorithm, TOTP};

#[cfg(feature = "steam")]
#[cfg_attr(docsrs, doc(cfg(feature = "steam")))]
impl TOTP {
#[cfg(feature = "otpauth")]
/// Will create a new instance of TOTP using the Steam algorithm with given parameters. See [the doc](struct.TOTP.html#fields) for reference as to how to choose those values
///
/// # Description
/// * `secret`: expect a non-encoded value, to pass in base32 string use `Secret::Encoded(String)`
///
/// # Example
///
/// ```rust
/// use totp_rs::{Secret, TOTP};
/// let secret = Secret::Encoded("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".into());
Expand All @@ -32,6 +35,8 @@ impl TOTP {
/// # Description
/// * `secret`: expect a non-encoded value, to pass in base32 string use `Secret::Encoded(String)`
///
/// # Example
///
/// ```rust
/// use totp_rs::{Secret, TOTP};
/// let secret = Secret::Encoded("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".to_string());
Expand Down
41 changes: 33 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
//! # }
//! ```

// enable `doc_cfg` feature for `docs.rs`.
#![cfg_attr(docsrs, feature(doc_cfg))]

mod custom_providers;
mod rfc;
mod secret;
Expand Down Expand Up @@ -88,6 +91,8 @@ pub enum Algorithm {
SHA256,
SHA512,
#[cfg(feature = "steam")]
#[cfg_attr(docsrs, doc(cfg(feature = "steam")))]
/// Steam TOTP token algorithm
Steam,
}

Expand Down Expand Up @@ -153,11 +158,13 @@ pub struct TOTP {
/// non-encoded value
pub secret: Vec<u8>,
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
/// The "Github" part of "Github:constantoine@github.com". Must not contain a colon `:`
/// For example, the name of your service/website.
/// Not mandatory, but strongly recommended!
pub issuer: Option<String>,
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
/// The "constantoine@github.com" part of "Github:constantoine@github.com". Must not contain a colon `:`
/// For example, the name of your user's account.
pub account_name: String,
Expand Down Expand Up @@ -210,6 +217,8 @@ impl core::fmt::Display for TOTP {
}

#[cfg(all(feature = "gen_secret", not(feature = "otpauth")))]
// because `Default` is implemented regardless of `otpauth` feature we don't specify it here
#[cfg_attr(docsrs, doc(cfg(feature = "gen_secret")))]
constantoine marked this conversation as resolved.
Show resolved Hide resolved
impl Default for TOTP {
fn default() -> Self {
return TOTP::new(
Expand All @@ -224,6 +233,7 @@ impl Default for TOTP {
}

#[cfg(all(feature = "gen_secret", feature = "otpauth"))]
#[cfg_attr(docsrs, doc(cfg(feature = "gen_secret")))]
impl Default for TOTP {
fn default() -> Self {
TOTP::new(
Expand All @@ -245,16 +255,18 @@ impl TOTP {
///
/// # Description
/// * `secret`: expect a non-encoded value, to pass in base32 string use `Secret::Encoded(String)`
/// * `digits`: MUST be between 6 & 8
/// * `secret`: Must have bitsize of at least 128
/// * `account_name`: Must not contain `:`
/// * `issuer`: Must not contain `:`
///
/// # Example
///
/// ```rust
/// use totp_rs::{Secret, TOTP, Algorithm};
/// let secret = Secret::Encoded("OBWGC2LOFVZXI4TJNZTS243FMNZGK5BNGEZDG".to_string());
/// let totp = TOTP::new(Algorithm::SHA1, 6, 1, 30, secret.to_bytes().unwrap(), None, "".to_string()).unwrap();
/// ```
/// * `digits`: MUST be between 6 & 8
/// * `secret`: Must have bitsize of at least 128
/// * `account_name`: Must not contain `:`
/// * `issuer`: Must not contain `:`
///
/// # Errors
///
Expand Down Expand Up @@ -293,6 +305,8 @@ impl TOTP {
/// # Description
/// * `secret`: expect a non-encoded value, to pass in base32 string use `Secret::Encoded(String)`
///
/// # Example
///
/// ```rust
/// use totp_rs::{Secret, TOTP, Algorithm};
/// let secret = Secret::Encoded("OBWGC2LOFVZXI4TJNZTS243FMNZGK5BNGEZDG".to_string());
Expand Down Expand Up @@ -323,14 +337,16 @@ impl TOTP {
///
/// # Description
/// * `secret`: expect a non-encoded value, to pass in base32 string use `Secret::Encoded(String)`
/// * `digits`: MUST be between 6 & 8
/// * `secret`: Must have bitsize of at least 128
///
/// # Example
///
/// ```rust
/// use totp_rs::{Secret, TOTP, Algorithm};
/// let secret = Secret::Encoded("OBWGC2LOFVZXI4TJNZTS243FMNZGK5BNGEZDG".to_string());
/// let totp = TOTP::new(Algorithm::SHA1, 6, 1, 30, secret.to_bytes().unwrap()).unwrap();
/// ```
/// * `digits`: MUST be between 6 & 8
/// * `secret`: Must have bitsize of at least 128
///
/// # Errors
///
Expand All @@ -353,6 +369,8 @@ impl TOTP {
/// # Description
/// * `secret`: expect a non-encoded value, to pass in base32 string use `Secret::Encoded(String)`
///
/// # Example
///
/// ```rust
/// use totp_rs::{Secret, TOTP, Algorithm};
/// let secret = Secret::Encoded("OBWGC2LOFVZXI4TJNZTS243FMNZGK5BNGEZDG".to_string());
Expand Down Expand Up @@ -475,6 +493,7 @@ impl TOTP {

/// Generate a TOTP from the standard otpauth URL
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
pub fn from_url<S: AsRef<str>>(url: S) -> Result<TOTP, TotpUrlError> {
let (algorithm, digits, skew, step, secret, issuer, account_name) =
Self::parts_from_url(url)?;
Expand All @@ -483,6 +502,7 @@ impl TOTP {

/// Generate a TOTP from the standard otpauth URL, using `TOTP::new_unchecked` internally
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
pub fn from_url_unchecked<S: AsRef<str>>(url: S) -> Result<TOTP, TotpUrlError> {
let (algorithm, digits, skew, step, secret, issuer, account_name) =
Self::parts_from_url(url)?;
Expand All @@ -499,6 +519,7 @@ impl TOTP {

/// Parse the TOTP parts from the standard otpauth URL
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
constantoine marked this conversation as resolved.
Show resolved Hide resolved
fn parts_from_url<S: AsRef<str>>(
url: S,
) -> Result<(Algorithm, usize, u8, u64, Vec<u8>, Option<String>, String), TotpUrlError> {
Expand Down Expand Up @@ -614,6 +635,7 @@ impl TOTP {
/// Label and issuer will be URL-encoded if needed be
/// Secret will be base 32'd without padding, as per RFC.
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
pub fn get_url(&self) -> String {
#[allow(unused_mut)]
let mut host = "totp";
Expand Down Expand Up @@ -645,6 +667,7 @@ impl TOTP {
}

#[cfg(feature = "qr")]
#[cfg_attr(docsrs, doc(cfg(feature = "qr")))]
impl TOTP {
#[deprecated(
since = "5.3.0",
Expand All @@ -665,7 +688,8 @@ impl TOTP {
/// This would require the get_url method to generate an url bigger than 2000 characters,
/// Which would be too long for some browsers anyway.
///
/// It will also return an error in case it can't encode the qr into a png. This shouldn't happen unless either the qrcode library returns malformed data, or the image library doesn't encode the data correctly
/// It will also return an error in case it can't encode the qr into a png.
/// This shouldn't happen unless either the qrcode library returns malformed data, or the image library doesn't encode the data correctly
pub fn get_qr_base64(&self) -> Result<String, String> {
let url = self.get_url();
qrcodegen_image::draw_base64(&url)
Expand All @@ -680,7 +704,8 @@ impl TOTP {
/// This would require the get_url method to generate an url bigger than 2000 characters,
/// Which would be too long for some browsers anyway.
///
/// It will also return an error in case it can't encode the qr into a png. This shouldn't happen unless either the qrcode library returns malformed data, or the image library doesn't encode the data correctly
/// It will also return an error in case it can't encode the qr into a png.
/// This shouldn't happen unless either the qrcode library returns malformed data, or the image library doesn't encode the data correctly
pub fn get_qr_png(&self) -> Result<Vec<u8>, String> {
let url = self.get_url();
qrcodegen_image::draw_png(&url)
Expand Down
4 changes: 4 additions & 0 deletions src/rfc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ pub struct Rfc6238 {
/// As per [rfc-4226](https://tools.ietf.org/html/rfc4226#section-4) the secret should come from a strong source, most likely a CSPRNG. It should be at least 128 bits, but 160 are recommended.
secret: Vec<u8>,
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
/// The "Github" part of "Github:constantoine@github.com". Must not contain a colon `:`
/// For example, the name of your service/website.
/// Not mandatory, but strongly recommended!
issuer: Option<String>,
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
/// The "constantoine@github.com" part of "Github:constantoine@github.com". Must not contain a colon `:`.
/// For example, the name of your user's account.
account_name: String,
Expand Down Expand Up @@ -156,12 +158,14 @@ impl Rfc6238 {
}

#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
/// Set the `issuer`.
pub fn issuer(&mut self, value: String) {
self.issuer = Some(value);
}

#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
/// Set the `account_name`.
pub fn account_name(&mut self, value: String) {
self.account_name = value;
Expand Down
4 changes: 2 additions & 2 deletions src/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl PartialEq for Secret {
}

#[cfg(feature = "gen_secret")]
#[cfg_attr(docsrs, doc(cfg(feature = "gen_secret")))]
impl Default for Secret {
fn default() -> Self {
Secret::generate_secret()
Expand Down Expand Up @@ -158,8 +159,6 @@ impl Secret {
}
}

/// ⚠️ requires feature `gen_secret`.
///
/// Generate a CSPRNG binary value of 160 bits,
/// the recomended size from [rfc-4226](https://www.rfc-editor.org/rfc/rfc4226#section-4).
///
Expand All @@ -168,6 +167,7 @@ impl Secret {
///
/// ⚠️ The generated secret is not guaranteed to be a valid UTF-8 sequence.
#[cfg(feature = "gen_secret")]
#[cfg_attr(docsrs, doc(cfg(feature = "gen_secret")))]
pub fn generate_secret() -> Secret {
use rand::Rng;

Expand Down
1 change: 1 addition & 0 deletions src/url_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::Rfc6238Error;
pub enum TotpUrlError {
/// Couldn't decode URL.
#[cfg(feature = "otpauth")]
#[cfg_attr(docsrs, doc(cfg(feature = "otpauth")))]
Url(ParseError),
/// Invalid scheme.
Scheme(String),
Expand Down
Loading