From 90f638974520060ff6015b290abc5ac5006bdd99 Mon Sep 17 00:00:00 2001 From: Harshil Sharma Date: Fri, 4 Jun 2021 18:53:15 +0530 Subject: [PATCH] Person Property Type (#406) * Added getWorkspaceUsers API * Integrated workspace user API in UI * Integrated workspace user API in UI * Added toto for implementation slot * Implemenmted getWorkspaceUSers to get data from Focalboard DB * Updated store mocks * Made select styles a shared constant * Removed unwanted diffs * Removed unwanted diffs * Updated snapshots for new property type * Added user store test * Added missing copyright notice * Returning error if no users found to retain original behavior * Minor fixes and added tests * Minor fixes * Used React context for workspace users * Used useContext hook, and added additional user ID -> user context to avoid that computation by all componnets * Mergerd both workspace user contextx * Minor review fix --- server/api/api.go | 54 + server/app/user.go | 7 + server/go.mod | 1 + server/go.sum | 2 + server/services/store/mockstore/mockstore.go | 255 ++--- .../services/store/sqlstore/sqlstore_test.go | 1 + server/services/store/sqlstore/user.go | 87 +- server/services/store/store.go | 1 + server/services/store/storetests/users.go | 52 + .../docs/html/.openapi-generator/VERSION | 2 +- server/swagger/docs/html/index.html | 991 +++++++++++++----- server/swagger/swagger.yml | 32 +- webapp/package-lock.json | 88 +- webapp/package.json | 4 +- webapp/src/components/cardDetail/comment.tsx | 1 - .../user/__snapshots__/user.test.tsx.snap | 185 ++++ .../src/components/properties/user/user.scss | 4 + .../components/properties/user/user.test.tsx | 116 ++ .../src/components/properties/user/user.tsx | 47 + .../src/components/propertyValueElement.tsx | 27 +- webapp/src/octoClient.ts | 9 + webapp/src/pages/boardPage.tsx | 73 +- webapp/src/theme.ts | 66 ++ webapp/src/user.tsx | 12 +- .../__snapshots__/propertyMenu.test.tsx.snap | 15 + webapp/src/widgets/propertyMenu.tsx | 5 + webapp/src/widgets/valueSelector.tsx | 100 +- 27 files changed, 1684 insertions(+), 553 deletions(-) create mode 100644 server/app/user.go create mode 100644 server/services/store/storetests/users.go create mode 100644 webapp/src/components/properties/user/__snapshots__/user.test.tsx.snap create mode 100644 webapp/src/components/properties/user/user.scss create mode 100644 webapp/src/components/properties/user/user.test.tsx create mode 100644 webapp/src/components/properties/user/user.tsx diff --git a/server/api/api.go b/server/api/api.go index f4c8eda3e..c8dace7d5 100644 --- a/server/api/api.go +++ b/server/api/api.go @@ -71,6 +71,7 @@ func (a *API) RegisterRoutes(r *mux.Router) { apiv1.HandleFunc("/workspaces/{workspaceID}", a.sessionRequired(a.handleGetWorkspace)).Methods("GET") apiv1.HandleFunc("/workspaces/{workspaceID}/regenerate_signup_token", a.sessionRequired(a.handlePostWorkspaceRegenerateSignupToken)).Methods("POST") + apiv1.HandleFunc("/workspaces/{workspaceID}/users", a.sessionRequired(a.getWorkspaceUsers)).Methods("GET") // User APIs apiv1.HandleFunc("/users/me", a.sessionRequired(a.handleGetMe)).Methods("GET") @@ -1133,6 +1134,59 @@ func (a *API) handleUploadFile(w http.ResponseWriter, r *http.Request) { jsonBytesResponse(w, http.StatusOK, data) } +func (a *API) getWorkspaceUsers(w http.ResponseWriter, r *http.Request) { + // swagger:operation GET /api/v1/workspaces/{workspaceID}/users getWorkspaceUsers + // + // Returns workspace users + // + // --- + // produces: + // - application/json + // parameters: + // - name: workspaceID + // in: path + // description: Workspace ID + // required: true + // type: string + // security: + // - BearerAuth: [] + // responses: + // '200': + // description: success + // schema: + // type: array + // items: + // "$ref": "#/definitions/User" + // default: + // description: internal error + // schema: + // "$ref": "#/definitions/ErrorResponse" + + vars := mux.Vars(r) + workspaceID := vars["workspaceID"] + + ctx := r.Context() + session := ctx.Value("session").(*model.Session) + if !a.app().DoesUserHaveWorkspaceAccess(session.UserID, workspaceID) { + a.errorResponse(w, http.StatusForbidden, "Access denied to workspace", errors.New("Access denied to workspace")) + return + } + + users, err := a.app().GetWorkspaceUsers(workspaceID) + if err != nil { + a.errorResponse(w, http.StatusInternalServerError, "", err) + return + } + + data, err := json.Marshal(users) + if err != nil { + a.errorResponse(w, http.StatusInternalServerError, "", err) + return + } + + jsonBytesResponse(w, http.StatusOK, data) +} + // Response helpers func (a *API) errorResponse(w http.ResponseWriter, code int, message string, sourceError error) { diff --git a/server/app/user.go b/server/app/user.go new file mode 100644 index 000000000..61488dfab --- /dev/null +++ b/server/app/user.go @@ -0,0 +1,7 @@ +package app + +import "github.com/mattermost/focalboard/server/model" + +func (a *App) GetWorkspaceUsers(workspaceID string) ([]*model.User, error) { + return a.store.GetUsersByWorkspace(workspaceID) +} diff --git a/server/go.mod b/server/go.mod index 7e8c3ae18..d878d53b1 100644 --- a/server/go.mod +++ b/server/go.mod @@ -27,6 +27,7 @@ require ( github.com/stretchr/testify v1.7.0 github.com/tidwall/gjson v1.7.3 // indirect golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20210324051608-47abb6519492 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/server/go.sum b/server/go.sum index a46e1d186..8eaf9dc3b 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1183,6 +1183,7 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1381,6 +1382,7 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= diff --git a/server/services/store/mockstore/mockstore.go b/server/services/store/mockstore/mockstore.go index 2512151df..a2a2ed3c1 100644 --- a/server/services/store/mockstore/mockstore.go +++ b/server/services/store/mockstore/mockstore.go @@ -36,133 +36,133 @@ func (m *MockStore) EXPECT() *MockStoreMockRecorder { } // CleanUpSessions mocks base method. -func (m *MockStore) CleanUpSessions(arg0 int64) error { +func (m *MockStore) CleanUpSessions(expireTime int64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CleanUpSessions", arg0) + ret := m.ctrl.Call(m, "CleanUpSessions", expireTime) ret0, _ := ret[0].(error) return ret0 } // CleanUpSessions indicates an expected call of CleanUpSessions. -func (mr *MockStoreMockRecorder) CleanUpSessions(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) CleanUpSessions(expireTime interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CleanUpSessions", reflect.TypeOf((*MockStore)(nil).CleanUpSessions), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CleanUpSessions", reflect.TypeOf((*MockStore)(nil).CleanUpSessions), expireTime) } // CreateSession mocks base method. -func (m *MockStore) CreateSession(arg0 *model.Session) error { +func (m *MockStore) CreateSession(session *model.Session) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateSession", arg0) + ret := m.ctrl.Call(m, "CreateSession", session) ret0, _ := ret[0].(error) return ret0 } // CreateSession indicates an expected call of CreateSession. -func (mr *MockStoreMockRecorder) CreateSession(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) CreateSession(session interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSession", reflect.TypeOf((*MockStore)(nil).CreateSession), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSession", reflect.TypeOf((*MockStore)(nil).CreateSession), session) } // CreateUser mocks base method. -func (m *MockStore) CreateUser(arg0 *model.User) error { +func (m *MockStore) CreateUser(user *model.User) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateUser", arg0) + ret := m.ctrl.Call(m, "CreateUser", user) ret0, _ := ret[0].(error) return ret0 } // CreateUser indicates an expected call of CreateUser. -func (mr *MockStoreMockRecorder) CreateUser(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) CreateUser(user interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockStore)(nil).CreateUser), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockStore)(nil).CreateUser), user) } // DeleteBlock mocks base method. -func (m *MockStore) DeleteBlock(arg0 store.Container, arg1, arg2 string) error { +func (m *MockStore) DeleteBlock(c store.Container, blockID, modifiedBy string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteBlock", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "DeleteBlock", c, blockID, modifiedBy) ret0, _ := ret[0].(error) return ret0 } // DeleteBlock indicates an expected call of DeleteBlock. -func (mr *MockStoreMockRecorder) DeleteBlock(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) DeleteBlock(c, blockID, modifiedBy interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBlock", reflect.TypeOf((*MockStore)(nil).DeleteBlock), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBlock", reflect.TypeOf((*MockStore)(nil).DeleteBlock), c, blockID, modifiedBy) } // DeleteSession mocks base method. -func (m *MockStore) DeleteSession(arg0 string) error { +func (m *MockStore) DeleteSession(sessionId string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteSession", arg0) + ret := m.ctrl.Call(m, "DeleteSession", sessionId) ret0, _ := ret[0].(error) return ret0 } // DeleteSession indicates an expected call of DeleteSession. -func (mr *MockStoreMockRecorder) DeleteSession(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) DeleteSession(sessionId interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSession", reflect.TypeOf((*MockStore)(nil).DeleteSession), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSession", reflect.TypeOf((*MockStore)(nil).DeleteSession), sessionId) } // GetActiveUserCount mocks base method. -func (m *MockStore) GetActiveUserCount(arg0 int64) (int, error) { +func (m *MockStore) GetActiveUserCount(updatedSecondsAgo int64) (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetActiveUserCount", arg0) + ret := m.ctrl.Call(m, "GetActiveUserCount", updatedSecondsAgo) ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } // GetActiveUserCount indicates an expected call of GetActiveUserCount. -func (mr *MockStoreMockRecorder) GetActiveUserCount(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetActiveUserCount(updatedSecondsAgo interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveUserCount", reflect.TypeOf((*MockStore)(nil).GetActiveUserCount), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveUserCount", reflect.TypeOf((*MockStore)(nil).GetActiveUserCount), updatedSecondsAgo) } // GetAllBlocks mocks base method. -func (m *MockStore) GetAllBlocks(arg0 store.Container) ([]model.Block, error) { +func (m *MockStore) GetAllBlocks(c store.Container) ([]model.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAllBlocks", arg0) + ret := m.ctrl.Call(m, "GetAllBlocks", c) ret0, _ := ret[0].([]model.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetAllBlocks indicates an expected call of GetAllBlocks. -func (mr *MockStoreMockRecorder) GetAllBlocks(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetAllBlocks(c interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllBlocks", reflect.TypeOf((*MockStore)(nil).GetAllBlocks), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllBlocks", reflect.TypeOf((*MockStore)(nil).GetAllBlocks), c) } // GetBlocksWithParent mocks base method. -func (m *MockStore) GetBlocksWithParent(arg0 store.Container, arg1 string) ([]model.Block, error) { +func (m *MockStore) GetBlocksWithParent(c store.Container, parentID string) ([]model.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlocksWithParent", arg0, arg1) + ret := m.ctrl.Call(m, "GetBlocksWithParent", c, parentID) ret0, _ := ret[0].([]model.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlocksWithParent indicates an expected call of GetBlocksWithParent. -func (mr *MockStoreMockRecorder) GetBlocksWithParent(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetBlocksWithParent(c, parentID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithParent", reflect.TypeOf((*MockStore)(nil).GetBlocksWithParent), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithParent", reflect.TypeOf((*MockStore)(nil).GetBlocksWithParent), c, parentID) } // GetBlocksWithParentAndType mocks base method. -func (m *MockStore) GetBlocksWithParentAndType(arg0 store.Container, arg1, arg2 string) ([]model.Block, error) { +func (m *MockStore) GetBlocksWithParentAndType(c store.Container, parentID, blockType string) ([]model.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlocksWithParentAndType", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "GetBlocksWithParentAndType", c, parentID, blockType) ret0, _ := ret[0].([]model.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlocksWithParentAndType indicates an expected call of GetBlocksWithParentAndType. -func (mr *MockStoreMockRecorder) GetBlocksWithParentAndType(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetBlocksWithParentAndType(c, parentID, blockType interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithParentAndType", reflect.TypeOf((*MockStore)(nil).GetBlocksWithParentAndType), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithParentAndType", reflect.TypeOf((*MockStore)(nil).GetBlocksWithParentAndType), c, parentID, blockType) } // GetBlocksWithRootID mocks base method. @@ -181,33 +181,33 @@ func (mr *MockStoreMockRecorder) GetBlocksWithRootID(arg0, arg1 interface{}) *go } // GetBlocksWithType mocks base method. -func (m *MockStore) GetBlocksWithType(arg0 store.Container, arg1 string) ([]model.Block, error) { +func (m *MockStore) GetBlocksWithType(c store.Container, blockType string) ([]model.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlocksWithType", arg0, arg1) + ret := m.ctrl.Call(m, "GetBlocksWithType", c, blockType) ret0, _ := ret[0].([]model.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlocksWithType indicates an expected call of GetBlocksWithType. -func (mr *MockStoreMockRecorder) GetBlocksWithType(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetBlocksWithType(c, blockType interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithType", reflect.TypeOf((*MockStore)(nil).GetBlocksWithType), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlocksWithType", reflect.TypeOf((*MockStore)(nil).GetBlocksWithType), c, blockType) } // GetParentID mocks base method. -func (m *MockStore) GetParentID(arg0 store.Container, arg1 string) (string, error) { +func (m *MockStore) GetParentID(c store.Container, blockID string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetParentID", arg0, arg1) + ret := m.ctrl.Call(m, "GetParentID", c, blockID) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // GetParentID indicates an expected call of GetParentID. -func (mr *MockStoreMockRecorder) GetParentID(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetParentID(c, blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParentID", reflect.TypeOf((*MockStore)(nil).GetParentID), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParentID", reflect.TypeOf((*MockStore)(nil).GetParentID), c, blockID) } // GetRegisteredUserCount mocks base method. @@ -226,78 +226,78 @@ func (mr *MockStoreMockRecorder) GetRegisteredUserCount() *gomock.Call { } // GetRootID mocks base method. -func (m *MockStore) GetRootID(arg0 store.Container, arg1 string) (string, error) { +func (m *MockStore) GetRootID(c store.Container, blockID string) (string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRootID", arg0, arg1) + ret := m.ctrl.Call(m, "GetRootID", c, blockID) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // GetRootID indicates an expected call of GetRootID. -func (mr *MockStoreMockRecorder) GetRootID(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetRootID(c, blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRootID", reflect.TypeOf((*MockStore)(nil).GetRootID), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRootID", reflect.TypeOf((*MockStore)(nil).GetRootID), c, blockID) } // GetSession mocks base method. -func (m *MockStore) GetSession(arg0 string, arg1 int64) (*model.Session, error) { +func (m *MockStore) GetSession(token string, expireTime int64) (*model.Session, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSession", arg0, arg1) + ret := m.ctrl.Call(m, "GetSession", token, expireTime) ret0, _ := ret[0].(*model.Session) ret1, _ := ret[1].(error) return ret0, ret1 } // GetSession indicates an expected call of GetSession. -func (mr *MockStoreMockRecorder) GetSession(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetSession(token, expireTime interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSession", reflect.TypeOf((*MockStore)(nil).GetSession), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSession", reflect.TypeOf((*MockStore)(nil).GetSession), token, expireTime) } // GetSharing mocks base method. -func (m *MockStore) GetSharing(arg0 store.Container, arg1 string) (*model.Sharing, error) { +func (m *MockStore) GetSharing(c store.Container, rootID string) (*model.Sharing, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSharing", arg0, arg1) + ret := m.ctrl.Call(m, "GetSharing", c, rootID) ret0, _ := ret[0].(*model.Sharing) ret1, _ := ret[1].(error) return ret0, ret1 } // GetSharing indicates an expected call of GetSharing. -func (mr *MockStoreMockRecorder) GetSharing(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetSharing(c, rootID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSharing", reflect.TypeOf((*MockStore)(nil).GetSharing), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSharing", reflect.TypeOf((*MockStore)(nil).GetSharing), c, rootID) } // GetSubTree2 mocks base method. -func (m *MockStore) GetSubTree2(arg0 store.Container, arg1 string) ([]model.Block, error) { +func (m *MockStore) GetSubTree2(c store.Container, blockID string) ([]model.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubTree2", arg0, arg1) + ret := m.ctrl.Call(m, "GetSubTree2", c, blockID) ret0, _ := ret[0].([]model.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetSubTree2 indicates an expected call of GetSubTree2. -func (mr *MockStoreMockRecorder) GetSubTree2(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetSubTree2(c, blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubTree2", reflect.TypeOf((*MockStore)(nil).GetSubTree2), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubTree2", reflect.TypeOf((*MockStore)(nil).GetSubTree2), c, blockID) } // GetSubTree3 mocks base method. -func (m *MockStore) GetSubTree3(arg0 store.Container, arg1 string) ([]model.Block, error) { +func (m *MockStore) GetSubTree3(c store.Container, blockID string) ([]model.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubTree3", arg0, arg1) + ret := m.ctrl.Call(m, "GetSubTree3", c, blockID) ret0, _ := ret[0].([]model.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetSubTree3 indicates an expected call of GetSubTree3. -func (mr *MockStoreMockRecorder) GetSubTree3(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetSubTree3(c, blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubTree3", reflect.TypeOf((*MockStore)(nil).GetSubTree3), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubTree3", reflect.TypeOf((*MockStore)(nil).GetSubTree3), c, blockID) } // GetSystemSettings mocks base method. @@ -316,63 +316,78 @@ func (mr *MockStoreMockRecorder) GetSystemSettings() *gomock.Call { } // GetUserByEmail mocks base method. -func (m *MockStore) GetUserByEmail(arg0 string) (*model.User, error) { +func (m *MockStore) GetUserByEmail(email string) (*model.User, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUserByEmail", arg0) + ret := m.ctrl.Call(m, "GetUserByEmail", email) ret0, _ := ret[0].(*model.User) ret1, _ := ret[1].(error) return ret0, ret1 } // GetUserByEmail indicates an expected call of GetUserByEmail. -func (mr *MockStoreMockRecorder) GetUserByEmail(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetUserByEmail(email interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByEmail", reflect.TypeOf((*MockStore)(nil).GetUserByEmail), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByEmail", reflect.TypeOf((*MockStore)(nil).GetUserByEmail), email) } // GetUserById mocks base method. -func (m *MockStore) GetUserById(arg0 string) (*model.User, error) { +func (m *MockStore) GetUserById(userID string) (*model.User, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUserById", arg0) + ret := m.ctrl.Call(m, "GetUserById", userID) ret0, _ := ret[0].(*model.User) ret1, _ := ret[1].(error) return ret0, ret1 } // GetUserById indicates an expected call of GetUserById. -func (mr *MockStoreMockRecorder) GetUserById(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetUserById(userID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserById", reflect.TypeOf((*MockStore)(nil).GetUserById), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserById", reflect.TypeOf((*MockStore)(nil).GetUserById), userID) } // GetUserByUsername mocks base method. -func (m *MockStore) GetUserByUsername(arg0 string) (*model.User, error) { +func (m *MockStore) GetUserByUsername(username string) (*model.User, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUserByUsername", arg0) + ret := m.ctrl.Call(m, "GetUserByUsername", username) ret0, _ := ret[0].(*model.User) ret1, _ := ret[1].(error) return ret0, ret1 } // GetUserByUsername indicates an expected call of GetUserByUsername. -func (mr *MockStoreMockRecorder) GetUserByUsername(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetUserByUsername(username interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByUsername", reflect.TypeOf((*MockStore)(nil).GetUserByUsername), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByUsername", reflect.TypeOf((*MockStore)(nil).GetUserByUsername), username) +} + +// GetUsersByWorkspace mocks base method. +func (m *MockStore) GetUsersByWorkspace(workspaceID string) ([]*model.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUsersByWorkspace", workspaceID) + ret0, _ := ret[0].([]*model.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUsersByWorkspace indicates an expected call of GetUsersByWorkspace. +func (mr *MockStoreMockRecorder) GetUsersByWorkspace(workspaceID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUsersByWorkspace", reflect.TypeOf((*MockStore)(nil).GetUsersByWorkspace), workspaceID) } // GetWorkspace mocks base method. -func (m *MockStore) GetWorkspace(arg0 string) (*model.Workspace, error) { +func (m *MockStore) GetWorkspace(ID string) (*model.Workspace, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetWorkspace", arg0) + ret := m.ctrl.Call(m, "GetWorkspace", ID) ret0, _ := ret[0].(*model.Workspace) ret1, _ := ret[1].(error) return ret0, ret1 } // GetWorkspace indicates an expected call of GetWorkspace. -func (mr *MockStoreMockRecorder) GetWorkspace(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) GetWorkspace(ID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspace", reflect.TypeOf((*MockStore)(nil).GetWorkspace), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspace", reflect.TypeOf((*MockStore)(nil).GetWorkspace), ID) } // HasWorkspaceAccess mocks base method. @@ -391,45 +406,45 @@ func (mr *MockStoreMockRecorder) HasWorkspaceAccess(arg0, arg1 interface{}) *gom } // InsertBlock mocks base method. -func (m *MockStore) InsertBlock(arg0 store.Container, arg1 model.Block) error { +func (m *MockStore) InsertBlock(c store.Container, block model.Block) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InsertBlock", arg0, arg1) + ret := m.ctrl.Call(m, "InsertBlock", c, block) ret0, _ := ret[0].(error) return ret0 } // InsertBlock indicates an expected call of InsertBlock. -func (mr *MockStoreMockRecorder) InsertBlock(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) InsertBlock(c, block interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertBlock", reflect.TypeOf((*MockStore)(nil).InsertBlock), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertBlock", reflect.TypeOf((*MockStore)(nil).InsertBlock), c, block) } // RefreshSession mocks base method. -func (m *MockStore) RefreshSession(arg0 *model.Session) error { +func (m *MockStore) RefreshSession(session *model.Session) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RefreshSession", arg0) + ret := m.ctrl.Call(m, "RefreshSession", session) ret0, _ := ret[0].(error) return ret0 } // RefreshSession indicates an expected call of RefreshSession. -func (mr *MockStoreMockRecorder) RefreshSession(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) RefreshSession(session interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RefreshSession", reflect.TypeOf((*MockStore)(nil).RefreshSession), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RefreshSession", reflect.TypeOf((*MockStore)(nil).RefreshSession), session) } // SetSystemSetting mocks base method. -func (m *MockStore) SetSystemSetting(arg0, arg1 string) error { +func (m *MockStore) SetSystemSetting(key, value string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetSystemSetting", arg0, arg1) + ret := m.ctrl.Call(m, "SetSystemSetting", key, value) ret0, _ := ret[0].(error) return ret0 } // SetSystemSetting indicates an expected call of SetSystemSetting. -func (mr *MockStoreMockRecorder) SetSystemSetting(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) SetSystemSetting(key, value interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSystemSetting", reflect.TypeOf((*MockStore)(nil).SetSystemSetting), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSystemSetting", reflect.TypeOf((*MockStore)(nil).SetSystemSetting), key, value) } // Shutdown mocks base method. @@ -447,99 +462,99 @@ func (mr *MockStoreMockRecorder) Shutdown() *gomock.Call { } // UpdateSession mocks base method. -func (m *MockStore) UpdateSession(arg0 *model.Session) error { +func (m *MockStore) UpdateSession(session *model.Session) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateSession", arg0) + ret := m.ctrl.Call(m, "UpdateSession", session) ret0, _ := ret[0].(error) return ret0 } // UpdateSession indicates an expected call of UpdateSession. -func (mr *MockStoreMockRecorder) UpdateSession(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) UpdateSession(session interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSession", reflect.TypeOf((*MockStore)(nil).UpdateSession), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSession", reflect.TypeOf((*MockStore)(nil).UpdateSession), session) } // UpdateUser mocks base method. -func (m *MockStore) UpdateUser(arg0 *model.User) error { +func (m *MockStore) UpdateUser(user *model.User) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateUser", arg0) + ret := m.ctrl.Call(m, "UpdateUser", user) ret0, _ := ret[0].(error) return ret0 } // UpdateUser indicates an expected call of UpdateUser. -func (mr *MockStoreMockRecorder) UpdateUser(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) UpdateUser(user interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockStore)(nil).UpdateUser), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockStore)(nil).UpdateUser), user) } // UpdateUserPassword mocks base method. -func (m *MockStore) UpdateUserPassword(arg0, arg1 string) error { +func (m *MockStore) UpdateUserPassword(username, password string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateUserPassword", arg0, arg1) + ret := m.ctrl.Call(m, "UpdateUserPassword", username, password) ret0, _ := ret[0].(error) return ret0 } // UpdateUserPassword indicates an expected call of UpdateUserPassword. -func (mr *MockStoreMockRecorder) UpdateUserPassword(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) UpdateUserPassword(username, password interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUserPassword", reflect.TypeOf((*MockStore)(nil).UpdateUserPassword), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUserPassword", reflect.TypeOf((*MockStore)(nil).UpdateUserPassword), username, password) } // UpdateUserPasswordByID mocks base method. -func (m *MockStore) UpdateUserPasswordByID(arg0, arg1 string) error { +func (m *MockStore) UpdateUserPasswordByID(userID, password string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateUserPasswordByID", arg0, arg1) + ret := m.ctrl.Call(m, "UpdateUserPasswordByID", userID, password) ret0, _ := ret[0].(error) return ret0 } // UpdateUserPasswordByID indicates an expected call of UpdateUserPasswordByID. -func (mr *MockStoreMockRecorder) UpdateUserPasswordByID(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) UpdateUserPasswordByID(userID, password interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUserPasswordByID", reflect.TypeOf((*MockStore)(nil).UpdateUserPasswordByID), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUserPasswordByID", reflect.TypeOf((*MockStore)(nil).UpdateUserPasswordByID), userID, password) } // UpsertSharing mocks base method. -func (m *MockStore) UpsertSharing(arg0 store.Container, arg1 model.Sharing) error { +func (m *MockStore) UpsertSharing(c store.Container, sharing model.Sharing) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpsertSharing", arg0, arg1) + ret := m.ctrl.Call(m, "UpsertSharing", c, sharing) ret0, _ := ret[0].(error) return ret0 } // UpsertSharing indicates an expected call of UpsertSharing. -func (mr *MockStoreMockRecorder) UpsertSharing(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) UpsertSharing(c, sharing interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertSharing", reflect.TypeOf((*MockStore)(nil).UpsertSharing), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertSharing", reflect.TypeOf((*MockStore)(nil).UpsertSharing), c, sharing) } // UpsertWorkspaceSettings mocks base method. -func (m *MockStore) UpsertWorkspaceSettings(arg0 model.Workspace) error { +func (m *MockStore) UpsertWorkspaceSettings(workspace model.Workspace) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpsertWorkspaceSettings", arg0) + ret := m.ctrl.Call(m, "UpsertWorkspaceSettings", workspace) ret0, _ := ret[0].(error) return ret0 } // UpsertWorkspaceSettings indicates an expected call of UpsertWorkspaceSettings. -func (mr *MockStoreMockRecorder) UpsertWorkspaceSettings(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) UpsertWorkspaceSettings(workspace interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceSettings", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceSettings), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceSettings", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceSettings), workspace) } // UpsertWorkspaceSignupToken mocks base method. -func (m *MockStore) UpsertWorkspaceSignupToken(arg0 model.Workspace) error { +func (m *MockStore) UpsertWorkspaceSignupToken(workspace model.Workspace) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpsertWorkspaceSignupToken", arg0) + ret := m.ctrl.Call(m, "UpsertWorkspaceSignupToken", workspace) ret0, _ := ret[0].(error) return ret0 } // UpsertWorkspaceSignupToken indicates an expected call of UpsertWorkspaceSignupToken. -func (mr *MockStoreMockRecorder) UpsertWorkspaceSignupToken(arg0 interface{}) *gomock.Call { +func (mr *MockStoreMockRecorder) UpsertWorkspaceSignupToken(workspace interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceSignupToken", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceSignupToken), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceSignupToken", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceSignupToken), workspace) } diff --git a/server/services/store/sqlstore/sqlstore_test.go b/server/services/store/sqlstore/sqlstore_test.go index 75dc6759d..c141e72b8 100644 --- a/server/services/store/sqlstore/sqlstore_test.go +++ b/server/services/store/sqlstore/sqlstore_test.go @@ -39,4 +39,5 @@ func TestBlocksStore(t *testing.T) { t.Run("BlocksStore", func(t *testing.T) { storetests.StoreTestBlocksStore(t, SetupTests) }) t.Run("SharingStore", func(t *testing.T) { storetests.StoreTestSharingStore(t, SetupTests) }) t.Run("SystemStore", func(t *testing.T) { storetests.StoreTestSystemStore(t, SetupTests) }) + t.Run("UserStore", func(t *testing.T) { storetests.StoreTestUserStore(t, SetupTests) }) } diff --git a/server/services/store/sqlstore/user.go b/server/services/store/sqlstore/user.go index 37994def8..83ac27326 100644 --- a/server/services/store/sqlstore/user.go +++ b/server/services/store/sqlstore/user.go @@ -1,8 +1,10 @@ package sqlstore import ( + "database/sql" "encoding/json" "errors" + "log" "time" "github.com/mattermost/focalboard/server/model" @@ -27,26 +29,52 @@ func (s *SQLStore) GetRegisteredUserCount() (int, error) { } func (s *SQLStore) getUserByCondition(condition sq.Eq) (*model.User, error) { + users, err := s.getUsersByCondition(condition) + if err != nil { + return nil, err + } + + if len(users) == 0 { + return nil, nil + } + + return users[0], nil +} + +func (s *SQLStore) getUsersByCondition(condition sq.Eq) ([]*model.User, error) { query := s.getQueryBuilder(). - Select("id", "username", "email", "password", "mfa_secret", "auth_service", "auth_data", "props", "create_at", "update_at", "delete_at"). + Select( + "id", + "username", + "email", + "password", + "mfa_secret", + "auth_service", + "auth_data", + "props", + "create_at", + "update_at", + "delete_at", + ). From(s.tablePrefix + "users"). Where(sq.Eq{"delete_at": 0}). Where(condition) - row := query.QueryRow() - user := model.User{} + rows, err := query.Query() + if err != nil { + log.Printf("getUsersByCondition ERROR: %v", err) + return nil, err + } - var propsBytes []byte - err := row.Scan(&user.ID, &user.Username, &user.Email, &user.Password, &user.MfaSecret, &user.AuthService, &user.AuthData, &propsBytes, &user.CreateAt, &user.UpdateAt, &user.DeleteAt) + users, err := s.usersFromRows(rows) if err != nil { return nil, err } - err = json.Unmarshal(propsBytes, &user.Props) - if err != nil { - return nil, err + if len(users) == 0 { + return nil, sql.ErrNoRows } - return &user, nil + return users, nil } func (s *SQLStore) GetUserById(userID string) (*model.User, error) { @@ -158,3 +186,44 @@ func (s *SQLStore) UpdateUserPasswordByID(userID, password string) error { return nil } + +func (s *SQLStore) GetUsersByWorkspace(workspaceID string) ([]*model.User, error) { + return s.getUsersByCondition(nil) +} + +func (s *SQLStore) usersFromRows(rows *sql.Rows) ([]*model.User, error) { + defer rows.Close() + + users := []*model.User{} + + for rows.Next() { + var user model.User + var propsBytes []byte + + err := rows.Scan( + &user.ID, + &user.Username, + &user.Email, + &user.Password, + &user.MfaSecret, + &user.AuthService, + &user.AuthData, + &propsBytes, + &user.CreateAt, + &user.UpdateAt, + &user.DeleteAt, + ) + if err != nil { + return nil, err + } + + err = json.Unmarshal(propsBytes, &user.Props) + if err != nil { + return nil, err + } + + users = append(users, &user) + } + + return users, nil +} diff --git a/server/services/store/store.go b/server/services/store/store.go index 0430d1542..1ac42afb9 100644 --- a/server/services/store/store.go +++ b/server/services/store/store.go @@ -36,6 +36,7 @@ type Store interface { UpdateUser(user *model.User) error UpdateUserPassword(username, password string) error UpdateUserPasswordByID(userID, password string) error + GetUsersByWorkspace(workspaceID string) ([]*model.User, error) GetActiveUserCount(updatedSecondsAgo int64) (int, error) GetSession(token string, expireTime int64) (*model.Session, error) diff --git a/server/services/store/storetests/users.go b/server/services/store/storetests/users.go new file mode 100644 index 000000000..dcbda3a22 --- /dev/null +++ b/server/services/store/storetests/users.go @@ -0,0 +1,52 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package storetests + +import ( + "database/sql" + "time" + + "github.com/google/uuid" + "github.com/mattermost/focalboard/server/model" + + "testing" + + "github.com/stretchr/testify/require" + + "github.com/mattermost/focalboard/server/services/store" +) + +func StoreTestUserStore(t *testing.T, setup func(t *testing.T) (store.Store, func())) { + t.Run("SetGetSystemSettings", func(t *testing.T) { + store, tearDown := setup(t) + defer tearDown() + testGetWorkspaceUsers(t, store) + }) +} + +func testGetWorkspaceUsers(t *testing.T, store store.Store) { + t.Run("GetWorkspaceUSers", func(t *testing.T) { + users, err := store.GetUsersByWorkspace("workspace_1") + require.Equal(t, 0, len(users)) + require.Equal(t, sql.ErrNoRows, err) + + userID := uuid.New().String() + + err = store.CreateUser(&model.User{ + ID: userID, + Username: "darth.vader", + }) + require.Nil(t, err) + + defer store.UpdateUser(&model.User{ + ID: userID, + DeleteAt: time.Now().Unix(), + }) + + users, err = store.GetUsersByWorkspace("workspace_1") + require.Equal(t, 1, len(users)) + require.Equal(t, "darth.vader", users[0].Username) + require.Nil(t, err) + }) +} diff --git a/server/swagger/docs/html/.openapi-generator/VERSION b/server/swagger/docs/html/.openapi-generator/VERSION index 32f3eaad0..3bff05917 100644 --- a/server/swagger/docs/html/.openapi-generator/VERSION +++ b/server/swagger/docs/html/.openapi-generator/VERSION @@ -1 +1 @@ -5.0.1 \ No newline at end of file +5.1.1 \ No newline at end of file diff --git a/server/swagger/docs/html/index.html b/server/swagger/docs/html/index.html index 7acf0abd3..df6ee824b 100644 --- a/server/swagger/docs/html/index.html +++ b/server/swagger/docs/html/index.html @@ -189,7 +189,7 @@ h={};g()}};typeof define==="function"&&define.amd&&define("google-code-prettify"