diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/services/authorization.rs | 50 | ||||
| -rw-r--r-- | src/services/mod.rs | 1 |
2 files changed, 51 insertions, 0 deletions
diff --git a/src/services/authorization.rs b/src/services/authorization.rs new file mode 100644 index 0000000..b9d57ae --- /dev/null +++ b/src/services/authorization.rs @@ -0,0 +1,50 @@ +use base64::Engine; +use raise::yeet; +use thiserror::Error; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Error)] +pub enum ParseBasicError { + #[error("Basic Authorization is required")] + NotBasic, + #[error("No credentials were provided for authorization")] + NoCredentials, + #[error("The credentials provided were not base64")] + InvalidBase64, + #[error("The decoded base64 credentials were not UTF-8")] + NotUtf8, + #[error("A colon (:) must be used to delimit the username and password")] + NoColon, +} + +/// Returns a username and a password from a Basic authorization header +pub fn parse_basic(value: &str) -> Result<(Box<str>, Box<str>), ParseBasicError> { + if !value.starts_with("Basic") { + yeet!(ParseBasicError::NotBasic); + } + + let value: String = value + .chars() + .skip(5) + .skip_while(|ch| ch.is_whitespace()) + .collect(); + + if value.is_empty() { + yeet!(ParseBasicError::NoCredentials); + } + + let Ok(bytes) = base64::engine::general_purpose::STANDARD.decode(value) else { + yeet!(ParseBasicError::InvalidBase64) + }; + + let Ok(value) = String::from_utf8(bytes) else { + yeet!(ParseBasicError::NotUtf8) + }; + + let mut parts = value.split(':'); + let username = parts.next().unwrap(); + let Some(password) = parts.next() else { + yeet!(ParseBasicError::NoColon) + }; + + Ok((Box::from(username), Box::from(password))) +} diff --git a/src/services/mod.rs b/src/services/mod.rs index 09d2159..deab694 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -1,3 +1,4 @@ +pub mod authorization; pub mod crypto; pub mod db; pub mod id; |
