From eae6d3e0b42012429a03c9b98ce27e9e2384bac1 Mon Sep 17 00:00:00 2001 From: rot1024 Date: Fri, 8 Mar 2024 21:25:34 +0900 Subject: [PATCH] feat(account): add host field to workspace member --- .../{user => workspace}/initializer.go | 30 +++++------ .../{user => workspace}/initializer_test.go | 50 +++++++++---------- account/accountdomain/workspace/member.go | 9 ++-- .../accountdomain/workspace/member_test.go | 11 ++-- .../accountinteractor/user_signup.go | 7 +-- .../accountinteractor/workspace.go | 13 ++++- .../accountinteractor/workspace_test.go | 1 + account/user.graphql | 2 + account/workspace.graphql | 1 + 9 files changed, 72 insertions(+), 52 deletions(-) rename account/accountdomain/{user => workspace}/initializer.go (58%) rename account/accountdomain/{user => workspace}/initializer_test.go (69%) diff --git a/account/accountdomain/user/initializer.go b/account/accountdomain/workspace/initializer.go similarity index 58% rename from account/accountdomain/user/initializer.go rename to account/accountdomain/workspace/initializer.go index f521b63b..c07b577c 100644 --- a/account/accountdomain/user/initializer.go +++ b/account/accountdomain/workspace/initializer.go @@ -1,44 +1,44 @@ -package user +package workspace import ( - "github.com/reearth/reearthx/account/accountdomain/workspace" + "github.com/reearth/reearthx/account/accountdomain/user" "golang.org/x/text/language" ) type InitParams struct { Email string Name string - Sub *Auth + Sub *user.Auth Password *string Lang *language.Tag - Theme *Theme - UserID *ID - WorkspaceID *WorkspaceID + Theme *user.Theme + UserID *user.ID + WorkspaceID *ID } -func Init(p InitParams) (*User, *workspace.Workspace, error) { +func Init(p InitParams) (*user.User, *Workspace, error) { if p.UserID == nil { - p.UserID = NewID().Ref() + p.UserID = user.NewID().Ref() } if p.WorkspaceID == nil { - p.WorkspaceID = NewWorkspaceID().Ref() + p.WorkspaceID = NewID().Ref() } if p.Lang == nil { p.Lang = &language.Tag{} } if p.Theme == nil { - t := ThemeDefault + t := user.ThemeDefault p.Theme = &t } if p.Sub == nil { - p.Sub = GenReearthSub(p.UserID.String()) + p.Sub = user.GenReearthSub(p.UserID.String()) } - b := New(). + b := user.New(). ID(*p.UserID). Name(p.Name). Email(p.Email). - Auths([]Auth{*p.Sub}). + Auths([]user.Auth{*p.Sub}). Lang(*p.Lang). Theme(*p.Theme) if p.Password != nil { @@ -50,10 +50,10 @@ func Init(p InitParams) (*User, *workspace.Workspace, error) { } // create a user's own workspace - t, err := workspace.New(). + t, err := New(). ID(*p.WorkspaceID). Name(p.Name). - Members(map[ID]workspace.Member{u.ID(): {Role: workspace.RoleOwner, Disabled: false, InvitedBy: u.ID()}}). + Members(map[user.ID]Member{u.ID(): {Role: RoleOwner, Disabled: false, InvitedBy: u.ID()}}). Personal(true). Build() if err != nil { diff --git a/account/accountdomain/user/initializer_test.go b/account/accountdomain/workspace/initializer_test.go similarity index 69% rename from account/accountdomain/user/initializer_test.go rename to account/accountdomain/workspace/initializer_test.go index d67edd9c..2536e389 100644 --- a/account/accountdomain/user/initializer_test.go +++ b/account/accountdomain/workspace/initializer_test.go @@ -1,49 +1,49 @@ -package user +package workspace import ( "testing" - "github.com/reearth/reearthx/account/accountdomain/workspace" + "github.com/reearth/reearthx/account/accountdomain/user" "github.com/stretchr/testify/assert" ) func TestInit(t *testing.T) { - uid := NewID() - tid := NewWorkspaceID() - expectedSub := Auth{ + uid := user.NewID() + tid := NewID() + expectedSub := user.Auth{ Provider: "###", Sub: "###", } tests := []struct { Name, Email, Username string - Sub Auth - UID *ID - TID *WorkspaceID - ExpectedUser *User - ExpectedWorkspace *workspace.Workspace + Sub user.Auth + UID *user.ID + TID *ID + ExpectedUser *user.User + ExpectedWorkspace *Workspace Err error }{ { Name: "Success create user", Email: "xx@yy.zz", Username: "nnn", - Sub: Auth{ + Sub: user.Auth{ Provider: "###", Sub: "###", }, UID: &uid, TID: &tid, - ExpectedUser: New(). + ExpectedUser: user.New(). ID(uid). Email("xx@yy.zz"). Name("nnn"). Workspace(tid). - Auths([]Auth{expectedSub}). + Auths([]user.Auth{expectedSub}). MustBuild(), - ExpectedWorkspace: workspace.New(). + ExpectedWorkspace: New(). ID(tid). Name("nnn"). - Members(map[ID]workspace.Member{uid: {Role: workspace.RoleOwner}}). + Members(map[user.ID]Member{uid: {Role: RoleOwner}}). Personal(true). MustBuild(), Err: nil, @@ -52,23 +52,23 @@ func TestInit(t *testing.T) { Name: "Success nil workspace id", Email: "xx@yy.zz", Username: "nnn", - Sub: Auth{ + Sub: user.Auth{ Provider: "###", Sub: "###", }, UID: &uid, TID: nil, - ExpectedUser: New(). + ExpectedUser: user.New(). ID(uid). Email("xx@yy.zz"). Name("nnn"). Workspace(tid). - Auths([]Auth{expectedSub}). + Auths([]user.Auth{expectedSub}). MustBuild(), - ExpectedWorkspace: workspace.New(). + ExpectedWorkspace: New(). NewID(). Name("nnn"). - Members(map[ID]workspace.Member{uid: {Role: workspace.RoleOwner}}). + Members(map[user.ID]Member{uid: {Role: RoleOwner}}). Personal(true). MustBuild(), Err: nil, @@ -77,23 +77,23 @@ func TestInit(t *testing.T) { Name: "Success nil id", Email: "xx@yy.zz", Username: "nnn", - Sub: Auth{ + Sub: user.Auth{ Provider: "###", Sub: "###", }, UID: nil, TID: &tid, - ExpectedUser: New(). + ExpectedUser: user.New(). NewID(). Email("xx@yy.zz"). Name("nnn"). Workspace(tid). - Auths([]Auth{expectedSub}). + Auths([]user.Auth{expectedSub}). MustBuild(), - ExpectedWorkspace: workspace.New(). + ExpectedWorkspace: New(). ID(tid). Name("nnn"). - Members(map[ID]workspace.Member{uid: {Role: workspace.RoleOwner}}). + Members(map[user.ID]Member{uid: {Role: RoleOwner}}). Personal(true). MustBuild(), Err: nil, diff --git a/account/accountdomain/workspace/member.go b/account/accountdomain/workspace/member.go index 7b2ca5f9..36536454 100644 --- a/account/accountdomain/workspace/member.go +++ b/account/accountdomain/workspace/member.go @@ -3,6 +3,7 @@ package workspace import ( "sort" + "github.com/reearth/reearthx/account/accountdomain/user" "github.com/reearth/reearthx/i18n" "github.com/reearth/reearthx/rerror" "github.com/samber/lo" @@ -20,6 +21,7 @@ type Member struct { Role Role Disabled bool InvitedBy UserID + Host string } type Members struct { @@ -177,11 +179,11 @@ func (m *Members) UpdateIntegrationRole(iId IntegrationID, role Role) error { return nil } -func (m *Members) Join(u UserID, role Role, i UserID) error { +func (m *Members) Join(u *user.User, role Role, i UserID) error { if m.fixed { return ErrCannotModifyPersonalWorkspace } - if _, ok := m.users[u]; ok { + if _, ok := m.users[u.ID()]; ok { return ErrUserAlreadyJoined } if role == Role("") { @@ -190,10 +192,11 @@ func (m *Members) Join(u UserID, role Role, i UserID) error { if m.users == nil { m.users = map[UserID]Member{} } - m.users[u] = Member{ + m.users[u.ID()] = Member{ Role: role, Disabled: false, InvitedBy: i, + Host: u.Host(), } return nil } diff --git a/account/accountdomain/workspace/member_test.go b/account/accountdomain/workspace/member_test.go index 3270559e..375a9f34 100644 --- a/account/accountdomain/workspace/member_test.go +++ b/account/accountdomain/workspace/member_test.go @@ -3,6 +3,7 @@ package workspace import ( "testing" + "github.com/reearth/reearthx/account/accountdomain/user" "github.com/stretchr/testify/assert" ) @@ -143,21 +144,23 @@ func TestMembers_Join(t *testing.T) { uid := NewUserID() uid2 := NewUserID() + u := user.New().ID(uid).Name("test").Email("test@example.com").MustBuild().WithHost("reearth") + // ok m := &Members{} - assert.NoError(t, m.Join(uid, RoleOwner, uid2)) + assert.NoError(t, m.Join(u, RoleOwner, uid2)) assert.Equal(t, map[UserID]Member{ - uid: {Role: RoleOwner, InvitedBy: uid2}, + uid: {Role: RoleOwner, InvitedBy: uid2, Host: "reearth"}, }, m.users) // fixed m = &Members{fixed: true} - assert.Equal(t, ErrCannotModifyPersonalWorkspace, m.Join(uid, RoleOwner, uid2)) + assert.Equal(t, ErrCannotModifyPersonalWorkspace, m.Join(u, RoleOwner, uid2)) assert.Nil(t, m.users) // already joined m = &Members{users: map[UserID]Member{uid: {Role: RoleOwner}}} - assert.Equal(t, ErrUserAlreadyJoined, m.Join(uid, RoleOwner, uid2)) + assert.Equal(t, ErrUserAlreadyJoined, m.Join(u, RoleOwner, uid2)) assert.Equal(t, map[UserID]Member{uid: {Role: RoleOwner}}, m.users) } diff --git a/account/accountusecase/accountinteractor/user_signup.go b/account/accountusecase/accountinteractor/user_signup.go index eba63fb2..b13154be 100644 --- a/account/accountusecase/accountinteractor/user_signup.go +++ b/account/accountusecase/accountinteractor/user_signup.go @@ -15,6 +15,7 @@ import ( textTmpl "text/template" "github.com/reearth/reearthx/account/accountdomain/user" + "github.com/reearth/reearthx/account/accountdomain/workspace" "github.com/reearth/reearthx/account/accountusecase/accountinterfaces" "github.com/reearth/reearthx/account/accountusecase/accountrepo" "github.com/reearth/reearthx/i18n" @@ -71,7 +72,7 @@ func (i *User) Signup(ctx context.Context, param accountinterfaces.SignupParam) return nil, err } - u, workspace, err := user.Init(user.InitParams{ + u, workspace, err := workspace.Init(workspace.InitParams{ Email: param.Email, Name: param.Name, Password: lo.ToPtr(param.Password), @@ -147,7 +148,7 @@ func (i *User) SignupOIDC(ctx context.Context, param accountinterfaces.SignupOID } // Initialize user and ws - u, ws, err := user.Init(user.InitParams{ + u, ws, err := workspace.Init(workspace.InitParams{ Email: email, Name: name, Sub: user.AuthFrom(sub).Ref(), @@ -190,7 +191,7 @@ func (i *User) FindOrCreate(ctx context.Context, param accountinterfaces.UserFin return nil, err } - u, workspace, err := user.Init(user.InitParams{ + u, workspace, err := workspace.Init(workspace.InitParams{ Email: ui.Email, Name: ui.Name, Sub: user.AuthFrom(param.Sub).Ref(), diff --git a/account/accountusecase/accountinteractor/workspace.go b/account/accountusecase/accountinteractor/workspace.go index 2bcb89c8..d25014ad 100644 --- a/account/accountusecase/accountinteractor/workspace.go +++ b/account/accountusecase/accountinteractor/workspace.go @@ -9,6 +9,7 @@ import ( "github.com/reearth/reearthx/account/accountusecase" "github.com/reearth/reearthx/account/accountusecase/accountinterfaces" "github.com/reearth/reearthx/account/accountusecase/accountrepo" + "github.com/reearth/reearthx/rerror" "github.com/samber/lo" "golang.org/x/exp/maps" ) @@ -49,6 +50,14 @@ func (i *Workspace) Create(ctx context.Context, name string, firstUser workspace return nil, user.ErrInvalidName } + firstUsers, err := i.userquery.FetchByID(ctx, []user.ID{firstUser}) + if err != nil || len(firstUsers) == 0 { + if err == nil { + return nil, rerror.ErrNotFound + } + return nil, err + } + ws, err := workspace.New(). NewID(). Name(name). @@ -57,7 +66,7 @@ func (i *Workspace) Create(ctx context.Context, name string, firstUser workspace return nil, err } - if err := ws.Members().Join(firstUser, workspace.RoleOwner, *operator.User); err != nil { + if err := ws.Members().Join(firstUsers[0], workspace.RoleOwner, *operator.User); err != nil { return nil, err } @@ -136,7 +145,7 @@ func (i *Workspace) AddUserMember(ctx context.Context, workspaceID workspace.ID, continue } - err = ws.Members().Join(m.ID(), users[m.ID()], *operator.User) + err = ws.Members().Join(m, users[m.ID()], *operator.User) if err != nil { return nil, err } diff --git a/account/accountusecase/accountinteractor/workspace_test.go b/account/accountusecase/accountinteractor/workspace_test.go index c5119a3b..8b4ec656 100644 --- a/account/accountusecase/accountinteractor/workspace_test.go +++ b/account/accountusecase/accountinteractor/workspace_test.go @@ -22,6 +22,7 @@ func TestWorkspace_Create(t *testing.T) { db := accountmemory.New() u := user.New().NewID().Name("aaa").Email("aaa@bbb.com").Workspace(accountdomain.NewWorkspaceID()).MustBuild() + _ = db.User.Save(ctx, u) workspaceUC := NewWorkspace(db, nil) op := &accountusecase.Operator{User: lo.ToPtr(u.ID())} ws, err := workspaceUC.Create(ctx, "workspace name", u.ID(), op) diff --git a/account/user.graphql b/account/user.graphql index 73897e19..97d1c4c6 100644 --- a/account/user.graphql +++ b/account/user.graphql @@ -4,6 +4,7 @@ type User implements Node { email: String! lang: Lang! theme: Theme! + host: String workspace: ID! auths: [String!]! } @@ -14,6 +15,7 @@ type Me { email: String! lang: Lang! theme: Theme! + host: String myWorkspaceId: ID! auths: [String!]! workspaces: [Workspace!]! diff --git a/account/workspace.graphql b/account/workspace.graphql index 0e66f680..5d6113c5 100644 --- a/account/workspace.graphql +++ b/account/workspace.graphql @@ -10,6 +10,7 @@ union WorkspaceMember = WorkspaceUserMember | WorkspaceIntegrationMember type WorkspaceUserMember { userId: ID! role: Role! + host: String user: User }