Lints and formatting
This commit is contained in:
parent
ccc6657083
commit
aac6d9f7b5
5 changed files with 62 additions and 40 deletions
28
src/crypt.rs
28
src/crypt.rs
|
@ -8,24 +8,24 @@ use openssl::sign::{Signer, Verifier};
|
||||||
use super::Result;
|
use super::Result;
|
||||||
|
|
||||||
pub fn sign(data: &str, key: &[u8], algorithm: &Algorithm) -> Result<String> {
|
pub fn sign(data: &str, key: &[u8], algorithm: &Algorithm) -> Result<String> {
|
||||||
match algorithm {
|
match *algorithm {
|
||||||
&Algorithm::HS256 => sign_hmac(data, key, MessageDigest::sha256()),
|
Algorithm::HS256 => sign_hmac(data, key, MessageDigest::sha256()),
|
||||||
&Algorithm::HS384 => sign_hmac(data, key, MessageDigest::sha384()),
|
Algorithm::HS384 => sign_hmac(data, key, MessageDigest::sha384()),
|
||||||
&Algorithm::HS512 => sign_hmac(data, key, MessageDigest::sha512()),
|
Algorithm::HS512 => sign_hmac(data, key, MessageDigest::sha512()),
|
||||||
&Algorithm::RS256 => sign_rsa(data, key, MessageDigest::sha256()),
|
Algorithm::RS256 => sign_rsa(data, key, MessageDigest::sha256()),
|
||||||
&Algorithm::RS384 => sign_rsa(data, key, MessageDigest::sha384()),
|
Algorithm::RS384 => sign_rsa(data, key, MessageDigest::sha384()),
|
||||||
&Algorithm::RS512 => sign_rsa(data, key, MessageDigest::sha512()),
|
Algorithm::RS512 => sign_rsa(data, key, MessageDigest::sha512()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify(target: &str, data: &str, key: &[u8], algorithm: &Algorithm) -> Result<bool> {
|
pub fn verify(target: &str, data: &str, key: &[u8], algorithm: &Algorithm) -> Result<bool> {
|
||||||
match algorithm {
|
match *algorithm {
|
||||||
&Algorithm::HS256 => verify_hmac(target, data, key, MessageDigest::sha256()),
|
Algorithm::HS256 => verify_hmac(target, data, key, MessageDigest::sha256()),
|
||||||
&Algorithm::HS384 => verify_hmac(target, data, key, MessageDigest::sha384()),
|
Algorithm::HS384 => verify_hmac(target, data, key, MessageDigest::sha384()),
|
||||||
&Algorithm::HS512 => verify_hmac(target, data, key, MessageDigest::sha512()),
|
Algorithm::HS512 => verify_hmac(target, data, key, MessageDigest::sha512()),
|
||||||
&Algorithm::RS256 => verify_rsa(target, data, key, MessageDigest::sha256()),
|
Algorithm::RS256 => verify_rsa(target, data, key, MessageDigest::sha256()),
|
||||||
&Algorithm::RS384 => verify_rsa(target, data, key, MessageDigest::sha384()),
|
Algorithm::RS384 => verify_rsa(target, data, key, MessageDigest::sha384()),
|
||||||
&Algorithm::RS512 => verify_rsa(target, data, key, MessageDigest::sha512()),
|
Algorithm::RS512 => verify_rsa(target, data, key, MessageDigest::sha512()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub enum Error {
|
||||||
impl error::Error for Error {
|
impl error::Error for Error {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Custom(ref message) => &message,
|
Error::Custom(ref message) => message,
|
||||||
Error::Utf8(ref err) => err.description(),
|
Error::Utf8(ref err) => err.description(),
|
||||||
Error::Base64(ref err) => err.description(),
|
Error::Base64(ref err) => err.description(),
|
||||||
Error::JSON(ref err) => err.description(),
|
Error::JSON(ref err) => err.description(),
|
||||||
|
@ -44,7 +44,7 @@ impl error::Error for Error {
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Custom(ref message) => f.write_str(&message),
|
Error::Custom(ref message) => f.write_str(message),
|
||||||
Error::Utf8(ref err) => err.fmt(f),
|
Error::Utf8(ref err) => err.fmt(f),
|
||||||
Error::Base64(ref err) => err.fmt(f),
|
Error::Base64(ref err) => err.fmt(f),
|
||||||
Error::JSON(ref err) => err.fmt(f),
|
Error::JSON(ref err) => err.fmt(f),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use base64::{encode_config, decode_config, URL_SAFE_NO_PAD};
|
use base64::{decode_config, encode_config, URL_SAFE_NO_PAD};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde_json::{self, Value};
|
use serde_json::{self, Value};
|
||||||
|
@ -38,10 +38,9 @@ impl<T: Serialize + DeserializeOwned> Header<T> {
|
||||||
|
|
||||||
let headers: Option<T> = serde_json::from_slice(&data).ok();
|
let headers: Option<T> = serde_json::from_slice(&data).ok();
|
||||||
|
|
||||||
|
|
||||||
Ok(Header {
|
Ok(Header {
|
||||||
alg: own.alg,
|
alg: own.alg,
|
||||||
headers: headers,
|
headers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +55,9 @@ impl<T: Serialize + DeserializeOwned> Header<T> {
|
||||||
let enc = encode_config((&*s).as_bytes(), URL_SAFE_NO_PAD);
|
let enc = encode_config((&*s).as_bytes(), URL_SAFE_NO_PAD);
|
||||||
Ok(enc)
|
Ok(enc)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Custom("Could not access additional headers.".to_owned()))
|
Err(Error::Custom(
|
||||||
|
"Could not access additional headers.".to_owned(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
41
src/lib.rs
41
src/lib.rs
|
@ -1,8 +1,8 @@
|
||||||
#![crate_name = "medallion"]
|
#![crate_name = "medallion"]
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![doc(html_root_url = "https://commandline.github.io/medallion/")]
|
#![doc(html_root_url = "https://commandline.github.io/medallion/")]
|
||||||
///! A crate for working with JSON WebTokens that use OpenSSL for RSA signing and encryption and
|
///! A crate for working with JSON `WebTokens` that use OpenSSL for RSA signing and encryption and
|
||||||
///! serde and serde_json for JSON encoding and decoding.
|
///! `serde` and `serde_json` for JSON encoding and decoding.
|
||||||
///!
|
///!
|
||||||
///! Tries to support the standard uses for JWTs while providing reasonable ways to extend,
|
///! Tries to support the standard uses for JWTs while providing reasonable ways to extend,
|
||||||
///! primarily by adding custom headers and claims to tokens.
|
///! primarily by adding custom headers and claims to tokens.
|
||||||
|
@ -19,7 +19,7 @@ use serde::de::DeserializeOwned;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use header::Header;
|
pub use header::Header;
|
||||||
pub use header::Algorithm;
|
pub use header::Algorithm;
|
||||||
pub use payload::{Payload, DefaultPayload};
|
pub use payload::{DefaultPayload, Payload};
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod header;
|
mod header;
|
||||||
|
@ -29,7 +29,7 @@ mod crypt;
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
/// A convenient type that binds the same type parameter for the custom claims, an empty tuple, as
|
/// A convenient type that binds the same type parameter for the custom claims, an empty tuple, as
|
||||||
/// DefaultPayload so that the two aliases may be used together to reduce boilerplate when no
|
/// `DefaultPayload` so that the two aliases may be used together to reduce boilerplate when no
|
||||||
/// custom claims are needed.
|
/// custom claims are needed.
|
||||||
pub type DefaultToken<H> = Token<H, ()>;
|
pub type DefaultToken<H> = Token<H, ()>;
|
||||||
|
|
||||||
|
@ -43,14 +43,15 @@ pub struct Token<H, C> {
|
||||||
|
|
||||||
/// Provide the ability to parse a token, verify it and sign/serialize it.
|
/// Provide the ability to parse a token, verify it and sign/serialize it.
|
||||||
impl<H, C> Token<H, C>
|
impl<H, C> Token<H, C>
|
||||||
where H: Serialize + DeserializeOwned,
|
where
|
||||||
C: Serialize + DeserializeOwned
|
H: Serialize + DeserializeOwned,
|
||||||
|
C: Serialize + DeserializeOwned,
|
||||||
{
|
{
|
||||||
pub fn new(header: Header<H>, payload: Payload<C>) -> Token<H, C> {
|
pub fn new(header: Header<H>, payload: Payload<C>) -> Token<H, C> {
|
||||||
Token {
|
Token {
|
||||||
raw: None,
|
raw: None,
|
||||||
header: header,
|
header,
|
||||||
payload: payload,
|
payload,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +93,9 @@ impl<H, C> Token<H, C>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, C> PartialEq for Token<H, C>
|
impl<H, C> PartialEq for Token<H, C>
|
||||||
where H: PartialEq,
|
where
|
||||||
C: PartialEq
|
H: PartialEq,
|
||||||
|
C: PartialEq,
|
||||||
{
|
{
|
||||||
fn eq(&self, other: &Token<H, C>) -> bool {
|
fn eq(&self, other: &Token<H, C>) -> bool {
|
||||||
self.header == other.header && self.payload == other.payload
|
self.header == other.header && self.payload == other.payload
|
||||||
|
@ -164,13 +166,24 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
pub fn roundtrip_rsa() {
|
pub fn roundtrip_rsa() {
|
||||||
let rsa_keypair = openssl::rsa::Rsa::generate(2048).unwrap();
|
let rsa_keypair = openssl::rsa::Rsa::generate(2048).unwrap();
|
||||||
let header: Header<()> = Header { alg: RS512, ..Default::default() };
|
let header: Header<()> = Header {
|
||||||
let token = DefaultToken { header: header, ..Default::default() };
|
alg: RS512,
|
||||||
let raw = token.sign(&rsa_keypair.private_key_to_pem().unwrap()).unwrap();
|
..Default::default()
|
||||||
|
};
|
||||||
|
let token = DefaultToken {
|
||||||
|
header: header,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let raw = token
|
||||||
|
.sign(&rsa_keypair.private_key_to_pem().unwrap())
|
||||||
|
.unwrap();
|
||||||
let same = DefaultToken::parse(&*raw).unwrap();
|
let same = DefaultToken::parse(&*raw).unwrap();
|
||||||
|
|
||||||
assert_eq!(token, same);
|
assert_eq!(token, same);
|
||||||
assert!(same.verify(&rsa_keypair.public_key_to_pem().unwrap()).unwrap());
|
assert!(
|
||||||
|
same.verify(&rsa_keypair.public_key_to_pem().unwrap())
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_for_range(nbf: Tm, exp: Tm) -> DefaultToken<()> {
|
fn create_for_range(nbf: Tm, exp: Tm) -> DefaultToken<()> {
|
||||||
|
|
|
@ -78,9 +78,10 @@ impl<T: Serialize + DeserializeOwned> Payload<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Custom("Could not access standard claims.".to_owned()))
|
Err(Error::Custom(
|
||||||
|
"Could not access standard claims.".to_owned(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify(&self) -> bool {
|
pub fn verify(&self) -> bool {
|
||||||
|
@ -101,7 +102,7 @@ impl<T: Serialize + DeserializeOwned> Payload<T> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use time::{self, Duration};
|
use time::{self, Duration};
|
||||||
use super::{Payload, DefaultPayload};
|
use super::{DefaultPayload, Payload};
|
||||||
|
|
||||||
#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
struct CustomClaims {
|
struct CustomClaims {
|
||||||
|
@ -154,7 +155,10 @@ mod tests {
|
||||||
fn roundtrip_custom() {
|
fn roundtrip_custom() {
|
||||||
let payload = create_custom();
|
let payload = create_custom();
|
||||||
let enc = payload.to_base64().unwrap();
|
let enc = payload.to_base64().unwrap();
|
||||||
assert_eq!(payload, Payload::<CustomClaims>::from_base64(&*enc).unwrap());
|
assert_eq!(
|
||||||
|
payload,
|
||||||
|
Payload::<CustomClaims>::from_base64(&*enc).unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -214,8 +218,12 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_with_nbf_exp(nbf_offset: i64, exp_offset: i64) -> DefaultPayload {
|
fn create_with_nbf_exp(nbf_offset: i64, exp_offset: i64) -> DefaultPayload {
|
||||||
let nbf = (time::now() - Duration::minutes(nbf_offset)).to_timespec().sec;
|
let nbf = (time::now() - Duration::minutes(nbf_offset))
|
||||||
let exp = (time::now() + Duration::minutes(exp_offset)).to_timespec().sec;
|
.to_timespec()
|
||||||
|
.sec;
|
||||||
|
let exp = (time::now() + Duration::minutes(exp_offset))
|
||||||
|
.to_timespec()
|
||||||
|
.sec;
|
||||||
DefaultPayload {
|
DefaultPayload {
|
||||||
nbf: Some(nbf as u64),
|
nbf: Some(nbf as u64),
|
||||||
exp: Some(exp as u64),
|
exp: Some(exp as u64),
|
||||||
|
|
Loading…
Reference in a new issue