mirror of
https://github.com/n08i40k/schedule-parser-rusted.git
synced 2025-12-06 09:47:50 +03:00
refactor(android)!: remove FCM support
This commit is contained in:
@@ -4,7 +4,7 @@ pub mod users {
|
||||
use crate::database::schema::users::dsl::*;
|
||||
use crate::state::AppState;
|
||||
use actix_web::web;
|
||||
use diesel::{ExpressionMethods, QueryResult, insert_into};
|
||||
use diesel::{insert_into, ExpressionMethods, QueryResult};
|
||||
use diesel::{QueryDsl, RunQueryDsl};
|
||||
use diesel::{SaveChangesDsl, SelectableHelper};
|
||||
use std::ops::DerefMut;
|
||||
@@ -146,19 +146,3 @@ pub mod users {
|
||||
.execute(state.get_database().await.deref_mut())
|
||||
}
|
||||
}
|
||||
|
||||
pub mod fcm {
|
||||
use crate::database::models::{FCM, User};
|
||||
use crate::state::AppState;
|
||||
use actix_web::web;
|
||||
use diesel::QueryDsl;
|
||||
use diesel::RunQueryDsl;
|
||||
use diesel::{BelongingToDsl, QueryResult, SelectableHelper};
|
||||
use std::ops::DerefMut;
|
||||
|
||||
pub async fn from_user(state: &web::Data<AppState>, user: &User) -> QueryResult<FCM> {
|
||||
FCM::belonging_to(&user)
|
||||
.select(FCM::as_select())
|
||||
.get_result(state.get_database().await.deref_mut())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use crate::database::driver;
|
||||
use crate::database::models::{User, FCM};
|
||||
use crate::extractors::base::{AsyncExtractor, FromRequestAsync};
|
||||
use crate::database::models::User;
|
||||
use crate::extractors::base::FromRequestAsync;
|
||||
use crate::state::AppState;
|
||||
use crate::utility::jwt;
|
||||
use actix_macros::MiddlewareError;
|
||||
use actix_web::body::BoxBody;
|
||||
use actix_web::dev::Payload;
|
||||
use actix_web::http::header;
|
||||
use actix_web::{web, FromRequest, HttpRequest};
|
||||
use actix_web::{web, HttpRequest};
|
||||
use derive_more::Display;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
@@ -95,48 +95,3 @@ impl FromRequestAsync for User {
|
||||
.map_err(|_| Error::NoUser.into())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UserExtractor<const FCM: bool> {
|
||||
user: User,
|
||||
|
||||
fcm: Option<FCM>,
|
||||
}
|
||||
|
||||
impl<const FCM: bool> UserExtractor<{ FCM }> {
|
||||
pub fn user(&self) -> &User {
|
||||
&self.user
|
||||
}
|
||||
|
||||
pub fn fcm(&self) -> &Option<FCM> {
|
||||
if !FCM {
|
||||
panic!("FCM marked as not required, but it has been requested")
|
||||
}
|
||||
|
||||
&self.fcm
|
||||
}
|
||||
}
|
||||
|
||||
/// Extractor of user and additional parameters from request with Bearer token.
|
||||
impl<const FCM: bool> FromRequestAsync for UserExtractor<{ FCM }> {
|
||||
type Error = actix_web::Error;
|
||||
|
||||
async fn from_request_async(
|
||||
req: &HttpRequest,
|
||||
payload: &mut Payload,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let user = AsyncExtractor::<User>::from_request(req, payload)
|
||||
.await?
|
||||
.into_inner();
|
||||
|
||||
let app_state = req.app_data::<web::Data<AppState>>().unwrap();
|
||||
|
||||
Ok(Self {
|
||||
fcm: if FCM {
|
||||
driver::fcm::from_user(&app_state, &user).await.ok()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
user,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
10
src/main.rs
10
src/main.rs
@@ -1,13 +1,13 @@
|
||||
use crate::middlewares::authorization::JWTAuthorization;
|
||||
use crate::middlewares::content_type::ContentTypeBootstrap;
|
||||
use crate::state::{AppState, new_app_state};
|
||||
use crate::state::{new_app_state, AppState};
|
||||
use actix_web::dev::{ServiceFactory, ServiceRequest};
|
||||
use actix_web::{App, Error, HttpServer};
|
||||
use dotenvy::dotenv;
|
||||
use log::info;
|
||||
use std::io;
|
||||
use utoipa_actix_web::AppExt;
|
||||
use utoipa_actix_web::scope::Scope;
|
||||
use utoipa_actix_web::AppExt;
|
||||
use utoipa_rapidoc::RapiDoc;
|
||||
|
||||
mod state;
|
||||
@@ -51,11 +51,6 @@ pub fn get_api_scope<
|
||||
.service(routes::schedule::teacher)
|
||||
.service(routes::schedule::teacher_names);
|
||||
|
||||
let fcm_scope = utoipa_actix_web::scope("/fcm")
|
||||
.wrap(JWTAuthorization::default())
|
||||
.service(routes::fcm::update_callback)
|
||||
.service(routes::fcm::set_token);
|
||||
|
||||
let flow_scope = utoipa_actix_web::scope("/flow")
|
||||
.wrap(JWTAuthorization {
|
||||
ignore: &["/telegram-auth"],
|
||||
@@ -70,7 +65,6 @@ pub fn get_api_scope<
|
||||
.service(auth_scope)
|
||||
.service(users_scope)
|
||||
.service(schedule_scope)
|
||||
.service(fcm_scope)
|
||||
.service(flow_scope)
|
||||
.service(vk_id_scope)
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
mod set_token;
|
||||
mod update_callback;
|
||||
|
||||
pub use set_token::*;
|
||||
pub use update_callback::*;
|
||||
@@ -1,94 +0,0 @@
|
||||
use crate::database;
|
||||
use crate::database::models::FCM;
|
||||
use crate::extractors::authorized_user::UserExtractor;
|
||||
use crate::extractors::base::AsyncExtractor;
|
||||
use crate::state::AppState;
|
||||
use actix_web::{HttpResponse, Responder, patch, web};
|
||||
use diesel::{RunQueryDsl, SaveChangesDsl};
|
||||
use firebase_messaging_rs::topic::TopicManagementSupport;
|
||||
use serde::Deserialize;
|
||||
use std::ops::DerefMut;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Params {
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
async fn get_fcm(
|
||||
app_state: &web::Data<AppState>,
|
||||
user_data: &UserExtractor<true>,
|
||||
token: String,
|
||||
) -> Result<FCM, diesel::result::Error> {
|
||||
match user_data.fcm() {
|
||||
Some(fcm) => {
|
||||
let mut fcm = fcm.clone();
|
||||
fcm.token = token;
|
||||
|
||||
Ok(fcm)
|
||||
}
|
||||
None => {
|
||||
let fcm = FCM {
|
||||
user_id: user_data.user().id.clone(),
|
||||
token,
|
||||
topics: vec![],
|
||||
};
|
||||
|
||||
match diesel::insert_into(database::schema::fcm::table)
|
||||
.values(&fcm)
|
||||
.execute(app_state.get_database().await.deref_mut())
|
||||
{
|
||||
Ok(_) => Ok(fcm),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[utoipa::path(responses((status = OK)))]
|
||||
#[patch("/set-token")]
|
||||
pub async fn set_token(
|
||||
app_state: web::Data<AppState>,
|
||||
web::Query(params): web::Query<Params>,
|
||||
user_data: AsyncExtractor<UserExtractor<true>>,
|
||||
) -> impl Responder {
|
||||
let user_data = user_data.into_inner();
|
||||
|
||||
// If token not changes - exit.
|
||||
if let Some(fcm) = user_data.fcm() {
|
||||
if fcm.token == params.token {
|
||||
return HttpResponse::Ok();
|
||||
}
|
||||
}
|
||||
|
||||
let fcm = get_fcm(&app_state, &user_data, params.token.clone()).await;
|
||||
if let Err(e) = fcm {
|
||||
eprintln!("Failed to get FCM: {e}");
|
||||
return HttpResponse::Ok();
|
||||
}
|
||||
|
||||
let mut fcm = fcm.ok().unwrap();
|
||||
|
||||
// Add default topics.
|
||||
if !fcm.topics.contains(&Some("common".to_string())) {
|
||||
fcm.topics.push(Some("common".to_string()));
|
||||
}
|
||||
|
||||
fcm.save_changes::<FCM>(app_state.get_database().await.deref_mut())
|
||||
.unwrap();
|
||||
|
||||
let fcm_client = app_state.get_fcm_client().await.unwrap();
|
||||
|
||||
for topic in fcm.topics.clone() {
|
||||
if let Some(topic) = topic {
|
||||
if let Err(error) = fcm_client
|
||||
.register_token_to_topic(&*topic, &*fcm.token)
|
||||
.await
|
||||
{
|
||||
eprintln!("Failed to subscribe token to topic: {:?}", error);
|
||||
return HttpResponse::Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
use crate::database::driver::users::UserSave;
|
||||
use crate::database::models::User;
|
||||
use crate::extractors::base::AsyncExtractor;
|
||||
use crate::state::AppState;
|
||||
use actix_web::{HttpResponse, Responder, post, web};
|
||||
|
||||
#[utoipa::path(responses(
|
||||
(status = OK),
|
||||
(status = INTERNAL_SERVER_ERROR)
|
||||
))]
|
||||
#[post("/update-callback/{version}")]
|
||||
async fn update_callback(
|
||||
app_state: web::Data<AppState>,
|
||||
version: web::Path<String>,
|
||||
user: AsyncExtractor<User>,
|
||||
) -> impl Responder {
|
||||
let mut user = user.into_inner();
|
||||
|
||||
user.android_version = Some(version.into_inner());
|
||||
|
||||
user.save(&app_state).await.unwrap();
|
||||
|
||||
HttpResponse::Ok()
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
pub mod auth;
|
||||
pub mod fcm;
|
||||
pub mod flow;
|
||||
pub mod schedule;
|
||||
mod schema;
|
||||
|
||||
@@ -131,7 +131,7 @@ pub mod user {
|
||||
use serde::Serialize;
|
||||
|
||||
//noinspection SpellCheckingInspection
|
||||
/// Используется для скрытия чувствительных полей, таких как хеш пароля или FCM
|
||||
/// Используется для скрытия чувствительных полей, таких как хеш пароля
|
||||
#[derive(Serialize, utoipa::ToSchema, ResponderJson, OkResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UserResponse {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
use firebase_messaging_rs::FCMClient;
|
||||
use std::env;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FCMClientData;
|
||||
|
||||
impl FCMClientData {
|
||||
pub async fn new() -> Option<Mutex<FCMClient>> {
|
||||
match env::var("GOOGLE_APPLICATION_CREDENTIALS") {
|
||||
Ok(_) => Some(Mutex::new(FCMClient::new().await.unwrap())),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
mod env;
|
||||
mod fcm_client;
|
||||
|
||||
pub use crate::state::env::AppEnv;
|
||||
use crate::state::fcm_client::FCMClientData;
|
||||
use actix_web::web;
|
||||
use diesel::{Connection, PgConnection};
|
||||
use firebase_messaging_rs::FCMClient;
|
||||
use providers::base::{ScheduleProvider, ScheduleSnapshot};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
@@ -18,7 +15,6 @@ pub struct AppState {
|
||||
database: Mutex<PgConnection>,
|
||||
providers: HashMap<String, Arc<dyn ScheduleProvider>>,
|
||||
env: AppEnv,
|
||||
fcm_client: Option<Mutex<FCMClient>>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
@@ -62,7 +58,6 @@ impl AppState {
|
||||
),
|
||||
env,
|
||||
providers,
|
||||
fcm_client: FCMClientData::new().await,
|
||||
};
|
||||
|
||||
if this.env.schedule.auto_update {
|
||||
@@ -92,13 +87,6 @@ impl AppState {
|
||||
pub fn get_env(&self) -> &AppEnv {
|
||||
&self.env
|
||||
}
|
||||
|
||||
pub async fn get_fcm_client(&'_ self) -> Option<MutexGuard<'_, FCMClient>> {
|
||||
match &self.fcm_client {
|
||||
Some(client) => Some(client.lock().await),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new object web::Data<AppState>.
|
||||
|
||||
Reference in New Issue
Block a user