autoendpoint/extractors/
token_info.rs

1use crate::error::{ApiError, ApiErrorKind};
2use crate::headers::util::get_owned_header;
3use actix_web::{dev::Payload, FromRequest, HttpRequest};
4use futures::future;
5use std::str::FromStr;
6
7/// Extracts basic token data from the webpush request path and headers
8#[derive(Debug)]
9pub struct TokenInfo {
10    pub api_version: ApiVersion,
11    pub token: String,
12    pub crypto_key_header: Option<String>,
13    pub auth_header: Option<String>,
14}
15
16impl FromRequest for TokenInfo {
17    type Error = ApiError;
18    type Future = future::Ready<Result<Self, Self::Error>>;
19
20    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
21        // Path variables
22        let api_version = match req.match_info().get("api_version").unwrap_or("v1").parse() {
23            Ok(version) => version,
24            Err(e) => return future::err(e),
25        };
26        let token = req
27            .match_info()
28            .get("token")
29            .expect("{token} must be part of the webpush path")
30            .to_string();
31
32        future::ok(TokenInfo {
33            api_version,
34            token,
35            crypto_key_header: get_owned_header(req, "crypto-key"),
36            auth_header: get_owned_header(req, "authorization"),
37        })
38    }
39}
40
41#[derive(Copy, Clone, Debug, PartialEq, Eq)]
42pub enum ApiVersion {
43    Version1,
44    Version2,
45}
46
47impl FromStr for ApiVersion {
48    type Err = ApiError;
49
50    fn from_str(s: &str) -> Result<Self, Self::Err> {
51        match s {
52            "v1" => Ok(ApiVersion::Version1),
53            "v2" => Ok(ApiVersion::Version2),
54            _ => Err(ApiErrorKind::InvalidApiVersion.into()),
55        }
56    }
57}