Browse Source

replace user_id with logger_user for auth

appflowy 3 years ago
parent
commit
9b571a08f7
45 changed files with 705 additions and 881 deletions
  1. 8 8
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/auth.pb.dart
  2. 2 2
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/auth.pbjson.dart
  3. 0 14
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/app_create.pb.dart
  4. 1 2
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/app_create.pbjson.dart
  5. 0 28
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_create.pb.dart
  6. 2 4
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_create.pbjson.dart
  7. 0 28
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_query.pb.dart
  8. 2 4
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_query.pbjson.dart
  9. 3 3
      backend/src/user_service/auth.rs
  10. 4 2
      backend/src/workspace_service/app/app.rs
  11. 3 1
      backend/src/workspace_service/app/router.rs
  12. 9 5
      backend/src/workspace_service/workspace/router.rs
  13. 10 6
      backend/src/workspace_service/workspace/workspace.rs
  14. 3 3
      backend/tests/api/auth.rs
  15. 29 25
      backend/tests/api/helper.rs
  16. 74 66
      backend/tests/api/workspace.rs
  17. 5 0
      rust-lib/flowy-net/src/config.rs
  18. 1 1
      rust-lib/flowy-user/Cargo.toml
  19. 3 5
      rust-lib/flowy-user/src/entities/auth.rs
  20. 30 30
      rust-lib/flowy-user/src/protobuf/model/auth.rs
  21. 1 1
      rust-lib/flowy-user/src/protobuf/proto/auth.proto
  22. 5 20
      rust-lib/flowy-user/src/services/server/server_api_mock.rs
  23. 6 19
      rust-lib/flowy-user/src/services/user/user_session.rs
  24. 2 6
      rust-lib/flowy-user/src/sql_tables/user.rs
  25. 3 2
      rust-lib/flowy-workspace/Cargo.toml
  26. 4 16
      rust-lib/flowy-workspace/src/entities/app/app_create.rs
  27. 3 24
      rust-lib/flowy-workspace/src/entities/workspace/workspace_create.rs
  28. 5 24
      rust-lib/flowy-workspace/src/entities/workspace/workspace_query.rs
  29. 3 11
      rust-lib/flowy-workspace/src/entities/workspace/workspace_update.rs
  30. 1 1
      rust-lib/flowy-workspace/src/handlers/workspace_handler.rs
  31. 0 3
      rust-lib/flowy-workspace/src/module.rs
  32. 60 106
      rust-lib/flowy-workspace/src/protobuf/model/app_create.rs
  33. 39 130
      rust-lib/flowy-workspace/src/protobuf/model/workspace_create.rs
  34. 15 108
      rust-lib/flowy-workspace/src/protobuf/model/workspace_query.rs
  35. 0 1
      rust-lib/flowy-workspace/src/protobuf/proto/app_create.proto
  36. 0 2
      rust-lib/flowy-workspace/src/protobuf/proto/workspace_create.proto
  37. 0 2
      rust-lib/flowy-workspace/src/protobuf/proto/workspace_query.proto
  38. 1 40
      rust-lib/flowy-workspace/src/services/app_controller.rs
  39. 8 0
      rust-lib/flowy-workspace/src/services/helper.rs
  40. 1 1
      rust-lib/flowy-workspace/src/services/mod.rs
  41. 15 8
      rust-lib/flowy-workspace/src/services/server/mod.rs
  42. 204 16
      rust-lib/flowy-workspace/src/services/server/server_api.rs
  43. 69 17
      rust-lib/flowy-workspace/src/services/server/server_api_mock.rs
  44. 0 38
      rust-lib/flowy-workspace/src/services/view_controller.rs
  45. 71 48
      rust-lib/flowy-workspace/src/services/workspace_controller.rs

+ 8 - 8
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/auth.pb.dart

