1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-12-04 03:51:55 +01:00

Badges and stable fixes

This commit is contained in:
svartalf 2018-05-20 13:15:59 +03:00
parent 8703f2f82e
commit 5964f4d767
5 changed files with 47 additions and 35 deletions

View File

@ -10,6 +10,10 @@ repository = "https://github.com/svartlaf/actix-web-httpauth.git"
documentation = "https://docs.rs/actix-web-httpauth/" documentation = "https://docs.rs/actix-web-httpauth/"
categories = ["web-programming::http-server"] categories = ["web-programming::http-server"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
exclude = [".travis.yml", ".gitignore"]
[badges]
travis-ci = { repository = "svartalf/actix-web-httpauth", branch = "master" }
[dependencies] [dependencies]
actix-web = "0.6" actix-web = "0.6"

View File

@ -1 +1,7 @@
# actix-web-httpauth # actix-web-httpauth
[![Build Status](https://travis-ci.org/svartalf/actix-web-httpauth.svg?branch=master)]
[![Docs](https://docs.rs/actix-web-httpauth/badge.svg)]
[![Crates.io](https://img.shields.io/crates/v/actix-web-httpauth.svg)]
HTTP authorization schemes for [actix-web](https://github.com/actix/actix-web) framework.

View File

@ -1,5 +1,5 @@
use std::fmt; use std::fmt;
use std::error; use std::error::Error;
use std::string; use std::string;
use base64; use base64;
@ -8,51 +8,53 @@ use actix_web::error::ResponseError;
use actix_web::http::{StatusCode, header}; use actix_web::http::{StatusCode, header};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Error { pub enum AuthError {
HeaderMissing, // HTTP 401 HeaderMissing, // HTTP 401
// TODO: Ensure that 401 should be returned if not a `Basic` mechanism is received // TODO: Ensure that 401 should be returned if not a `Basic` mechanism is received
InvalidMechanism, // HTTP 401 ? InvalidMechanism, // HTTP 401 ?
HeaderMalformed, // HTTP 400 HeaderMalformed, // HTTP 400
} }
impl fmt::Display for Error { impl fmt::Display for AuthError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match self { f.write_str(self.description())
Error::HeaderMissing => "HTTP 'Authorization' header is missing",
Error::InvalidMechanism => "Wrong mechanizm for a HTTP 'Authorization' header, expected 'Basic'",
Error::HeaderMalformed => "Malformed HTTP 'Authorization' header",
};
f.write_str(msg)
} }
} }
impl error::Error for Error {} impl Error for AuthError {
fn description(&self) -> &str {
match *self {
AuthError::HeaderMissing => "HTTP 'Authorization' header is missing",
AuthError::InvalidMechanism => "Wrong mechanism for a HTTP 'Authorization' header, expected 'Basic'",
AuthError::HeaderMalformed => "Malformed HTTP 'Authorization' header",
}
}
}
impl From<header::ToStrError> for Error { impl From<header::ToStrError> for AuthError {
fn from(_: header::ToStrError) -> Self { fn from(_: header::ToStrError) -> Self {
Error::HeaderMalformed AuthError::HeaderMalformed
} }
} }
impl From<base64::DecodeError> for Error { impl From<base64::DecodeError> for AuthError {
fn from(_: base64::DecodeError) -> Self { fn from(_: base64::DecodeError) -> Self {
Error::HeaderMalformed AuthError::HeaderMalformed
} }
} }
impl From<string::FromUtf8Error> for Error { impl From<string::FromUtf8Error> for AuthError {
fn from(_: string::FromUtf8Error) -> Self { fn from(_: string::FromUtf8Error) -> Self {
Error::HeaderMalformed AuthError::HeaderMalformed
} }
} }
impl ResponseError for Error { impl ResponseError for AuthError {
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
let status = match self { let status = match *self {
Error::HeaderMissing => StatusCode::UNAUTHORIZED, AuthError::HeaderMissing => StatusCode::UNAUTHORIZED,
Error::InvalidMechanism => StatusCode::UNAUTHORIZED, AuthError::InvalidMechanism => StatusCode::UNAUTHORIZED,
Error::HeaderMalformed => StatusCode::BAD_REQUEST, AuthError::HeaderMalformed => StatusCode::BAD_REQUEST,
}; };
HttpResponse::build(status) HttpResponse::build(status)

View File

@ -5,4 +5,4 @@ mod schemes;
mod errors; mod errors;
pub use schemes::*; pub use schemes::*;
pub use errors::Error; pub use errors::AuthError;

View File

@ -1,7 +1,7 @@
use base64; use base64;
use actix_web::{HttpRequest, HttpMessage, FromRequest}; use actix_web::{HttpRequest, HttpMessage, FromRequest};
use errors::Error; use errors::AuthError;
/// Extractor for `Authorization: Basic {payload}` HTTP request header. /// Extractor for `Authorization: Basic {payload}` HTTP request header.
/// ///
@ -23,28 +23,28 @@ pub struct BasicAuth {
impl<S> FromRequest<S> for BasicAuth { impl<S> FromRequest<S> for BasicAuth {
type Config = (); type Config = ();
type Result = Result<Self, Error>; type Result = Result<Self, AuthError>;
fn from_request(req: &HttpRequest<S>, _cfg: &<Self as FromRequest<S>>::Config) -> <Self as FromRequest<S>>::Result { fn from_request(req: &HttpRequest<S>, _cfg: &<Self as FromRequest<S>>::Config) -> <Self as FromRequest<S>>::Result {
let header = req.headers().get("Authorization") let header = req.headers().get("Authorization")
.ok_or(Error::HeaderMissing)? .ok_or(AuthError::HeaderMissing)?
.to_str()?; .to_str()?;
let mut parts = header.splitn(2, ' '); let mut parts = header.splitn(2, ' ');
// Authorization mechanism // Authorization mechanism
match parts.next() { match parts.next() {
None => return Err(Error::InvalidMechanism), None => return Err(AuthError::InvalidMechanism),
Some(mechanism) if mechanism != "Basic" => return Err(Error::InvalidMechanism), Some(mechanism) if mechanism != "Basic" => return Err(AuthError::InvalidMechanism),
_ => () _ => ()
} }
// Authorization payload // Authorization payload
let payload = parts.next().ok_or(Error::HeaderMalformed)?; let payload = parts.next().ok_or(AuthError::HeaderMalformed)?;
let payload = base64::decode(payload)?; let payload = base64::decode(payload)?;
let payload = String::from_utf8(payload)?; let payload = String::from_utf8(payload)?;
let mut parts = payload.splitn(2, ':'); let mut parts = payload.splitn(2, ':');
let user = parts.next().ok_or(Error::HeaderMalformed)?; let user = parts.next().ok_or(AuthError::HeaderMalformed)?;
let password = parts.next().ok_or(Error::HeaderMalformed)?; let password = parts.next().ok_or(AuthError::HeaderMalformed)?;
Ok(BasicAuth{ Ok(BasicAuth{
username: user.to_string(), username: user.to_string(),
@ -59,7 +59,7 @@ mod tests {
use actix_web::FromRequest; use actix_web::FromRequest;
use actix_web::test::TestRequest; use actix_web::test::TestRequest;
use super::{BasicAuth, Error}; use super::{BasicAuth, AuthError};
#[test] #[test]
fn test_valid_auth() { fn test_valid_auth() {
@ -80,7 +80,7 @@ mod tests {
assert!(auth.is_err()); assert!(auth.is_err());
let err = auth.err().unwrap(); let err = auth.err().unwrap();
assert_eq!(err, Error::HeaderMissing); assert_eq!(err, AuthError::HeaderMissing);
} }
#[test] #[test]
@ -91,7 +91,7 @@ mod tests {
assert!(auth.is_err()); assert!(auth.is_err());
let err = auth.err().unwrap(); let err = auth.err().unwrap();
assert_eq!(err, Error::InvalidMechanism); assert_eq!(err, AuthError::InvalidMechanism);
} }
#[test] #[test]
@ -102,7 +102,7 @@ mod tests {
assert!(auth.is_err()); assert!(auth.is_err());
let err = auth.err().unwrap(); let err = auth.err().unwrap();
assert_eq!(err, Error::HeaderMalformed); assert_eq!(err, AuthError::HeaderMalformed);
} }
#[test] #[test]