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:
parent
8703f2f82e
commit
5964f4d767
@ -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"
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
|
@ -5,4 +5,4 @@ mod schemes;
|
|||||||
mod errors;
|
mod errors;
|
||||||
|
|
||||||
pub use schemes::*;
|
pub use schemes::*;
|
||||||
pub use errors::Error;
|
pub use errors::AuthError;
|
||||||
|
@ -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]
|
||||||
|
Loading…
Reference in New Issue
Block a user