use std::collections::HashMap; use std::io::SeekFrom; use std::ptr::null; use actix_identity::Identity; use actix_web::{HttpResponse, post, web}; use chrono::{FixedOffset, Utc}; use sea_orm::ActiveValue::NotSet; use serde::{Deserialize, Serialize}; use crate::api::JsonResponse; use crate::AppState; use crate::entity::{doc_info, tag_info}; use crate::entity::user_info::Model; use crate::errors::{AppError, UserError}; use crate::service::user_info::Mutation; use crate::service::user_info::Query; fn now()->chrono::DateTime{ Utc::now().with_timezone(&FixedOffset::east_opt(3600*8).unwrap()) } pub(crate) fn create_auth_token(user: &Model) -> u64 { use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, }; let mut hasher = DefaultHasher::new(); user.hash(&mut hasher); hasher.finish() } #[derive(Clone, Debug, Serialize, Deserialize)] pub(crate) struct LoginParams { pub(crate) email: String, pub(crate) password: String, } #[post("/v1.0/login")] async fn login( data: web::Data, identity: Identity, input: web::Json ) -> Result { match Query::login(&data.conn, &input.email, &input.password).await? { Some(user) => { let _ = Mutation::update_login_status(user.uid,&data.conn).await?; let token = create_auth_token(&user).to_string(); identity.remember(token.clone()); let json_response = JsonResponse { code: 200, err: "".to_owned(), data: token.clone(), }; Ok(HttpResponse::Ok() .content_type("application/json") .append_header(("X-Auth-Token", token)) .body(serde_json::to_string(&json_response)?)) } None => Err(UserError::LoginFailed.into()) } } #[post("/v1.0/register")] async fn register(model: web::Json, data: web::Data) -> Result { let mut result = HashMap::new(); let u = Query::find_user_infos(&data.conn, &model.email).await?; if let Some(_) = u { let json_response = JsonResponse { code: 500, err: "Email registered!".to_owned(), data: (), }; return Ok(HttpResponse::Ok() .content_type("application/json") .body(serde_json::to_string(&json_response)?)); } let usr = Mutation::create_user(&data.conn, &model).await?; result.insert("uid", usr.uid.clone().unwrap()); crate::service::doc_info::Mutation::create_doc_info(&data.conn, doc_info::Model{ did:Default::default(), uid: usr.uid.clone().unwrap(), doc_name: "/".into(), size: 0, location: "".into(), r#type: "folder".to_string(), created_at: now(), updated_at: now(), is_deleted:Default::default(), }).await?; let tnm = vec!["视频","图片","音乐","文档"]; let tregx = vec![ ".*\\.(mpg|mpeg|avi|rm|rmvb|mov|wmv|asf|dat|asx|wvx|mpe|mpa)", ".*\\.(png|tif|gif|pcx|tga|exif|fpx|svg|psd|cdr|pcd|dxf|ufo|eps|ai|raw|WMF|webp|avif|apng)", ".*\\.(WAV|FLAC|APE|ALAC|WavPack|WV|MP3|AAC|Ogg|Vorbis|Opus)", ".*\\.(pdf|doc|ppt|yml|xml|htm|json|csv|txt|ini|xsl|wps|rtf|hlp)" ]; for i in 0..4 { crate::service::tag_info::Mutation::create_tag(&data.conn, tag_info::Model{ tid: Default::default(), uid: usr.uid.clone().unwrap(), tag_name: tnm[i].to_owned(), regx: tregx[i].to_owned(), color: (i+1).to_owned() as i16, icon: (i+1).to_owned() as i16, folder_id: 0, created_at: Default::default(), updated_at: Default::default(), }).await?; } let json_response = JsonResponse { code: 200, err: "".to_owned(), data: result, }; Ok(HttpResponse::Ok() .content_type("application/json") .body(serde_json::to_string(&json_response)?)) } #[post("/v1.0/setting")] async fn setting(model: web::Json, data: web::Data) -> Result { let _ = Mutation::update_user_by_id(&data.conn, &model).await?; let json_response = JsonResponse { code: 200, err: "".to_owned(), data: (), }; Ok(HttpResponse::Ok() .content_type("application/json") .body(serde_json::to_string(&json_response)?)) }