Bläddra i källkod

check params using flowy-user entities

appflowy 3 år sedan
förälder
incheckning
d6c761917b

+ 3 - 3
backend/src/entities/token.rs

@@ -4,7 +4,7 @@ use crate::{
 };
 use chrono::{Duration, Local};
 use derive_more::{From, Into};
-use flowy_net::errors::{Code, ServerError};
+use flowy_net::errors::{ErrorCode, ServerError};
 use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
 use serde::{Deserialize, Serialize};
 
@@ -51,7 +51,7 @@ impl Token {
             &EncodingKey::from_secret(jwt_secret().as_ref()),
         )
         .map(Into::into)
-        .map_err(|err| ServerError::internal().with_msg(err))
+        .map_err(|err| ServerError::internal().context(err))
     }
 
     pub fn decode_token(token: &Self) -> Result<Claim, ServerError> {
@@ -61,6 +61,6 @@ impl Token {
             &Validation::new(DEFAULT_ALGORITHM),
         )
         .map(|data| Ok(data.claims))
-        .map_err(|err| ServerError::unauthorized().with_msg(err))?
+        .map_err(|err| ServerError::unauthorized().context(err))?
     }
 }

+ 3 - 3
backend/src/routers/utils.rs

@@ -1,7 +1,7 @@
 use crate::config::MAX_PAYLOAD_SIZE;
 use actix_web::web;
 use flowy_net::{
-    errors::{Code, ServerError},
+    errors::{ErrorCode, ServerError},
     response::*,
 };
 use futures::StreamExt;
