    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84

    use std::fmt;

    use actix_web::{
        error::ParseError,
        http::header::{Header, HeaderName, HeaderValue, TryIntoHeaderValue, AUTHORIZATION},
        HttpMessage,
    };

    use crate::headers::authorization::scheme::Scheme;

    /// `Authorization` header, defined in [RFC 7235](https://tools.ietf.org/html/rfc7235#section-4.2)
    ///
    /// The "Authorization" header field allows a user agent to authenticate itself with an origin
    /// server—usually, but not necessarily, after receiving a 401 (Unauthorized) response. Its value
    /// consists of credentials containing the authentication information of the user agent for the
    /// realm of the resource being requested.
    ///
    /// `Authorization` is generic over an [authentication scheme](Scheme).
    ///
    /// # Examples
    /// ```
    /// # use actix_web::{HttpRequest, Result, http::header::Header};
    /// # use actix_web_httpauth::headers::authorization::{Authorization, Basic};
    /// fn handler(req: HttpRequest) -> Result<String> {
    ///     let auth = Authorization::<Basic>::parse(&req)?;
    ///
    ///     Ok(format!("Hello, {}!", auth.as_ref().user_id()))
    /// }
    /// ```
    #[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct Authorization<S: Scheme>(S);

    impl<S: Scheme> Authorization<S> {
        /// Consumes `Authorization` header and returns inner [`Scheme`] implementation.
        pub fn into_scheme(self) -> S {
            self.0
        }
    }

    impl<S: Scheme> From<S> for Authorization<S> {
        fn from(scheme: S) -> Authorization<S> {
            Authorization(scheme)
        }
    }

    impl<S: Scheme> AsRef<S> for Authorization<S> {
        fn as_ref(&self) -> &S {
            &self.0
        }
    }

    impl<S: Scheme> AsMut<S> for Authorization<S> {
        fn as_mut(&mut self) -> &mut S {
            &mut self.0
        }
    }

    impl<S: Scheme> fmt::Display for Authorization<S> {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            fmt::Display::fmt(&self.0, f)
        }
    }

    impl<S: Scheme> Header for Authorization<S> {
        #[inline]
        fn name() -> HeaderName {
            AUTHORIZATION
        }

        fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError> {
            let header = msg.headers().get(Self::name()).ok_or(ParseError::Header)?;
            let scheme = S::parse(header).map_err(|_| ParseError::Header)?;

            Ok(Authorization(scheme))
        }
    }

    impl<S: Scheme> TryIntoHeaderValue for Authorization<S> {
        type Error = <S as TryIntoHeaderValue>::Error;

        fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
            self.0.try_into_value()
        }
    }