    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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101

    use std::fmt;

    use actix_web::error::ParseError;
    use actix_web::http::header::{Header, HeaderName, HeaderValue, TryIntoHeaderValue, AUTHORIZATION};
    use actix_web::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` header is generic over [authentication
    /// scheme](./trait.Scheme.html).
    ///
    /// # Example
    ///
    /// ```
    /// # use actix_web::http::header::Header;
    /// # use actix_web::{HttpRequest, Result};
    /// # 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(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, Clone)]
    pub struct Authorization<S: Scheme>(S);

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

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

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

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

    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(AUTHORIZATION).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()
        }
    }

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