Skip to content

Commit

Permalink
Merge pull request #64 from AntonnMal/docs-revision
Browse files Browse the repository at this point in the history
Added crate feature requirements to docs
  • Loading branch information
constantoine authored Jan 19, 2024
2 parents 7873dc0 + 4b11a71 commit 17844d6
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 12 deletions.
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"]

[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
40 changes: 32 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")))]
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 Down Expand Up @@ -614,6 +634,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 +666,7 @@ impl TOTP {
}

#[cfg(feature = "qr")]
#[cfg_attr(docsrs, doc(cfg(feature = "qr")))]
impl TOTP {
#[deprecated(
since = "5.3.0",
Expand All @@ -665,7 +687,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 +703,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

0 comments on commit 17844d6

Please sign in to comment.