@@ -23,11 +23,11 @@ pub fn parse_from_bytes<T: Message>(bytes: &[u8]) -> Result<T, ServerError> {
 pub async fn poll_payload(mut payload: web::Payload) -> Result<web::BytesMut, ServerError> {
     let mut body = web::BytesMut::new();
     while let Some(chunk) = payload.next().await {
-        let chunk = chunk.map_err(|err| ServerError::internal().with_msg(err))?;
+        let chunk = chunk.map_err(|err| ServerError::internal().context(err))?;
 
         if (body.len() + chunk.len()) > MAX_PAYLOAD_SIZE {
             return Err(ServerError {
-                code: Code::PayloadOverflow,
+                code: ErrorCode::PayloadOverflow,
                 msg: "Payload overflow".to_string(),
             });
         }

+ 15 - 8
backend/src/user_service/auth_service.rs

@@ -6,11 +6,12 @@ use actix_identity::Identity;
 use anyhow::Context;
 use chrono::Utc;
 use flowy_net::{
-    errors::{Code, ServerError},
+    errors::{ErrorCode, ServerError},
     response::FlowyResponse,
 };
 use flowy_user::{
     entities::{SignInResponse, SignUpResponse},
+    prelude::parser::{UserEmail, UserPassword},
     protobuf::{SignInParams, SignUpParams},
 };
 use sqlx::{Error, PgPool, Postgres, Transaction};
@@ -21,17 +22,23 @@ pub async fn sign_in(
     params: SignInParams,
     id: Identity,
 ) -> Result<FlowyResponse, ServerError> {
+    let email =
+        UserEmail::parse(params.email).map_err(|e| ServerError::params_invalid().context(e))?;
+    let password = UserPassword::parse(params.password)
+        .map_err(|e| ServerError::params_invalid().context(e))?;
+
     let mut transaction = pool
         .begin()
         .await
         .context("Failed to acquire a Postgres connection to sign in")?;
-    let user = read_user(&mut transaction, &params.email).await?;
+
+    let user = read_user(&mut transaction, &email.0).await?;
     transaction
         .commit()
         .await
         .context("Failed to commit SQL transaction to sign in.")?;
 
-    match verify_password(&params.password, &user.password) {
+    match verify_password(&password.0, &user.password) {
         Ok(true) => {
             let token = Token::create_token(&user)?;
             let data = SignInResponse {
@@ -43,7 +50,7 @@ pub async fn sign_in(
             id.remember(data.token.clone());
             FlowyResponse::success(data)
         },
-        _ => Err(ServerError::passwordNotMatch()),
+        _ => Err(ServerError::password_not_match()),
     }
 }
 
@@ -77,11 +84,11 @@ async fn is_email_exist(
         .bind(email)
         .fetch_optional(transaction)
         .await
-        .map_err(|err| ServerError::internal().with_msg(err))?;
+        .map_err(|err| ServerError::internal().context(err))?;
 
     match result {
         Some(_) => Err(ServerError {
-            code: Code::EmailAlreadyExists,
+            code: ErrorCode::EmailAlreadyExists,
             msg: format!("{} already exists", email),
         }),
         None => Ok(()),
@@ -96,7 +103,7 @@ async fn read_user(
         .bind(email)
         .fetch_one(transaction)
         .await
-        .map_err(|err| ServerError::internal().with_msg(err))?;
+        .map_err(|err| ServerError::internal().context(err))?;
 
     Ok(user)
 }
@@ -120,7 +127,7 @@ async fn insert_user(
     )
     .execute(transaction)
     .await
-    .map_err(|e| ServerError::internal().with_msg(e))?;
+    .map_err(|e| ServerError::internal().context(e))?;
 
     let data = SignUpResponse {
         uid: uuid.to_string(),

+ 3 - 3
backend/src/user_service/utils.rs

@@ -1,5 +1,5 @@
 use bcrypt::{hash, verify, BcryptError, DEFAULT_COST};
-use flowy_net::errors::{Code, ServerError};
+use flowy_net::errors::{ErrorCode, ServerError};
 use jsonwebtoken::Algorithm;
 
 pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() }
@@ -10,14 +10,14 @@ pub fn hash_password(plain: &str) -> Result<String, ServerError> {
         .and_then(|c| c.parse().ok())
         .unwrap_or(DEFAULT_COST);
 
-    hash(plain, hashing_cost).map_err(|e| ServerError::internal().with_msg(e))
+    hash(plain, hashing_cost).map_err(|e| ServerError::internal().context(e))
 }
 
 pub fn verify_password(source: &str, hash: &str) -> Result<bool, ServerError> {
     match verify(source, hash) {
         Ok(true) => Ok(true),
         _ => Err(ServerError {
-            code: Code::PasswordNotMatch,
+            code: ErrorCode::PasswordNotMatch,
             msg: "Username and password don't match".to_string(),
         }),
     }

+ 1 - 0
rust-lib/flowy-net/src/config.rs

@@ -4,4 +4,5 @@ pub const HOST: &'static str = "http://localhost:8000";
 
 lazy_static! {
     pub static ref SIGN_UP_URL: String = format!("{}/api/register", HOST);
+    pub static ref SIGN_IN_URL: String = format!("{}/api/auth", HOST);
 }

+ 12 - 9
rust-lib/flowy-net/src/errors.rs

@@ -7,7 +7,7 @@ use crate::response::FlowyResponse;
 
 #[derive(thiserror::Error, Debug, Serialize, Deserialize, Clone)]
 pub struct ServerError {
-    pub code: Code,
+    pub code: ErrorCode,
     pub msg: String,
 }
 
@@ -24,13 +24,14 @@ macro_rules! static_error {
 }
 
 impl ServerError {
-    static_error!(internal, Code::InternalError);
-    static_error!(http, Code::HttpError);
-    static_error!(payload_none, Code::PayloadUnexpectedNone);
-    static_error!(unauthorized, Code::Unauthorized);
-    static_error!(passwordNotMatch, Code::PasswordNotMatch);
-
-    pub fn with_msg<T: Debug>(mut self, error: T) -> Self {
+    static_error!(internal, ErrorCode::InternalError);
+    static_error!(http, ErrorCode::HttpError);
+    static_error!(payload_none, ErrorCode::PayloadUnexpectedNone);
+    static_error!(unauthorized, ErrorCode::Unauthorized);
+    static_error!(password_not_match, ErrorCode::PasswordNotMatch);
+    static_error!(params_invalid, ErrorCode::ParamsInvalid);
+
+    pub fn context<T: Debug>(mut self, error: T) -> Self {
         self.msg = format!("{:?}", error);
         self
     }
@@ -54,7 +55,7 @@ impl std::convert::From<&ServerError> for FlowyResponse {
 
 #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug, Clone, derive_more::Display)]
 #[repr(u16)]
-pub enum Code {
+pub enum ErrorCode {
     #[display(fmt = "Token is invalid")]
     InvalidToken       = 1,
     #[display(fmt = "Unauthorized")]
@@ -65,6 +66,8 @@ pub enum Code {
     PayloadSerdeFail   = 4,
     #[display(fmt = "Unexpected empty payload")]
     PayloadUnexpectedNone = 5,
+    #[display(fmt = "Params is invalid")]
+    ParamsInvalid      = 6,
 
     #[display(fmt = "Protobuf serde error")]
     ProtobufError      = 10,

+ 3 - 3
rust-lib/flowy-net/src/request/request.rs

@@ -1,5 +1,5 @@
 use crate::{
-    errors::{Code, ServerError},
+    errors::{ErrorCode, ServerError},
     response::FlowyResponse,
 };
 use bytes::Bytes;
@@ -83,7 +83,7 @@ impl HttpRequestBuilder {
         match data {
             None => {
                 let msg = format!("Request: {} receives unexpected empty body", self.url);
-                Err(ServerError::payload_none().with_msg(msg))
+                Err(ServerError::payload_none().context(msg))
             },
             Some(data) => Ok(T2::try_from(data)?),
         }
@@ -121,7 +121,7 @@ async fn get_response_data(original: Response) -> Result<Bytes, ServerError> {
             Some(error) => Err(error),
         }
     } else {
-        Err(ServerError::http().with_msg(original))
+        Err(ServerError::http().context(original))
     }
 }
 

+ 12 - 12
rust-lib/flowy-net/src/response/response.rs

@@ -1,4 +1,4 @@
-use crate::errors::{Code, ServerError};
+use crate::errors::{ErrorCode, ServerError};
 use bytes::Bytes;
 use serde::{Deserialize, Serialize};
 use std::{convert::TryInto, error::Error, fmt::Debug};
@@ -25,35 +25,35 @@ impl FlowyResponse {
 impl std::convert::From<protobuf::ProtobufError> for ServerError {
     fn from(err: protobuf::ProtobufError) -> Self {
         ServerError {
-            code: Code::ProtobufError,
+            code: ErrorCode::ProtobufError,
             msg: format!("{}", err),
         }
     }
 }
 
 impl std::convert::From<RecvError> for ServerError {
-    fn from(error: RecvError) -> Self { ServerError::internal().with_msg(error) }
+    fn from(error: RecvError) -> Self { ServerError::internal().context(error) }
 }
 
 impl std::convert::From<serde_json::Error> for ServerError {
     fn from(e: serde_json::Error) -> Self {
         let msg = format!("Serial error: {:?}", e);
         ServerError {
-            code: Code::SerdeError,
+            code: ErrorCode::SerdeError,
             msg,
         }
     }
 }
 
 impl std::convert::From<anyhow::Error> for ServerError {
-    fn from(error: anyhow::Error) -> Self { ServerError::internal().with_msg(error) }
+    fn from(error: anyhow::Error) -> Self { ServerError::internal().context(error) }
 }
 
 impl std::convert::From<reqwest::Error> for ServerError {
     fn from(error: reqwest::Error) -> Self {
         if error.is_timeout() {
             return ServerError {
-                code: Code::ConnectTimeout,
+                code: ErrorCode::ConnectTimeout,
                 msg: format!("{}", error),
             };
         }
@@ -62,22 +62,22 @@ impl std::convert::From<reqwest::Error> for ServerError {
             let hyper_error: Option<&hyper::Error> = error.source().unwrap().downcast_ref();
             return match hyper_error {
                 None => ServerError {
-                    code: Code::ConnectRefused,
+                    code: ErrorCode::ConnectRefused,
                     msg: format!("{:?}", error),
                 },
                 Some(hyper_error) => {
-                    let mut code = Code::InternalError;
+                    let mut code = ErrorCode::InternalError;
                     let msg = format!("{}", error);
                     if hyper_error.is_closed() {
-                        code = Code::ConnectClose;
+                        code = ErrorCode::ConnectClose;
                     }
 
                     if hyper_error.is_connect() {
-                        code = Code::ConnectRefused;
+                        code = ErrorCode::ConnectRefused;
                     }
 
                     if hyper_error.is_canceled() {
-                        code = Code::ConnectCancel;
+                        code = ErrorCode::ConnectCancel;
                     }
 
                     if hyper_error.is_timeout() {}
@@ -89,7 +89,7 @@ impl std::convert::From<reqwest::Error> for ServerError {
 
         let msg = format!("{:?}", error);
         ServerError {
-            code: Code::ProtobufError,
+            code: ErrorCode::ProtobufError,
             msg,
         }
     }

+ 1 - 1
rust-lib/flowy-user/src/entities/mod.rs

@@ -2,7 +2,7 @@ pub use sign_in::*;
 pub use sign_up::*;
 pub use user_detail::*;
 pub use user_update::*;
-mod parser;
+pub mod parser;
 mod sign_in;
 pub mod sign_up;
 mod user_detail;

+ 5 - 0
rust-lib/flowy-user/src/errors.rs

@@ -63,6 +63,7 @@ pub enum UserErrCode {
         fmt = "Password should contain a minimum of 6 characters with 1 special 1 letter and 1 numeric"
     )]
     PasswordFormatInvalid = 33,
+
     #[display(fmt = "User name is too long")]
     UserNameTooLong      = 40,
     #[display(fmt = "User name contain forbidden characters")]
@@ -83,6 +84,10 @@ pub enum UserErrCode {
     NetworkError         = 100,
 }
 
+impl UserErrCode {
+    pub fn to_string(&self) -> String { format!("{}", self) }
+}
+
 impl std::default::Default for UserErrCode {
     fn default() -> Self { UserErrCode::Unknown }
 }

+ 3 - 10
rust-lib/flowy-user/src/services/user/user_server.rs

@@ -4,7 +4,7 @@ use crate::{
 };
 
 use flowy_net::{
-    config::SIGN_UP_URL,
+    config::*,
     future::ResultFuture,
     request::{http_post, HttpRequestBuilder},
 };
@@ -35,15 +35,8 @@ impl UserServer for UserServerImpl {
         ResultFuture::new(async move { user_sign_up(params, SIGN_UP_URL.as_ref()).await })
     }
 
-    fn sign_in(&self, _params: SignInParams) -> ResultFuture<SignInResponse, UserError> {
-        // let user_id = params.email.clone();
-        // Ok(UserTable::new(
-        //     user_id,
-        //     "".to_owned(),
-        //     params.email,
-        //     params.password,
-        // ))
-        unimplemented!()
+    fn sign_in(&self, params: SignInParams) -> ResultFuture<SignInResponse, UserError> {
+        ResultFuture::new(async move { user_sign_in(params, SIGN_IN_URL.as_ref()).await })
     }
 
     fn sign_out(&self, _user_id: &str) -> ResultFuture<(), UserError> {