From 55454c5bece51b1fdbd3dbf3a9ed357a24cf52cf Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 10 Jul 2021 16:27:20 +0800 Subject: [PATCH] save user info to database after sign up --- .idea/appflowy_client.iml | 1 + .../flowy_sdk/lib/protobuf/user.pb.dart | 44 ++++++--- .../flowy_sdk/lib/protobuf/user.pbjson.dart | 7 +- rust-lib/Cargo.toml | 5 +- rust-lib/dart-ffi/src/lib.rs | 10 +- rust-lib/flowy-database/src/errors.rs | 16 ---- rust-lib/flowy-database/src/lib.rs | 26 +++-- rust-lib/flowy-dispatch/src/data.rs | 8 +- rust-lib/flowy-dispatch/src/dispatch.rs | 4 +- rust-lib/flowy-dispatch/src/error/mod.rs | 3 - .../src/{error/error.rs => errors/errors.rs} | 36 ++++--- rust-lib/flowy-dispatch/src/errors/mod.rs | 3 + rust-lib/flowy-dispatch/src/lib.rs | 6 +- rust-lib/flowy-dispatch/src/module/data.rs | 11 ++- rust-lib/flowy-dispatch/src/module/module.rs | 20 ++-- .../flowy-dispatch/src/request/request.rs | 16 ++-- .../flowy-dispatch/src/response/builder.rs | 6 +- .../flowy-dispatch/src/response/responder.rs | 4 +- .../flowy-dispatch/src/response/response.rs | 6 +- .../flowy-dispatch/src/service/handler.rs | 14 +-- rust-lib/flowy-infra/Cargo.toml | 9 ++ rust-lib/flowy-infra/src/lib.rs | 1 + rust-lib/flowy-sdk/src/module.rs | 8 +- rust-lib/flowy-sqlite/src/database.rs | 9 +- rust-lib/flowy-sqlite/src/pool.rs | 7 +- rust-lib/flowy-user/Cargo.toml | 3 + rust-lib/flowy-user/src/domain/mod.rs | 3 +- rust-lib/flowy-user/src/domain/tables/mod.rs | 3 + .../src/domain/tables/user_table.rs | 30 ++++++ rust-lib/flowy-user/src/domain/user/mod.rs | 2 - rust-lib/flowy-user/src/domain/user/user.rs | 24 ----- .../flowy-user/src/domain/user_session.rs | 48 ---------- rust-lib/flowy-user/src/errors.rs | 39 +++++--- rust-lib/flowy-user/src/handlers/auth.rs | 9 +- rust-lib/flowy-user/src/lib.rs | 6 +- rust-lib/flowy-user/src/module.rs | 6 +- .../flowy-user/src/protobuf/model/user.rs | 94 ++++++++++++++----- .../flowy-user/src/protobuf/proto/user.proto | 7 +- .../user_db.rs => services/database.rs} | 32 ++++--- rust-lib/flowy-user/src/services/mod.rs | 3 + rust-lib/flowy-user/src/services/register.rs | 22 +++++ .../src/services/user_session/builder.rs | 23 +++++ .../src/services/user_session/mod.rs | 5 + .../src/services/user_session/user_session.rs | 86 +++++++++++++++++ .../tests/{auth.rs => auth_test.rs} | 8 +- rust-lib/flowy-user/tests/main.rs | 2 +- 46 files changed, 458 insertions(+), 277 deletions(-) delete mode 100644 rust-lib/flowy-database/src/errors.rs delete mode 100644 rust-lib/flowy-dispatch/src/error/mod.rs rename rust-lib/flowy-dispatch/src/{error/error.rs => errors/errors.rs} (77%) create mode 100644 rust-lib/flowy-dispatch/src/errors/mod.rs create mode 100644 rust-lib/flowy-infra/Cargo.toml create mode 100644 rust-lib/flowy-infra/src/lib.rs create mode 100644 rust-lib/flowy-user/src/domain/tables/mod.rs create mode 100644 rust-lib/flowy-user/src/domain/tables/user_table.rs delete mode 100644 rust-lib/flowy-user/src/domain/user/user.rs delete mode 100644 rust-lib/flowy-user/src/domain/user_session.rs rename rust-lib/flowy-user/src/{domain/user_db.rs => services/database.rs} (65%) create mode 100644 rust-lib/flowy-user/src/services/mod.rs create mode 100644 rust-lib/flowy-user/src/services/register.rs create mode 100644 rust-lib/flowy-user/src/services/user_session/builder.rs create mode 100644 rust-lib/flowy-user/src/services/user_session/mod.rs create mode 100644 rust-lib/flowy-user/src/services/user_session/user_session.rs rename rust-lib/flowy-user/tests/{auth.rs => auth_test.rs} (95%) diff --git a/.idea/appflowy_client.iml b/.idea/appflowy_client.iml index 5797d19e1e..d20a79f9a5 100644 --- a/.idea/appflowy_client.iml +++ b/.idea/appflowy_client.iml @@ -18,6 +18,7 @@ + diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/user.pb.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/user.pb.dart index a719e1486a..87ca30e92c 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/user.pb.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/user.pb.dart @@ -11,19 +11,24 @@ import 'package:protobuf/protobuf.dart' as $pb; class User extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'User', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password') + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password') ..hasRequiredFields = false ; User._() : super(); factory User({ + $core.String? id, $core.String? name, $core.String? email, $core.String? password, }) { final _result = create(); + if (id != null) { + _result.id = id; + } if (name != null) { _result.name = name; } @@ -57,30 +62,39 @@ class User extends $pb.GeneratedMessage { static User? _defaultInstance; @$pb.TagNumber(1) - $core.String get name => $_getSZ(0); + $core.String get id => $_getSZ(0); @$pb.TagNumber(1) - set name($core.String v) { $_setString(0, v); } + set id($core.String v) { $_setString(0, v); } @$pb.TagNumber(1) - $core.bool hasName() => $_has(0); + $core.bool hasId() => $_has(0); @$pb.TagNumber(1) - void clearName() => clearField(1); + void clearId() => clearField(1); @$pb.TagNumber(2) - $core.String get email => $_getSZ(1); + $core.String get name => $_getSZ(1); @$pb.TagNumber(2) - set email($core.String v) { $_setString(1, v); } + set name($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasEmail() => $_has(1); + $core.bool hasName() => $_has(1); @$pb.TagNumber(2) - void clearEmail() => clearField(2); + void clearName() => clearField(2); @$pb.TagNumber(3) - $core.String get password => $_getSZ(2); + $core.String get email => $_getSZ(2); @$pb.TagNumber(3) - set password($core.String v) { $_setString(2, v); } + set email($core.String v) { $_setString(2, v); } @$pb.TagNumber(3) - $core.bool hasPassword() => $_has(2); + $core.bool hasEmail() => $_has(2); @$pb.TagNumber(3) - void clearPassword() => clearField(3); + void clearEmail() => clearField(3); + + @$pb.TagNumber(4) + $core.String get password => $_getSZ(3); + @$pb.TagNumber(4) + set password($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasPassword() => $_has(3); + @$pb.TagNumber(4) + void clearPassword() => clearField(4); } diff --git a/app_flowy/packages/flowy_sdk/lib/protobuf/user.pbjson.dart b/app_flowy/packages/flowy_sdk/lib/protobuf/user.pbjson.dart index d3bd749d12..36c34d6e0d 100644 --- a/app_flowy/packages/flowy_sdk/lib/protobuf/user.pbjson.dart +++ b/app_flowy/packages/flowy_sdk/lib/protobuf/user.pbjson.dart @@ -9,9 +9,10 @@ import 'dart:core' as $core; const User$json = const { '1': 'User', '2': const [ - const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, - const {'1': 'email', '3': 2, '4': 1, '5': 9, '10': 'email'}, - const {'1': 'password', '3': 3, '4': 1, '5': 9, '10': 'password'}, + const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'}, + const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'}, + const {'1': 'email', '3': 3, '4': 1, '5': 9, '10': 'email'}, + const {'1': 'password', '3': 4, '4': 1, '5': 9, '10': 'password'}, ], }; diff --git a/rust-lib/Cargo.toml b/rust-lib/Cargo.toml index 8cb3a7822f..477f04ecca 100644 --- a/rust-lib/Cargo.toml +++ b/rust-lib/Cargo.toml @@ -8,8 +8,9 @@ members = [ "flowy-ast", "flowy-derive", "flowy-test", - "flowy-sqlite", - "flowy-database", + "flowy-sqlite", + "flowy-database", + "flowy-infra", ] [profile.dev] diff --git a/rust-lib/dart-ffi/src/lib.rs b/rust-lib/dart-ffi/src/lib.rs index 57878432e9..f492acf5cf 100644 --- a/rust-lib/dart-ffi/src/lib.rs +++ b/rust-lib/dart-ffi/src/lib.rs @@ -36,8 +36,8 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) { let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into(); log::trace!( "[FFI]: {} Async Event: {:?} with {} port", - &request.id(), - &request.event(), + &request.id, + &request.event, port ); @@ -50,11 +50,7 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) { #[no_mangle] pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 { let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into(); - log::trace!( - "[FFI]: {} Sync Event: {:?}", - &request.id(), - &request.event(), - ); + log::trace!("[FFI]: {} Sync Event: {:?}", &request.id, &request.event,); let _response = EventDispatch::sync_send(request); // FFIResponse { } diff --git a/rust-lib/flowy-database/src/errors.rs b/rust-lib/flowy-database/src/errors.rs deleted file mode 100644 index 0688df0fb5..0000000000 --- a/rust-lib/flowy-database/src/errors.rs +++ /dev/null @@ -1,16 +0,0 @@ -use flowy_sqlite::Error; -use std::io; - -#[derive(Debug)] -pub enum DataBaseError { - InitError(String), - IOError(String), -} - -impl std::convert::From for DataBaseError { - fn from(error: flowy_sqlite::Error) -> Self { DataBaseError::InitError(format!("{:?}", error)) } -} - -impl std::convert::From for DataBaseError { - fn from(error: io::Error) -> Self { DataBaseError::IOError(format!("{:?}", error)) } -} diff --git a/rust-lib/flowy-database/src/lib.rs b/rust-lib/flowy-database/src/lib.rs index e011a1aa71..ce3a43f690 100644 --- a/rust-lib/flowy-database/src/lib.rs +++ b/rust-lib/flowy-database/src/lib.rs @@ -1,29 +1,37 @@ -mod errors; -mod schema; +pub mod schema; #[macro_use] extern crate diesel; +pub use diesel::*; + #[macro_use] extern crate diesel_derives; +pub use diesel_derives::*; + #[macro_use] extern crate diesel_migrations; -pub use errors::*; -pub use flowy_sqlite::{DBConnection, DataBase}; +pub use flowy_sqlite::{DBConnection, Database}; use diesel_migrations::*; -use flowy_sqlite::PoolConfig; -use std::path::Path; +use flowy_sqlite::{Error, PoolConfig}; +use std::{io, path::Path}; embed_migrations!("../flowy-database/migrations/"); pub const DB_NAME: &str = "flowy-database.db"; -pub fn init(storage_path: &str) -> Result { +pub fn init(storage_path: &str) -> Result { if !Path::new(storage_path).exists() { std::fs::create_dir_all(storage_path)?; } - let pool_config = PoolConfig::default(); - let database = DataBase::new(storage_path, DB_NAME, pool_config)?; + let database = Database::new(storage_path, DB_NAME, pool_config).map_err(as_io_error)?; + let conn = database.get_connection().map_err(as_io_error)?; + embedded_migrations::run(&*conn); Ok(database) } + +fn as_io_error(e: Error) -> io::Error { + let msg = format!("{:?}", e); + io::Error::new(io::ErrorKind::NotConnected, msg) +} diff --git a/rust-lib/flowy-dispatch/src/data.rs b/rust-lib/flowy-dispatch/src/data.rs index 961caec70c..8167e73421 100644 --- a/rust-lib/flowy-dispatch/src/data.rs +++ b/rust-lib/flowy-dispatch/src/data.rs @@ -1,5 +1,5 @@ use crate::{ - error::{InternalError, SystemError}, + errors::{DispatchError, InternalError}, request::{unexpected_none_payload, EventRequest, FromRequest, Payload}, response::{EventResponse, Responder, ResponseBuilder, ToBytes}, util::ready::{ready, Ready}, @@ -53,8 +53,8 @@ impl FromRequest for Data where T: FromBytes + 'static, { - type Error = SystemError; - type Future = Ready>; + type Error = DispatchError; + type Future = Ready>; #[inline] fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future { @@ -76,7 +76,7 @@ where match self.into_inner().into_bytes() { Ok(bytes) => ResponseBuilder::Ok().data(bytes.to_vec()).build(), Err(e) => { - let system_err: SystemError = InternalError::new(format!("{:?}", e)).into(); + let system_err: DispatchError = InternalError::new(format!("{:?}", e)).into(); system_err.into() }, } diff --git a/rust-lib/flowy-dispatch/src/dispatch.rs b/rust-lib/flowy-dispatch/src/dispatch.rs index bc9cd31059..d2cc1a58bf 100644 --- a/rust-lib/flowy-dispatch/src/dispatch.rs +++ b/rust-lib/flowy-dispatch/src/dispatch.rs @@ -1,5 +1,5 @@ use crate::{ - error::{Error, InternalError, SystemError}, + errors::{DispatchError, Error, InternalError}, module::{as_module_map, Module, ModuleMap, ModuleRequest}, response::EventResponse, service::{Service, ServiceFactory}, @@ -129,7 +129,7 @@ pub(crate) struct DispatchService { impl Service for DispatchService { type Response = EventResponse; - type Error = SystemError; + type Error = DispatchError; type Future = BoxFuture<'static, Result>; #[cfg_attr( diff --git a/rust-lib/flowy-dispatch/src/error/mod.rs b/rust-lib/flowy-dispatch/src/error/mod.rs deleted file mode 100644 index 3925f93ff7..0000000000 --- a/rust-lib/flowy-dispatch/src/error/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod error; - -pub use error::*; diff --git a/rust-lib/flowy-dispatch/src/error/error.rs b/rust-lib/flowy-dispatch/src/errors/errors.rs similarity index 77% rename from rust-lib/flowy-dispatch/src/error/error.rs rename to rust-lib/flowy-dispatch/src/errors/errors.rs index a0fa6c6e7b..795cb6280b 100644 --- a/rust-lib/flowy-dispatch/src/error/error.rs +++ b/rust-lib/flowy-dispatch/src/errors/errors.rs @@ -8,45 +8,43 @@ use std::{fmt, option::NoneError}; use tokio::sync::mpsc::error::SendError; pub trait Error: fmt::Debug + fmt::Display + DynClone + Send + Sync { - fn status_code(&self) -> StatusCode; - - fn as_response(&self) -> EventResponse { EventResponse::new(self.status_code()) } + fn as_response(&self) -> EventResponse { EventResponse::new(StatusCode::Err) } } dyn_clone::clone_trait_object!(Error); -impl From for SystemError { - fn from(err: T) -> SystemError { - SystemError { +impl From for DispatchError { + fn from(err: T) -> DispatchError { + DispatchError { inner: Box::new(err), } } } #[derive(Clone)] -pub struct SystemError { +pub struct DispatchError { inner: Box, } -impl SystemError { +impl DispatchError { pub fn inner_error(&self) -> &dyn Error { self.inner.as_ref() } } -impl fmt::Display for SystemError { +impl fmt::Display for DispatchError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.inner, f) } } -impl fmt::Debug for SystemError { +impl fmt::Debug for DispatchError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", &self.inner) } } -impl std::error::Error for SystemError { +impl std::error::Error for DispatchError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } fn cause(&self) -> Option<&dyn std::error::Error> { None } } -impl From> for SystemError { +impl From> for DispatchError { fn from(err: SendError) -> Self { InternalError { inner: format!("{}", err), @@ -55,7 +53,7 @@ impl From> for SystemError { } } -impl From for SystemError { +impl From for DispatchError { fn from(s: NoneError) -> Self { InternalError { inner: format!("Unexpected none: {:?}", s), @@ -64,16 +62,16 @@ impl From for SystemError { } } -impl From for SystemError { +impl From for DispatchError { fn from(s: String) -> Self { InternalError { inner: s }.into() } } -impl From for EventResponse { - fn from(err: SystemError) -> Self { err.inner_error().as_response() } +impl From for EventResponse { + fn from(err: DispatchError) -> Self { err.inner_error().as_response() } } #[derive(Clone)] -pub struct InternalError { +pub(crate) struct InternalError { inner: T, } @@ -99,8 +97,6 @@ impl Error for InternalError where T: fmt::Debug + fmt::Display + 'static + Clone + Send + Sync, { - fn status_code(&self) -> StatusCode { StatusCode::Err } - fn as_response(&self) -> EventResponse { let error = InternalError { inner: format!("{}", self.inner), @@ -111,7 +107,7 @@ where } } -impl Serialize for SystemError { +impl Serialize for DispatchError { fn serialize(&self, serializer: S) -> Result<::Ok, ::Error> where S: Serializer, diff --git a/rust-lib/flowy-dispatch/src/errors/mod.rs b/rust-lib/flowy-dispatch/src/errors/mod.rs new file mode 100644 index 0000000000..852f5c0f5e --- /dev/null +++ b/rust-lib/flowy-dispatch/src/errors/mod.rs @@ -0,0 +1,3 @@ +mod errors; + +pub use errors::*; diff --git a/rust-lib/flowy-dispatch/src/lib.rs b/rust-lib/flowy-dispatch/src/lib.rs index 0b282287f5..25947f8b68 100644 --- a/rust-lib/flowy-dispatch/src/lib.rs +++ b/rust-lib/flowy-dispatch/src/lib.rs @@ -1,6 +1,6 @@ #![feature(try_trait)] -mod error; +mod errors; mod module; mod request; mod response; @@ -11,6 +11,8 @@ mod data; mod dispatch; mod system; +pub use errors::Error; + pub mod prelude { - pub use crate::{data::*, dispatch::*, error::*, module::*, request::*, response::*}; + pub use crate::{data::*, dispatch::*, errors::*, module::*, request::*, response::*}; } diff --git a/rust-lib/flowy-dispatch/src/module/data.rs b/rust-lib/flowy-dispatch/src/module/data.rs index 59a8ece442..552decc122 100644 --- a/rust-lib/flowy-dispatch/src/module/data.rs +++ b/rust-lib/flowy-dispatch/src/module/data.rs @@ -1,5 +1,5 @@ use crate::{ - error::{InternalError, SystemError}, + errors::{DispatchError, InternalError}, request::{payload::Payload, EventRequest, FromRequest}, util::ready::{ready, Ready}, }; @@ -43,15 +43,18 @@ impl FromRequest for ModuleData where T: ?Sized + Send + Sync + 'static, { - type Error = SystemError; - type Future = Ready>; + type Error = DispatchError; + type Future = Ready>; #[inline] fn from_request(req: &EventRequest, _: &mut Payload) -> Self::Future { if let Some(data) = req.module_data::>() { ready(Ok(data.clone())) } else { - let msg = format!("Failed to get the module data(type: {})", type_name::()); + let msg = format!( + "Failed to get the module data of type: {}", + type_name::() + ); log::error!("{}", msg,); ready(Err(InternalError::new(msg).into())) } diff --git a/rust-lib/flowy-dispatch/src/module/module.rs b/rust-lib/flowy-dispatch/src/module/module.rs index b4e74b3c89..a715e93b53 100644 --- a/rust-lib/flowy-dispatch/src/module/module.rs +++ b/rust-lib/flowy-dispatch/src/module/module.rs @@ -12,7 +12,7 @@ use futures_core::ready; use pin_project::pin_project; use crate::{ - error::{InternalError, SystemError}, + errors::{DispatchError, InternalError}, module::{container::ModuleDataMap, ModuleData}, request::{payload::Payload, EventRequest, FromRequest}, response::{EventResponse, Responder}, @@ -51,7 +51,8 @@ impl std::convert::From for Event { fn from(t: T) -> Self { Event(format!("{}", t)) } } -pub type EventServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, SystemError>; +pub type EventServiceFactory = + BoxServiceFactory<(), ServiceRequest, ServiceResponse, DispatchError>; pub struct Module { pub name: String, @@ -111,8 +112,8 @@ impl Module { #[derive(Debug)] pub struct ModuleRequest { - pub(crate) id: String, - pub(crate) event: Event, + pub id: String, + pub event: Event, pub(crate) payload: Payload, } @@ -145,7 +146,7 @@ impl std::fmt::Display for ModuleRequest { impl ServiceFactory for Module { type Response = EventResponse; - type Error = SystemError; + type Error = DispatchError; type Service = BoxService; type Context = (); type Future = BoxFuture<'static, Result>; @@ -171,7 +172,7 @@ pub struct ModuleService { impl Service for ModuleService { type Response = EventResponse; - type Error = SystemError; + type Error = DispatchError; type Future = BoxFuture<'static, Result>; fn call(&self, request: ModuleRequest) -> Self::Future { @@ -196,17 +197,14 @@ impl Service for ModuleService { } } -// type BoxModuleService = BoxService; - #[pin_project] pub struct ModuleServiceFuture { #[pin] - fut: BoxFuture<'static, Result>, + fut: BoxFuture<'static, Result>, } impl Future for ModuleServiceFuture { - type Output = Result; + type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { diff --git a/rust-lib/flowy-dispatch/src/request/request.rs b/rust-lib/flowy-dispatch/src/request/request.rs index 805f12492c..0d0b2c93ee 100644 --- a/rust-lib/flowy-dispatch/src/request/request.rs +++ b/rust-lib/flowy-dispatch/src/request/request.rs @@ -1,7 +1,7 @@ use std::future::Future; use crate::{ - error::{InternalError, SystemError}, + errors::{DispatchError, InternalError}, module::{Event, ModuleDataMap}, request::payload::Payload, util::ready::{ready, Ready}, @@ -48,7 +48,7 @@ impl EventRequest { } pub trait FromRequest: Sized { - type Error: Into; + type Error: Into; type Future: Future>; fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future; @@ -56,15 +56,15 @@ pub trait FromRequest: Sized { #[doc(hidden)] impl FromRequest for () { - type Error = SystemError; - type Future = Ready>; + type Error = DispatchError; + type Future = Ready>; fn from_request(_req: &EventRequest, _payload: &mut Payload) -> Self::Future { ready(Ok(())) } } #[doc(hidden)] impl FromRequest for String { - type Error = SystemError; + type Error = DispatchError; type Future = Ready>; fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future { @@ -75,7 +75,7 @@ impl FromRequest for String { } } -pub fn unexpected_none_payload(request: &EventRequest) -> SystemError { +pub fn unexpected_none_payload(request: &EventRequest) -> DispatchError { log::warn!("{:?} expected payload", &request.event); InternalError::new("Expected payload").into() } @@ -85,7 +85,7 @@ impl FromRequest for Result where T: FromRequest, { - type Error = SystemError; + type Error = DispatchError; type Future = FromRequestFuture; fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future { @@ -105,7 +105,7 @@ impl Future for FromRequestFuture where Fut: Future>, { - type Output = Result, SystemError>; + type Output = Result, DispatchError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); diff --git a/rust-lib/flowy-dispatch/src/response/builder.rs b/rust-lib/flowy-dispatch/src/response/builder.rs index 6834529593..abfe55184a 100644 --- a/rust-lib/flowy-dispatch/src/response/builder.rs +++ b/rust-lib/flowy-dispatch/src/response/builder.rs @@ -1,5 +1,5 @@ use crate::{ - error::SystemError, + errors::DispatchError, request::Payload, response::{EventResponse, StatusCode}, }; @@ -14,7 +14,7 @@ macro_rules! static_response { pub struct ResponseBuilder { pub payload: T, pub status: StatusCode, - pub error: Option, + pub error: Option, } impl ResponseBuilder { @@ -31,7 +31,7 @@ impl ResponseBuilder { self } - pub fn error(mut self, error: SystemError) -> Self { + pub fn error(mut self, error: DispatchError) -> Self { self.error = Some(error); self } diff --git a/rust-lib/flowy-dispatch/src/response/responder.rs b/rust-lib/flowy-dispatch/src/response/responder.rs index 7acbba0266..8a2bacdd53 100644 --- a/rust-lib/flowy-dispatch/src/response/responder.rs +++ b/rust-lib/flowy-dispatch/src/response/responder.rs @@ -1,5 +1,5 @@ #[allow(unused_imports)] -use crate::error::{InternalError, SystemError}; +use crate::errors::{DispatchError, InternalError}; use crate::{ request::EventRequest, response::{EventResponse, ResponseBuilder}, @@ -28,7 +28,7 @@ impl_responder!(Bytes); impl Responder for Result where T: Responder, - E: Into, + E: Into, { fn respond_to(self, request: &EventRequest) -> EventResponse { match self { diff --git a/rust-lib/flowy-dispatch/src/response/response.rs b/rust-lib/flowy-dispatch/src/response/response.rs index f245026bf4..edc6e63789 100644 --- a/rust-lib/flowy-dispatch/src/response/response.rs +++ b/rust-lib/flowy-dispatch/src/response/response.rs @@ -1,6 +1,6 @@ use crate::{ data::Data, - error::SystemError, + errors::DispatchError, request::{EventRequest, Payload}, response::Responder, }; @@ -19,7 +19,7 @@ pub struct EventResponse { #[derivative(Debug = "ignore")] pub payload: Payload, pub status_code: StatusCode, - pub error: Option, + pub error: Option, } impl EventResponse { @@ -58,7 +58,7 @@ pub type ResponseResult = std::result::Result, E>; pub fn response_ok(data: T) -> Result, E> where - E: Into, + E: Into, { Ok(Data(data)) } diff --git a/rust-lib/flowy-dispatch/src/service/handler.rs b/rust-lib/flowy-dispatch/src/service/handler.rs index 9524ef4469..d756c43236 100644 --- a/rust-lib/flowy-dispatch/src/service/handler.rs +++ b/rust-lib/flowy-dispatch/src/service/handler.rs @@ -9,7 +9,7 @@ use futures_core::ready; use pin_project::pin_project; use crate::{ - error::SystemError, + errors::DispatchError, request::{payload::Payload, EventRequest, FromRequest}, response::{EventResponse, Responder}, service::{Service, ServiceFactory, ServiceRequest, ServiceResponse}, @@ -73,7 +73,7 @@ where R::Output: Responder, { type Response = ServiceResponse; - type Error = SystemError; + type Error = DispatchError; type Service = Self; type Context = (); type Future = Ready>; @@ -89,7 +89,7 @@ where R::Output: Responder, { type Response = ServiceResponse; - type Error = SystemError; + type Error = DispatchError; type Future = HandlerServiceFuture; fn call(&self, req: ServiceRequest) -> Self::Future { @@ -118,7 +118,7 @@ where R: Future + Sync + Send, R::Output: Responder, { - type Output = Result; + type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { @@ -132,7 +132,7 @@ where }, Err(err) => { let req = req.take().unwrap(); - let system_err: SystemError = err.into(); + let system_err: DispatchError = err.into(); let res: EventResponse = system_err.into(); return Poll::Ready(Ok(ServiceResponse::new(req, res))); }, @@ -175,7 +175,7 @@ macro_rules! tuple_from_req ({$tuple_type:ident, $(($n:tt, $T:ident)),+} => { #[allow(unused_parens)] impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+) { - type Error = SystemError; + type Error = DispatchError; type Future = $tuple_type<$($T),+>; fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future { @@ -196,7 +196,7 @@ macro_rules! tuple_from_req ({$tuple_type:ident, $(($n:tt, $T:ident)),+} => { impl<$($T: FromRequest),+> Future for $tuple_type<$($T),+> { - type Output = Result<($($T,)+), SystemError>; + type Output = Result<($($T,)+), DispatchError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); diff --git a/rust-lib/flowy-infra/Cargo.toml b/rust-lib/flowy-infra/Cargo.toml new file mode 100644 index 0000000000..5588b36d0b --- /dev/null +++ b/rust-lib/flowy-infra/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "flowy-infra" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +uuid = { version = "0.8", features = ["serde", "v4"] } \ No newline at end of file diff --git a/rust-lib/flowy-infra/src/lib.rs b/rust-lib/flowy-infra/src/lib.rs new file mode 100644 index 0000000000..802948d07d --- /dev/null +++ b/rust-lib/flowy-infra/src/lib.rs @@ -0,0 +1 @@ +pub fn uuid() -> String { uuid::Uuid::new_v4().to_string() } diff --git a/rust-lib/flowy-sdk/src/module.rs b/rust-lib/flowy-sdk/src/module.rs index 3426eb85f1..f209360a48 100644 --- a/rust-lib/flowy-sdk/src/module.rs +++ b/rust-lib/flowy-sdk/src/module.rs @@ -1,5 +1,5 @@ use flowy_dispatch::prelude::Module; -use flowy_user::prelude::user_session::{UserSession, UserSessionConfig}; +use flowy_user::prelude::{UserSession, UserSessionBuilder, UserSessionConfig}; use std::sync::Arc; pub struct ModuleConfig { @@ -7,8 +7,6 @@ pub struct ModuleConfig { } pub fn build_modules(config: ModuleConfig) -> Vec { - let user_config = UserSessionConfig::new(&config.root); - let user_session = Arc::new(UserSession::new(user_config)); - - vec![flowy_user::module::create(user_session)] + let user_session = UserSessionBuilder::new().root_dir(&config.root).build(); + vec![flowy_user::module::create(Arc::new(user_session))] } diff --git a/rust-lib/flowy-sqlite/src/database.rs b/rust-lib/flowy-sqlite/src/database.rs index 82a5c9d3b5..e3aec6c171 100644 --- a/rust-lib/flowy-sqlite/src/database.rs +++ b/rust-lib/flowy-sqlite/src/database.rs @@ -4,16 +4,21 @@ use crate::{ }; use r2d2::PooledConnection; -pub struct DataBase { +pub struct Database { uri: String, pool: ConnectionPool, } pub type DBConnection = PooledConnection; -impl DataBase { +impl Database { pub fn new(dir: &str, name: &str, pool_config: PoolConfig) -> Result { let uri = db_file_uri(dir, name); + + if !std::path::PathBuf::from(dir).exists() { + log::error!("Create database failed. {} not exists", &dir); + } + let pool = ConnectionPool::new(pool_config, &uri)?; Ok(Self { uri, pool }) } diff --git a/rust-lib/flowy-sqlite/src/pool.rs b/rust-lib/flowy-sqlite/src/pool.rs index 9452675813..ebc010eab1 100644 --- a/rust-lib/flowy-sqlite/src/pool.rs +++ b/rust-lib/flowy-sqlite/src/pool.rs @@ -115,12 +115,7 @@ impl ManageConnection for ConnectionManager { type Connection = SqliteConnection; type Error = crate::Error; - fn connect(&self) -> Result { - if !std::path::PathBuf::from(&self.db_uri).exists() { - log::error!("db file not exists"); - } - Ok(SqliteConnection::establish(&self.db_uri)?) - } + fn connect(&self) -> Result { Ok(SqliteConnection::establish(&self.db_uri)?) } fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> { Ok(conn.execute("SELECT 1").map(|_| ())?) diff --git a/rust-lib/flowy-user/Cargo.toml b/rust-lib/flowy-user/Cargo.toml index 00819ddbfa..b9ea3c4d56 100644 --- a/rust-lib/flowy-user/Cargo.toml +++ b/rust-lib/flowy-user/Cargo.toml @@ -12,6 +12,7 @@ flowy-log = { path = "../flowy-log" } flowy-derive = { path = "../flowy-derive" } flowy-database = { path = "../flowy-database" } flowy-sqlite = { path = "../flowy-sqlite" } +flowy-infra = { path = "../flowy-infra" } tracing = { version = "0.1", features = ["log"] } bytes = "1.0" @@ -23,6 +24,8 @@ log = "0.4.14" protobuf = {version = "2.18.0"} lazy_static = "1.4.0" fancy-regex = "0.5.0" +diesel = {version = "1.4.7", features = ["sqlite"]} +diesel_derives = {version = "1.4.1", features = ["sqlite"]} [dev-dependencies] quickcheck = "0.9.2" diff --git a/rust-lib/flowy-user/src/domain/mod.rs b/rust-lib/flowy-user/src/domain/mod.rs index 72d7ee6bd4..307289622e 100644 --- a/rust-lib/flowy-user/src/domain/mod.rs +++ b/rust-lib/flowy-user/src/domain/mod.rs @@ -1,4 +1,3 @@ pub use user::*; +pub mod tables; pub mod user; -pub mod user_db; -pub mod user_session; diff --git a/rust-lib/flowy-user/src/domain/tables/mod.rs b/rust-lib/flowy-user/src/domain/tables/mod.rs new file mode 100644 index 0000000000..9ec3bba54d --- /dev/null +++ b/rust-lib/flowy-user/src/domain/tables/mod.rs @@ -0,0 +1,3 @@ +mod user_table; + +pub use user_table::*; diff --git a/rust-lib/flowy-user/src/domain/tables/user_table.rs b/rust-lib/flowy-user/src/domain/tables/user_table.rs new file mode 100644 index 0000000000..85a2b75b7a --- /dev/null +++ b/rust-lib/flowy-user/src/domain/tables/user_table.rs @@ -0,0 +1,30 @@ +use crate::domain::{UserEmail, UserName, UserPassword}; +use flowy_database::schema::user_table; +use flowy_derive::ProtoBuf; + +#[derive(ProtoBuf, Clone, Default, Queryable, Identifiable, Insertable)] +#[table_name = "user_table"] +pub struct User { + #[pb(index = 1)] + pub(crate) id: String, + + #[pb(index = 2)] + name: String, + + #[pb(index = 3)] + email: String, + + #[pb(index = 4)] + password: String, +} + +impl User { + pub fn new(id: String, name: String, email: String, password: String) -> Self { + Self { + id, + name, + email, + password, + } + } +} diff --git a/rust-lib/flowy-user/src/domain/user/mod.rs b/rust-lib/flowy-user/src/domain/user/mod.rs index 6dcd7b2dda..6f67248772 100644 --- a/rust-lib/flowy-user/src/domain/user/mod.rs +++ b/rust-lib/flowy-user/src/domain/user/mod.rs @@ -1,13 +1,11 @@ mod sign_in; mod sign_up; -mod user; mod user_email; mod user_name; mod user_password; pub use sign_in::*; pub use sign_up::*; -pub use user::*; pub use user_email::*; pub use user_name::*; pub use user_password::*; diff --git a/rust-lib/flowy-user/src/domain/user/user.rs b/rust-lib/flowy-user/src/domain/user/user.rs deleted file mode 100644 index b2aaead93d..0000000000 --- a/rust-lib/flowy-user/src/domain/user/user.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::domain::{UserEmail, UserName, UserPassword}; -use flowy_derive::ProtoBuf; - -#[derive(ProtoBuf, Default)] -pub struct User { - #[pb(index = 1)] - name: String, - - #[pb(index = 2)] - email: String, - - #[pb(index = 3)] - password: String, -} - -impl User { - pub fn new(name: UserName, email: UserEmail, password: UserPassword) -> Self { - Self { - name: name.0, - email: email.0, - password: password.0, - } - } -} diff --git a/rust-lib/flowy-user/src/domain/user_session.rs b/rust-lib/flowy-user/src/domain/user_session.rs deleted file mode 100644 index 2f8aa0a2cb..0000000000 --- a/rust-lib/flowy-user/src/domain/user_session.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::{domain::user_db::UserDB, errors::UserError}; -use flowy_sqlite::DBConnection; -use lazy_static::lazy_static; -use std::sync::RwLock; - -lazy_static! { - pub static ref CURRENT_USER_ID: RwLock> = RwLock::new(None); -} -fn get_current_user_id() -> Result, UserError> { - match CURRENT_USER_ID.read() { - Ok(read_guard) => Ok((*read_guard).clone()), - Err(e) => { - log::error!("Get current user id failed: {:?}", e); - Err(e.into()) - }, - } -} - -pub struct UserSessionConfig { - root_dir: String, -} - -impl UserSessionConfig { - pub fn new(root_dir: &str) -> Self { - Self { - root_dir: root_dir.to_owned(), - } - } -} - -pub struct UserSession { - db: UserDB, - config: UserSessionConfig, -} - -impl UserSession { - pub fn new(config: UserSessionConfig) -> Self { - let db = UserDB::new(&config.root_dir); - Self { db, config } - } - - pub fn get_db_connection(&self) -> Result { - match get_current_user_id()? { - None => Err(UserError::UserNotLogin), - Some(user_id) => self.db.get_connection(&user_id), - } - } -} diff --git a/rust-lib/flowy-user/src/errors.rs b/rust-lib/flowy-user/src/errors.rs index 171bf24d6d..55f498fc50 100644 --- a/rust-lib/flowy-user/src/errors.rs +++ b/rust-lib/flowy-user/src/errors.rs @@ -1,23 +1,34 @@ -use flowy_database::DataBaseError; -use std::sync::PoisonError; +use derive_more::Display; +use flowy_dispatch::prelude::{DispatchError, EventResponse, ResponseBuilder, StatusCode}; +use std::{io, sync::PoisonError}; -#[derive(Debug)] +#[derive(Debug, Clone, Display)] pub enum UserError { - DBInit(String), - DBNotInit, - UserNotLogin, - DBConnection(String), + #[display(fmt = "User db error:{}", _0)] + Database(String), + #[display(fmt = "User auth error:{}", _0)] + Auth(String), + #[display(fmt = "User sync error: {}", _0)] PoisonError(String), } -impl std::convert::From for UserError { - fn from(error: DataBaseError) -> Self { UserError::DBInit(format!("{:?}", error)) } -} - -impl std::convert::From> for UserError { - fn from(error: PoisonError) -> Self { UserError::PoisonError(format!("{:?}", error)) } +impl std::convert::From for UserError { + fn from(error: flowy_database::result::Error) -> Self { + UserError::Database(format!("{:?}", error)) + } } impl std::convert::From for UserError { - fn from(e: flowy_sqlite::Error) -> Self { UserError::DBConnection(format!("{:?}", e)) } + fn from(e: flowy_sqlite::Error) -> Self { UserError::Database(format!("{:?}", e)) } +} + +impl std::convert::From for String { + fn from(e: UserError) -> Self { format!("{:?}", e) } +} + +impl std::convert::Into for UserError { + fn into(self) -> DispatchError { + let user_error: String = self.into(); + user_error.into() + } } diff --git a/rust-lib/flowy-user/src/handlers/auth.rs b/rust-lib/flowy-user/src/handlers/auth.rs index ccf6aec459..49e390df1a 100644 --- a/rust-lib/flowy-user/src/handlers/auth.rs +++ b/rust-lib/flowy-user/src/handlers/auth.rs @@ -1,4 +1,4 @@ -use crate::domain::{user::*, user_session::UserSession}; +use crate::{domain::user::*, services::user_session::UserSession}; use flowy_dispatch::prelude::*; use std::{convert::TryInto, sync::Arc}; @@ -21,16 +21,19 @@ pub async fn user_sign_in(data: Data) -> ResponseResult, session: ModuleData>, ) -> ResponseResult { - let _params: SignUpParams = data.into_inner().try_into()?; + let params: SignUpParams = data.into_inner().try_into()?; // TODO: user sign up + let _user = session.sign_up(params)?; + let fake_resp = SignUpResponse::new(true); response_ok(fake_resp) } diff --git a/rust-lib/flowy-user/src/lib.rs b/rust-lib/flowy-user/src/lib.rs index fa3376178b..6107fefe72 100644 --- a/rust-lib/flowy-user/src/lib.rs +++ b/rust-lib/flowy-user/src/lib.rs @@ -4,7 +4,11 @@ pub mod event; mod handlers; pub mod module; mod protobuf; +mod services; + +#[macro_use] +extern crate flowy_database; pub mod prelude { - pub use crate::{domain::*, handlers::auth::*}; + pub use crate::{domain::*, handlers::auth::*, services::user_session::*}; } diff --git a/rust-lib/flowy-user/src/module.rs b/rust-lib/flowy-user/src/module.rs index 4985026e3b..b123ef2857 100644 --- a/rust-lib/flowy-user/src/module.rs +++ b/rust-lib/flowy-user/src/module.rs @@ -1,10 +1,6 @@ use flowy_dispatch::prelude::*; -use crate::{ - domain::{user_db::*, user_session::UserSession}, - event::UserEvent, - handlers::*, -}; +use crate::{event::UserEvent, handlers::*, services::user_session::UserSession}; use std::sync::Arc; pub fn create(user_session: Arc) -> Module { diff --git a/rust-lib/flowy-user/src/protobuf/model/user.rs b/rust-lib/flowy-user/src/protobuf/model/user.rs index 6a25acecf3..e6cc7cf66f 100644 --- a/rust-lib/flowy-user/src/protobuf/model/user.rs +++ b/rust-lib/flowy-user/src/protobuf/model/user.rs @@ -26,6 +26,7 @@ #[derive(PartialEq,Clone,Default)] pub struct User { // message fields + pub id: ::std::string::String, pub name: ::std::string::String, pub email: ::std::string::String, pub password: ::std::string::String, @@ -45,7 +46,33 @@ impl User { ::std::default::Default::default() } - // string name = 1; + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string name = 2; pub fn get_name(&self) -> &str { @@ -71,7 +98,7 @@ impl User { ::std::mem::replace(&mut self.name, ::std::string::String::new()) } - // string email = 2; + // string email = 3; pub fn get_email(&self) -> &str { @@ -97,7 +124,7 @@ impl User { ::std::mem::replace(&mut self.email, ::std::string::String::new()) } - // string password = 3; + // string password = 4; pub fn get_password(&self) -> &str { @@ -134,12 +161,15 @@ impl ::protobuf::Message for User { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; }, 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?; + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; }, 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?; + }, + 4 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?; }, _ => { @@ -154,14 +184,17 @@ impl ::protobuf::Message for User { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.name); + my_size += ::protobuf::rt::string_size(2, &self.name); } if !self.email.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.email); + my_size += ::protobuf::rt::string_size(3, &self.email); } if !self.password.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.password); + my_size += ::protobuf::rt::string_size(4, &self.password); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -169,14 +202,17 @@ impl ::protobuf::Message for User { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } if !self.name.is_empty() { - os.write_string(1, &self.name)?; + os.write_string(2, &self.name)?; } if !self.email.is_empty() { - os.write_string(2, &self.email)?; + os.write_string(3, &self.email)?; } if !self.password.is_empty() { - os.write_string(3, &self.password)?; + os.write_string(4, &self.password)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -216,6 +252,11 @@ impl ::protobuf::Message for User { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &User| { &m.id }, + |m: &mut User| { &mut m.id }, + )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "name", |m: &User| { &m.name }, @@ -247,6 +288,7 @@ impl ::protobuf::Message for User { impl ::protobuf::Clear for User { fn clear(&mut self) { + self.id.clear(); self.name.clear(); self.email.clear(); self.password.clear(); @@ -267,19 +309,23 @@ impl ::protobuf::reflect::ProtobufValue for User { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\nuser.proto\"L\n\x04User\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04nam\ - e\x12\x14\n\x05email\x18\x02\x20\x01(\tR\x05email\x12\x1a\n\x08password\ - \x18\x03\x20\x01(\tR\x08passwordJ\xcf\x01\n\x06\x12\x04\0\0\x06\x01\n\ - \x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x06\x01\n\n\ - \n\x03\x04\0\x01\x12\x03\x02\x08\x0c\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\ - \x04\x14\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\ - \x02\0\x01\x12\x03\x03\x0b\x0f\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\ - \x12\x13\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x15\n\x0c\n\x05\x04\0\ - \x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\ - \x0b\x10\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x13\x14\n\x0b\n\x04\ - \x04\0\x02\x02\x12\x03\x05\x04\x18\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\ - \x05\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x0b\x13\n\x0c\n\x05\ - \x04\0\x02\x02\x03\x12\x03\x05\x16\x17b\x06proto3\ + \n\nuser.proto\"\\\n\x04User\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\ + \x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05email\x18\ + \x03\x20\x01(\tR\x05email\x12\x1a\n\x08password\x18\x04\x20\x01(\tR\x08p\ + asswordJ\x86\x02\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\x0c\x12\x03\0\0\ + \x12\n\n\n\x02\x04\0\x12\x04\x02\0\x07\x01\n\n\n\x03\x04\0\x01\x12\x03\ + \x02\x08\x0c\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\x05\x04\ + \0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\ + \x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\x0b\n\x04\x04\0\ + \x02\x01\x12\x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\ + \x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\ + \0\x02\x01\x03\x12\x03\x04\x12\x13\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\ + \x04\x15\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\ + \0\x02\x02\x01\x12\x03\x05\x0b\x10\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\ + \x05\x13\x14\n\x0b\n\x04\x04\0\x02\x03\x12\x03\x06\x04\x18\n\x0c\n\x05\ + \x04\0\x02\x03\x05\x12\x03\x06\x04\n\n\x0c\n\x05\x04\0\x02\x03\x01\x12\ + \x03\x06\x0b\x13\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x06\x16\x17b\x06p\ + roto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/rust-lib/flowy-user/src/protobuf/proto/user.proto b/rust-lib/flowy-user/src/protobuf/proto/user.proto index 22471a969e..6ae8d964d1 100644 --- a/rust-lib/flowy-user/src/protobuf/proto/user.proto +++ b/rust-lib/flowy-user/src/protobuf/proto/user.proto @@ -1,7 +1,8 @@ syntax = "proto3"; message User { - string name = 1; - string email = 2; - string password = 3; + string id = 1; + string name = 2; + string email = 3; + string password = 4; } diff --git a/rust-lib/flowy-user/src/domain/user_db.rs b/rust-lib/flowy-user/src/services/database.rs similarity index 65% rename from rust-lib/flowy-user/src/domain/user_db.rs rename to rust-lib/flowy-user/src/services/database.rs index 532ccdce41..1979747f76 100644 --- a/rust-lib/flowy-user/src/domain/user_db.rs +++ b/rust-lib/flowy-user/src/services/database.rs @@ -1,5 +1,5 @@ use crate::errors::UserError; -use flowy_database::{DBConnection, DataBase}; +use flowy_database::{DBConnection, Database}; use lazy_static::lazy_static; use std::{ cell::RefCell, @@ -22,7 +22,7 @@ fn get_user_id() -> Option { USER_ID.with(|id| id.borrow().clone()) } static IS_USER_DB_INIT: AtomicBool = AtomicBool::new(false); lazy_static! { - static ref USER_DB_INNER: RwLock> = RwLock::new(None); + static ref DB: RwLock> = RwLock::new(None); } pub(crate) struct UserDB { @@ -37,17 +37,23 @@ impl UserDB { } fn open_user_db(&self, user_id: &str) -> Result<(), UserError> { - let user_dir = format!("{}/{}", self.db_dir, user_id); - let database = flowy_database::init(&user_dir)?; - let mut write_guard = USER_DB_INNER.write()?; + let dir = format!("{}/{}", self.db_dir, user_id); + let db = flowy_database::init(&dir).map_err(|e| UserError::Database(format!("{:?}", e)))?; + + let mut user_db = DB + .write() + .map_err(|e| UserError::Database(format!("Open user db failed. {:?}", e)))?; + *(user_db) = Some(db); + set_user_id(Some(user_id.to_owned())); - *(write_guard) = Some(database); IS_USER_DB_INIT.store(true, Ordering::SeqCst); Ok(()) } pub(crate) fn close_user_db(&mut self) -> Result<(), UserError> { - let mut write_guard = USER_DB_INNER.write()?; + let mut write_guard = DB + .write() + .map_err(|e| UserError::Database(format!("Close user db failed. {:?}", e)))?; *write_guard = None; set_user_id(None); IS_USER_DB_INIT.store(false, Ordering::SeqCst); @@ -62,16 +68,20 @@ impl UserDB { let thread_user_id = get_user_id(); if thread_user_id != Some(user_id.to_owned()) { let msg = format!( - "DataBase owner does not match. origin: {:?}, current: {}", + "Database owner does not match. origin: {:?}, current: {}", thread_user_id, user_id ); log::error!("{}", msg); - return Err(UserError::DBConnection(msg)); + return Err(UserError::Database(msg)); } - let read_guard = USER_DB_INNER.read()?; + let read_guard = DB + .read() + .map_err(|e| UserError::Database(format!("Get user db connection fail. {:?}", e)))?; match read_guard.as_ref() { - None => Err(UserError::DBNotInit), + None => Err(UserError::Database( + "Database is not initialization".to_owned(), + )), Some(database) => Ok(database.get_connection()?), } } diff --git a/rust-lib/flowy-user/src/services/mod.rs b/rust-lib/flowy-user/src/services/mod.rs new file mode 100644 index 0000000000..af6b60f500 --- /dev/null +++ b/rust-lib/flowy-user/src/services/mod.rs @@ -0,0 +1,3 @@ +pub mod database; +mod register; +pub mod user_session; diff --git a/rust-lib/flowy-user/src/services/register.rs b/rust-lib/flowy-user/src/services/register.rs new file mode 100644 index 0000000000..1b36c8d6fe --- /dev/null +++ b/rust-lib/flowy-user/src/services/register.rs @@ -0,0 +1,22 @@ +use crate::{ + domain::{tables::User, SignUpParams}, + errors::UserError, +}; + +pub trait UserRegister { + fn register_user(&self, params: SignUpParams) -> Result; +} + +pub struct MockUserRegister {} + +impl UserRegister for MockUserRegister { + fn register_user(&self, params: SignUpParams) -> Result { + let user_id = "9527".to_owned(); + Ok(User::new( + user_id, + params.name, + params.email, + params.password, + )) + } +} diff --git a/rust-lib/flowy-user/src/services/user_session/builder.rs b/rust-lib/flowy-user/src/services/user_session/builder.rs new file mode 100644 index 0000000000..83d5443ece --- /dev/null +++ b/rust-lib/flowy-user/src/services/user_session/builder.rs @@ -0,0 +1,23 @@ +use crate::services::{ + register::MockUserRegister, + user_session::{UserSession, UserSessionConfig}, +}; + +pub struct UserSessionBuilder { + config: Option, +} + +impl UserSessionBuilder { + pub fn new() -> Self { Self { config: None } } + + pub fn root_dir(mut self, dir: &str) -> Self { + self.config = Some(UserSessionConfig::new(dir)); + self + } + + pub fn build(mut self) -> UserSession { + let config = self.config.take().unwrap(); + let register = MockUserRegister {}; + UserSession::new(config, register) + } +} diff --git a/rust-lib/flowy-user/src/services/user_session/mod.rs b/rust-lib/flowy-user/src/services/user_session/mod.rs new file mode 100644 index 0000000000..ec189c878f --- /dev/null +++ b/rust-lib/flowy-user/src/services/user_session/mod.rs @@ -0,0 +1,5 @@ +mod builder; +mod user_session; + +pub use builder::*; +pub use user_session::*; diff --git a/rust-lib/flowy-user/src/services/user_session/user_session.rs b/rust-lib/flowy-user/src/services/user_session/user_session.rs new file mode 100644 index 0000000000..c8e9bbabbb --- /dev/null +++ b/rust-lib/flowy-user/src/services/user_session/user_session.rs @@ -0,0 +1,86 @@ +use crate::{ + domain::{tables::User, SignUpParams}, + errors::UserError, + services::{database::UserDB, register::UserRegister}, +}; +use ::diesel::query_dsl::*; +use flowy_database::schema::user_table; +use flowy_sqlite::DBConnection; +use lazy_static::lazy_static; +use std::sync::RwLock; + +pub struct UserSessionConfig { + root_dir: String, +} + +impl UserSessionConfig { + pub fn new(root_dir: &str) -> Self { + Self { + root_dir: root_dir.to_owned(), + } + } +} + +pub struct UserSession { + database: UserDB, + config: UserSessionConfig, + register: Box, +} + +impl UserSession { + pub fn new(config: UserSessionConfig, register: R) -> Self + where + R: 'static + UserRegister + Send + Sync, + { + let db = UserDB::new(&config.root_dir); + Self { + database: db, + config, + register: Box::new(register), + } + } + + pub fn get_db_connection(&self) -> Result { + match get_current_user_id()? { + None => Err(UserError::Auth("User is not login yet".to_owned())), + Some(user_id) => self.database.get_connection(&user_id), + } + } + + pub fn sign_up(&self, params: SignUpParams) -> Result { + let user = self.register.register_user(params)?; + set_current_user_id(Some(user.id.clone())); + + let conn = self.get_db_connection()?; + let _ = diesel::insert_into(user_table::table) + .values(user.clone()) + .execute(&*conn)?; + + Ok(user) + } + + pub fn sign_out(&self) -> Result<(), UserError> { + set_current_user_id(None); + // TODO: close the db + unimplemented!() + } +} + +lazy_static! { + pub static ref CURRENT_USER_ID: RwLock> = RwLock::new(None); +} +fn get_current_user_id() -> Result, UserError> { + let current_user_id = CURRENT_USER_ID + .read() + .map_err(|e| UserError::Auth(format!("Read current user id failed. {:?}", e)))?; + + Ok((*current_user_id).clone()) +} + +pub fn set_current_user_id(user_id: Option) -> Result<(), UserError> { + let mut current_user_id = CURRENT_USER_ID + .write() + .map_err(|e| UserError::Auth(format!("Write current user id failed. {:?}", e)))?; + *current_user_id = user_id; + Ok(()) +} diff --git a/rust-lib/flowy-user/tests/auth.rs b/rust-lib/flowy-user/tests/auth_test.rs similarity index 95% rename from rust-lib/flowy-user/tests/auth.rs rename to rust-lib/flowy-user/tests/auth_test.rs index 607138ef99..b428ccb15f 100644 --- a/rust-lib/flowy-user/tests/auth.rs +++ b/rust-lib/flowy-user/tests/auth_test.rs @@ -9,11 +9,9 @@ fn sign_up_success() { password: valid_password(), }; - let response = EventTester::new(SignUp) - .request(request) - .sync_send() - .parse::(); - dbg!(&response); + let response = EventTester::new(SignUp).request(request).sync_send(); + // .parse::(); + // dbg!(&response); } #[test] diff --git a/rust-lib/flowy-user/tests/main.rs b/rust-lib/flowy-user/tests/main.rs index 12bc9de49d..1a19c4b5eb 100644 --- a/rust-lib/flowy-user/tests/main.rs +++ b/rust-lib/flowy-user/tests/main.rs @@ -1 +1 @@ -mod auth; +mod auth_test;