autoendpoint/extractors/
user.rs1use crate::error::{ApiErrorKind, ApiResult};
4use crate::extractors::routers::RouterType;
5use crate::server::AppState;
6use actix_http::StatusCode;
7use autopush_common::db::{client::DbClient, User};
8use autopush_common::metric_name::MetricName;
9use autopush_common::metrics::StatsdClientExt;
10use cadence::StatsdClient;
11use uuid::Uuid;
12
13pub async fn validate_user(
20 user: &User,
21 channel_id: &Uuid,
22 app_state: &AppState,
23) -> ApiResult<RouterType> {
24 let router_type = match user.router_type.parse::<RouterType>() {
25 Ok(router_type) => router_type,
26 Err(_) => {
27 debug!("Unknown router type, dropping user"; "user" => ?user);
28 drop_user(user.uaid, app_state.db.as_ref(), &app_state.metrics).await?;
29 return Err(ApiErrorKind::NoSubscription.into());
30 }
31 };
32
33 if router_type == RouterType::GCM {
38 debug!("Encountered GCM record, dropping user"; "user" => ?user);
39 app_state
41 .metrics
42 .incr_with_tags(MetricName::NotificationBridgeError)
43 .with_tag("platform", "gcm")
44 .with_tag("reason", "gcm_kill")
45 .with_tag("error", &StatusCode::GONE.to_string())
46 .send();
47 drop_user(user.uaid, app_state.db.as_ref(), &app_state.metrics).await?;
48 return Err(ApiErrorKind::Router(crate::routers::RouterError::NotFound).into());
49 }
50
51 if router_type == RouterType::WebPush {
52 validate_webpush_user(user, channel_id, app_state.db.as_ref()).await?;
53 }
54
55 Ok(router_type)
56}
57
58async fn validate_webpush_user(user: &User, channel_id: &Uuid, db: &dyn DbClient) -> ApiResult<()> {
60 let channel_ids = db.get_channels(&user.uaid).await?;
62
63 if !channel_ids.contains(channel_id) {
64 return Err(ApiErrorKind::NoSubscription.into());
65 }
66
67 Ok(())
68}
69
70pub async fn drop_user(uaid: Uuid, db: &dyn DbClient, metrics: &StatsdClient) -> ApiResult<()> {
72 metrics
73 .incr_with_tags(MetricName::UpdatesDropUser)
74 .with_tag("errno", "102")
75 .send();
76
77 db.remove_user(&uaid).await?;
78
79 Ok(())
80}