firebase_auth/
actix_feature.rs

1use actix_web::error::ErrorUnauthorized;
2use actix_web::{dev, http::header::Header, web, Error, FromRequest, HttpRequest};
3use actix_web_httpauth::headers::authorization::{Authorization, Bearer};
4use futures::future::{err, ok, Ready};
5use tracing::debug;
6
7use crate::{FirebaseAuth, FirebaseUser};
8
9fn get_bearer_token(header: &str) -> Option<String> {
10    let prefix_len = "Bearer ".len();
11
12    match header.len() {
13        l if l < prefix_len => None,
14        _ => Some(header[prefix_len..].to_string()),
15    }
16}
17
18impl FromRequest for FirebaseUser {
19    type Error = Error;
20    type Future = Ready<Result<Self, Self::Error>>;
21
22    fn from_request(req: &HttpRequest, _: &mut dev::Payload) -> Self::Future {
23        let firebase_auth = req
24                .app_data::<web::Data<FirebaseAuth>>()
25                .expect("must init FirebaseAuth in Application Data. see description in https://crates.io/crates/firebase-auth");
26
27        let bearer = match Authorization::<Bearer>::parse(req) {
28            Err(e) => return err(e.into()),
29            Ok(v) => get_bearer_token(&v.to_string()).unwrap_or_default(),
30        };
31
32        debug!("Got bearer token {}", bearer);
33
34        match firebase_auth.verify(&bearer) {
35            Err(e) => err(ErrorUnauthorized(format!("Failed to verify Token {}", e))),
36            Ok(user) => ok(user),
37        }
38    }
39}