@@ -372,7 +372,7 @@ class SignUpParams extends $pb.GeneratedMessage {
 
 class SignUpResponse extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignUpResponse', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'uid')
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
     ..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') ? '' : 'token')
@@ -381,14 +381,14 @@ class SignUpResponse extends $pb.GeneratedMessage {
 
   SignUpResponse._() : super();
   factory SignUpResponse({
-    $core.String? uid,
+    $core.String? userId,
     $core.String? name,
     $core.String? email,
     $core.String? token,
   }) {
     final _result = create();
-    if (uid != null) {
-      _result.uid = uid;
+    if (userId != null) {
+      _result.userId = userId;
     }
     if (name != null) {
       _result.name = name;
@@ -423,13 +423,13 @@ class SignUpResponse extends $pb.GeneratedMessage {
   static SignUpResponse? _defaultInstance;
 
   @$pb.TagNumber(1)
-  $core.String get uid => $_getSZ(0);
+  $core.String get userId => $_getSZ(0);
   @$pb.TagNumber(1)
-  set uid($core.String v) { $_setString(0, v); }
+  set userId($core.String v) { $_setString(0, v); }
   @$pb.TagNumber(1)
-  $core.bool hasUid() => $_has(0);
+  $core.bool hasUserId() => $_has(0);
   @$pb.TagNumber(1)
-  void clearUid() => clearField(1);
+  void clearUserId() => clearField(1);
 
   @$pb.TagNumber(2)
   $core.String get name => $_getSZ(1);

+ 2 - 2
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/auth.pbjson.dart

@@ -71,7 +71,7 @@ final $typed_data.Uint8List signUpParamsDescriptor = $convert.base64Decode('CgxT
 const SignUpResponse$json = const {
   '1': 'SignUpResponse',
   '2': const [
-    const {'1': 'uid', '3': 1, '4': 1, '5': 9, '10': 'uid'},
+    const {'1': 'user_id', '3': 1, '4': 1, '5': 9, '10': 'userId'},
     const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
     const {'1': 'email', '3': 3, '4': 1, '5': 9, '10': 'email'},
     const {'1': 'token', '3': 4, '4': 1, '5': 9, '10': 'token'},
@@ -79,4 +79,4 @@ const SignUpResponse$json = const {
 };
 
 /// Descriptor for `SignUpResponse`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List signUpResponseDescriptor = $convert.base64Decode('Cg5TaWduVXBSZXNwb25zZRIQCgN1aWQYASABKAlSA3VpZBISCgRuYW1lGAIgASgJUgRuYW1lEhQKBWVtYWlsGAMgASgJUgVlbWFpbBIUCgV0b2tlbhgEIAEoCVIFdG9rZW4=');
+final $typed_data.Uint8List signUpResponseDescriptor = $convert.base64Decode('Cg5TaWduVXBSZXNwb25zZRIXCgd1c2VyX2lkGAEgASgJUgZ1c2VySWQSEgoEbmFtZRgCIAEoCVIEbmFtZRIUCgVlbWFpbBgDIAEoCVIFZW1haWwSFAoFdG9rZW4YBCABKAlSBXRva2Vu');

+ 0 - 14
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/app_create.pb.dart

@@ -156,7 +156,6 @@ class CreateAppParams extends $pb.GeneratedMessage {
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
     ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
     ..aOM<ColorStyle>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'colorStyle', subBuilder: ColorStyle.create)
-    ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
     ..hasRequiredFields = false
   ;
 
@@ -166,7 +165,6 @@ class CreateAppParams extends $pb.GeneratedMessage {
     $core.String? name,
     $core.String? desc,
     ColorStyle? colorStyle,
-    $core.String? userId,
   }) {
     final _result = create();
     if (workspaceId != null) {
@@ -181,9 +179,6 @@ class CreateAppParams extends $pb.GeneratedMessage {
     if (colorStyle != null) {
       _result.colorStyle = colorStyle;
     }
-    if (userId != null) {
-      _result.userId = userId;
-    }
     return _result;
   }
   factory CreateAppParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -244,15 +239,6 @@ class CreateAppParams extends $pb.GeneratedMessage {
   void clearColorStyle() => clearField(4);
   @$pb.TagNumber(4)
   ColorStyle ensureColorStyle() => $_ensure(3);
-
-  @$pb.TagNumber(5)
-  $core.String get userId => $_getSZ(4);
-  @$pb.TagNumber(5)
-  set userId($core.String v) { $_setString(4, v); }
-  @$pb.TagNumber(5)
-  $core.bool hasUserId() => $_has(4);
-  @$pb.TagNumber(5)
-  void clearUserId() => clearField(5);
 }
 
 class App extends $pb.GeneratedMessage {

+ 1 - 2
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/app_create.pbjson.dart

@@ -39,12 +39,11 @@ const CreateAppParams$json = const {
     const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
     const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'},
     const {'1': 'color_style', '3': 4, '4': 1, '5': 11, '6': '.ColorStyle', '10': 'colorStyle'},
-    const {'1': 'user_id', '3': 5, '4': 1, '5': 9, '10': 'userId'},
   ],
 };
 
 /// Descriptor for `CreateAppParams`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List createAppParamsDescriptor = $convert.base64Decode('Cg9DcmVhdGVBcHBQYXJhbXMSIQoMd29ya3NwYWNlX2lkGAEgASgJUgt3b3Jrc3BhY2VJZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSLAoLY29sb3Jfc3R5bGUYBCABKAsyCy5Db2xvclN0eWxlUgpjb2xvclN0eWxlEhcKB3VzZXJfaWQYBSABKAlSBnVzZXJJZA==');
+final $typed_data.Uint8List createAppParamsDescriptor = $convert.base64Decode('Cg9DcmVhdGVBcHBQYXJhbXMSIQoMd29ya3NwYWNlX2lkGAEgASgJUgt3b3Jrc3BhY2VJZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSLAoLY29sb3Jfc3R5bGUYBCABKAsyCy5Db2xvclN0eWxlUgpjb2xvclN0eWxl');
 @$core.Deprecated('Use appDescriptor instead')
 const App$json = const {
   '1': 'App',

+ 0 - 28
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_create.pb.dart

@@ -15,7 +15,6 @@ class CreateWorkspaceRequest extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateWorkspaceRequest', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
-    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
     ..hasRequiredFields = false
   ;
 
@@ -23,7 +22,6 @@ class CreateWorkspaceRequest extends $pb.GeneratedMessage {
   factory CreateWorkspaceRequest({
     $core.String? name,
     $core.String? desc,
-    $core.String? userId,
   }) {
     final _result = create();
     if (name != null) {
@@ -32,9 +30,6 @@ class CreateWorkspaceRequest extends $pb.GeneratedMessage {
     if (desc != null) {
       _result.desc = desc;
     }
-    if (userId != null) {
-      _result.userId = userId;
-    }
     return _result;
   }
   factory CreateWorkspaceRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -75,22 +70,12 @@ class CreateWorkspaceRequest extends $pb.GeneratedMessage {
   $core.bool hasDesc() => $_has(1);
   @$pb.TagNumber(2)
   void clearDesc() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $core.String get userId => $_getSZ(2);
-  @$pb.TagNumber(3)
-  set userId($core.String v) { $_setString(2, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasUserId() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearUserId() => clearField(3);
 }
 
 class CreateWorkspaceParams extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateWorkspaceParams', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
-    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
     ..hasRequiredFields = false
   ;
 
@@ -98,7 +83,6 @@ class CreateWorkspaceParams extends $pb.GeneratedMessage {
   factory CreateWorkspaceParams({
     $core.String? name,
     $core.String? desc,
-    $core.String? userId,
   }) {
     final _result = create();
     if (name != null) {
@@ -107,9 +91,6 @@ class CreateWorkspaceParams extends $pb.GeneratedMessage {
     if (desc != null) {
       _result.desc = desc;
     }
-    if (userId != null) {
-      _result.userId = userId;
-    }
     return _result;
   }
   factory CreateWorkspaceParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -150,15 +131,6 @@ class CreateWorkspaceParams extends $pb.GeneratedMessage {
   $core.bool hasDesc() => $_has(1);
   @$pb.TagNumber(2)
   void clearDesc() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $core.String get userId => $_getSZ(2);
-  @$pb.TagNumber(3)
-  set userId($core.String v) { $_setString(2, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasUserId() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearUserId() => clearField(3);
 }
 
 class Workspace extends $pb.GeneratedMessage {

+ 2 - 4
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_create.pbjson.dart

@@ -14,24 +14,22 @@ const CreateWorkspaceRequest$json = const {
   '2': const [
     const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'},
     const {'1': 'desc', '3': 2, '4': 1, '5': 9, '10': 'desc'},
-    const {'1': 'user_id', '3': 3, '4': 1, '5': 9, '10': 'userId'},
   ],
 };
 
 /// Descriptor for `CreateWorkspaceRequest`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List createWorkspaceRequestDescriptor = $convert.base64Decode('ChZDcmVhdGVXb3Jrc3BhY2VSZXF1ZXN0EhIKBG5hbWUYASABKAlSBG5hbWUSEgoEZGVzYxgCIAEoCVIEZGVzYxIXCgd1c2VyX2lkGAMgASgJUgZ1c2VySWQ=');
+final $typed_data.Uint8List createWorkspaceRequestDescriptor = $convert.base64Decode('ChZDcmVhdGVXb3Jrc3BhY2VSZXF1ZXN0EhIKBG5hbWUYASABKAlSBG5hbWUSEgoEZGVzYxgCIAEoCVIEZGVzYw==');
 @$core.Deprecated('Use createWorkspaceParamsDescriptor instead')
 const CreateWorkspaceParams$json = const {
   '1': 'CreateWorkspaceParams',
   '2': const [
     const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'},
     const {'1': 'desc', '3': 2, '4': 1, '5': 9, '10': 'desc'},
-    const {'1': 'user_id', '3': 3, '4': 1, '5': 9, '10': 'userId'},
   ],
 };
 
 /// Descriptor for `CreateWorkspaceParams`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List createWorkspaceParamsDescriptor = $convert.base64Decode('ChVDcmVhdGVXb3Jrc3BhY2VQYXJhbXMSEgoEbmFtZRgBIAEoCVIEbmFtZRISCgRkZXNjGAIgASgJUgRkZXNjEhcKB3VzZXJfaWQYAyABKAlSBnVzZXJJZA==');
+final $typed_data.Uint8List createWorkspaceParamsDescriptor = $convert.base64Decode('ChVDcmVhdGVXb3Jrc3BhY2VQYXJhbXMSEgoEbmFtZRgBIAEoCVIEbmFtZRISCgRkZXNjGAIgASgJUgRkZXNj');
 @$core.Deprecated('Use workspaceDescriptor instead')
 const Workspace$json = const {
   '1': 'Workspace',

+ 0 - 28
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_query.pb.dart

@@ -22,22 +22,17 @@ class QueryWorkspaceRequest extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryWorkspaceRequest', createEmptyInstance: create)
     ..oo(0, [1])
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'workspaceId')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
     ..hasRequiredFields = false
   ;
 
   QueryWorkspaceRequest._() : super();
   factory QueryWorkspaceRequest({
     $core.String? workspaceId,
-    $core.String? userId,
   }) {
     final _result = create();
     if (workspaceId != null) {
       _result.workspaceId = workspaceId;
     }
-    if (userId != null) {
-      _result.userId = userId;
-    }
     return _result;
   }
   factory QueryWorkspaceRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -72,15 +67,6 @@ class QueryWorkspaceRequest extends $pb.GeneratedMessage {
   $core.bool hasWorkspaceId() => $_has(0);
   @$pb.TagNumber(1)
   void clearWorkspaceId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get userId => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set userId($core.String v) { $_setString(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasUserId() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearUserId() => clearField(2);
 }
 
 enum QueryWorkspaceParams_OneOfWorkspaceId {
@@ -96,22 +82,17 @@ class QueryWorkspaceParams extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryWorkspaceParams', createEmptyInstance: create)
     ..oo(0, [1])
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'workspaceId')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
     ..hasRequiredFields = false
   ;
 
   QueryWorkspaceParams._() : super();
   factory QueryWorkspaceParams({
     $core.String? workspaceId,
-    $core.String? userId,
   }) {
     final _result = create();
     if (workspaceId != null) {
       _result.workspaceId = workspaceId;
     }
-    if (userId != null) {
-      _result.userId = userId;
-    }
     return _result;
   }
   factory QueryWorkspaceParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -146,14 +127,5 @@ class QueryWorkspaceParams extends $pb.GeneratedMessage {
   $core.bool hasWorkspaceId() => $_has(0);
   @$pb.TagNumber(1)
   void clearWorkspaceId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get userId => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set userId($core.String v) { $_setString(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasUserId() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearUserId() => clearField(2);
 }
 

+ 2 - 4
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/workspace_query.pbjson.dart

@@ -13,7 +13,6 @@ const QueryWorkspaceRequest$json = const {
   '1': 'QueryWorkspaceRequest',
   '2': const [
     const {'1': 'workspace_id', '3': 1, '4': 1, '5': 9, '9': 0, '10': 'workspaceId'},
-    const {'1': 'user_id', '3': 2, '4': 1, '5': 9, '10': 'userId'},
   ],
   '8': const [
     const {'1': 'one_of_workspace_id'},
@@ -21,13 +20,12 @@ const QueryWorkspaceRequest$json = const {
 };
 
 /// Descriptor for `QueryWorkspaceRequest`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List queryWorkspaceRequestDescriptor = $convert.base64Decode('ChVRdWVyeVdvcmtzcGFjZVJlcXVlc3QSIwoMd29ya3NwYWNlX2lkGAEgASgJSABSC3dvcmtzcGFjZUlkEhcKB3VzZXJfaWQYAiABKAlSBnVzZXJJZEIVChNvbmVfb2Zfd29ya3NwYWNlX2lk');
+final $typed_data.Uint8List queryWorkspaceRequestDescriptor = $convert.base64Decode('ChVRdWVyeVdvcmtzcGFjZVJlcXVlc3QSIwoMd29ya3NwYWNlX2lkGAEgASgJSABSC3dvcmtzcGFjZUlkQhUKE29uZV9vZl93b3Jrc3BhY2VfaWQ=');
 @$core.Deprecated('Use queryWorkspaceParamsDescriptor instead')
 const QueryWorkspaceParams$json = const {
   '1': 'QueryWorkspaceParams',
   '2': const [
     const {'1': 'workspace_id', '3': 1, '4': 1, '5': 9, '9': 0, '10': 'workspaceId'},
-    const {'1': 'user_id', '3': 2, '4': 1, '5': 9, '10': 'userId'},
   ],
   '8': const [
     const {'1': 'one_of_workspace_id'},
@@ -35,4 +33,4 @@ const QueryWorkspaceParams$json = const {
 };
 
 /// Descriptor for `QueryWorkspaceParams`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List queryWorkspaceParamsDescriptor = $convert.base64Decode('ChRRdWVyeVdvcmtzcGFjZVBhcmFtcxIjCgx3b3Jrc3BhY2VfaWQYASABKAlIAFILd29ya3NwYWNlSWQSFwoHdXNlcl9pZBgCIAEoCVIGdXNlcklkQhUKE29uZV9vZl93b3Jrc3BhY2VfaWQ=');
+final $typed_data.Uint8List queryWorkspaceParamsDescriptor = $convert.base64Decode('ChRRdWVyeVdvcmtzcGFjZVBhcmFtcxIjCgx3b3Jrc3BhY2VfaWQYASABKAlIAFILd29ya3NwYWNlSWRCFQoTb25lX29mX3dvcmtzcGFjZV9pZA==');

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

@@ -87,9 +87,9 @@ pub async fn register_user(
     .await
     .context("Failed to insert user")?;
 
-    let logged_user = LoggedUser::new(&response_data.uid);
+    let logged_user = LoggedUser::new(&response_data.user_id);
     let _ = AUTHORIZED_USERS.store_auth(logged_user, true)?;
-    let _ = create_default_workspace(&mut transaction, response_data.get_uid()).await?;
+    let _ = create_default_workspace(&mut transaction, response_data.get_user_id()).await?;
 
     transaction
         .commit()
@@ -250,7 +250,7 @@ async fn insert_new_user(
     .map_err(|e| ServerError::internal().context(e))?;
 
     let mut response = SignUpResponse::default();
-    response.set_uid(uuid.to_string());
+    response.set_user_id(uuid.to_string());
     response.set_name(name.to_string());
     response.set_email(email.to_string());
     response.set_token(token.into());

+ 4 - 2
backend/src/workspace_service/app/app.rs

@@ -3,6 +3,7 @@ use flowy_net::{errors::ServerError, response::FlowyResponse};
 use crate::{
     entities::workspace::AppTable,
     sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
+    user_service::LoggedUser,
     workspace_service::{
         app::{check_app_id, make_app_from_table, Builder},
         view::read_views_belong_to_id,
@@ -25,17 +26,18 @@ use sqlx::{postgres::PgArguments, PgPool, Postgres};
 pub(crate) async fn create_app(
     pool: &PgPool,
     mut params: CreateAppParams,
+    logged_user: LoggedUser,
 ) -> Result<FlowyResponse, ServerError> {
     let name = AppName::parse(params.take_name()).map_err(invalid_params)?;
     let workspace_id = WorkspaceId::parse(params.take_workspace_id()).map_err(invalid_params)?;
-    let user_id = UserId::parse(params.take_user_id()).map_err(invalid_params)?;
+    let user_id = logged_user.get_user_id()?.to_string();
     let desc = AppDesc::parse(params.take_desc()).map_err(invalid_params)?;
     let mut transaction = pool
         .begin()
         .await
         .context("Failed to acquire a Postgres connection to create app")?;
 
-    let (sql, args, app) = Builder::new(user_id.as_ref(), workspace_id.as_ref())
+    let (sql, args, app) = Builder::new(&user_id, workspace_id.as_ref())
         .name(name.as_ref())
         .desc(desc.as_ref())
         .color_style(params.take_color_style())

+ 3 - 1
backend/src/workspace_service/app/router.rs

@@ -3,6 +3,7 @@ use crate::{
     workspace_service::app::app::{create_app, delete_app, read_app, update_app},
 };
 
+use crate::user_service::LoggedUser;
 use actix_web::{
     web::{Data, Payload},
     HttpResponse,
@@ -19,9 +20,10 @@ use sqlx::PgPool;
 pub async fn create_handler(
     payload: Payload,
     pool: Data<PgPool>,
+    logged_user: LoggedUser,
 ) -> Result<HttpResponse, ServerError> {
     let params: CreateAppParams = parse_from_payload(payload).await?;
-    let resp = create_app(pool.get_ref(), params).await?;
+    let resp = create_app(pool.get_ref(), params, logged_user).await?;
     Ok(resp.into())
 }
 

+ 9 - 5
backend/src/workspace_service/workspace/router.rs

@@ -8,6 +8,7 @@ use crate::{
     },
 };
 
+use crate::user_service::LoggedUser;
 use actix_web::{
     web::{Data, Path, Payload},
     HttpResponse,
@@ -24,15 +25,17 @@ use sqlx::PgPool;
 pub async fn create_handler(
     payload: Payload,
     pool: Data<PgPool>,
+    logged_user: LoggedUser,
 ) -> Result<HttpResponse, ServerError> {
     let params: CreateWorkspaceParams = parse_from_payload(payload).await?;
-    let resp = create_workspace(pool.get_ref(), params).await?;
+    let resp = create_workspace(pool.get_ref(), params, logged_user).await?;
     Ok(resp.into())
 }
 
 pub async fn read_handler(
     payload: Payload,
     pool: Data<PgPool>,
+    logged_user: LoggedUser,
 ) -> Result<HttpResponse, ServerError> {
     let params: QueryWorkspaceParams = parse_from_payload(payload).await?;
     let workspace_id = if params.has_workspace_id() {
@@ -40,14 +43,14 @@ pub async fn read_handler(
     } else {
         None
     };
-    let resp = read_workspaces(pool.get_ref(), params.get_user_id(), workspace_id).await?;
-
+    let resp = read_workspaces(pool.get_ref(), workspace_id, logged_user).await?;
     Ok(resp.into())
 }
 
 pub async fn delete_handler(
     payload: Payload,
     pool: Data<PgPool>,
+    _logged_user: LoggedUser,
 ) -> Result<HttpResponse, ServerError> {
     let params: DeleteWorkspaceParams = parse_from_payload(payload).await?;
     let resp = delete_workspace(pool.get_ref(), params.get_workspace_id()).await?;
@@ -57,6 +60,7 @@ pub async fn delete_handler(
 pub async fn update_handler(
     payload: Payload,
     pool: Data<PgPool>,
+    _logged_user: LoggedUser,
 ) -> Result<HttpResponse, ServerError> {
     let params: UpdateWorkspaceParams = parse_from_payload(payload).await?;
     let resp = update_workspace(pool.get_ref(), params).await?;
@@ -64,9 +68,9 @@ pub async fn update_handler(
 }
 
 pub async fn workspace_list(
-    user_id: Path<String>,
     pool: Data<PgPool>,
+    logged_user: LoggedUser,
 ) -> Result<HttpResponse, ServerError> {
-    let resp = read_workspaces(pool.get_ref(), &user_id, None).await?;
+    let resp = read_workspaces(pool.get_ref(), None, logged_user).await?;
     Ok(resp.into())
 }

+ 10 - 6
backend/src/workspace_service/workspace/workspace.rs

@@ -12,7 +12,10 @@ use flowy_net::{
 };
 use flowy_user::entities::parser::UserId;
 
-use crate::workspace_service::workspace::{check_workspace_id, make_workspace_from_table};
+use crate::{
+    user_service::LoggedUser,
+    workspace_service::workspace::{check_workspace_id, make_workspace_from_table},
+};
 use flowy_workspace::{
     entities::workspace::parser::{WorkspaceDesc, WorkspaceName},
     protobuf::{CreateWorkspaceParams, RepeatedApp, RepeatedWorkspace, UpdateWorkspaceParams},
@@ -22,17 +25,18 @@ use sqlx::{postgres::PgArguments, PgPool, Postgres};
 pub(crate) async fn create_workspace(
     pool: &PgPool,
     params: CreateWorkspaceParams,
+    logged_user: LoggedUser,
 ) -> Result<FlowyResponse, ServerError> {
     let name = WorkspaceName::parse(params.get_name().to_owned()).map_err(invalid_params)?;
     let desc = WorkspaceDesc::parse(params.get_desc().to_owned()).map_err(invalid_params)?;
-    let user_id = UserId::parse(params.user_id).map_err(invalid_params)?;
+    let user_id = logged_user.get_user_id()?.to_string();
 
     let mut transaction = pool
         .begin()
         .await
         .context("Failed to acquire a Postgres connection to create workspace")?;
 
-    let (sql, args, workspace) = Builder::new(user_id.as_ref())
+    let (sql, args, workspace) = Builder::new(&user_id)
         .name(name.as_ref())
         .desc(desc.as_ref())
         .build()?;
@@ -128,10 +132,10 @@ pub(crate) async fn delete_workspace(
 
 pub async fn read_workspaces(
     pool: &PgPool,
-    user_id: &str,
     workspace_id: Option<String>,
+    logged_user: LoggedUser,
 ) -> Result<FlowyResponse, ServerError> {
-    let user_id = UserId::parse(user_id.to_string()).map_err(invalid_params)?;
+    let user_id = logged_user.get_user_id()?.to_string();
     let mut transaction = pool
         .begin()
         .await
@@ -139,7 +143,7 @@ pub async fn read_workspaces(
 
     let mut builder = SqlBuilder::select("workspace_table")
         .add_field("*")
-        .and_where_eq("user_id", user_id.as_ref());
+        .and_where_eq("user_id", &user_id);
 
     if let Some(workspace_id) = workspace_id {
         let workspace_id = check_workspace_id(workspace_id)?;

+ 3 - 3
backend/tests/api/auth.rs

@@ -73,7 +73,7 @@ async fn user_update_password() {
     let password = "HelloWorld123!";
     let sign_up_resp = register_user(&app, email, password).await;
 
-    let params = UpdateUserParams::new(&sign_up_resp.uid).password("Hello123!");
+    let params = UpdateUserParams::new(&sign_up_resp.user_id).password("Hello123!");
     app.update_user_detail(&sign_up_resp.token, params)
         .await
         .unwrap();
@@ -96,7 +96,7 @@ async fn user_update_name() {
     let app = spawn_app().await;
     let sign_up_resp = sign_up_user(&app).await;
     let name = "tom".to_string();
-    let params = UpdateUserParams::new(&sign_up_resp.uid).name(&name);
+    let params = UpdateUserParams::new(&sign_up_resp.user_id).name(&name);
     app.update_user_detail(&sign_up_resp.token, params)
         .await
         .unwrap();
@@ -110,7 +110,7 @@ async fn user_update_email() {
     let app = spawn_app().await;
     let sign_up_resp = sign_up_user(&app).await;
     let email = "[email protected]".to_string();
-    let params = UpdateUserParams::new(&sign_up_resp.uid).email(&email);
+    let params = UpdateUserParams::new(&sign_up_resp.user_id).email(&email);
     app.update_user_detail(&sign_up_resp.token, params)
         .await
         .unwrap();

+ 29 - 25
backend/tests/api/helper.rs

@@ -4,7 +4,7 @@ use backend::{
 };
 
 use flowy_user::{errors::UserError, prelude::*};
-use flowy_workspace::prelude::*;
+use flowy_workspace::prelude::{server::*, *};
 use sqlx::{Connection, Executor, PgConnection, PgPool};
 use uuid::Uuid;
 
@@ -46,70 +46,74 @@ impl TestApp {
         update_user_detail_request(token, params, &url).await
     }
 
-    pub async fn create_workspace(&self, params: CreateWorkspaceParams) -> Workspace {
+    pub async fn create_workspace(&self, params: CreateWorkspaceParams, token: &str) -> Workspace {
         let url = format!("{}/api/workspace", self.address);
-        let workspace = create_workspace_request(params, &url).await.unwrap();
+        let workspace = create_workspace_request(token, params, &url).await.unwrap();
         workspace
     }
 
-    pub async fn read_workspaces(&self, params: QueryWorkspaceParams) -> RepeatedWorkspace {
+    pub async fn read_workspaces(
+        &self,
+        params: QueryWorkspaceParams,
+        token: &str,
+    ) -> RepeatedWorkspace {
         let url = format!("{}/api/workspace", self.address);
-        let workspaces = read_workspaces_request(params, &url).await.unwrap();
+        let workspaces = read_workspaces_request(token, params, &url).await.unwrap();
         workspaces
     }
 
-    pub async fn update_workspace(&self, params: UpdateWorkspaceParams) {
+    pub async fn update_workspace(&self, params: UpdateWorkspaceParams, token: &str) {
         let url = format!("{}/api/workspace", self.address);
-        update_workspace_request(params, &url).await.unwrap();
+        update_workspace_request(token, params, &url).await.unwrap();
     }
 
-    pub async fn delete_workspace(&self, params: DeleteWorkspaceParams) {
+    pub async fn delete_workspace(&self, params: DeleteWorkspaceParams, token: &str) {
         let url = format!("{}/api/workspace", self.address);
-        delete_workspace_request(params, &url).await.unwrap();
+        delete_workspace_request(token, params, &url).await.unwrap();
     }
 
-    pub async fn create_app(&self, params: CreateAppParams) -> App {
+    pub async fn create_app(&self, params: CreateAppParams, token: &str) -> App {
         let url = format!("{}/api/app", self.address);
-        let app = create_app_request(params, &url).await.unwrap();
+        let app = create_app_request(token, params, &url).await.unwrap();
         app
     }
 
-    pub async fn read_app(&self, params: QueryAppParams) -> Option<App> {
+    pub async fn read_app(&self, params: QueryAppParams, token: &str) -> Option<App> {
         let url = format!("{}/api/app", self.address);
-        let app = read_app_request(params, &url).await.unwrap();
+        let app = read_app_request(token, params, &url).await.unwrap();
         app
     }
 
-    pub async fn update_app(&self, params: UpdateAppParams) {
+    pub async fn update_app(&self, params: UpdateAppParams, token: &str) {
         let url = format!("{}/api/app", self.address);
-        update_app_request(params, &url).await.unwrap();
+        update_app_request(token, params, &url).await.unwrap();
     }
 
-    pub async fn delete_app(&self, params: DeleteAppParams) {
+    pub async fn delete_app(&self, params: DeleteAppParams, token: &str) {
         let url = format!("{}/api/app", self.address);
-        delete_app_request(params, &url).await.unwrap();
+        delete_app_request(token, params, &url).await.unwrap();
     }
 
-    pub async fn create_view(&self, params: CreateViewParams) -> View {
+    pub async fn create_view(&self, params: CreateViewParams, token: &str) -> View {
         let url = format!("{}/api/view", self.address);
-        let view = create_view_request(params, &url).await.unwrap();
+        let view = create_view_request(token, params, &url).await.unwrap();
         view
     }
 
-    pub async fn read_view(&self, params: QueryViewParams) -> Option<View> {
+    pub async fn read_view(&self, params: QueryViewParams, token: &str) -> Option<View> {
         let url = format!("{}/api/view", self.address);
-        let view = read_view_request(params, &url).await.unwrap();
+        let view = read_view_request(token, params, &url).await.unwrap();
         view
     }
 
-    pub async fn update_view(&self, params: UpdateViewParams) {
+    pub async fn update_view(&self, params: UpdateViewParams, token: &str) {
         let url = format!("{}/api/view", self.address);
-        update_view_request(params, &url).await.unwrap();
+        update_view_request(token, params, &url).await.unwrap();
     }
 
-    pub async fn delete_view(&self, params: DeleteViewParams) {
+    pub async fn delete_view(&self, params: DeleteViewParams, token: &str) {
         let url = format!("{}/api/view", self.address);
-        delete_view_request(params, &url).await.unwrap();
+        delete_view_request(token, params, &url).await.unwrap();
     }
 
     pub(crate) async fn register_test_user(&self) -> SignUpResponse {

+ 74 - 66
backend/tests/api/workspace.rs

@@ -21,21 +21,21 @@ async fn workspace_create() {
 #[actix_rt::test]
 async fn workspace_read() {
     let app = spawn_app().await;
-    let (workspace_1, user_id) = create_test_workspace(&app).await;
-    let read_params = QueryWorkspaceParams::new(&user_id).workspace_id(&workspace_1.id);
-    log::info!("{:?}", app.read_workspaces(read_params).await);
+    let (workspace_1, token) = create_test_workspace(&app).await;
+    let read_params = QueryWorkspaceParams::new().workspace_id(&workspace_1.id);
+    log::info!("{:?}", app.read_workspaces(read_params, &token).await);
 }
 
 #[actix_rt::test]
 async fn workspace_read_with_belongs() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let _ = create_test_app(&application, &workspace.id, &user_id).await;
-    let _ = create_test_app(&application, &workspace.id, &user_id).await;
-    let _ = create_test_app(&application, &workspace.id, &user_id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let _ = create_test_app(&application, &workspace.id, &token).await;
+    let _ = create_test_app(&application, &workspace.id, &token).await;
+    let _ = create_test_app(&application, &workspace.id, &token).await;
 
-    let read_params = QueryWorkspaceParams::new(&user_id).workspace_id(&workspace.id);
-    let workspaces = application.read_workspaces(read_params).await;
+    let read_params = QueryWorkspaceParams::new().workspace_id(&workspace.id);
+    let workspaces = application.read_workspaces(read_params, &token).await;
     let workspace = workspaces.items.first().unwrap();
     assert_eq!(workspace.apps.len(), 3);
 }
@@ -43,30 +43,30 @@ async fn workspace_read_with_belongs() {
 #[actix_rt::test]
 async fn workspace_update() {
     let app = spawn_app().await;
-    let (workspace_1, user_id) = create_test_workspace(&app).await;
+    let (workspace_1, token) = create_test_workspace(&app).await;
     let update_params = UpdateWorkspaceParams {
         id: workspace_1.id.clone(),
         name: Some("workspace 2".to_string()),
         desc: Some("rename workspace description".to_string()),
     };
-    app.update_workspace(update_params).await;
+    app.update_workspace(update_params, &token).await;
 
-    let read_params = QueryWorkspaceParams::new(&user_id).workspace_id(&workspace_1.id);
-    let workspace_2 = app.read_workspaces(read_params).await;
+    let read_params = QueryWorkspaceParams::new().workspace_id(&workspace_1.id);
+    let workspace_2 = app.read_workspaces(read_params, &token).await;
     log::info!("{:?}", workspace_2);
 }
 
 #[actix_rt::test]
 async fn workspace_delete() {
     let app = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&app).await;
+    let (workspace, token) = create_test_workspace(&app).await;
     let delete_params = DeleteWorkspaceParams {
         workspace_id: workspace.id.clone(),
     };
 
-    let _ = app.delete_workspace(delete_params).await;
-    let read_params = QueryWorkspaceParams::new(&user_id).workspace_id(&workspace.id);
-    let repeated_workspace = app.read_workspaces(read_params).await;
+    let _ = app.delete_workspace(delete_params, &token).await;
+    let read_params = QueryWorkspaceParams::new().workspace_id(&workspace.id);
+    let repeated_workspace = app.read_workspaces(read_params, &token).await;
     assert_eq!(repeated_workspace.len(), 0);
 }
 
@@ -76,150 +76,157 @@ async fn create_test_workspace(app: &TestApp) -> (Workspace, String) {
     let params = CreateWorkspaceParams {
         name: "My first workspace".to_string(),
         desc: "This is my first workspace".to_string(),
-        user_id: response.uid.clone(),
     };
-    let workspace = app.create_workspace(params).await;
-    (workspace, response.uid)
+    let workspace = app.create_workspace(params, &response.token).await;
+    (workspace, response.token)
 }
 
 #[actix_rt::test]
 async fn app_create() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
     log::info!("{:?}", app);
 }
 
 #[actix_rt::test]
 async fn app_read() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
     let read_params = QueryAppParams::new(&app.id);
-    log::info!("{:?}", application.read_app(read_params).await.unwrap());
+    log::info!(
+        "{:?}",
+        application.read_app(read_params, &token).await.unwrap()
+    );
 }
 
 #[actix_rt::test]
 async fn app_read_with_belongs() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
 
-    let _ = create_test_view(&application, &app.id).await;
-    let _ = create_test_view(&application, &app.id).await;
+    let _ = create_test_view(&application, &app.id, &token).await;
+    let _ = create_test_view(&application, &app.id, &token).await;
 
     let read_params = QueryAppParams::new(&app.id).read_belongings();
-    let app = application.read_app(read_params).await.unwrap();
+    let app = application.read_app(read_params, &token).await.unwrap();
     assert_eq!(app.belongings.len(), 2);
 }
 
 #[actix_rt::test]
 async fn app_read_with_belongs_in_trash() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
 
-    let _ = create_test_view(&application, &app.id).await;
-    let view = create_test_view(&application, &app.id).await;
+    let _ = create_test_view(&application, &app.id, &token).await;
+    let view = create_test_view(&application, &app.id, &token).await;
 
     let update_params = UpdateViewParams::new(&view.id).trash();
-    application.update_view(update_params).await;
+    application.update_view(update_params, &token).await;
 
     let read_params = QueryAppParams::new(&app.id).read_belongings();
-    let app = application.read_app(read_params).await.unwrap();
+    let app = application.read_app(read_params, &token).await.unwrap();
     assert_eq!(app.belongings.len(), 1);
 }
 
 #[actix_rt::test]
 async fn app_update() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
 
     let update_params = UpdateAppParams::new(&app.id).name("flowy");
-    application.update_app(update_params).await;
+    application.update_app(update_params, &token).await;
 
     let read_params = QueryAppParams::new(&app.id);
-    let app = application.read_app(read_params).await.unwrap();
+    let app = application.read_app(read_params, &token).await.unwrap();
     log::info!("{:?}", app);
 }
 
 #[actix_rt::test]
 async fn app_delete() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
 
     let delete_params = DeleteAppParams {
         app_id: app.id.clone(),
     };
-    application.delete_app(delete_params).await;
+    application.delete_app(delete_params, &token).await;
 
     let read_params = QueryAppParams::new(&app.id);
-    assert_eq!(application.read_app(read_params).await.is_none(), true);
+    assert_eq!(
+        application.read_app(read_params, &token).await.is_none(),
+        true
+    );
 }
 
-async fn create_test_app(app: &TestApp, workspace_id: &str, user_id: &str) -> App {
+async fn create_test_app(app: &TestApp, workspace_id: &str, token: &str) -> App {
     let params = CreateAppParams {
         workspace_id: workspace_id.to_owned(),
         name: "My first app".to_string(),
         desc: "This is my first app".to_string(),
         color_style: ColorStyle::default(),
-        user_id: user_id.to_string(),
     };
 
-    let app = app.create_app(params).await;
+    let app = app.create_app(params, token).await;
     app
 }
 
 #[actix_rt::test]
 async fn view_create() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
 
-    let view = create_test_view(&application, &app.id).await;
+    let view = create_test_view(&application, &app.id, &token).await;
     log::info!("{:?}", view);
 }
 
 #[actix_rt::test]
 async fn view_update() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
-    let view = create_test_view(&application, &app.id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
+    let view = create_test_view(&application, &app.id, &token).await;
 
     // update
     let update_params = UpdateViewParams::new(&view.id)
         .trash()
         .name("new view name");
-    application.update_view(update_params).await;
+    application.update_view(update_params, &token).await;
 
     // read
     let read_params = QueryViewParams::new(&view.id).trash();
-    let view = application.read_view(read_params).await;
+    let view = application.read_view(read_params, &token).await;
     log::info!("{:?}", view);
 }
 
 #[actix_rt::test]
 async fn view_delete() {
     let application = spawn_app().await;
-    let (workspace, user_id) = create_test_workspace(&application).await;
-    let app = create_test_app(&application, &workspace.id, &user_id).await;
-    let view = create_test_view(&application, &app.id).await;
+    let (workspace, token) = create_test_workspace(&application).await;
+    let app = create_test_app(&application, &workspace.id, &token).await;
+    let view = create_test_view(&application, &app.id, &token).await;
 
     // delete
     let delete_params = DeleteViewParams {
         view_id: view.id.clone(),
     };
-    application.delete_view(delete_params).await;
+    application.delete_view(delete_params, &token).await;
 
     // read
     let read_params = QueryViewParams::new(&view.id).trash();
-    assert_eq!(application.read_view(read_params).await.is_none(), true);
+    assert_eq!(
+        application.read_view(read_params, &token).await.is_none(),
+        true
+    );
 }
 
-async fn create_test_view(application: &TestApp, app_id: &str) -> View {
+async fn create_test_view(application: &TestApp, app_id: &str, token: &str) -> View {
     let params = CreateViewParams {
         belong_to_id: app_id.to_string(),
         name: "My first view".to_string(),
@@ -227,7 +234,7 @@ async fn create_test_view(application: &TestApp, app_id: &str) -> View {
         thumbnail: "http://1.png".to_string(),
         view_type: ViewType::Doc,
     };
-    let app = application.create_view(params).await;
+    let app = application.create_view(params, token).await;
     app
 }
 
@@ -239,12 +246,13 @@ async fn workspace_list_read() {
         let params = CreateWorkspaceParams {
             name: format!("{} workspace", i),
             desc: format!("This is my {} workspace", i),
-            user_id: response.uid.clone(),
         };
-        let _ = application.create_workspace(params).await;
+        let _ = application.create_workspace(params, &response.token).await;
     }
 
-    let read_params = QueryWorkspaceParams::new(&response.uid);
-    let workspaces = application.read_workspaces(read_params).await;
+    let read_params = QueryWorkspaceParams::new();
+    let workspaces = application
+        .read_workspaces(read_params, &response.token)
+        .await;
     assert_eq!(workspaces.len(), 4);
 }

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

@@ -9,4 +9,9 @@ lazy_static! {
     pub static ref SIGN_IN_URL: String = format!("{}/api/auth", HOST);
     pub static ref SIGN_OUT_URL: String = format!("{}/api/auth", HOST);
     pub static ref USER_PROFILE_URL: String = format!("{}/api/user", HOST);
+
+    //
+    pub static ref WORKSPACE_URL: String = format!("{}/api/workspace", HOST);
+    pub static ref APP_URL: String = format!("{}/api/app", HOST);
+    pub static ref VIEW_URL: String = format!("{}/api/view", HOST);
 }

+ 1 - 1
rust-lib/flowy-user/Cargo.toml

@@ -34,7 +34,7 @@ once_cell = "1.7.2"
 parking_lot = "0.11"
 strum = "0.21"
 strum_macros = "0.21"
-tokio = { version = "1", features = ["full"] }
+tokio = { version = "1", features = ["rt"] }
 pin-project = "1.0.0"
 futures-core = { version = "0.3", default-features = false }
 r2d2 = "0.8.9"

+ 3 - 5
rust-lib/flowy-user/src/entities/auth.rs

@@ -40,8 +40,7 @@ impl TryInto<SignInParams> for SignInRequest {
 
     fn try_into(self) -> Result<SignInParams, Self::Error> {
         let email = UserEmail::parse(self.email).map_err(|e| ErrorBuilder::new(e).build())?;
-        let password =
-            UserPassword::parse(self.password).map_err(|e| ErrorBuilder::new(e).build())?;
+        let password = UserPassword::parse(self.password).map_err(|e| ErrorBuilder::new(e).build())?;
 
         Ok(SignInParams {
             email: email.0,
@@ -66,8 +65,7 @@ impl TryInto<SignUpParams> for SignUpRequest {
 
     fn try_into(self) -> Result<SignUpParams, Self::Error> {
         let email = UserEmail::parse(self.email).map_err(|e| ErrorBuilder::new(e).build())?;
-        let password =
-            UserPassword::parse(self.password).map_err(|e| ErrorBuilder::new(e).build())?;
+        let password = UserPassword::parse(self.password).map_err(|e| ErrorBuilder::new(e).build())?;
         let name = UserName::parse(self.name).map_err(|e| ErrorBuilder::new(e).build())?;
 
         Ok(SignUpParams {
@@ -93,7 +91,7 @@ pub struct SignUpParams {
 #[derive(ProtoBuf, Debug, Default)]
 pub struct SignUpResponse {
     #[pb(index = 1)]
-    pub uid: String,
+    pub user_id: String,
 
     #[pb(index = 2)]
     pub name: String,

+ 30 - 30
rust-lib/flowy-user/src/protobuf/model/auth.rs

@@ -1199,7 +1199,7 @@ impl ::protobuf::reflect::ProtobufValue for SignUpParams {
 #[derive(PartialEq,Clone,Default)]
 pub struct SignUpResponse {
     // message fields
-    pub uid: ::std::string::String,
+    pub user_id: ::std::string::String,
     pub name: ::std::string::String,
     pub email: ::std::string::String,
     pub token: ::std::string::String,
@@ -1219,30 +1219,30 @@ impl SignUpResponse {
         ::std::default::Default::default()
     }
 
-    // string uid = 1;
+    // string user_id = 1;
 
 
-    pub fn get_uid(&self) -> &str {
-        &self.uid
+    pub fn get_user_id(&self) -> &str {
+        &self.user_id
     }
-    pub fn clear_uid(&mut self) {
-        self.uid.clear();
+    pub fn clear_user_id(&mut self) {
+        self.user_id.clear();
     }
 
     // Param is passed by value, moved
-    pub fn set_uid(&mut self, v: ::std::string::String) {
-        self.uid = v;
+    pub fn set_user_id(&mut self, v: ::std::string::String) {
+        self.user_id = v;
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_uid(&mut self) -> &mut ::std::string::String {
-        &mut self.uid
+    pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
+        &mut self.user_id
     }
 
     // Take field
-    pub fn take_uid(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.uid, ::std::string::String::new())
+    pub fn take_user_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.user_id, ::std::string::String::new())
     }
 
     // string name = 2;
@@ -1334,7 +1334,7 @@ impl ::protobuf::Message for SignUpResponse {
             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.uid)?;
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
                 },
                 2 => {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
@@ -1357,8 +1357,8 @@ impl ::protobuf::Message for SignUpResponse {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if !self.uid.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.uid);
+        if !self.user_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.user_id);
         }
         if !self.name.is_empty() {
             my_size += ::protobuf::rt::string_size(2, &self.name);
@@ -1375,8 +1375,8 @@ impl ::protobuf::Message for SignUpResponse {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if !self.uid.is_empty() {
-            os.write_string(1, &self.uid)?;
+        if !self.user_id.is_empty() {
+            os.write_string(1, &self.user_id)?;
         }
         if !self.name.is_empty() {
             os.write_string(2, &self.name)?;
@@ -1426,9 +1426,9 @@ impl ::protobuf::Message for SignUpResponse {
         descriptor.get(|| {
             let mut fields = ::std::vec::Vec::new();
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "uid",
-                |m: &SignUpResponse| { &m.uid },
-                |m: &mut SignUpResponse| { &mut m.uid },
+                "user_id",
+                |m: &SignUpResponse| { &m.user_id },
+                |m: &mut SignUpResponse| { &mut m.user_id },
             ));
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
                 "name",
@@ -1461,7 +1461,7 @@ impl ::protobuf::Message for SignUpResponse {
 
 impl ::protobuf::Clear for SignUpResponse {
     fn clear(&mut self) {
-        self.uid.clear();
+        self.user_id.clear();
         self.name.clear();
         self.email.clear();
         self.token.clear();
@@ -1493,12 +1493,12 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x01(\tR\x04name\x12\x1a\n\x08password\x18\x03\x20\x01(\tR\x08password\"\
     T\n\x0cSignUpParams\x12\x14\n\x05email\x18\x01\x20\x01(\tR\x05email\x12\
     \x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x1a\n\x08password\x18\x03\
-    \x20\x01(\tR\x08password\"b\n\x0eSignUpResponse\x12\x10\n\x03uid\x18\x01\
-    \x20\x01(\tR\x03uid\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\
-    \x14\n\x05email\x18\x03\x20\x01(\tR\x05email\x12\x14\n\x05token\x18\x04\
-    \x20\x01(\tR\x05tokenJ\x80\t\n\x06\x12\x04\0\0\x1f\x01\n\x08\n\x01\x0c\
-    \x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\
-    \x01\x12\x03\x02\x08\x15\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x15\n\
+    \x20\x01(\tR\x08password\"i\n\x0eSignUpResponse\x12\x17\n\x07user_id\x18\
+    \x01\x20\x01(\tR\x06userId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\
+    \x12\x14\n\x05email\x18\x03\x20\x01(\tR\x05email\x12\x14\n\x05token\x18\
+    \x04\x20\x01(\tR\x05tokenJ\x80\t\n\x06\x12\x04\0\0\x1f\x01\n\x08\n\x01\
+    \x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\
+    \0\x01\x12\x03\x02\x08\x15\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x15\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\x10\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x13\x14\n\
     \x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x18\n\x0c\n\x05\x04\0\x02\x01\
@@ -1543,9 +1543,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x12\x03\x18\x04\n\n\x0c\n\x05\x04\x04\x02\x02\x01\x12\x03\x18\x0b\x13\n\
     \x0c\n\x05\x04\x04\x02\x02\x03\x12\x03\x18\x16\x17\n\n\n\x02\x04\x05\x12\
     \x04\x1a\0\x1f\x01\n\n\n\x03\x04\x05\x01\x12\x03\x1a\x08\x16\n\x0b\n\x04\
-    \x04\x05\x02\0\x12\x03\x1b\x04\x13\n\x0c\n\x05\x04\x05\x02\0\x05\x12\x03\
-    \x1b\x04\n\n\x0c\n\x05\x04\x05\x02\0\x01\x12\x03\x1b\x0b\x0e\n\x0c\n\x05\
-    \x04\x05\x02\0\x03\x12\x03\x1b\x11\x12\n\x0b\n\x04\x04\x05\x02\x01\x12\
+    \x04\x05\x02\0\x12\x03\x1b\x04\x17\n\x0c\n\x05\x04\x05\x02\0\x05\x12\x03\
+    \x1b\x04\n\n\x0c\n\x05\x04\x05\x02\0\x01\x12\x03\x1b\x0b\x12\n\x0c\n\x05\
+    \x04\x05\x02\0\x03\x12\x03\x1b\x15\x16\n\x0b\n\x04\x04\x05\x02\x01\x12\
     \x03\x1c\x04\x14\n\x0c\n\x05\x04\x05\x02\x01\x05\x12\x03\x1c\x04\n\n\x0c\
     \n\x05\x04\x05\x02\x01\x01\x12\x03\x1c\x0b\x0f\n\x0c\n\x05\x04\x05\x02\
     \x01\x03\x12\x03\x1c\x12\x13\n\x0b\n\x04\x04\x05\x02\x02\x12\x03\x1d\x04\

+ 1 - 1
rust-lib/flowy-user/src/protobuf/proto/auth.proto

@@ -25,7 +25,7 @@ message SignUpParams {
     string password = 3;
 }
 message SignUpResponse {
-    string uid = 1;
+    string user_id = 1;
     string name = 2;
     string email = 3;
     string token = 4;

+ 5 - 20
rust-lib/flowy-user/src/services/server/server_api_mock.rs

@@ -1,12 +1,5 @@
 use crate::{
-    entities::{
-        SignInParams,
-        SignInResponse,
-        SignUpParams,
-        SignUpResponse,
-        UpdateUserParams,
-        UserDetail,
-    },
+    entities::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserDetail},
     errors::{ErrorBuilder, ErrorCode, UserError},
 };
 
@@ -22,7 +15,7 @@ impl UserServerAPI for UserServerMock {
         let uid = uuid();
         ResultFuture::new(async move {
             Ok(SignUpResponse {
-                uid,
+                user_id: uid,
                 name: params.name,
                 email: params.email,
                 token: "fake token".to_owned(),
@@ -41,19 +34,11 @@ impl UserServerAPI for UserServerMock {
         })
     }
 
-    fn sign_out(&self, _token: &str) -> ResultFuture<(), UserError> {
-        ResultFuture::new(async { Ok(()) })
-    }
+    fn sign_out(&self, _token: &str) -> ResultFuture<(), UserError> { ResultFuture::new(async { Ok(()) }) }
 
-    fn update_user(&self, _token: &str, _params: UpdateUserParams) -> ResultFuture<(), UserError> {
-        ResultFuture::new(async { Ok(()) })
-    }
+    fn update_user(&self, _token: &str, _params: UpdateUserParams) -> ResultFuture<(), UserError> { ResultFuture::new(async { Ok(()) }) }
 
     fn get_user_detail(&self, _token: &str) -> ResultFuture<UserDetail, UserError> {
-        ResultFuture::new(async {
-            Err(ErrorBuilder::new(ErrorCode::Unknown)
-                .msg("mock data, ignore this error")
-                .build())
-        })
+        ResultFuture::new(async { Err(ErrorBuilder::new(ErrorCode::Unknown).msg("mock data, ignore this error").build()) })
     }
 }

+ 6 - 19
rust-lib/flowy-user/src/services/user/user_session.rs

@@ -80,7 +80,7 @@ impl UserSession {
 
     pub async fn sign_up(&self, params: SignUpParams) -> Result<UserTable, UserError> {
         let resp = self.server.sign_up(params).await?;
-        let session = Session::new(&resp.uid, &resp.token);
+        let session = Session::new(&resp.user_id, &resp.token);
         let _ = self.set_session(Some(session))?;
         let user_table = self.save_user(resp.into()).await?;
 
@@ -95,8 +95,7 @@ impl UserSession {
         }
 
         let conn = self.get_db_connection()?;
-        let _ =
-            diesel::delete(dsl::user_table.filter(dsl::id.eq(&session.user_id))).execute(&*conn)?;
+        let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&session.user_id))).execute(&*conn)?;
         let _ = self.server.sign_out(&session.token);
         let _ = self.database.close_user_db(&session.user_id)?;
         let _ = self.set_session(None)?;
@@ -106,11 +105,7 @@ impl UserSession {
 
     pub async fn update_user(&self, params: UpdateUserParams) -> Result<(), UserError> {
         let session = self.get_session()?;
-        match self
-            .server
-            .update_user(&session.token, params.clone())
-            .await
-        {
+        match self.server.update_user(&session.token, params.clone()).await {
             Ok(_) => {},
             Err(e) => {
                 // TODO: retry?
@@ -161,9 +156,7 @@ impl UserSession {
 impl UserSession {
     async fn save_user(&self, user: UserTable) -> Result<UserTable, UserError> {
         let conn = self.get_db_connection()?;
-        let _ = diesel::insert_into(user_table::table)
-            .values(user.clone())
-            .execute(&*conn)?;
+        let _ = diesel::insert_into(user_table::table).values(user.clone()).execute(&*conn)?;
 
         Ok(user)
     }
@@ -202,11 +195,7 @@ impl UserSession {
     }
 }
 
-pub async fn update_user(
-    _server: Server,
-    pool: Arc<ConnectionPool>,
-    params: UpdateUserParams,
-) -> Result<(), UserError> {
+pub async fn update_user(_server: Server, pool: Arc<ConnectionPool>, params: UpdateUserParams) -> Result<(), UserError> {
     let changeset = UserTableChangeset::new(params);
     let conn = pool.get()?;
     diesel_update_table!(user_table, changeset, conn);
@@ -221,9 +210,7 @@ pub fn current_user_id() -> Result<String, UserError> {
 }
 
 impl UserDatabaseConnection for UserSession {
-    fn get_connection(&self) -> Result<DBConnection, String> {
-        self.get_db_connection().map_err(|e| format!("{:?}", e))
-    }
+    fn get_connection(&self) -> Result<DBConnection, String> { self.get_db_connection().map_err(|e| format!("{:?}", e)) }
 }
 
 const SESSION_CACHE_KEY: &str = "session_cache_key";

+ 2 - 6
rust-lib/flowy-user/src/sql_tables/user.rs

@@ -29,15 +29,11 @@ impl UserTable {
 }
 
 impl std::convert::From<SignUpResponse> for UserTable {
-    fn from(resp: SignUpResponse) -> Self {
-        UserTable::new(resp.uid, resp.name, resp.email, "".to_owned())
-    }
+    fn from(resp: SignUpResponse) -> Self { UserTable::new(resp.user_id, resp.name, resp.email, "".to_owned()) }
 }
 
 impl std::convert::From<SignInResponse> for UserTable {
-    fn from(resp: SignInResponse) -> Self {
-        UserTable::new(resp.uid, resp.name, resp.email, resp.token)
-    }
+    fn from(resp: SignInResponse) -> Self { UserTable::new(resp.uid, resp.name, resp.email, resp.token) }
 }
 
 #[derive(AsChangeset, Identifiable, Default, Debug)]

+ 3 - 2
rust-lib/flowy-workspace/Cargo.toml

@@ -13,16 +13,17 @@ flowy-database = { path = "../flowy-database" }
 flowy-sqlite = { path = "../flowy-sqlite" }
 flowy-infra = { path = "../flowy-infra" }
 flowy-observable = { path = "../flowy-observable" }
+flowy-net = { path = "../flowy-net" }
+
 protobuf = {version = "2.18.0"}
 log = "0.4.14"
 diesel = {version = "1.4.7", features = ["sqlite"]}
 diesel_derives = {version = "1.4.1", features = ["sqlite"]}
 futures-core = { version = "0.3", default-features = false }
 pin-project = "1.0.0"
-flowy-net = { path = "../flowy-net" }
 strum = "0.21"
 strum_macros = "0.21"
-
+tokio = { version = "1", features = ["rt"] }
 lazy_static = "1.4.0"
 serde = { version = "1.0", features = ["derive"] }
 derive_more = {version = "0.99", features = ["display"]}

+ 4 - 16
rust-lib/flowy-workspace/src/entities/app/app_create.rs

@@ -45,36 +45,24 @@ pub struct CreateAppParams {
 
     #[pb(index = 4)]
     pub color_style: ColorStyle,
-
-    #[pb(index = 5)]
-    pub user_id: String,
 }
 
 impl TryInto<CreateAppParams> for CreateAppRequest {
     type Error = WorkspaceError;
 
     fn try_into(self) -> Result<CreateAppParams, Self::Error> {
-        let name = AppName::parse(self.name)
-            .map_err(|e| ErrorBuilder::new(ErrorCode::AppNameInvalid).msg(e).build())?;
+        let name = AppName::parse(self.name).map_err(|e| ErrorBuilder::new(ErrorCode::AppNameInvalid).msg(e).build())?;
 
-        let id = WorkspaceId::parse(self.workspace_id).map_err(|e| {
-            ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid)
-                .msg(e)
-                .build()
-        })?;
+        let id = WorkspaceId::parse(self.workspace_id).map_err(|e| ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid).msg(e).build())?;
 
-        let color_style = AppColorStyle::parse(self.color_style).map_err(|e| {
-            ErrorBuilder::new(ErrorCode::AppColorStyleInvalid)
-                .msg(e)
-                .build()
-        })?;
+        let color_style =
+            AppColorStyle::parse(self.color_style).map_err(|e| ErrorBuilder::new(ErrorCode::AppColorStyleInvalid).msg(e).build())?;
 
         Ok(CreateAppParams {
             workspace_id: id.0,
             name: name.0,
             desc: self.desc,
             color_style: color_style.0,
-            user_id: "".to_string(),
         })
     }
 }

+ 3 - 24
rust-lib/flowy-workspace/src/entities/workspace/workspace_create.rs

@@ -13,49 +13,28 @@ pub struct CreateWorkspaceRequest {
 
     #[pb(index = 2)]
     pub desc: String,
-
-    #[pb(index = 3)]
-    pub user_id: String,
 }
 
-#[derive(ProtoBuf, Default)]
+#[derive(Clone, ProtoBuf, Default)]
 pub struct CreateWorkspaceParams {
     #[pb(index = 1)]
     pub name: String,
 
     #[pb(index = 2)]
     pub desc: String,
-
-    #[pb(index = 3)]
-    pub user_id: String,
 }
 
 impl TryInto<CreateWorkspaceParams> for CreateWorkspaceRequest {
     type Error = WorkspaceError;
 
     fn try_into(self) -> Result<CreateWorkspaceParams, Self::Error> {
-        let name = WorkspaceName::parse(self.name).map_err(|e| {
-            ErrorBuilder::new(ErrorCode::WorkspaceNameInvalid)
-                .msg(e)
-                .build()
-        })?;
-
-        let desc = WorkspaceDesc::parse(self.desc).map_err(|e| {
-            ErrorBuilder::new(ErrorCode::WorkspaceDescInvalid)
-                .msg(e)
-                .build()
-        })?;
+        let name = WorkspaceName::parse(self.name).map_err(|e| ErrorBuilder::new(ErrorCode::WorkspaceNameInvalid).msg(e).build())?;
 
-        if self.user_id.is_empty() {
-            return Err(ErrorBuilder::new(ErrorCode::UserIdIsEmpty)
-                .msg("Create workspace failed. UserId is empty")
-                .build());
-        }
+        let desc = WorkspaceDesc::parse(self.desc).map_err(|e| ErrorBuilder::new(ErrorCode::WorkspaceDescInvalid).msg(e).build())?;
 
         Ok(CreateWorkspaceParams {
             name: name.0,
             desc: desc.0,
-            user_id: self.user_id,
         })
     }
 }

+ 5 - 24
rust-lib/flowy-workspace/src/entities/workspace/workspace_query.rs

@@ -7,18 +7,10 @@ pub struct QueryWorkspaceRequest {
     // return all workspace if workspace_id is None
     #[pb(index = 1, one_of)]
     pub workspace_id: Option<String>,
-
-    #[pb(index = 2)]
-    pub user_id: String,
 }
 
 impl QueryWorkspaceRequest {
-    pub fn new(user_id: &str) -> Self {
-        Self {
-            workspace_id: None,
-            user_id: user_id.to_owned(),
-        }
-    }
+    pub fn new() -> Self { Self { workspace_id: None } }
 
     pub fn workspace_id(mut self, workspace_id: &str) -> Self {
         self.workspace_id = Some(workspace_id.to_owned());
@@ -27,20 +19,16 @@ impl QueryWorkspaceRequest {
 }
 
 // Read all workspaces if the workspace_id is None
-#[derive(ProtoBuf, Default)]
+#[derive(Clone, ProtoBuf, Default)]
 pub struct QueryWorkspaceParams {
     #[pb(index = 1, one_of)]
     pub workspace_id: Option<String>,
-
-    #[pb(index = 2)]
-    pub user_id: String,
 }
 
 impl QueryWorkspaceParams {
-    pub fn new(user_id: &str) -> Self {
+    pub fn new() -> Self {
         Self {
             workspace_id: None,
-            user_id: user_id.to_owned(),
             ..Default::default()
         }
     }
@@ -59,18 +47,11 @@ impl TryInto<QueryWorkspaceParams> for QueryWorkspaceRequest {
             None => None,
             Some(workspace_id) => Some(
                 WorkspaceId::parse(workspace_id)
-                    .map_err(|e| {
-                        ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid)
-                            .msg(e)
-                            .build()
-                    })?
+                    .map_err(|e| ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid).msg(e).build())?
                     .0,
             ),
         };
 
-        Ok(QueryWorkspaceParams {
-            workspace_id,
-            user_id: self.user_id,
-        })
+        Ok(QueryWorkspaceParams { workspace_id })
     }
 }

+ 3 - 11
rust-lib/flowy-workspace/src/entities/workspace/workspace_update.rs

@@ -16,7 +16,7 @@ pub struct UpdateWorkspaceRequest {
     desc: Option<String>,
 }
 
-#[derive(ProtoBuf, Default)]
+#[derive(Clone, ProtoBuf, Default)]
 pub struct UpdateWorkspaceParams {
     #[pb(index = 1)]
     pub id: String,
@@ -36,20 +36,12 @@ impl TryInto<UpdateWorkspaceParams> for UpdateWorkspaceRequest {
             None => None,
             Some(name) => Some(
                 WorkspaceName::parse(name)
-                    .map_err(|e| {
-                        ErrorBuilder::new(ErrorCode::WorkspaceNameInvalid)
-                            .msg(e)
-                            .build()
-                    })?
+                    .map_err(|e| ErrorBuilder::new(ErrorCode::WorkspaceNameInvalid).msg(e).build())?
                     .0,
             ),
         };
 
-        let id = WorkspaceId::parse(self.id).map_err(|e| {
-            ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid)
-                .msg(e)
-                .build()
-        })?;
+        let id = WorkspaceId::parse(self.id).map_err(|e| ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid).msg(e).build())?;
 
         Ok(UpdateWorkspaceParams {
             id: id.0,

+ 1 - 1
rust-lib/flowy-workspace/src/handlers/workspace_handler.rs

@@ -29,7 +29,7 @@ pub(crate) async fn read_workspaces(
     controller: Unit<Arc<WorkspaceController>>,
 ) -> DataResult<RepeatedWorkspace, WorkspaceError> {
     let params: QueryWorkspaceParams = data.into_inner().try_into()?;
-    let workspaces = controller.read_workspaces(params.workspace_id).await?;
+    let workspaces = controller.read_workspaces(params).await?;
     data_result(workspaces)
 }
 

+ 0 - 3
rust-lib/flowy-workspace/src/module.rs

@@ -18,9 +18,6 @@ pub trait WorkspaceDeps: WorkspaceUser + WorkspaceDatabase {}
 pub trait WorkspaceUser: Send + Sync {
     fn user_id(&self) -> Result<String, WorkspaceError>;
     fn token(&self) -> Result<String, WorkspaceError>;
-    // fn set_cur_workspace_id(&self, id: &str) -> DispatchFuture<Result<(),
-    // WorkspaceError>>; fn get_cur_workspace(&self) ->
-    // DispatchFuture<Result<CurrentWorkspace, WorkspaceError>>;
 }
 
 pub trait WorkspaceDatabase: Send + Sync {

+ 60 - 106
rust-lib/flowy-workspace/src/protobuf/model/app_create.rs

@@ -489,7 +489,6 @@ pub struct CreateAppParams {
     pub name: ::std::string::String,
     pub desc: ::std::string::String,
     pub color_style: ::protobuf::SingularPtrField<ColorStyle>,
-    pub user_id: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -616,32 +615,6 @@ impl CreateAppParams {
     pub fn take_color_style(&mut self) -> ColorStyle {
         self.color_style.take().unwrap_or_else(|| ColorStyle::new())
     }
-
-    // string user_id = 5;
-
-
-    pub fn get_user_id(&self) -> &str {
-        &self.user_id
-    }
-    pub fn clear_user_id(&mut self) {
-        self.user_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_user_id(&mut self, v: ::std::string::String) {
-        self.user_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
-        &mut self.user_id
-    }
-
-    // Take field
-    pub fn take_user_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.user_id, ::std::string::String::new())
-    }
 }
 
 impl ::protobuf::Message for CreateAppParams {
@@ -670,9 +643,6 @@ impl ::protobuf::Message for CreateAppParams {
                 4 => {
                     ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.color_style)?;
                 },
-                5 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
-                },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                 },
@@ -698,9 +668,6 @@ impl ::protobuf::Message for CreateAppParams {
             let len = v.compute_size();
             my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
         }
-        if !self.user_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(5, &self.user_id);
-        }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
         my_size
@@ -721,9 +688,6 @@ impl ::protobuf::Message for CreateAppParams {
             os.write_raw_varint32(v.get_cached_size())?;
             v.write_to_with_cached_sizes(os)?;
         }
-        if !self.user_id.is_empty() {
-            os.write_string(5, &self.user_id)?;
-        }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
     }
@@ -782,11 +746,6 @@ impl ::protobuf::Message for CreateAppParams {
                 |m: &CreateAppParams| { &m.color_style },
                 |m: &mut CreateAppParams| { &mut m.color_style },
             ));
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "user_id",
-                |m: &CreateAppParams| { &m.user_id },
-                |m: &mut CreateAppParams| { &mut m.user_id },
-            ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateAppParams>(
                 "CreateAppParams",
                 fields,
@@ -807,7 +766,6 @@ impl ::protobuf::Clear for CreateAppParams {
         self.name.clear();
         self.desc.clear();
         self.color_style.clear();
-        self.user_id.clear();
         self.unknown_fields.clear();
     }
 }
@@ -1373,72 +1331,68 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\
     \x01(\tR\x04desc\x12,\n\x0bcolor_style\x18\x04\x20\x01(\x0b2\x0b.ColorSt\
     yleR\ncolorStyle\"-\n\nColorStyle\x12\x1f\n\x0btheme_color\x18\x01\x20\
-    \x01(\tR\nthemeColor\"\xa3\x01\n\x0fCreateAppParams\x12!\n\x0cworkspace_\
+    \x01(\tR\nthemeColor\"\x8a\x01\n\x0fCreateAppParams\x12!\n\x0cworkspace_\
     id\x18\x01\x20\x01(\tR\x0bworkspaceId\x12\x12\n\x04name\x18\x02\x20\x01(\
     \tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12,\n\x0bcolo\
-    r_style\x18\x04\x20\x01(\x0b2\x0b.ColorStyleR\ncolorStyle\x12\x17\n\x07u\
-    ser_id\x18\x05\x20\x01(\tR\x06userId\"\xa9\x01\n\x03App\x12\x0e\n\x02id\
-    \x18\x01\x20\x01(\tR\x02id\x12!\n\x0cworkspace_id\x18\x02\x20\x01(\tR\
-    \x0bworkspaceId\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04name\x12\x12\n\
-    \x04desc\x18\x04\x20\x01(\tR\x04desc\x12-\n\nbelongings\x18\x05\x20\x01(\
-    \x0b2\r.RepeatedViewR\nbelongings\x12\x18\n\x07version\x18\x06\x20\x01(\
-    \x03R\x07version\")\n\x0bRepeatedApp\x12\x1a\n\x05items\x18\x01\x20\x03(\
-    \x0b2\x04.AppR\x05itemsJ\xca\x08\n\x06\x12\x04\0\0\x1d\x01\n\x08\n\x01\
-    \x0c\x12\x03\0\0\x12\n\t\n\x02\x03\0\x12\x03\x01\0\x1b\n\n\n\x02\x04\0\
-    \x12\x04\x03\0\x08\x01\n\n\n\x03\x04\0\x01\x12\x03\x03\x08\x18\n\x0b\n\
-    \x04\x04\0\x02\0\x12\x03\x04\x04\x1c\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\
-    \x04\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x04\x0b\x17\n\x0c\n\x05\
-    \x04\0\x02\0\x03\x12\x03\x04\x1a\x1b\n\x0b\n\x04\x04\0\x02\x01\x12\x03\
-    \x05\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x05\x04\n\n\x0c\n\x05\
-    \x04\0\x02\x01\x01\x12\x03\x05\x0b\x0f\n\x0c\n\x05\x04\0\x02\x01\x03\x12\
-    \x03\x05\x12\x13\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x06\x04\x14\n\x0c\n\
-    \x05\x04\0\x02\x02\x05\x12\x03\x06\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\
-    \x12\x03\x06\x0b\x0f\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x06\x12\x13\n\
-    \x0b\n\x04\x04\0\x02\x03\x12\x03\x07\x04\x1f\n\x0c\n\x05\x04\0\x02\x03\
-    \x06\x12\x03\x07\x04\x0e\n\x0c\n\x05\x04\0\x02\x03\x01\x12\x03\x07\x0f\
-    \x1a\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x07\x1d\x1e\n\n\n\x02\x04\x01\
-    \x12\x04\t\0\x0b\x01\n\n\n\x03\x04\x01\x01\x12\x03\t\x08\x12\n\x0b\n\x04\
-    \x04\x01\x02\0\x12\x03\n\x04\x1b\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\n\
-    \x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\n\x0b\x16\n\x0c\n\x05\x04\
-    \x01\x02\0\x03\x12\x03\n\x19\x1a\n\n\n\x02\x04\x02\x12\x04\x0c\0\x12\x01\
-    \n\n\n\x03\x04\x02\x01\x12\x03\x0c\x08\x17\n\x0b\n\x04\x04\x02\x02\0\x12\
-    \x03\r\x04\x1c\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\r\x04\n\n\x0c\n\x05\
-    \x04\x02\x02\0\x01\x12\x03\r\x0b\x17\n\x0c\n\x05\x04\x02\x02\0\x03\x12\
-    \x03\r\x1a\x1b\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0e\x04\x14\n\x0c\n\
-    \x05\x04\x02\x02\x01\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\x01\
-    \x01\x12\x03\x0e\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0e\x12\
-    \x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x0f\x04\x14\n\x0c\n\x05\x04\x02\
-    \x02\x02\x05\x12\x03\x0f\x04\n\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\
-    \x0f\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0f\x12\x13\n\x0b\n\
-    \x04\x04\x02\x02\x03\x12\x03\x10\x04\x1f\n\x0c\n\x05\x04\x02\x02\x03\x06\
-    \x12\x03\x10\x04\x0e\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03\x10\x0f\x1a\
-    \n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03\x10\x1d\x1e\n\x0b\n\x04\x04\x02\
-    \x02\x04\x12\x03\x11\x04\x17\n\x0c\n\x05\x04\x02\x02\x04\x05\x12\x03\x11\
-    \x04\n\n\x0c\n\x05\x04\x02\x02\x04\x01\x12\x03\x11\x0b\x12\n\x0c\n\x05\
-    \x04\x02\x02\x04\x03\x12\x03\x11\x15\x16\n\n\n\x02\x04\x03\x12\x04\x13\0\
-    \x1a\x01\n\n\n\x03\x04\x03\x01\x12\x03\x13\x08\x0b\n\x0b\n\x04\x04\x03\
-    \x02\0\x12\x03\x14\x04\x12\n\x0c\n\x05\x04\x03\x02\0\x05\x12\x03\x14\x04\
-    \n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x14\x0b\r\n\x0c\n\x05\x04\x03\
-    \x02\0\x03\x12\x03\x14\x10\x11\n\x0b\n\x04\x04\x03\x02\x01\x12\x03\x15\
-    \x04\x1c\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x15\x04\n\n\x0c\n\x05\
-    \x04\x03\x02\x01\x01\x12\x03\x15\x0b\x17\n\x0c\n\x05\x04\x03\x02\x01\x03\
-    \x12\x03\x15\x1a\x1b\n\x0b\n\x04\x04\x03\x02\x02\x12\x03\x16\x04\x14\n\
-    \x0c\n\x05\x04\x03\x02\x02\x05\x12\x03\x16\x04\n\n\x0c\n\x05\x04\x03\x02\
-    \x02\x01\x12\x03\x16\x0b\x0f\n\x0c\n\x05\x04\x03\x02\x02\x03\x12\x03\x16\
-    \x12\x13\n\x0b\n\x04\x04\x03\x02\x03\x12\x03\x17\x04\x14\n\x0c\n\x05\x04\
-    \x03\x02\x03\x05\x12\x03\x17\x04\n\n\x0c\n\x05\x04\x03\x02\x03\x01\x12\
-    \x03\x17\x0b\x0f\n\x0c\n\x05\x04\x03\x02\x03\x03\x12\x03\x17\x12\x13\n\
-    \x0b\n\x04\x04\x03\x02\x04\x12\x03\x18\x04\x20\n\x0c\n\x05\x04\x03\x02\
-    \x04\x06\x12\x03\x18\x04\x10\n\x0c\n\x05\x04\x03\x02\x04\x01\x12\x03\x18\
-    \x11\x1b\n\x0c\n\x05\x04\x03\x02\x04\x03\x12\x03\x18\x1e\x1f\n\x0b\n\x04\
-    \x04\x03\x02\x05\x12\x03\x19\x04\x16\n\x0c\n\x05\x04\x03\x02\x05\x05\x12\
-    \x03\x19\x04\t\n\x0c\n\x05\x04\x03\x02\x05\x01\x12\x03\x19\n\x11\n\x0c\n\
-    \x05\x04\x03\x02\x05\x03\x12\x03\x19\x14\x15\n\n\n\x02\x04\x04\x12\x04\
-    \x1b\0\x1d\x01\n\n\n\x03\x04\x04\x01\x12\x03\x1b\x08\x13\n\x0b\n\x04\x04\
-    \x04\x02\0\x12\x03\x1c\x04\x1b\n\x0c\n\x05\x04\x04\x02\0\x04\x12\x03\x1c\
-    \x04\x0c\n\x0c\n\x05\x04\x04\x02\0\x06\x12\x03\x1c\r\x10\n\x0c\n\x05\x04\
-    \x04\x02\0\x01\x12\x03\x1c\x11\x16\n\x0c\n\x05\x04\x04\x02\0\x03\x12\x03\
-    \x1c\x19\x1ab\x06proto3\
+    r_style\x18\x04\x20\x01(\x0b2\x0b.ColorStyleR\ncolorStyle\"\xa9\x01\n\
+    \x03App\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12!\n\x0cworkspace_id\
+    \x18\x02\x20\x01(\tR\x0bworkspaceId\x12\x12\n\x04name\x18\x03\x20\x01(\t\
+    R\x04name\x12\x12\n\x04desc\x18\x04\x20\x01(\tR\x04desc\x12-\n\nbelongin\
+    gs\x18\x05\x20\x01(\x0b2\r.RepeatedViewR\nbelongings\x12\x18\n\x07versio\
+    n\x18\x06\x20\x01(\x03R\x07version\")\n\x0bRepeatedApp\x12\x1a\n\x05item\
+    s\x18\x01\x20\x03(\x0b2\x04.AppR\x05itemsJ\x93\x08\n\x06\x12\x04\0\0\x1c\
+    \x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\t\n\x02\x03\0\x12\x03\x01\0\x1b\n\
+    \n\n\x02\x04\0\x12\x04\x03\0\x08\x01\n\n\n\x03\x04\0\x01\x12\x03\x03\x08\
+    \x18\n\x0b\n\x04\x04\0\x02\0\x12\x03\x04\x04\x1c\n\x0c\n\x05\x04\0\x02\0\
+    \x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x04\x0b\x17\n\
+    \x0c\n\x05\x04\0\x02\0\x03\x12\x03\x04\x1a\x1b\n\x0b\n\x04\x04\0\x02\x01\
+    \x12\x03\x05\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x05\x04\n\n\
+    \x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x05\x0b\x0f\n\x0c\n\x05\x04\0\x02\
+    \x01\x03\x12\x03\x05\x12\x13\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x06\x04\
+    \x14\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x06\x04\n\n\x0c\n\x05\x04\0\
+    \x02\x02\x01\x12\x03\x06\x0b\x0f\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\
+    \x06\x12\x13\n\x0b\n\x04\x04\0\x02\x03\x12\x03\x07\x04\x1f\n\x0c\n\x05\
+    \x04\0\x02\x03\x06\x12\x03\x07\x04\x0e\n\x0c\n\x05\x04\0\x02\x03\x01\x12\
+    \x03\x07\x0f\x1a\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\x07\x1d\x1e\n\n\n\
+    \x02\x04\x01\x12\x04\t\0\x0b\x01\n\n\n\x03\x04\x01\x01\x12\x03\t\x08\x12\
+    \n\x0b\n\x04\x04\x01\x02\0\x12\x03\n\x04\x1b\n\x0c\n\x05\x04\x01\x02\0\
+    \x05\x12\x03\n\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\n\x0b\x16\n\
+    \x0c\n\x05\x04\x01\x02\0\x03\x12\x03\n\x19\x1a\n\n\n\x02\x04\x02\x12\x04\
+    \x0c\0\x11\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0c\x08\x17\n\x0b\n\x04\x04\
+    \x02\x02\0\x12\x03\r\x04\x1c\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\r\x04\
+    \n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\r\x0b\x17\n\x0c\n\x05\x04\x02\
+    \x02\0\x03\x12\x03\r\x1a\x1b\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0e\x04\
+    \x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\
+    \x02\x02\x01\x01\x12\x03\x0e\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\
+    \x03\x0e\x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x0f\x04\x14\n\x0c\n\
+    \x05\x04\x02\x02\x02\x05\x12\x03\x0f\x04\n\n\x0c\n\x05\x04\x02\x02\x02\
+    \x01\x12\x03\x0f\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0f\x12\
+    \x13\n\x0b\n\x04\x04\x02\x02\x03\x12\x03\x10\x04\x1f\n\x0c\n\x05\x04\x02\
+    \x02\x03\x06\x12\x03\x10\x04\x0e\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03\
+    \x10\x0f\x1a\n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03\x10\x1d\x1e\n\n\n\
+    \x02\x04\x03\x12\x04\x12\0\x19\x01\n\n\n\x03\x04\x03\x01\x12\x03\x12\x08\
+    \x0b\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x13\x04\x12\n\x0c\n\x05\x04\x03\
+    \x02\0\x05\x12\x03\x13\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x13\
+    \x0b\r\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x13\x10\x11\n\x0b\n\x04\x04\
+    \x03\x02\x01\x12\x03\x14\x04\x1c\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\
+    \x14\x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x14\x0b\x17\n\x0c\n\
+    \x05\x04\x03\x02\x01\x03\x12\x03\x14\x1a\x1b\n\x0b\n\x04\x04\x03\x02\x02\
+    \x12\x03\x15\x04\x14\n\x0c\n\x05\x04\x03\x02\x02\x05\x12\x03\x15\x04\n\n\
+    \x0c\n\x05\x04\x03\x02\x02\x01\x12\x03\x15\x0b\x0f\n\x0c\n\x05\x04\x03\
+    \x02\x02\x03\x12\x03\x15\x12\x13\n\x0b\n\x04\x04\x03\x02\x03\x12\x03\x16\
+    \x04\x14\n\x0c\n\x05\x04\x03\x02\x03\x05\x12\x03\x16\x04\n\n\x0c\n\x05\
+    \x04\x03\x02\x03\x01\x12\x03\x16\x0b\x0f\n\x0c\n\x05\x04\x03\x02\x03\x03\
+    \x12\x03\x16\x12\x13\n\x0b\n\x04\x04\x03\x02\x04\x12\x03\x17\x04\x20\n\
+    \x0c\n\x05\x04\x03\x02\x04\x06\x12\x03\x17\x04\x10\n\x0c\n\x05\x04\x03\
+    \x02\x04\x01\x12\x03\x17\x11\x1b\n\x0c\n\x05\x04\x03\x02\x04\x03\x12\x03\
+    \x17\x1e\x1f\n\x0b\n\x04\x04\x03\x02\x05\x12\x03\x18\x04\x16\n\x0c\n\x05\
+    \x04\x03\x02\x05\x05\x12\x03\x18\x04\t\n\x0c\n\x05\x04\x03\x02\x05\x01\
+    \x12\x03\x18\n\x11\n\x0c\n\x05\x04\x03\x02\x05\x03\x12\x03\x18\x14\x15\n\
+    \n\n\x02\x04\x04\x12\x04\x1a\0\x1c\x01\n\n\n\x03\x04\x04\x01\x12\x03\x1a\
+    \x08\x13\n\x0b\n\x04\x04\x04\x02\0\x12\x03\x1b\x04\x1b\n\x0c\n\x05\x04\
+    \x04\x02\0\x04\x12\x03\x1b\x04\x0c\n\x0c\n\x05\x04\x04\x02\0\x06\x12\x03\
+    \x1b\r\x10\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x1b\x11\x16\n\x0c\n\x05\
+    \x04\x04\x02\0\x03\x12\x03\x1b\x19\x1ab\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 39 - 130
rust-lib/flowy-workspace/src/protobuf/model/workspace_create.rs

@@ -28,7 +28,6 @@ pub struct CreateWorkspaceRequest {
     // message fields
     pub name: ::std::string::String,
     pub desc: ::std::string::String,
-    pub user_id: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -96,32 +95,6 @@ impl CreateWorkspaceRequest {
     pub fn take_desc(&mut self) -> ::std::string::String {
         ::std::mem::replace(&mut self.desc, ::std::string::String::new())
     }
-
-    // string user_id = 3;
-
-
-    pub fn get_user_id(&self) -> &str {
-        &self.user_id
-    }
-    pub fn clear_user_id(&mut self) {
-        self.user_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_user_id(&mut self, v: ::std::string::String) {
-        self.user_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
-        &mut self.user_id
-    }
-
-    // Take field
-    pub fn take_user_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.user_id, ::std::string::String::new())
-    }
 }
 
 impl ::protobuf::Message for CreateWorkspaceRequest {
@@ -139,9 +112,6 @@ impl ::protobuf::Message for CreateWorkspaceRequest {
                 2 => {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?;
                 },
-                3 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
-                },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                 },
@@ -160,9 +130,6 @@ impl ::protobuf::Message for CreateWorkspaceRequest {
         if !self.desc.is_empty() {
             my_size += ::protobuf::rt::string_size(2, &self.desc);
         }
-        if !self.user_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(3, &self.user_id);
-        }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
         my_size
@@ -175,9 +142,6 @@ impl ::protobuf::Message for CreateWorkspaceRequest {
         if !self.desc.is_empty() {
             os.write_string(2, &self.desc)?;
         }
-        if !self.user_id.is_empty() {
-            os.write_string(3, &self.user_id)?;
-        }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
     }
@@ -226,11 +190,6 @@ impl ::protobuf::Message for CreateWorkspaceRequest {
                 |m: &CreateWorkspaceRequest| { &m.desc },
                 |m: &mut CreateWorkspaceRequest| { &mut m.desc },
             ));
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "user_id",
-                |m: &CreateWorkspaceRequest| { &m.user_id },
-                |m: &mut CreateWorkspaceRequest| { &mut m.user_id },
-            ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateWorkspaceRequest>(
                 "CreateWorkspaceRequest",
                 fields,
@@ -249,7 +208,6 @@ impl ::protobuf::Clear for CreateWorkspaceRequest {
     fn clear(&mut self) {
         self.name.clear();
         self.desc.clear();
-        self.user_id.clear();
         self.unknown_fields.clear();
     }
 }
@@ -271,7 +229,6 @@ pub struct CreateWorkspaceParams {
     // message fields
     pub name: ::std::string::String,
     pub desc: ::std::string::String,
-    pub user_id: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -339,32 +296,6 @@ impl CreateWorkspaceParams {
     pub fn take_desc(&mut self) -> ::std::string::String {
         ::std::mem::replace(&mut self.desc, ::std::string::String::new())
     }
-
-    // string user_id = 3;
-
-
-    pub fn get_user_id(&self) -> &str {
-        &self.user_id
-    }
-    pub fn clear_user_id(&mut self) {
-        self.user_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_user_id(&mut self, v: ::std::string::String) {
-        self.user_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
-        &mut self.user_id
-    }
-
-    // Take field
-    pub fn take_user_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.user_id, ::std::string::String::new())
-    }
 }
 
 impl ::protobuf::Message for CreateWorkspaceParams {
@@ -382,9 +313,6 @@ impl ::protobuf::Message for CreateWorkspaceParams {
                 2 => {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?;
                 },
-                3 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
-                },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                 },
@@ -403,9 +331,6 @@ impl ::protobuf::Message for CreateWorkspaceParams {
         if !self.desc.is_empty() {
             my_size += ::protobuf::rt::string_size(2, &self.desc);
         }
-        if !self.user_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(3, &self.user_id);
-        }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
         my_size
@@ -418,9 +343,6 @@ impl ::protobuf::Message for CreateWorkspaceParams {
         if !self.desc.is_empty() {
             os.write_string(2, &self.desc)?;
         }
-        if !self.user_id.is_empty() {
-            os.write_string(3, &self.user_id)?;
-        }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
     }
@@ -469,11 +391,6 @@ impl ::protobuf::Message for CreateWorkspaceParams {
                 |m: &CreateWorkspaceParams| { &m.desc },
                 |m: &mut CreateWorkspaceParams| { &mut m.desc },
             ));
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "user_id",
-                |m: &CreateWorkspaceParams| { &m.user_id },
-                |m: &mut CreateWorkspaceParams| { &mut m.user_id },
-            ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateWorkspaceParams>(
                 "CreateWorkspaceParams",
                 fields,
@@ -492,7 +409,6 @@ impl ::protobuf::Clear for CreateWorkspaceParams {
     fn clear(&mut self) {
         self.name.clear();
         self.desc.clear();
-        self.user_id.clear();
         self.unknown_fields.clear();
     }
 }
@@ -976,53 +892,46 @@ impl ::protobuf::reflect::ProtobufValue for RepeatedWorkspace {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x16workspace_create.proto\x1a\x10app_create.proto\"Y\n\x16CreateWorks\
+    \n\x16workspace_create.proto\x1a\x10app_create.proto\"@\n\x16CreateWorks\
     paceRequest\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\x12\x12\n\x04d\
-    esc\x18\x02\x20\x01(\tR\x04desc\x12\x17\n\x07user_id\x18\x03\x20\x01(\tR\
-    \x06userId\"X\n\x15CreateWorkspaceParams\x12\x12\n\x04name\x18\x01\x20\
-    \x01(\tR\x04name\x12\x12\n\x04desc\x18\x02\x20\x01(\tR\x04desc\x12\x17\n\
-    \x07user_id\x18\x03\x20\x01(\tR\x06userId\"e\n\tWorkspace\x12\x0e\n\x02i\
-    d\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04nam\
-    e\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x20\n\x04apps\x18\
-    \x04\x20\x01(\x0b2\x0c.RepeatedAppR\x04apps\"5\n\x11RepeatedWorkspace\
-    \x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.WorkspaceR\x05itemsJ\xe8\x05\
-    \n\x06\x12\x04\0\0\x15\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\t\n\x02\x03\
-    \0\x12\x03\x01\0\x1a\n\n\n\x02\x04\0\x12\x04\x03\0\x07\x01\n\n\n\x03\x04\
-    \0\x01\x12\x03\x03\x08\x1e\n\x0b\n\x04\x04\0\x02\0\x12\x03\x04\x04\x14\n\
-    \x0c\n\x05\x04\0\x02\0\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\
-    \x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x04\x12\x13\n\
-    \x0b\n\x04\x04\0\x02\x01\x12\x03\x05\x04\x14\n\x0c\n\x05\x04\0\x02\x01\
-    \x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x05\x0b\x0f\
-    \n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x05\x12\x13\n\x0b\n\x04\x04\0\x02\
-    \x02\x12\x03\x06\x04\x17\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x06\x04\n\
-    \n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x06\x0b\x12\n\x0c\n\x05\x04\0\x02\
-    \x02\x03\x12\x03\x06\x15\x16\n\n\n\x02\x04\x01\x12\x04\x08\0\x0c\x01\n\n\
-    \n\x03\x04\x01\x01\x12\x03\x08\x08\x1d\n\x0b\n\x04\x04\x01\x02\0\x12\x03\
-    \t\x04\x14\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\t\x04\n\n\x0c\n\x05\x04\
-    \x01\x02\0\x01\x12\x03\t\x0b\x0f\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\t\
-    \x12\x13\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\n\x04\x14\n\x0c\n\x05\x04\
-    \x01\x02\x01\x05\x12\x03\n\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\
-    \n\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\n\x12\x13\n\x0b\n\x04\
-    \x04\x01\x02\x02\x12\x03\x0b\x04\x17\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\
-    \x03\x0b\x04\n\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\x0b\x0b\x12\n\x0c\
-    \n\x05\x04\x01\x02\x02\x03\x12\x03\x0b\x15\x16\n\n\n\x02\x04\x02\x12\x04\
-    \r\0\x12\x01\n\n\n\x03\x04\x02\x01\x12\x03\r\x08\x11\n\x0b\n\x04\x04\x02\
-    \x02\0\x12\x03\x0e\x04\x12\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0e\x04\
-    \n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0e\x0b\r\n\x0c\n\x05\x04\x02\
-    \x02\0\x03\x12\x03\x0e\x10\x11\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0f\
-    \x04\x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\x0f\x04\n\n\x0c\n\x05\
-    \x04\x02\x02\x01\x01\x12\x03\x0f\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\
-    \x12\x03\x0f\x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x10\x04\x14\n\
-    \x0c\n\x05\x04\x02\x02\x02\x05\x12\x03\x10\x04\n\n\x0c\n\x05\x04\x02\x02\
-    \x02\x01\x12\x03\x10\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x10\
-    \x12\x13\n\x0b\n\x04\x04\x02\x02\x03\x12\x03\x11\x04\x19\n\x0c\n\x05\x04\
-    \x02\x02\x03\x06\x12\x03\x11\x04\x0f\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\
-    \x03\x11\x10\x14\n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03\x11\x17\x18\n\n\
-    \n\x02\x04\x03\x12\x04\x13\0\x15\x01\n\n\n\x03\x04\x03\x01\x12\x03\x13\
-    \x08\x19\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x14\x04!\n\x0c\n\x05\x04\x03\
-    \x02\0\x04\x12\x03\x14\x04\x0c\n\x0c\n\x05\x04\x03\x02\0\x06\x12\x03\x14\
-    \r\x16\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x14\x17\x1c\n\x0c\n\x05\x04\
-    \x03\x02\0\x03\x12\x03\x14\x1f\x20b\x06proto3\
+    esc\x18\x02\x20\x01(\tR\x04desc\"?\n\x15CreateWorkspaceParams\x12\x12\n\
+    \x04name\x18\x01\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x02\x20\x01(\
+    \tR\x04desc\"e\n\tWorkspace\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\
+    \x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\
+    \x20\x01(\tR\x04desc\x12\x20\n\x04apps\x18\x04\x20\x01(\x0b2\x0c.Repeate\
+    dAppR\x04apps\"5\n\x11RepeatedWorkspace\x12\x20\n\x05items\x18\x01\x20\
+    \x03(\x0b2\n.WorkspaceR\x05itemsJ\xfa\x04\n\x06\x12\x04\0\0\x13\x01\n\
+    \x08\n\x01\x0c\x12\x03\0\0\x12\n\t\n\x02\x03\0\x12\x03\x01\0\x1a\n\n\n\
+    \x02\x04\0\x12\x04\x03\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\x03\x08\x1e\
+    \n\x0b\n\x04\x04\0\x02\0\x12\x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\0\x05\
+    \x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x04\x0b\x0f\n\x0c\
+    \n\x05\x04\0\x02\0\x03\x12\x03\x04\x12\x13\n\x0b\n\x04\x04\0\x02\x01\x12\
+    \x03\x05\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x05\x04\n\n\x0c\n\
+    \x05\x04\0\x02\x01\x01\x12\x03\x05\x0b\x0f\n\x0c\n\x05\x04\0\x02\x01\x03\
+    \x12\x03\x05\x12\x13\n\n\n\x02\x04\x01\x12\x04\x07\0\n\x01\n\n\n\x03\x04\
+    \x01\x01\x12\x03\x07\x08\x1d\n\x0b\n\x04\x04\x01\x02\0\x12\x03\x08\x04\
+    \x14\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\
+    \x02\0\x01\x12\x03\x08\x0b\x0f\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x08\
+    \x12\x13\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\t\x04\x14\n\x0c\n\x05\x04\
+    \x01\x02\x01\x05\x12\x03\t\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\
+    \t\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\t\x12\x13\n\n\n\x02\
+    \x04\x02\x12\x04\x0b\0\x10\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0b\x08\x11\
+    \n\x0b\n\x04\x04\x02\x02\0\x12\x03\x0c\x04\x12\n\x0c\n\x05\x04\x02\x02\0\
+    \x05\x12\x03\x0c\x04\n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0c\x0b\r\n\
+    \x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x0c\x10\x11\n\x0b\n\x04\x04\x02\x02\
+    \x01\x12\x03\r\x04\x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\r\x04\n\n\
+    \x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\r\x0b\x0f\n\x0c\n\x05\x04\x02\x02\
+    \x01\x03\x12\x03\r\x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x0e\x04\
+    \x14\n\x0c\n\x05\x04\x02\x02\x02\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\
+    \x02\x02\x02\x01\x12\x03\x0e\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\
+    \x03\x0e\x12\x13\n\x0b\n\x04\x04\x02\x02\x03\x12\x03\x0f\x04\x19\n\x0c\n\
+    \x05\x04\x02\x02\x03\x06\x12\x03\x0f\x04\x0f\n\x0c\n\x05\x04\x02\x02\x03\
+    \x01\x12\x03\x0f\x10\x14\n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03\x0f\x17\
+    \x18\n\n\n\x02\x04\x03\x12\x04\x11\0\x13\x01\n\n\n\x03\x04\x03\x01\x12\
+    \x03\x11\x08\x19\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x12\x04!\n\x0c\n\x05\
+    \x04\x03\x02\0\x04\x12\x03\x12\x04\x0c\n\x0c\n\x05\x04\x03\x02\0\x06\x12\
+    \x03\x12\r\x16\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x12\x17\x1c\n\x0c\n\
+    \x05\x04\x03\x02\0\x03\x12\x03\x12\x1f\x20b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 15 - 108
rust-lib/flowy-workspace/src/protobuf/model/workspace_query.rs

@@ -25,8 +25,6 @@
 
 #[derive(PartialEq,Clone,Default)]
 pub struct QueryWorkspaceRequest {
-    // message fields
-    pub user_id: ::std::string::String,
     // message oneof groups
     pub one_of_workspace_id: ::std::option::Option<QueryWorkspaceRequest_oneof_one_of_workspace_id>,
     // special fields
@@ -98,32 +96,6 @@ impl QueryWorkspaceRequest {
             ::std::string::String::new()
         }
     }
-
-    // string user_id = 2;
-
-
-    pub fn get_user_id(&self) -> &str {
-        &self.user_id
-    }
-    pub fn clear_user_id(&mut self) {
-        self.user_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_user_id(&mut self, v: ::std::string::String) {
-        self.user_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
-        &mut self.user_id
-    }
-
-    // Take field
-    pub fn take_user_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.user_id, ::std::string::String::new())
-    }
 }
 
 impl ::protobuf::Message for QueryWorkspaceRequest {
@@ -141,9 +113,6 @@ impl ::protobuf::Message for QueryWorkspaceRequest {
                     }
                     self.one_of_workspace_id = ::std::option::Option::Some(QueryWorkspaceRequest_oneof_one_of_workspace_id::workspace_id(is.read_string()?));
                 },
-                2 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
-                },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                 },
@@ -156,9 +125,6 @@ impl ::protobuf::Message for QueryWorkspaceRequest {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if !self.user_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(2, &self.user_id);
-        }
         if let ::std::option::Option::Some(ref v) = self.one_of_workspace_id {
             match v {
                 &QueryWorkspaceRequest_oneof_one_of_workspace_id::workspace_id(ref v) => {
@@ -172,9 +138,6 @@ impl ::protobuf::Message for QueryWorkspaceRequest {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if !self.user_id.is_empty() {
-            os.write_string(2, &self.user_id)?;
-        }
         if let ::std::option::Option::Some(ref v) = self.one_of_workspace_id {
             match v {
                 &QueryWorkspaceRequest_oneof_one_of_workspace_id::workspace_id(ref v) => {
@@ -225,11 +188,6 @@ impl ::protobuf::Message for QueryWorkspaceRequest {
                 QueryWorkspaceRequest::has_workspace_id,
                 QueryWorkspaceRequest::get_workspace_id,
             ));
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "user_id",
-                |m: &QueryWorkspaceRequest| { &m.user_id },
-                |m: &mut QueryWorkspaceRequest| { &mut m.user_id },
-            ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<QueryWorkspaceRequest>(
                 "QueryWorkspaceRequest",
                 fields,
@@ -247,7 +205,6 @@ impl ::protobuf::Message for QueryWorkspaceRequest {
 impl ::protobuf::Clear for QueryWorkspaceRequest {
     fn clear(&mut self) {
         self.one_of_workspace_id = ::std::option::Option::None;
-        self.user_id.clear();
         self.unknown_fields.clear();
     }
 }
@@ -266,8 +223,6 @@ impl ::protobuf::reflect::ProtobufValue for QueryWorkspaceRequest {
 
 #[derive(PartialEq,Clone,Default)]
 pub struct QueryWorkspaceParams {
-    // message fields
-    pub user_id: ::std::string::String,
     // message oneof groups
     pub one_of_workspace_id: ::std::option::Option<QueryWorkspaceParams_oneof_one_of_workspace_id>,
     // special fields
@@ -339,32 +294,6 @@ impl QueryWorkspaceParams {
             ::std::string::String::new()
         }
     }
-
-    // string user_id = 2;
-
-
-    pub fn get_user_id(&self) -> &str {
-        &self.user_id
-    }
-    pub fn clear_user_id(&mut self) {
-        self.user_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_user_id(&mut self, v: ::std::string::String) {
-        self.user_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
-        &mut self.user_id
-    }
-
-    // Take field
-    pub fn take_user_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.user_id, ::std::string::String::new())
-    }
 }
 
 impl ::protobuf::Message for QueryWorkspaceParams {
@@ -382,9 +311,6 @@ impl ::protobuf::Message for QueryWorkspaceParams {
                     }
                     self.one_of_workspace_id = ::std::option::Option::Some(QueryWorkspaceParams_oneof_one_of_workspace_id::workspace_id(is.read_string()?));
                 },
-                2 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
-                },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                 },
@@ -397,9 +323,6 @@ impl ::protobuf::Message for QueryWorkspaceParams {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if !self.user_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(2, &self.user_id);
-        }
         if let ::std::option::Option::Some(ref v) = self.one_of_workspace_id {
             match v {
                 &QueryWorkspaceParams_oneof_one_of_workspace_id::workspace_id(ref v) => {
@@ -413,9 +336,6 @@ impl ::protobuf::Message for QueryWorkspaceParams {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if !self.user_id.is_empty() {
-            os.write_string(2, &self.user_id)?;
-        }
         if let ::std::option::Option::Some(ref v) = self.one_of_workspace_id {
             match v {
                 &QueryWorkspaceParams_oneof_one_of_workspace_id::workspace_id(ref v) => {
@@ -466,11 +386,6 @@ impl ::protobuf::Message for QueryWorkspaceParams {
                 QueryWorkspaceParams::has_workspace_id,
                 QueryWorkspaceParams::get_workspace_id,
             ));
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "user_id",
-                |m: &QueryWorkspaceParams| { &m.user_id },
-                |m: &mut QueryWorkspaceParams| { &mut m.user_id },
-            ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<QueryWorkspaceParams>(
                 "QueryWorkspaceParams",
                 fields,
@@ -488,7 +403,6 @@ impl ::protobuf::Message for QueryWorkspaceParams {
 impl ::protobuf::Clear for QueryWorkspaceParams {
     fn clear(&mut self) {
         self.one_of_workspace_id = ::std::option::Option::None;
-        self.user_id.clear();
         self.unknown_fields.clear();
     }
 }
@@ -506,28 +420,21 @@ impl ::protobuf::reflect::ProtobufValue for QueryWorkspaceParams {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x15workspace_query.proto\"l\n\x15QueryWorkspaceRequest\x12#\n\x0cwork\
-    space_id\x18\x01\x20\x01(\tH\0R\x0bworkspaceId\x12\x17\n\x07user_id\x18\
-    \x02\x20\x01(\tR\x06userIdB\x15\n\x13one_of_workspace_id\"k\n\x14QueryWo\
-    rkspaceParams\x12#\n\x0cworkspace_id\x18\x01\x20\x01(\tH\0R\x0bworkspace\
-    Id\x12\x17\n\x07user_id\x18\x02\x20\x01(\tR\x06userIdB\x15\n\x13one_of_w\
-    orkspace_idJ\xd4\x02\n\x06\x12\x04\0\0\t\x01\n\x08\n\x01\x0c\x12\x03\0\0\
-    \x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\
-    \x02\x08\x1d\n\x0b\n\x04\x04\0\x08\0\x12\x03\x03\x04:\n\x0c\n\x05\x04\0\
-    \x08\0\x01\x12\x03\x03\n\x1d\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x208\n\
-    \x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x20&\n\x0c\n\x05\x04\0\x02\0\x01\
-    \x12\x03\x03'3\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x0367\n\x0b\n\x04\x04\
-    \0\x02\x01\x12\x03\x04\x04\x17\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\x12\n\x0c\n\x05\x04\
-    \0\x02\x01\x03\x12\x03\x04\x15\x16\n\n\n\x02\x04\x01\x12\x04\x06\0\t\x01\
-    \n\n\n\x03\x04\x01\x01\x12\x03\x06\x08\x1c\n\x0b\n\x04\x04\x01\x08\0\x12\
-    \x03\x07\x04:\n\x0c\n\x05\x04\x01\x08\0\x01\x12\x03\x07\n\x1d\n\x0b\n\
-    \x04\x04\x01\x02\0\x12\x03\x07\x208\n\x0c\n\x05\x04\x01\x02\0\x05\x12\
-    \x03\x07\x20&\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x07'3\n\x0c\n\x05\
-    \x04\x01\x02\0\x03\x12\x03\x0767\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x08\
-    \x04\x17\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\n\n\x0c\n\x05\
-    \x04\x01\x02\x01\x01\x12\x03\x08\x0b\x12\n\x0c\n\x05\x04\x01\x02\x01\x03\
-    \x12\x03\x08\x15\x16b\x06proto3\
+    \n\x15workspace_query.proto\"S\n\x15QueryWorkspaceRequest\x12#\n\x0cwork\
+    space_id\x18\x01\x20\x01(\tH\0R\x0bworkspaceIdB\x15\n\x13one_of_workspac\
+    e_id\"R\n\x14QueryWorkspaceParams\x12#\n\x0cworkspace_id\x18\x01\x20\x01\
+    (\tH\0R\x0bworkspaceIdB\x15\n\x13one_of_workspace_idJ\xe6\x01\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\x04\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x1d\n\x0b\n\x04\x04\0\
+    \x08\0\x12\x03\x03\x04:\n\x0c\n\x05\x04\0\x08\0\x01\x12\x03\x03\n\x1d\n\
+    \x0b\n\x04\x04\0\x02\0\x12\x03\x03\x208\n\x0c\n\x05\x04\0\x02\0\x05\x12\
+    \x03\x03\x20&\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03'3\n\x0c\n\x05\x04\
+    \0\x02\0\x03\x12\x03\x0367\n\n\n\x02\x04\x01\x12\x04\x05\0\x07\x01\n\n\n\
+    \x03\x04\x01\x01\x12\x03\x05\x08\x1c\n\x0b\n\x04\x04\x01\x08\0\x12\x03\
+    \x06\x04:\n\x0c\n\x05\x04\x01\x08\0\x01\x12\x03\x06\n\x1d\n\x0b\n\x04\
+    \x04\x01\x02\0\x12\x03\x06\x208\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\
+    \x06\x20&\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x06'3\n\x0c\n\x05\x04\
+    \x01\x02\0\x03\x12\x03\x0667b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 0 - 1
rust-lib/flowy-workspace/src/protobuf/proto/app_create.proto

@@ -15,7 +15,6 @@ message CreateAppParams {
     string name = 2;
     string desc = 3;
     ColorStyle color_style = 4;
-    string user_id = 5;
 }
 message App {
     string id = 1;

+ 0 - 2
rust-lib/flowy-workspace/src/protobuf/proto/workspace_create.proto

@@ -4,12 +4,10 @@ import "app_create.proto";
 message CreateWorkspaceRequest {
     string name = 1;
     string desc = 2;
-    string user_id = 3;
 }
 message CreateWorkspaceParams {
     string name = 1;
     string desc = 2;
-    string user_id = 3;
 }
 message Workspace {
     string id = 1;

+ 0 - 2
rust-lib/flowy-workspace/src/protobuf/proto/workspace_query.proto

@@ -2,9 +2,7 @@ syntax = "proto3";
 
 message QueryWorkspaceRequest {
     oneof one_of_workspace_id { string workspace_id = 1; };
-    string user_id = 2;
 }
 message QueryWorkspaceParams {
     oneof one_of_workspace_id { string workspace_id = 1; };
-    string user_id = 2;
 }

+ 1 - 40
rust-lib/flowy-workspace/src/services/app_controller.rs

@@ -34,12 +34,8 @@ impl AppController {
         }
     }
 
-    pub(crate) fn create_app(&self, mut params: CreateAppParams) -> Result<App, WorkspaceError> {
-        let user_id = self.user.user_id()?;
-        params.user_id = user_id;
-
+    pub(crate) fn create_app(&self, params: CreateAppParams) -> Result<App, WorkspaceError> {
         // TODO: server
-
         let app_table = AppTable::new(params);
         let app: App = app_table.clone().into();
         let _ = self.sql.create_app(app_table)?;
@@ -79,38 +75,3 @@ impl AppController {
         }
     }
 }
-
-pub async fn create_app_request(params: CreateAppParams, url: &str) -> Result<App, WorkspaceError> {
-    let app = HttpRequestBuilder::post(&url.to_owned())
-        .protobuf(params)?
-        .send()
-        .await?
-        .response()
-        .await?;
-    Ok(app)
-}
-
-pub async fn read_app_request(params: QueryAppParams, url: &str) -> Result<Option<App>, WorkspaceError> {
-    let result = HttpRequestBuilder::get(&url.to_owned()).protobuf(params)?.send().await;
-
-    match result {
-        Ok(builder) => Ok(Some(builder.response::<App>().await?)),
-        Err(e) => {
-            if e.is_not_found() {
-                Ok(None)
-            } else {
-                Err(e.into())
-            }
-        },
-    }
-}
-
-pub async fn update_app_request(params: UpdateAppParams, url: &str) -> Result<(), WorkspaceError> {
-    let _ = HttpRequestBuilder::patch(&url.to_owned()).protobuf(params)?.send().await?;
-    Ok(())
-}
-
-pub async fn delete_app_request(params: DeleteAppParams, url: &str) -> Result<(), WorkspaceError> {
-    let _ = HttpRequestBuilder::delete(&url.to_owned()).protobuf(params)?.send().await?;
-    Ok(())
-}

+ 8 - 0
rust-lib/flowy-workspace/src/services/helper.rs

@@ -1 +1,9 @@
+use std::future::Future;
 
+pub fn spawn<F>(f: F)
+where
+    F: Future + Send + 'static,
+    F::Output: Send + 'static,
+{
+    tokio::spawn(f);
+}

+ 1 - 1
rust-lib/flowy-workspace/src/services/mod.rs

@@ -5,6 +5,6 @@ pub use workspace_controller::*;
 mod app_controller;
 mod database;
 mod helper;
-pub(crate) mod server;
+pub mod server;
 mod view_controller;
 mod workspace_controller;

+ 15 - 8
rust-lib/flowy-workspace/src/services/server/mod.rs

@@ -6,9 +6,16 @@ pub use server_api_mock::*;
 
 use crate::{
     entities::{
-        app::{CreateAppParams, DeleteAppParams, QueryAppParams, UpdateAppParams},
-        view::{CreateViewParams, DeleteViewParams, QueryViewParams, UpdateViewParams},
-        workspace::{CreateWorkspaceParams, DeleteWorkspaceParams, QueryWorkspaceParams, RepeatedWorkspace, UpdateWorkspaceParams},
+        app::{App, CreateAppParams, DeleteAppParams, QueryAppParams, UpdateAppParams},
+        view::{CreateViewParams, DeleteViewParams, QueryViewParams, UpdateViewParams, View},
+        workspace::{
+            CreateWorkspaceParams,
+            DeleteWorkspaceParams,
+            QueryWorkspaceParams,
+            RepeatedWorkspace,
+            UpdateWorkspaceParams,
+            Workspace,
+        },
     },
     errors::WorkspaceError,
 };
@@ -19,7 +26,7 @@ pub(crate) type Server = Arc<dyn WorkspaceServerAPI + Send + Sync>;
 
 pub trait WorkspaceServerAPI {
     // Workspace
-    fn create_workspace(&self, token: &str, params: CreateWorkspaceParams) -> ResultFuture<(), WorkspaceError>;
+    fn create_workspace(&self, token: &str, params: CreateWorkspaceParams) -> ResultFuture<Workspace, WorkspaceError>;
 
     fn read_workspace(&self, token: &str, params: QueryWorkspaceParams) -> ResultFuture<RepeatedWorkspace, WorkspaceError>;
 
@@ -28,17 +35,17 @@ pub trait WorkspaceServerAPI {
     fn delete_workspace(&self, token: &str, params: DeleteWorkspaceParams) -> ResultFuture<(), WorkspaceError>;
 
     // View
-    fn create_view(&self, token: &str, params: CreateViewParams) -> ResultFuture<(), WorkspaceError>;
+    fn create_view(&self, token: &str, params: CreateViewParams) -> ResultFuture<View, WorkspaceError>;
 
-    fn read_view(&self, token: &str, params: QueryViewParams) -> ResultFuture<(), WorkspaceError>;
+    fn read_view(&self, token: &str, params: QueryViewParams) -> ResultFuture<Option<View>, WorkspaceError>;
 
     fn delete_view(&self, token: &str, params: DeleteViewParams) -> ResultFuture<(), WorkspaceError>;
 
     fn update_view(&self, token: &str, params: UpdateViewParams) -> ResultFuture<(), WorkspaceError>;
 
     // App
-    fn create_app(&self, token: &str, params: CreateAppParams) -> ResultFuture<(), WorkspaceError>;
-    fn read_app(&self, token: &str, params: QueryAppParams) -> ResultFuture<(), WorkspaceError>;
+    fn create_app(&self, token: &str, params: CreateAppParams) -> ResultFuture<App, WorkspaceError>;
+    fn read_app(&self, token: &str, params: QueryAppParams) -> ResultFuture<Option<App>, WorkspaceError>;
     fn update_app(&self, token: &str, params: UpdateAppParams) -> ResultFuture<(), WorkspaceError>;
     fn delete_app(&self, token: &str, params: DeleteAppParams) -> ResultFuture<(), WorkspaceError>;
 }

+ 204 - 16
rust-lib/flowy-workspace/src/services/server/server_api.rs

@@ -1,38 +1,226 @@
 use crate::{
     entities::{
-        app::{CreateAppParams, DeleteAppParams, QueryAppParams, UpdateAppParams},
-        view::{CreateViewParams, DeleteViewParams, QueryViewParams, UpdateViewParams},
-        workspace::{CreateWorkspaceParams, DeleteWorkspaceParams, QueryWorkspaceParams, RepeatedWorkspace, UpdateWorkspaceParams},
+        app::{App, CreateAppParams, DeleteAppParams, QueryAppParams, UpdateAppParams},
+        view::{CreateViewParams, DeleteViewParams, QueryViewParams, UpdateViewParams, View},
+        workspace::{
+            CreateWorkspaceParams,
+            DeleteWorkspaceParams,
+            QueryWorkspaceParams,
+            RepeatedWorkspace,
+            UpdateWorkspaceParams,
+            Workspace,
+        },
     },
     errors::WorkspaceError,
     services::server::WorkspaceServerAPI,
 };
 use flowy_infra::future::ResultFuture;
-
+use flowy_net::{config::*, request::HttpRequestBuilder};
 pub struct WorkspaceServer {}
 
 impl WorkspaceServerAPI for WorkspaceServer {
-    fn create_workspace(&self, token: &str, params: CreateWorkspaceParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn create_workspace(&self, token: &str, params: CreateWorkspaceParams) -> ResultFuture<Workspace, WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { create_workspace_request(&token, params, WORKSPACE_URL.as_ref()).await })
+    }
+
+    fn read_workspace(&self, token: &str, params: QueryWorkspaceParams) -> ResultFuture<RepeatedWorkspace, WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { read_workspaces_request(&token, params, WORKSPACE_URL.as_ref()).await })
+    }
+
+    fn update_workspace(&self, token: &str, params: UpdateWorkspaceParams) -> ResultFuture<(), WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { update_workspace_request(&token, params, WORKSPACE_URL.as_ref()).await })
+    }
+
+    fn delete_workspace(&self, token: &str, params: DeleteWorkspaceParams) -> ResultFuture<(), WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { delete_workspace_request(&token, params, WORKSPACE_URL.as_ref()).await })
+    }
+
+    fn create_view(&self, token: &str, params: CreateViewParams) -> ResultFuture<View, WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { create_view_request(&token, params, VIEW_URL.as_ref()).await })
+    }
+
+    fn read_view(&self, token: &str, params: QueryViewParams) -> ResultFuture<Option<View>, WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { read_view_request(&token, params, VIEW_URL.as_ref()).await })
+    }
+
+    fn delete_view(&self, token: &str, params: DeleteViewParams) -> ResultFuture<(), WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { delete_view_request(&token, params, VIEW_URL.as_ref()).await })
+    }
+
+    fn update_view(&self, token: &str, params: UpdateViewParams) -> ResultFuture<(), WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { update_view_request(&token, params, VIEW_URL.as_ref()).await })
+    }
+
+    fn create_app(&self, token: &str, params: CreateAppParams) -> ResultFuture<App, WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { create_app_request(&token, params, APP_URL.as_ref()).await })
+    }
+
+    fn read_app(&self, token: &str, params: QueryAppParams) -> ResultFuture<Option<App>, WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { read_app_request(&token, params, APP_URL.as_ref()).await })
+    }
+
+    fn update_app(&self, token: &str, params: UpdateAppParams) -> ResultFuture<(), WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { update_app_request(&token, params, APP_URL.as_ref()).await })
+    }
+
+    fn delete_app(&self, token: &str, params: DeleteAppParams) -> ResultFuture<(), WorkspaceError> {
+        let token = token.to_owned();
+        ResultFuture::new(async move { delete_app_request(&token, params, APP_URL.as_ref()).await })
+    }
+}
+
+pub async fn create_workspace_request(token: &str, params: CreateWorkspaceParams, url: &str) -> Result<Workspace, WorkspaceError> {
+    let workspace = HttpRequestBuilder::post(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?
+        .response()
+        .await?;
+    Ok(workspace)
+}
+
+pub async fn read_workspaces_request(token: &str, params: QueryWorkspaceParams, url: &str) -> Result<RepeatedWorkspace, WorkspaceError> {
+    let result = HttpRequestBuilder::get(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?
+        .response::<RepeatedWorkspace>()
+        .await;
+
+    match result {
+        Ok(repeated_workspace) => Ok(repeated_workspace),
+        Err(e) => Err(e.into()),
+    }
+}
 
-    fn read_workspace(&self, token: &str, params: QueryWorkspaceParams) -> ResultFuture<RepeatedWorkspace, WorkspaceError> { unimplemented!() }
+pub async fn update_workspace_request(token: &str, params: UpdateWorkspaceParams, url: &str) -> Result<(), WorkspaceError> {
+    let _ = HttpRequestBuilder::patch(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?;
+    Ok(())
+}
+
+pub async fn delete_workspace_request(token: &str, params: DeleteWorkspaceParams, url: &str) -> Result<(), WorkspaceError> {
+    let _ = HttpRequestBuilder::delete(url)
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?;
+    Ok(())
+}
 
-    fn update_workspace(&self, token: &str, params: UpdateWorkspaceParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+// App
+pub async fn create_app_request(token: &str, params: CreateAppParams, url: &str) -> Result<App, WorkspaceError> {
+    let app = HttpRequestBuilder::post(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?
+        .response()
+        .await?;
+    Ok(app)
+}
 
-    fn delete_workspace(&self, token: &str, params: DeleteWorkspaceParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+pub async fn read_app_request(token: &str, params: QueryAppParams, url: &str) -> Result<Option<App>, WorkspaceError> {
+    let result = HttpRequestBuilder::get(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await;
 
-    fn create_view(&self, token: &str, params: CreateViewParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    match result {
+        Ok(builder) => Ok(Some(builder.response::<App>().await?)),
+        Err(e) => {
+            if e.is_not_found() {
+                Ok(None)
+            } else {
+                Err(e.into())
+            }
+        },
+    }
+}
 
-    fn read_view(&self, token: &str, params: QueryViewParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+pub async fn update_app_request(token: &str, params: UpdateAppParams, url: &str) -> Result<(), WorkspaceError> {
+    let _ = HttpRequestBuilder::patch(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?;
+    Ok(())
+}
 
-    fn delete_view(&self, token: &str, params: DeleteViewParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+pub async fn delete_app_request(token: &str, params: DeleteAppParams, url: &str) -> Result<(), WorkspaceError> {
+    let _ = HttpRequestBuilder::delete(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?;
+    Ok(())
+}
 
-    fn update_view(&self, token: &str, params: UpdateViewParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+// View
+pub async fn create_view_request(token: &str, params: CreateViewParams, url: &str) -> Result<View, WorkspaceError> {
+    let view = HttpRequestBuilder::post(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?
+        .response()
+        .await?;
+    Ok(view)
+}
 
-    fn create_app(&self, token: &str, params: CreateAppParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+pub async fn read_view_request(token: &str, params: QueryViewParams, url: &str) -> Result<Option<View>, WorkspaceError> {
+    let result = HttpRequestBuilder::get(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await;
 
-    fn read_app(&self, token: &str, params: QueryAppParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    match result {
+        Ok(builder) => {
+            let view = builder.response::<View>().await?;
+            Ok(Some(view))
+        },
+        Err(e) => {
+            if e.is_not_found() {
+                Ok(None)
+            } else {
+                Err(e.into())
+            }
+        },
+    }
+}
 
-    fn update_app(&self, token: &str, params: UpdateAppParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+pub async fn update_view_request(token: &str, params: UpdateViewParams, url: &str) -> Result<(), WorkspaceError> {
+    let _ = HttpRequestBuilder::patch(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?;
+    Ok(())
+}
 
-    fn delete_app(&self, token: &str, params: DeleteAppParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+pub async fn delete_view_request(token: &str, params: DeleteViewParams, url: &str) -> Result<(), WorkspaceError> {
+    let _ = HttpRequestBuilder::delete(&url.to_owned())
+        .header(HEADER_TOKEN, token)
+        .protobuf(params)?
+        .send()
+        .await?;
+    Ok(())
 }

+ 69 - 17
rust-lib/flowy-workspace/src/services/server/server_api_mock.rs

@@ -1,40 +1,92 @@
 use crate::{
     entities::{
-        app::{CreateAppParams, DeleteAppParams, QueryAppParams, UpdateAppParams},
-        view::{CreateViewParams, DeleteViewParams, QueryViewParams, UpdateViewParams},
-        workspace::{CreateWorkspaceParams, DeleteWorkspaceParams, QueryWorkspaceParams, RepeatedWorkspace, UpdateWorkspaceParams},
+        app::{App, CreateAppParams, DeleteAppParams, QueryAppParams, RepeatedApp, UpdateAppParams},
+        view::{CreateViewParams, DeleteViewParams, QueryViewParams, RepeatedView, UpdateViewParams, View},
+        workspace::{
+            CreateWorkspaceParams,
+            DeleteWorkspaceParams,
+            QueryWorkspaceParams,
+            RepeatedWorkspace,
+            UpdateWorkspaceParams,
+            Workspace,
+        },
     },
     errors::WorkspaceError,
     services::server::WorkspaceServerAPI,
 };
-use flowy_infra::future::ResultFuture;
+use flowy_infra::{future::ResultFuture, uuid};
 
 pub struct WorkspaceServerMock {}
 
 impl WorkspaceServerAPI for WorkspaceServerMock {
-    fn create_workspace(&self, token: &str, params: CreateWorkspaceParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn create_workspace(&self, _token: &str, params: CreateWorkspaceParams) -> ResultFuture<Workspace, WorkspaceError> {
+        let workspace = Workspace {
+            id: uuid(),
+            name: params.name,
+            desc: params.desc,
+            apps: RepeatedApp::default(),
+        };
 
-    fn read_workspace(&self, token: &str, params: QueryWorkspaceParams) -> ResultFuture<RepeatedWorkspace, WorkspaceError> {
-        unimplemented!()
+        ResultFuture::new(async { Ok(workspace) })
     }
 
-    fn update_workspace(&self, token: &str, params: UpdateWorkspaceParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn read_workspace(&self, _token: &str, _params: QueryWorkspaceParams) -> ResultFuture<RepeatedWorkspace, WorkspaceError> {
+        ResultFuture::new(async {
+            let repeated_workspace = RepeatedWorkspace { items: vec![] };
+            Ok(repeated_workspace)
+        })
+    }
 
-    fn delete_workspace(&self, token: &str, params: DeleteWorkspaceParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn update_workspace(&self, _token: &str, _params: UpdateWorkspaceParams) -> ResultFuture<(), WorkspaceError> {
+        ResultFuture::new(async { Ok(()) })
+    }
 
-    fn create_view(&self, token: &str, params: CreateViewParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn delete_workspace(&self, _token: &str, _params: DeleteWorkspaceParams) -> ResultFuture<(), WorkspaceError> {
+        ResultFuture::new(async { Ok(()) })
+    }
+
+    fn create_view(&self, _token: &str, params: CreateViewParams) -> ResultFuture<View, WorkspaceError> {
+        let view = View {
+            id: uuid(),
+            belong_to_id: params.belong_to_id,
+            name: params.name,
+            desc: params.desc,
+            view_type: params.view_type,
+            version: 0,
+            belongings: RepeatedView::default(),
+        };
+        ResultFuture::new(async { Ok(view) })
+    }
 
-    fn read_view(&self, token: &str, params: QueryViewParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn read_view(&self, _token: &str, _params: QueryViewParams) -> ResultFuture<Option<View>, WorkspaceError> {
+        ResultFuture::new(async { Ok((None)) })
+    }
 
-    fn delete_view(&self, token: &str, params: DeleteViewParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn delete_view(&self, _token: &str, _params: DeleteViewParams) -> ResultFuture<(), WorkspaceError> {
+        ResultFuture::new(async { Ok(()) })
+    }
 
-    fn update_view(&self, token: &str, params: UpdateViewParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn update_view(&self, _token: &str, _params: UpdateViewParams) -> ResultFuture<(), WorkspaceError> {
+        ResultFuture::new(async { Ok(()) })
+    }
 
-    fn create_app(&self, token: &str, params: CreateAppParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn create_app(&self, _token: &str, params: CreateAppParams) -> ResultFuture<App, WorkspaceError> {
+        let app = App {
+            id: uuid(),
+            workspace_id: params.workspace_id,
+            name: params.name,
+            desc: params.desc,
+            belongings: RepeatedView::default(),
+            version: 0,
+        };
+        ResultFuture::new(async { Ok(app) })
+    }
 
-    fn read_app(&self, token: &str, params: QueryAppParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn read_app(&self, _token: &str, _params: QueryAppParams) -> ResultFuture<Option<App>, WorkspaceError> {
+        ResultFuture::new(async { Ok(None) })
+    }
 
-    fn update_app(&self, token: &str, params: UpdateAppParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn update_app(&self, _token: &str, _params: UpdateAppParams) -> ResultFuture<(), WorkspaceError> { ResultFuture::new(async { Ok(()) }) }
 
-    fn delete_app(&self, token: &str, params: DeleteAppParams) -> ResultFuture<(), WorkspaceError> { unimplemented!() }
+    fn delete_app(&self, _token: &str, _params: DeleteAppParams) -> ResultFuture<(), WorkspaceError> { ResultFuture::new(async { Ok(()) }) }
 }

+ 0 - 38
rust-lib/flowy-workspace/src/services/view_controller.rs

@@ -61,41 +61,3 @@ impl ViewController {
         Ok(())
     }
 }
-
-pub async fn create_view_request(params: CreateViewParams, url: &str) -> Result<View, WorkspaceError> {
-    let view = HttpRequestBuilder::post(&url.to_owned())
-        .protobuf(params)?
-        .send()
-        .await?
-        .response()
-        .await?;
-    Ok(view)
-}
-
-pub async fn read_view_request(params: QueryViewParams, url: &str) -> Result<Option<View>, WorkspaceError> {
-    let result = HttpRequestBuilder::get(&url.to_owned()).protobuf(params)?.send().await;
-
-    match result {
-        Ok(builder) => {
-            let view = builder.response::<View>().await?;
-            Ok(Some(view))
-        },
-        Err(e) => {
-            if e.is_not_found() {
-                Ok(None)
-            } else {
-                Err(e.into())
-            }
-        },
-    }
-}
-
-pub async fn update_view_request(params: UpdateViewParams, url: &str) -> Result<(), WorkspaceError> {
-    let _ = HttpRequestBuilder::patch(&url.to_owned()).protobuf(params)?.send().await?;
-    Ok(())
-}
-
-pub async fn delete_view_request(params: DeleteViewParams, url: &str) -> Result<(), WorkspaceError> {
-    let _ = HttpRequestBuilder::delete(&url.to_owned()).protobuf(params)?.send().await?;
-    Ok(())
-}

+ 71 - 48
rust-lib/flowy-workspace/src/services/workspace_controller.rs

@@ -3,13 +3,13 @@ use crate::{
     errors::*,
     module::{WorkspaceDatabase, WorkspaceUser},
     observable::{send_observable, WorkspaceObservable},
-    services::{server::Server, AppController},
+    services::{helper::spawn, server::Server, AppController},
     sql_tables::workspace::{WorkspaceSql, WorkspaceTable, WorkspaceTableChangeset},
 };
 use flowy_dispatch::prelude::DispatchFuture;
 use flowy_infra::kv::KVStore;
 use flowy_net::request::HttpRequestBuilder;
-use std::sync::Arc;
+use std::{future::Future, sync::Arc};
 
 pub(crate) struct WorkspaceController {
     pub user: Arc<dyn WorkspaceUser>,
@@ -35,9 +35,9 @@ impl WorkspaceController {
     }
 
     pub(crate) async fn create_workspace(&self, params: CreateWorkspaceParams) -> Result<Workspace, WorkspaceError> {
-        let user_id = params.user_id.clone();
-        // TODO: server
+        let _ = self.create_workspace_on_server(params.clone()).await?;
 
+        let user_id = self.user.user_id()?;
         let workspace_table = WorkspaceTable::new(params, &user_id);
         let workspace: Workspace = workspace_table.clone().into();
         let _ = self.sql.create_workspace(workspace_table)?;
@@ -46,10 +46,11 @@ impl WorkspaceController {
     }
 
     pub(crate) fn update_workspace(&self, params: UpdateWorkspaceParams) -> Result<(), WorkspaceError> {
-        let changeset = WorkspaceTableChangeset::new(params);
+        let changeset = WorkspaceTableChangeset::new(params.clone());
         let workspace_id = changeset.id.clone();
         let _ = self.sql.update_workspace(changeset)?;
 
+        let _ = self.update_workspace_on_server(params.clone())?;
         send_observable(&workspace_id, WorkspaceObservable::WorkspaceUpdated);
         Ok(())
     }
@@ -57,6 +58,7 @@ impl WorkspaceController {
     pub(crate) fn delete_workspace(&self, workspace_id: &str) -> Result<(), WorkspaceError> {
         let user_id = self.user.user_id()?;
         let _ = self.sql.delete_workspace(workspace_id)?;
+
         send_observable(&user_id, WorkspaceObservable::UserDeleteWorkspace);
         Ok(())
     }
@@ -75,23 +77,25 @@ impl WorkspaceController {
         }
     }
 
-    pub(crate) async fn read_workspaces(&self, workspace_id: Option<String>) -> Result<RepeatedWorkspace, WorkspaceError> {
+    pub(crate) async fn read_workspaces(&self, params: QueryWorkspaceParams) -> Result<RepeatedWorkspace, WorkspaceError> {
+        self.read_workspaces_on_server(params.clone());
         let user_id = self.user.user_id()?;
-        let workspace_tables = self.read_workspace_table(workspace_id, user_id).await?;
+        let workspace_tables = self.read_workspace_table(params.workspace_id, user_id).await?;
         let mut workspaces = vec![];
         for table in workspace_tables {
             let apps = self.read_apps(&table.id).await?;
             let mut workspace: Workspace = table.into();
             workspace.apps.items = apps;
-
             workspaces.push(workspace);
         }
         Ok(RepeatedWorkspace { items: workspaces })
     }
 
     pub(crate) async fn read_cur_workspace(&self) -> Result<Workspace, WorkspaceError> {
-        let workspace_id = get_current_workspace()?;
-        let mut repeated_workspace = self.read_workspaces(Some(workspace_id.clone())).await?;
+        let params = QueryWorkspaceParams {
+            workspace_id: Some(get_current_workspace()?),
+        };
+        let mut repeated_workspace = self.read_workspaces(params).await?;
 
         if repeated_workspace.is_empty() {
             return Err(ErrorBuilder::new(ErrorCode::RecordNotFound).build());
@@ -136,52 +140,71 @@ impl WorkspaceController {
     }
 }
 
-const CURRENT_WORKSPACE_ID: &str = "current_workspace_id";
-
-fn set_current_workspace(workspace: &str) { KVStore::set_str(CURRENT_WORKSPACE_ID, workspace.to_owned()); }
+impl WorkspaceController {
+    fn token_server(&self) -> Result<(String, Server), WorkspaceError> {
+        let token = self.user.token()?;
+        let server = self.server.clone();
+        Ok((token, server))
+    }
 
-fn get_current_workspace() -> Result<String, WorkspaceError> {
-    match KVStore::get_str(CURRENT_WORKSPACE_ID) {
-        None => Err(ErrorBuilder::new(ErrorCode::CurrentWorkspaceNotFound).build()),
-        Some(workspace_id) => Ok(workspace_id),
+    async fn create_workspace_on_server(&self, params: CreateWorkspaceParams) -> Result<(), WorkspaceError> {
+        let token = self.user.token()?;
+        let _ = self.server.create_workspace(&token, params).await?;
+        Ok(())
     }
-}
 
-pub async fn create_workspace_request(params: CreateWorkspaceParams, url: &str) -> Result<Workspace, WorkspaceError> {
-    let workspace = HttpRequestBuilder::post(&url.to_owned())
-        .protobuf(params)?
-        .send()
-        .await?
-        .response()
-        .await?;
-    Ok(workspace)
-}
+    fn update_workspace_on_server(&self, params: UpdateWorkspaceParams) -> Result<(), WorkspaceError> {
+        let (token, server) = self.token_server()?;
+        spawn(async move {
+            match server.update_workspace(&token, params).await {
+                Ok(_) => {},
+                Err(e) => {
+                    // TODO: retry?
+                    log::error!("Update workspace failed: {:?}", e);
+                },
+            }
+        });
+        Ok(())
+    }
 
-pub async fn read_workspaces_request(params: QueryWorkspaceParams, url: &str) -> Result<RepeatedWorkspace, WorkspaceError> {
-    let result = HttpRequestBuilder::get(&url.to_owned())
-        .protobuf(params)?
-        .send()
-        .await?
-        .response::<RepeatedWorkspace>()
-        .await;
+    fn delete_workspace_on_server(&self, params: DeleteWorkspaceParams) -> Result<(), WorkspaceError> {
+        let (token, server) = self.token_server()?;
+        spawn(async move {
+            match server.delete_workspace(&token, params).await {
+                Ok(_) => {},
+                Err(e) => {
+                    // TODO: retry?
+                    log::error!("Delete workspace failed: {:?}", e);
+                },
+            }
+        });
+        Ok(())
+    }
 
-    match result {
-        Ok(repeated_workspace) => Ok(repeated_workspace),
-        Err(e) => Err(e.into()),
+    fn read_workspaces_on_server(&self, params: QueryWorkspaceParams) -> Result<(), WorkspaceError> {
+        let (token, server) = self.token_server()?;
+        spawn(async move {
+            match server.read_workspace(&token, params).await {
+                Ok(_) => {
+                    // TODO: notify
+                },
+                Err(e) => {
+                    // TODO: retry?
+                    log::error!("Delete workspace failed: {:?}", e);
+                },
+            }
+        });
+        Ok(())
     }
 }
 
-pub async fn update_workspace_request(params: UpdateWorkspaceParams, url: &str) -> Result<(), WorkspaceError> {
-    let _ = HttpRequestBuilder::patch(&url.to_owned()).protobuf(params)?.send().await?;
-    Ok(())
-}
+const CURRENT_WORKSPACE_ID: &str = "current_workspace_id";
 
-pub async fn delete_workspace_request(params: DeleteWorkspaceParams, url: &str) -> Result<(), WorkspaceError> {
-    let _ = HttpRequestBuilder::delete(url).protobuf(params)?.send().await?;
-    Ok(())
-}
+fn set_current_workspace(workspace: &str) { KVStore::set_str(CURRENT_WORKSPACE_ID, workspace.to_owned()); }
 
-pub async fn read_workspace_list_request(url: &str) -> Result<RepeatedWorkspace, WorkspaceError> {
-    let workspaces = HttpRequestBuilder::get(url).send().await?.response::<RepeatedWorkspace>().await?;
-    Ok(workspaces)
+fn get_current_workspace() -> Result<String, WorkspaceError> {
+    match KVStore::get_str(CURRENT_WORKSPACE_ID) {
+        None => Err(ErrorBuilder::new(ErrorCode::CurrentWorkspaceNotFound).build()),
+        Some(workspace_id) => Ok(workspace_id),
+    }
 }