PLT-2057 User as a first class object (#2648)

* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding TeamMember to system

* Fixing all unit tests on the backend

* Fixing merge conflicts

* Fixing merge conflict

* Adding javascript unit tests

* Adding client side unit test

* Cleaning up the clint side tests

* Fixing msg

* Adding more client side unit tests

* Adding more using tests

* Adding last bit of client side unit tests and adding make cmd

* Fixing bad merge

* Fixing libraries

* Updating to new client side API

* Fixing borken unit test

* Fixing unit tests

* ugg...trying to beat gofmt

* ugg...trying to beat gofmt

* Cleaning up remainder of the server side routes

* Adding inital load api

* Increased coverage of webhook unit tests (#2660)

* Adding loading ... to root html

* Fixing bad merge

* Removing explicit content type so superagent will guess corectly (#2685)

* Fixing merge and unit tests

* Adding create team UI

* Fixing signup flows

* Adding LDAP unit tests and enterprise unit test helper (#2702)

* Add the ability to reset MFA from the commandline (#2706)

* Fixing compliance unit tests

* Fixing client side tests

* Adding open server to system console

* Moving websocket connection

* Fixing unit test

* Fixing unit tests

* Fixing unit tests

* Adding nickname and more LDAP unit tests (#2717)

* Adding join open teams

* Cleaning up all TODOs in the code

* Fixing web sockets

* Removing unused webockets file

* PLT-2533 Add the ability to reset a user's MFA from the system console (#2715)

* Add the ability to reset a user's MFA from the system console

* Add client side unit test for adminResetMfa

* Reorganizing authentication to fix LDAP error message (#2723)

* Fixing failing unit test

* Initial upgrade db code

* Adding upgrade script

* Fixing upgrade script after running on core

* Update OAuth and Claim routes to work with user model changes (#2739)

* Fixing perminant deletion. Adding ability to delete all user and the entire database (#2740)

* Fixing team invite ldap login call (#2741)

* Fixing bluebar and some img stuff

* Fix all the different file upload web utils (#2743)

* Fixing invalid session redirect (#2744)

* Redirect on bad channel name (#2746)

* Fixing a bunch of issue and removing dead code

* Patch to fix error message on leave channel (#2747)

* Setting EnableOpenServer to false by default

* Fixing config

* Fixing upgrade

* Fixing reported bugs

* Bug fixes for PLT-2057

* PLT-2563 Redo password recovery to use a database table (#2745)

* Redo password recovery to use a database table

* Update reset password audits

* Split out admin and user reset password APIs to be separate

* Delete password recovery when user is permanently deleted

* Consolidate password resetting into a single function

* Removed private channels as an option for outgoing webhooks (#2752)

* PLT-2577/PLT-2552 Fixes for backstage (#2753)

* Added URL to incoming webhook list

* Fixed client functions for adding/removing integrations

* Disallowed slash commands without trigger words

* Fixed clientside handling of errors on AddCommand page

* Minor auth cleanup (#2758)

* Changed EditPostModal to just close if you save without making any changes (#2759)

* Renamed client -> Client in async_client.jsx and fixed eslint warnings (#2756)

* Fixed url in channel info modal (#2755)

* Fixing reported issues

* Moving to version 3 of the apis

* Fixing command unit tests (#2760)

* Adding team admins

* Fixing DM issue

* Fixing eslint error

* Properly set EditPostModal's originalText state in all cases (#2762)

* Update client config check to assume features is defined if server is licensed (#2772)

* Fixing url link

* Fixing issue with websocket crashing when sending messages to different teams
Этот коммит содержится в:
Corey Hulen
2016-04-21 22:37:01 -07:00
родитель 5c755463ed
Коммит 2e5617c29b
268 изменённых файлов: 13214 добавлений и 9686 удалений

Просмотреть файл

@@ -28,17 +28,6 @@ func NewSqlAuditStore(sqlStore *SqlStore) AuditStore {
}
func (s SqlAuditStore) UpgradeSchemaIfNeeded() {
// ADDED for 2.2 REMOVE for 2.6
extraLength := s.GetMaxLengthOfColumnIfExists("Audits", "ExtraInfo")
if len(extraLength) > 0 && extraLength != "1024" {
s.AlterColumnTypeIfExists("Audits", "ExtraInfo", "VARCHAR(1024)", "VARCHAR(1024)")
}
// ADDED for 2.2 REMOVE for 2.6
actionLength := s.GetMaxLengthOfColumnIfExists("Audits", "Action")
if len(actionLength) > 0 && actionLength != "512" {
s.AlterColumnTypeIfExists("Audits", "Action", "VARCHAR(512)", "VARCHAR(512)")
}
}
func (s SqlAuditStore) CreateIndexesIfNotExists() {

Просмотреть файл

@@ -95,6 +95,7 @@ func (s SqlChannelStore) SaveDirectChannel(directchannel *model.Channel, member1
if transaction, err := s.GetMaster().Begin(); err != nil {
result.Err = model.NewLocAppError("SqlChannelStore.SaveDirectChannel", "store.sql_channel.save_direct_channel.open_transaction.app_error", nil, err.Error())
} else {
directchannel.TeamId = ""
channelResult := s.saveChannelT(transaction, directchannel)
if channelResult.Err != nil {
@@ -330,7 +331,7 @@ func (s SqlChannelStore) GetChannels(teamId string, userId string) StoreChannel
result := StoreResult{}
var data []channelWithMember
_, err := s.GetReplica().Select(&data, "SELECT * FROM Channels, ChannelMembers WHERE Id = ChannelId AND TeamId = :TeamId AND UserId = :UserId AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
_, err := s.GetReplica().Select(&data, "SELECT * FROM Channels, ChannelMembers WHERE Id = ChannelId AND UserId = :UserId AND DeleteAt = 0 AND (TeamId = :TeamId OR TeamId = '') ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
if err != nil {
result.Err = model.NewLocAppError("SqlChannelStore.GetChannels", "store.sql_channel.get_channels.get.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error())
@@ -411,7 +412,7 @@ func (s SqlChannelStore) GetChannelCounts(teamId string, userId string) StoreCha
result := StoreResult{}
var data []channelIdWithCountAndUpdateAt
_, err := s.GetReplica().Select(&data, "SELECT Id, TotalMsgCount, UpdateAt FROM Channels WHERE Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = :UserId) AND TeamId = :TeamId AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
_, err := s.GetReplica().Select(&data, "SELECT Id, TotalMsgCount, UpdateAt FROM Channels WHERE Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = :UserId) AND (TeamId = :TeamId OR TeamId = '') AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
if err != nil {
result.Err = model.NewLocAppError("SqlChannelStore.GetChannelCounts", "store.sql_channel.get_channel_counts.get.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error())
@@ -441,7 +442,7 @@ func (s SqlChannelStore) GetByName(teamId string, name string) StoreChannel {
channel := model.Channel{}
if err := s.GetReplica().SelectOne(&channel, "SELECT * FROM Channels WHERE TeamId = :TeamId AND Name= :Name AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId, "Name": name}); err != nil {
if err := s.GetReplica().SelectOne(&channel, "SELECT * FROM Channels WHERE (TeamId = :TeamId OR TeamId = '') AND Name = :Name AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId, "Name": name}); err != nil {
if err == sql.ErrNoRows {
result.Err = model.NewLocAppError("SqlChannelStore.GetByName", MISSING_CHANNEL_ERROR, nil, "teamId="+teamId+", "+"name="+name+", "+err.Error())
} else {
@@ -719,6 +720,37 @@ func (s SqlChannelStore) PermanentDeleteMembersByUser(userId string) StoreChanne
return storeChannel
}
func (s SqlChannelStore) CheckPermissionsToNoTeam(channelId string, userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
count, err := s.GetReplica().SelectInt(
`SELECT
COUNT(0)
FROM
Channels,
ChannelMembers
WHERE
Channels.Id = ChannelMembers.ChannelId
AND Channels.DeleteAt = 0
AND ChannelMembers.ChannelId = :ChannelId
AND ChannelMembers.UserId = :UserId`,
map[string]interface{}{"ChannelId": channelId, "UserId": userId})
if err != nil {
result.Err = model.NewLocAppError("SqlChannelStore.CheckPermissionsTo", "store.sql_channel.check_permissions.app_error", nil, "channel_id="+channelId+", user_id="+userId+", "+err.Error())
} else {
result.Data = count
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlChannelStore) CheckPermissionsTo(teamId string, channelId string, userId string) StoreChannel {
storeChannel := make(StoreChannel)
@@ -733,7 +765,7 @@ func (s SqlChannelStore) CheckPermissionsTo(teamId string, channelId string, use
ChannelMembers
WHERE
Channels.Id = ChannelMembers.ChannelId
AND Channels.TeamId = :TeamId
AND (Channels.TeamId = :TeamId OR Channels.TeamId = '')
AND Channels.DeleteAt = 0
AND ChannelMembers.ChannelId = :ChannelId
AND ChannelMembers.UserId = :UserId`,
@@ -765,7 +797,7 @@ func (s SqlChannelStore) CheckPermissionsToByName(teamId string, channelName str
ChannelMembers
WHERE
Channels.Id = ChannelMembers.ChannelId
AND Channels.TeamId = :TeamId
AND (Channels.TeamId = :TeamId OR Channels.TeamId = '')
AND Channels.Name = :Name
AND Channels.DeleteAt = 0
AND ChannelMembers.UserId = :UserId`,

Просмотреть файл

@@ -67,17 +67,17 @@ func TestChannelStoreSaveDirectChannel(t *testing.T) {
o1.Name = "a" + model.NewId() + "b"
o1.Type = model.CHANNEL_DIRECT
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
u1.Nickname = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
u2 := model.User{}
u2.TeamId = model.NewId()
u2 := &model.User{}
u2.Email = model.NewId()
u2.Nickname = model.NewId()
Must(store.User().Save(&u2))
Must(store.User().Save(u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
m1 := model.ChannelMember{}
m1.ChannelId = o1.Id
@@ -163,17 +163,17 @@ func TestChannelStoreGet(t *testing.T) {
t.Fatal("Missing id should have failed")
}
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
u1.Nickname = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
u2 := model.User{}
u2.TeamId = model.NewId()
u2.Email = model.NewId()
u2.Nickname = model.NewId()
Must(store.User().Save(&u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
o2 := model.Channel{}
o2.TeamId = model.NewId()
@@ -309,16 +309,16 @@ func TestChannelMemberStore(t *testing.T) {
t1 := c1t1.ExtraUpdateAt
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
u1.Nickname = model.NewId()
Must(store.User().Save(&u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
u2 := model.User{}
u2.TeamId = model.NewId()
u2.Email = model.NewId()
u2.Nickname = model.NewId()
Must(store.User().Save(&u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
o1 := model.ChannelMember{}
o1.ChannelId = c1.Id
@@ -405,16 +405,16 @@ func TestChannelDeleteMemberStore(t *testing.T) {
t1 := c1t1.ExtraUpdateAt
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
u1.Nickname = model.NewId()
Must(store.User().Save(&u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
u2 := model.User{}
u2.TeamId = model.NewId()
u2.Email = model.NewId()
u2.Nickname = model.NewId()
Must(store.User().Save(&u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}))
o1 := model.ChannelMember{}
o1.ChannelId = c1.Id
@@ -469,6 +469,11 @@ func TestChannelStorePermissionsTo(t *testing.T) {
t.Fatal("should have permissions")
}
count = (<-store.Channel().CheckPermissionsToNoTeam(o1.Id, m1.UserId)).Data.(int64)
if count != 1 {
t.Fatal("should have permissions")
}
count = (<-store.Channel().CheckPermissionsTo("junk", o1.Id, m1.UserId)).Data.(int64)
if count != 0 {
t.Fatal("shouldn't have permissions")
@@ -479,11 +484,21 @@ func TestChannelStorePermissionsTo(t *testing.T) {
t.Fatal("shouldn't have permissions")
}
count = (<-store.Channel().CheckPermissionsToNoTeam("junk", m1.UserId)).Data.(int64)
if count != 0 {
t.Fatal("shouldn't have permissions")
}
count = (<-store.Channel().CheckPermissionsTo(o1.TeamId, o1.Id, "junk")).Data.(int64)
if count != 0 {
t.Fatal("shouldn't have permissions")
}
count = (<-store.Channel().CheckPermissionsToNoTeam(o1.Id, "junk")).Data.(int64)
if count != 0 {
t.Fatal("shouldn't have permissions")
}
channelId := (<-store.Channel().CheckPermissionsToByName(o1.TeamId, o1.Name, m1.UserId)).Data.(string)
if channelId != o1.Id {
t.Fatal("should have permissions")
@@ -786,12 +801,12 @@ func TestGetMemberCount(t *testing.T) {
t.Logf("c1.Id = %v", c1.Id)
u1 := model.User{
TeamId: teamId,
u1 := &model.User{
Email: model.NewId(),
DeleteAt: 0,
}
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
m1 := model.ChannelMember{
ChannelId: c1.Id,
@@ -807,11 +822,11 @@ func TestGetMemberCount(t *testing.T) {
}
u2 := model.User{
TeamId: teamId,
Email: model.NewId(),
DeleteAt: 0,
}
Must(store.User().Save(&u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}))
m2 := model.ChannelMember{
ChannelId: c1.Id,
@@ -828,11 +843,11 @@ func TestGetMemberCount(t *testing.T) {
// make sure members of other channels aren't counted
u3 := model.User{
TeamId: teamId,
Email: model.NewId(),
DeleteAt: 0,
}
Must(store.User().Save(&u3))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u3.Id}))
m3 := model.ChannelMember{
ChannelId: c2.Id,
@@ -848,12 +863,12 @@ func TestGetMemberCount(t *testing.T) {
}
// make sure inactive users aren't counted
u4 := model.User{
TeamId: teamId,
u4 := &model.User{
Email: model.NewId(),
DeleteAt: 10000,
}
Must(store.User().Save(&u4))
Must(store.User().Save(u4))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u4.Id}))
m4 := model.ChannelMember{
ChannelId: c1.Id,
@@ -892,12 +907,12 @@ func TestUpdateExtrasByUser(t *testing.T) {
t.Logf("c1.Id = %v", c1.Id)
u1 := model.User{
TeamId: teamId,
u1 := &model.User{
Email: model.NewId(),
DeleteAt: 0,
}
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
m1 := model.ChannelMember{
ChannelId: c1.Id,
@@ -907,7 +922,7 @@ func TestUpdateExtrasByUser(t *testing.T) {
Must(store.Channel().SaveMember(&m1))
u1.DeleteAt = model.GetMillis()
Must(store.User().Update(&u1, true))
Must(store.User().Update(u1, true))
if result := <-store.Channel().ExtraUpdateByUser(u1.Id, u1.DeleteAt); result.Err != nil {
t.Fatal("failed to update extras by user: %v", result.Err)
@@ -920,7 +935,7 @@ func TestUpdateExtrasByUser(t *testing.T) {
}
u1.DeleteAt = 0
Must(store.User().Update(&u1, true))
Must(store.User().Update(u1, true))
if result := <-store.Channel().ExtraUpdateByUser(u1.Id, u1.DeleteAt); result.Err != nil {
t.Fatal("failed to update extras by user: %v", result.Err)

Просмотреть файл

@@ -16,6 +16,7 @@ func TestCommandStoreSave(t *testing.T) {
o1.Method = model.COMMAND_METHOD_POST
o1.TeamId = model.NewId()
o1.URL = "http://nowhere.com/"
o1.Trigger = "trigger"
if err := (<-store.Command().Save(&o1)).Err; err != nil {
t.Fatal("couldn't save item", err)
@@ -34,6 +35,7 @@ func TestCommandStoreGet(t *testing.T) {
o1.Method = model.COMMAND_METHOD_POST
o1.TeamId = model.NewId()
o1.URL = "http://nowhere.com/"
o1.Trigger = "trigger"
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
@@ -58,6 +60,7 @@ func TestCommandStoreGetByTeam(t *testing.T) {
o1.Method = model.COMMAND_METHOD_POST
o1.TeamId = model.NewId()
o1.URL = "http://nowhere.com/"
o1.Trigger = "trigger"
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
@@ -86,6 +89,7 @@ func TestCommandStoreDelete(t *testing.T) {
o1.Method = model.COMMAND_METHOD_POST
o1.TeamId = model.NewId()
o1.URL = "http://nowhere.com/"
o1.Trigger = "trigger"
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
@@ -115,6 +119,7 @@ func TestCommandStoreDeleteByUser(t *testing.T) {
o1.Method = model.COMMAND_METHOD_POST
o1.TeamId = model.NewId()
o1.URL = "http://nowhere.com/"
o1.Trigger = "trigger"
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
@@ -144,6 +149,7 @@ func TestCommandStoreUpdate(t *testing.T) {
o1.Method = model.COMMAND_METHOD_POST
o1.TeamId = model.NewId()
o1.URL = "http://nowhere.com/"
o1.Trigger = "trigger"
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)
@@ -162,6 +168,7 @@ func TestCommandCount(t *testing.T) {
o1.Method = model.COMMAND_METHOD_POST
o1.TeamId = model.NewId()
o1.URL = "http://nowhere.com/"
o1.Trigger = "trigger"
o1 = (<-store.Command().Save(o1)).Data.(*model.Command)

Просмотреть файл

@@ -58,16 +58,16 @@ func TestComplianceExport(t *testing.T) {
t1 = Must(store.Team().Save(t1)).(*model.Team)
u1 := &model.User{}
u1.TeamId = t1.Id
u1.Email = model.NewId()
u1.Username = model.NewId()
u1 = Must(store.User().Save(u1)).(*model.User)
Must(store.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u1.Id}))
u2 := &model.User{}
u2.TeamId = t1.Id
u2.Email = model.NewId()
u2.Username = model.NewId()
u2 = Must(store.User().Save(u2)).(*model.User)
Must(store.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u2.Id}))
c1 := &model.Channel{}
c1.TeamId = t1.Id

Просмотреть файл

@@ -652,7 +652,7 @@ func (s SqlPostStore) Search(teamId string, userId string, params *model.SearchP
ChannelMembers
WHERE
Id = ChannelId
AND TeamId = :TeamId
AND (TeamId = :TeamId OR TeamId = '')
AND UserId = :UserId
AND DeleteAt = 0
CHANNEL_FILTER)
@@ -693,9 +693,11 @@ func (s SqlPostStore) Search(teamId string, userId string, params *model.SearchP
SELECT
Id
FROM
Users
Users,
TeamMembers
WHERE
TeamId = :TeamId
TeamMembers.TeamId = :TeamId
AND Users.Id = TeamMembers.UserId
AND Username IN (`+inClause+`))`, 1)
} else if len(params.FromUsers) == 1 {
queryParams["FromUser"] = params.FromUsers[0]
@@ -704,9 +706,11 @@ func (s SqlPostStore) Search(teamId string, userId string, params *model.SearchP
SELECT
Id
FROM
Users
Users,
TeamMembers
WHERE
TeamId = :TeamId
TeamMembers.TeamId = :TeamId
AND Users.Id = TeamMembers.UserId
AND Username = :FromUser)`, 1)
} else {
searchQuery = strings.Replace(searchQuery, "POST_FILTER", "", 1)

124
store/sql_recovery_store.go Обычный файл
Просмотреть файл

@@ -0,0 +1,124 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package store
import (
"github.com/mattermost/platform/model"
)
type SqlPasswordRecoveryStore struct {
*SqlStore
}
func NewSqlPasswordRecoveryStore(sqlStore *SqlStore) PasswordRecoveryStore {
s := &SqlPasswordRecoveryStore{sqlStore}
for _, db := range sqlStore.GetAllConns() {
table := db.AddTableWithName(model.PasswordRecovery{}, "PasswordRecovery").SetKeys(false, "UserId")
table.ColMap("UserId").SetMaxSize(26)
table.ColMap("Code").SetMaxSize(128)
}
return s
}
func (s SqlPasswordRecoveryStore) UpgradeSchemaIfNeeded() {
}
func (s SqlPasswordRecoveryStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_password_recovery_code", "PasswordRecovery", "Code")
}
func (s SqlPasswordRecoveryStore) SaveOrUpdate(recovery *model.PasswordRecovery) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
recovery.PreSave()
if result.Err = recovery.IsValid(); result.Err != nil {
storeChannel <- result
close(storeChannel)
return
}
if err := s.GetReplica().SelectOne(&model.PasswordRecovery{}, "SELECT * FROM PasswordRecovery WHERE UserId = :UserId", map[string]interface{}{"UserId": recovery.UserId}); err == nil {
if _, err := s.GetMaster().Update(recovery); err != nil {
result.Err = model.NewLocAppError("SqlPasswordRecoveryStore.SaveOrUpdate", "store.sql_recover.update.app_error", nil, "")
}
} else {
if err := s.GetMaster().Insert(recovery); err != nil {
result.Err = model.NewLocAppError("SqlPasswordRecoveryStore.SaveOrUpdate", "store.sql_recover.save.app_error", nil, "")
}
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlPasswordRecoveryStore) Delete(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
if _, err := s.GetMaster().Exec("DELETE FROM PasswordRecovery WHERE UserId = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
result.Err = model.NewLocAppError("SqlPasswordRecoveryStore.Delete", "store.sql_recover.delete.app_error", nil, "")
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlPasswordRecoveryStore) Get(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
recovery := model.PasswordRecovery{}
if err := s.GetReplica().SelectOne(&recovery, "SELECT * FROM PasswordRecovery WHERE UserId = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
result.Err = model.NewLocAppError("SqlPasswordRecoveryStore.Get", "store.sql_recover.get.app_error", nil, "")
}
result.Data = &recovery
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlPasswordRecoveryStore) GetByCode(code string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
recovery := model.PasswordRecovery{}
if err := s.GetReplica().SelectOne(&recovery, "SELECT * FROM PasswordRecovery WHERE Code = :Code", map[string]interface{}{"Code": code}); err != nil {
result.Err = model.NewLocAppError("SqlPasswordRecoveryStore.GetByCode", "store.sql_recover.get_by_code.app_error", nil, "")
}
result.Data = &recovery
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}

54
store/sql_recovery_store_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,54 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package store
import (
"github.com/mattermost/platform/model"
"testing"
)
func TestSqlPasswordRecoveryGet(t *testing.T) {
Setup()
recovery := &model.PasswordRecovery{UserId: "12345678901234567890123456"}
Must(store.PasswordRecovery().SaveOrUpdate(recovery))
result := <-store.PasswordRecovery().Get(recovery.UserId)
rrecovery := result.Data.(*model.PasswordRecovery)
if rrecovery.Code != recovery.Code {
t.Fatal("codes didn't match")
}
result2 := <-store.PasswordRecovery().GetByCode(recovery.Code)
rrecovery2 := result2.Data.(*model.PasswordRecovery)
if rrecovery2.Code != recovery.Code {
t.Fatal("codes didn't match")
}
}
func TestSqlPasswordRecoverySaveOrUpdate(t *testing.T) {
Setup()
recovery := &model.PasswordRecovery{UserId: "12345678901234567890123456"}
if err := (<-store.PasswordRecovery().SaveOrUpdate(recovery)).Err; err != nil {
t.Fatal(err)
}
// not duplicate, testing update
if err := (<-store.PasswordRecovery().SaveOrUpdate(recovery)).Err; err != nil {
t.Fatal(err)
}
}
func TestSqlPasswordRecoveryDelete(t *testing.T) {
Setup()
recovery := &model.PasswordRecovery{UserId: "12345678901234567890123456"}
Must(store.PasswordRecovery().SaveOrUpdate(recovery))
if err := (<-store.PasswordRecovery().Delete(recovery.UserId)).Err; err != nil {
t.Fatal(err)
}
}

Просмотреть файл

@@ -21,7 +21,6 @@ func NewSqlSessionStore(sqlStore *SqlStore) SessionStore {
table.ColMap("Id").SetMaxSize(26)
table.ColMap("Token").SetMaxSize(26)
table.ColMap("UserId").SetMaxSize(26)
table.ColMap("TeamId").SetMaxSize(26)
table.ColMap("DeviceId").SetMaxSize(512)
table.ColMap("Roles").SetMaxSize(64)
table.ColMap("Props").SetMaxSize(1000)
@@ -63,12 +62,22 @@ func (me SqlSessionStore) Save(session *model.Session) StoreChannel {
l4g.Error(utils.T("store.sql_session.save.cleanup.error"), cur.Err)
}
tcs := me.Team().GetTeamsForUser(session.UserId)
if err := me.GetMaster().Insert(session); err != nil {
result.Err = model.NewLocAppError("SqlSessionStore.Save", "store.sql_session.save.app_error", nil, "id="+session.Id+", "+err.Error())
return
} else {
result.Data = session
}
if rtcs := <-tcs; rtcs.Err != nil {
result.Err = model.NewLocAppError("SqlSessionStore.Save", "store.sql_session.save.app_error", nil, "id="+session.Id+", "+rtcs.Err.Error())
return
} else {
session.TeamMembers = rtcs.Data.([]*model.TeamMember)
}
storeChannel <- result
close(storeChannel)
}()
@@ -91,6 +100,14 @@ func (me SqlSessionStore) Get(sessionIdOrToken string) StoreChannel {
result.Err = model.NewLocAppError("SqlSessionStore.Get", "store.sql_session.get.app_error", nil, "sessionIdOrToken="+sessionIdOrToken)
} else {
result.Data = sessions[0]
tcs := me.Team().GetTeamsForUser(sessions[0].UserId)
if rtcs := <-tcs; rtcs.Err != nil {
result.Err = model.NewLocAppError("SqlSessionStore.Get", "store.sql_session.get.app_error", nil, "sessionIdOrToken="+sessionIdOrToken+", "+rtcs.Err.Error())
return
} else {
sessions[0].TeamMembers = rtcs.Data.([]*model.TeamMember)
}
}
storeChannel <- result
@@ -111,9 +128,10 @@ func (me SqlSessionStore) GetSessions(userId string) StoreChannel {
}
result := StoreResult{}
var sessions []*model.Session
tcs := me.Team().GetTeamsForUser(userId)
if _, err := me.GetReplica().Select(&sessions, "SELECT * FROM Sessions WHERE UserId = :UserId ORDER BY LastActivityAt DESC", map[string]interface{}{"UserId": userId}); err != nil {
result.Err = model.NewLocAppError("SqlSessionStore.GetSessions", "store.sql_session.get_sessions.app_error", nil, err.Error())
} else {
@@ -121,6 +139,15 @@ func (me SqlSessionStore) GetSessions(userId string) StoreChannel {
result.Data = sessions
}
if rtcs := <-tcs; rtcs.Err != nil {
result.Err = model.NewLocAppError("SqlSessionStore.GetSessions", "store.sql_session.get_sessions.app_error", nil, rtcs.Err.Error())
return
} else {
for _, session := range sessions {
session.TeamMembers = rtcs.Data.([]*model.TeamMember)
}
}
storeChannel <- result
close(storeChannel)
}()
@@ -146,15 +173,15 @@ func (me SqlSessionStore) Remove(sessionIdOrToken string) StoreChannel {
return storeChannel
}
func (me SqlSessionStore) RemoveAllSessionsForTeam(teamId string) StoreChannel {
func (me SqlSessionStore) RemoveAllSessions() StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
_, err := me.GetMaster().Exec("DELETE FROM Sessions WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId})
_, err := me.GetMaster().Exec("DELETE FROM Sessions")
if err != nil {
result.Err = model.NewLocAppError("SqlSessionStore.RemoveAllSessionsForTeam", "store.sql_session.remove_all_sessions_for_team.app_error", nil, "id="+teamId+", err="+err.Error())
result.Err = model.NewLocAppError("SqlSessionStore.RemoveAllSessions", "store.sql_session.remove_all_sessions_for_team.app_error", nil, err.Error())
}
storeChannel <- result
@@ -256,7 +283,7 @@ func (me SqlSessionStore) UpdateDeviceId(id, deviceId string) StoreChannel {
return storeChannel
}
func (me SqlSessionStore) AnalyticsSessionCount(teamId string) StoreChannel {
func (me SqlSessionStore) AnalyticsSessionCount() StoreChannel {
storeChannel := make(StoreChannel)
go func() {
@@ -269,11 +296,7 @@ func (me SqlSessionStore) AnalyticsSessionCount(teamId string) StoreChannel {
Sessions
WHERE ExpiresAt > :Time`
if len(teamId) > 0 {
query += " AND TeamId = :TeamId"
}
if c, err := me.GetReplica().SelectInt(query, map[string]interface{}{"Time": model.GetMillis(), "TeamId": teamId}); err != nil {
if c, err := me.GetReplica().SelectInt(query, map[string]interface{}{"Time": model.GetMillis()}); err != nil {
result.Err = model.NewLocAppError("SqlSessionStore.AnalyticsSessionCount", "store.sql_session.analytics_session_count.app_error", nil, err.Error())
} else {
result.Data = c

Просмотреть файл

@@ -13,7 +13,6 @@ func TestSessionStoreSave(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
if err := (<-store.Session().Save(&s1)).Err; err != nil {
t.Fatal(err)
@@ -25,17 +24,14 @@ func TestSessionGet(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
Must(store.Session().Save(&s1))
s2 := model.Session{}
s2.UserId = s1.UserId
s2.TeamId = s1.TeamId
Must(store.Session().Save(&s2))
s3 := model.Session{}
s3.UserId = s1.UserId
s3.TeamId = s1.TeamId
s3.ExpiresAt = 1
Must(store.Session().Save(&s3))
@@ -62,7 +58,6 @@ func TestSessionRemove(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
Must(store.Session().Save(&s1))
if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil {
@@ -85,7 +80,6 @@ func TestSessionRemoveAll(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
Must(store.Session().Save(&s1))
if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil {
@@ -96,7 +90,7 @@ func TestSessionRemoveAll(t *testing.T) {
}
}
Must(store.Session().RemoveAllSessionsForTeam(s1.TeamId))
Must(store.Session().RemoveAllSessions())
if rs2 := (<-store.Session().Get(s1.Id)); rs2.Err == nil {
t.Fatal("should have been removed")
@@ -108,7 +102,6 @@ func TestSessionRemoveByUser(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
Must(store.Session().Save(&s1))
if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil {
@@ -131,7 +124,6 @@ func TestSessionRemoveToken(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
Must(store.Session().Save(&s1))
if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil {
@@ -162,7 +154,6 @@ func TestSessionUpdateDeviceId(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
Must(store.Session().Save(&s1))
if rs1 := (<-store.Session().UpdateDeviceId(s1.Id, model.PUSH_NOTIFY_APPLE+":1234567890")); rs1.Err != nil {
@@ -171,7 +162,6 @@ func TestSessionUpdateDeviceId(t *testing.T) {
s2 := model.Session{}
s2.UserId = model.NewId()
s2.TeamId = model.NewId()
Must(store.Session().Save(&s2))
if rs2 := (<-store.Session().UpdateDeviceId(s2.Id, model.PUSH_NOTIFY_APPLE+":1234567890")); rs2.Err != nil {
@@ -184,7 +174,6 @@ func TestSessionStoreUpdateLastActivityAt(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
Must(store.Session().Save(&s1))
if err := (<-store.Session().UpdateLastActivityAt(s1.Id, 1234567890)).Err; err != nil {
@@ -206,23 +195,14 @@ func TestSessionCount(t *testing.T) {
s1 := model.Session{}
s1.UserId = model.NewId()
s1.TeamId = model.NewId()
s1.ExpiresAt = model.GetMillis() + 100000
Must(store.Session().Save(&s1))
if r1 := <-store.Session().AnalyticsSessionCount(""); r1.Err != nil {
if r1 := <-store.Session().AnalyticsSessionCount(); r1.Err != nil {
t.Fatal(r1.Err)
} else {
if r1.Data.(int64) == 0 {
t.Fatal("should have at least 1 session")
}
}
if r2 := <-store.Session().AnalyticsSessionCount(s1.TeamId); r2.Err != nil {
t.Fatal(r2.Err)
} else {
if r2.Data.(int64) != 1 {
t.Fatal("should have 1 session")
}
}
}

Просмотреть файл

@@ -36,25 +36,26 @@ const (
)
type SqlStore struct {
master *gorp.DbMap
replicas []*gorp.DbMap
team TeamStore
channel ChannelStore
post PostStore
user UserStore
audit AuditStore
compliance ComplianceStore
session SessionStore
oauth OAuthStore
system SystemStore
webhook WebhookStore
command CommandStore
preference PreferenceStore
license LicenseStore
master *gorp.DbMap
replicas []*gorp.DbMap
team TeamStore
channel ChannelStore
post PostStore
user UserStore
audit AuditStore
compliance ComplianceStore
session SessionStore
oauth OAuthStore
system SystemStore
webhook WebhookStore
command CommandStore
preference PreferenceStore
license LicenseStore
recovery PasswordRecoveryStore
SchemaVersion string
}
func NewSqlStore() Store {
func initConnection() *SqlStore {
sqlStore := &SqlStore{}
sqlStore.master = setupConnection("master", utils.Cfg.SqlSettings.DriverName,
@@ -75,25 +76,43 @@ func NewSqlStore() Store {
}
}
schemaVersion := sqlStore.GetCurrentSchemaVersion()
sqlStore.SchemaVersion = sqlStore.GetCurrentSchemaVersion()
return sqlStore
}
func NewSqlStore() Store {
sqlStore := initConnection()
// If the version is already set then we are potentially in an 'upgrade needed' state
if schemaVersion != "" {
if sqlStore.SchemaVersion != "" {
// Check to see if it's the most current database schema version
if !model.IsCurrentVersion(schemaVersion) {
if !model.IsCurrentVersion(sqlStore.SchemaVersion) {
// If we are upgrading from the previous version then print a warning and continue
if model.IsPreviousVersionsSupported(schemaVersion) {
l4g.Warn(utils.T("store.sql.schema_out_of_date.warn"), schemaVersion)
if model.IsPreviousVersionsSupported(sqlStore.SchemaVersion) {
l4g.Warn(utils.T("store.sql.schema_out_of_date.warn"), sqlStore.SchemaVersion)
l4g.Warn(utils.T("store.sql.schema_upgrade_attempt.warn"), model.CurrentVersion)
} else {
// If this is an 'upgrade needed' state but the user is attempting to skip a version then halt the world
l4g.Critical(utils.T("store.sql.schema_version.critical"), schemaVersion)
l4g.Critical(utils.T("store.sql.schema_version.critical"), sqlStore.SchemaVersion)
time.Sleep(time.Second)
panic(fmt.Sprintf(utils.T("store.sql.schema_version.critical"), schemaVersion))
panic(fmt.Sprintf(utils.T("store.sql.schema_version.critical"), sqlStore.SchemaVersion))
}
}
}
// This is a speical case for upgrading the schema to the 3.0 user model
// ADDED for 3.0 REMOVE for 3.4
if sqlStore.SchemaVersion == "2.2.0" ||
sqlStore.SchemaVersion == "2.1.0" ||
sqlStore.SchemaVersion == "2.0.0" {
l4g.Critical("The database version of %v cannot be automatically upgraded to 3.0 schema", sqlStore.SchemaVersion)
l4g.Critical("You will need to run the command line tool './platform -upgrade_db_30'")
l4g.Critical("Please see 'http://www.mattermost.org/upgrade-to-3-0/' for more information on how to upgrade.")
time.Sleep(time.Second)
os.Exit(1)
}
sqlStore.team = NewSqlTeamStore(sqlStore)
sqlStore.channel = NewSqlChannelStore(sqlStore)
sqlStore.post = NewSqlPostStore(sqlStore)
@@ -107,10 +126,13 @@ func NewSqlStore() Store {
sqlStore.command = NewSqlCommandStore(sqlStore)
sqlStore.preference = NewSqlPreferenceStore(sqlStore)
sqlStore.license = NewSqlLicenseStore(sqlStore)
sqlStore.recovery = NewSqlPasswordRecoveryStore(sqlStore)
err := sqlStore.master.CreateTablesIfNotExists()
if err != nil {
l4g.Critical(utils.T("store.sql.creating_tables.critical"), err)
time.Sleep(time.Second)
os.Exit(1)
}
sqlStore.team.(*SqlTeamStore).UpgradeSchemaIfNeeded()
@@ -126,6 +148,7 @@ func NewSqlStore() Store {
sqlStore.command.(*SqlCommandStore).UpgradeSchemaIfNeeded()
sqlStore.preference.(*SqlPreferenceStore).UpgradeSchemaIfNeeded()
sqlStore.license.(*SqlLicenseStore).UpgradeSchemaIfNeeded()
sqlStore.recovery.(*SqlPasswordRecoveryStore).UpgradeSchemaIfNeeded()
sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists()
sqlStore.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
@@ -140,22 +163,44 @@ func NewSqlStore() Store {
sqlStore.command.(*SqlCommandStore).CreateIndexesIfNotExists()
sqlStore.preference.(*SqlPreferenceStore).CreateIndexesIfNotExists()
sqlStore.license.(*SqlLicenseStore).CreateIndexesIfNotExists()
sqlStore.recovery.(*SqlPasswordRecoveryStore).CreateIndexesIfNotExists()
sqlStore.preference.(*SqlPreferenceStore).DeleteUnusedFeatures()
if model.IsPreviousVersionsSupported(schemaVersion) && !model.IsCurrentVersion(schemaVersion) {
if model.IsPreviousVersionsSupported(sqlStore.SchemaVersion) && !model.IsCurrentVersion(sqlStore.SchemaVersion) {
sqlStore.system.Update(&model.System{Name: "Version", Value: model.CurrentVersion})
sqlStore.SchemaVersion = model.CurrentVersion
l4g.Warn(utils.T("store.sql.upgraded.warn"), model.CurrentVersion)
}
if schemaVersion == "" {
if sqlStore.SchemaVersion == "" {
sqlStore.system.Save(&model.System{Name: "Version", Value: model.CurrentVersion})
sqlStore.SchemaVersion = model.CurrentVersion
l4g.Info(utils.T("store.sql.schema_set.info"), model.CurrentVersion)
}
return sqlStore
}
// ADDED for 3.0 REMOVE for 3.4
// This is a speical case for upgrading the schema to the 3.0 user model
func NewSqlStoreForUpgrade30() *SqlStore {
sqlStore := initConnection()
sqlStore.team = NewSqlTeamStore(sqlStore)
sqlStore.user = NewSqlUserStore(sqlStore)
sqlStore.system = NewSqlSystemStore(sqlStore)
err := sqlStore.master.CreateTablesIfNotExists()
if err != nil {
l4g.Critical(utils.T("store.sql.creating_tables.critical"), err)
time.Sleep(time.Second)
os.Exit(1)
}
return sqlStore
}
func setupConnection(con_type string, driver string, dataSource string, maxIdle int, maxOpen int, trace bool) *gorp.DbMap {
db, err := dbsql.Open(driver, dataSource)
@@ -426,15 +471,24 @@ func (ss SqlStore) AlterColumnTypeIfExists(tableName string, columnName string,
return true
}
func (ss SqlStore) CreateUniqueIndexIfNotExists(indexName string, tableName string, columnName string) {
ss.createIndexIfNotExists(indexName, tableName, columnName, INDEX_TYPE_DEFAULT, true)
}
func (ss SqlStore) CreateIndexIfNotExists(indexName string, tableName string, columnName string) {
ss.createIndexIfNotExists(indexName, tableName, columnName, INDEX_TYPE_DEFAULT)
ss.createIndexIfNotExists(indexName, tableName, columnName, INDEX_TYPE_DEFAULT, false)
}
func (ss SqlStore) CreateFullTextIndexIfNotExists(indexName string, tableName string, columnName string) {
ss.createIndexIfNotExists(indexName, tableName, columnName, INDEX_TYPE_FULL_TEXT)
ss.createIndexIfNotExists(indexName, tableName, columnName, INDEX_TYPE_FULL_TEXT, false)
}
func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, columnName string, indexType string) {
func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, columnName string, indexType string, unique bool) {
uniqueStr := ""
if unique {
uniqueStr = "UNIQUE "
}
if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
_, err := ss.GetMaster().SelectStr("SELECT $1::regclass", indexName)
@@ -447,7 +501,7 @@ func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, co
if indexType == INDEX_TYPE_FULL_TEXT {
query = "CREATE INDEX " + indexName + " ON " + tableName + " USING gin(to_tsvector('english', " + columnName + "))"
} else {
query = "CREATE INDEX " + indexName + " ON " + tableName + " (" + columnName + ")"
query = "CREATE " + uniqueStr + "INDEX " + indexName + " ON " + tableName + " (" + columnName + ")"
}
_, err = ss.GetMaster().Exec(query)
@@ -474,7 +528,7 @@ func (ss SqlStore) createIndexIfNotExists(indexName string, tableName string, co
fullTextIndex = " FULLTEXT "
}
_, err = ss.GetMaster().Exec("CREATE " + fullTextIndex + " INDEX " + indexName + " ON " + tableName + " (" + columnName + ")")
_, err = ss.GetMaster().Exec("CREATE " + uniqueStr + fullTextIndex + " INDEX " + indexName + " ON " + tableName + " (" + columnName + ")")
if err != nil {
l4g.Critical(utils.T("store.sql.create_index.critical"), err)
time.Sleep(time.Second)
@@ -623,6 +677,14 @@ func (ss SqlStore) License() LicenseStore {
return ss.license
}
func (ss SqlStore) PasswordRecovery() PasswordRecoveryStore {
return ss.recovery
}
func (ss SqlStore) DropAllTables() {
ss.master.TruncateTables()
}
type mattermConverter struct{}
func (me mattermConverter) ToDb(val interface{}) (interface{}, error) {

Просмотреть файл

@@ -6,7 +6,6 @@ package store
import (
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"strings"
)
type SqlTeamStore struct {
@@ -25,6 +24,11 @@ func NewSqlTeamStore(sqlStore *SqlStore) TeamStore {
table.ColMap("CompanyName").SetMaxSize(64)
table.ColMap("AllowedDomains").SetMaxSize(500)
table.ColMap("InviteId").SetMaxSize(32)
tablem := db.AddTableWithName(model.TeamMember{}, "TeamMembers").SetKeys(false, "TeamId", "UserId")
tablem.ColMap("TeamId").SetMaxSize(26)
tablem.ColMap("UserId").SetMaxSize(26)
tablem.ColMap("Roles").SetMaxSize(64)
}
return s
@@ -36,6 +40,9 @@ func (s SqlTeamStore) UpgradeSchemaIfNeeded() {
func (s SqlTeamStore) CreateIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_teams_name", "Teams", "Name")
s.CreateIndexIfNotExists("idx_teams_invite_id", "Teams", "InviteId")
s.CreateIndexIfNotExists("idx_teammembers_team_id", "TeamMembers", "TeamId")
s.CreateIndexIfNotExists("idx_teammembers_user_id", "TeamMembers", "UserId")
}
func (s SqlTeamStore) Save(team *model.Team) StoreChannel {
@@ -218,34 +225,6 @@ func (s SqlTeamStore) GetByName(name string) StoreChannel {
return storeChannel
}
func (s SqlTeamStore) GetTeamsForEmail(email string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
email = strings.ToLower(email)
var data []*model.Team
if _, err := s.GetReplica().Select(&data, "SELECT Teams.* FROM Teams, Users WHERE Teams.Id = Users.TeamId AND Users.Email = :Email", map[string]interface{}{"Email": email}); err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.GetTeamsForEmail", "store.sql_team.get_teams_for_email.app_error", nil, "email="+email+", "+err.Error())
}
for _, team := range data {
if len(team.InviteId) == 0 {
team.InviteId = team.Id
}
}
result.Data = data
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) GetAll() StoreChannel {
storeChannel := make(StoreChannel)
@@ -272,16 +251,42 @@ func (s SqlTeamStore) GetAll() StoreChannel {
return storeChannel
}
func (s SqlTeamStore) GetTeamsByUserId(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
var data []*model.Team
if _, err := s.GetReplica().Select(&data, "SELECT Teams.* FROM Teams, TeamMembers WHERE TeamMembers.TeamId = Teams.Id AND TeamMembers.UserId = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.GetTeamsByUserId", "store.sql_team.get_all.app_error", nil, err.Error())
}
for _, team := range data {
if len(team.InviteId) == 0 {
team.InviteId = team.Id
}
}
result.Data = data
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) GetAllTeamListing() StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
query := "SELECT * FROM Teams WHERE AllowTeamListing = 1"
query := "SELECT * FROM Teams WHERE AllowOpenInvite = 1"
if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
query = "SELECT * FROM Teams WHERE AllowTeamListing = true"
query = "SELECT * FROM Teams WHERE AllowOpenInvite = true"
}
var data []*model.Team
@@ -339,3 +344,165 @@ func (s SqlTeamStore) AnalyticsTeamCount() StoreChannel {
return storeChannel
}
func (s SqlTeamStore) SaveMember(member *model.TeamMember) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
if result.Err = member.IsValid(); result.Err != nil {
storeChannel <- result
close(storeChannel)
return
}
if count, err := s.GetMaster().SelectInt("SELECT COUNT(0) FROM TeamMembers WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": member.TeamId}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, "teamId="+member.TeamId+", "+err.Error())
storeChannel <- result
close(storeChannel)
return
} else if int(count) > utils.Cfg.TeamSettings.MaxUsersPerTeam {
result.Err = model.NewLocAppError("SqlUserStore.Save", "store.sql_user.save.max_accounts.app_error", nil, "teamId="+member.TeamId)
storeChannel <- result
close(storeChannel)
return
}
if err := s.GetMaster().Insert(member); err != nil {
if IsUniqueConstraintError(err.Error(), "TeamId", "teammembers_pkey") {
result.Err = model.NewLocAppError("SqlTeamStore.SaveMember", "store.sql_team.save_member.exists.app_error", nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error())
} else {
result.Err = model.NewLocAppError("SqlTeamStore.SaveMember", "store.sql_team.save_member.save.app_error", nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error())
}
} else {
result.Data = member
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) UpdateMember(member *model.TeamMember) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
if result.Err = member.IsValid(); result.Err != nil {
storeChannel <- result
close(storeChannel)
return
}
if _, err := s.GetMaster().Update(member); err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.UpdateMember", "store.sql_team.save_member.save.app_error", nil, err.Error())
} else {
result.Data = member
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) GetMembers(teamId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
var members []*model.TeamMember
_, err := s.GetReplica().Select(&members, "SELECT * FROM TeamMembers WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId})
if err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "teamId="+teamId+" "+err.Error())
} else {
result.Data = members
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) GetTeamsForUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
var members []*model.TeamMember
_, err := s.GetReplica().Select(&members, "SELECT * FROM TeamMembers WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
if err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error())
} else {
result.Data = members
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) RemoveMember(teamId string, userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
_, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE TeamId = :TeamId AND UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId})
if err != nil {
result.Err = model.NewLocAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", user_id="+userId+", "+err.Error())
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) RemoveAllMembersByTeam(teamId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
_, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId})
if err != nil {
result.Err = model.NewLocAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error())
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) RemoveAllMembersByUser(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
_, err := s.GetMaster().Exec("DELETE FROM TeamMembers WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
if err != nil {
result.Err = model.NewLocAppError("SqlChannelStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "user_id="+userId+", "+err.Error())
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}

Просмотреть файл

@@ -14,7 +14,7 @@ func TestTeamStoreSave(t *testing.T) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
@@ -37,7 +37,7 @@ func TestTeamStoreUpdate(t *testing.T) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
if err := (<-store.Team().Save(&o1)).Err; err != nil {
@@ -66,7 +66,7 @@ func TestTeamStoreUpdateDisplayName(t *testing.T) {
o1 := &model.Team{}
o1.DisplayName = "Display Name"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
o1 = (<-store.Team().Save(o1)).Data.(*model.Team)
@@ -88,7 +88,7 @@ func TestTeamStoreGet(t *testing.T) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
Must(store.Team().Save(&o1))
@@ -111,7 +111,7 @@ func TestTeamStoreGetByName(t *testing.T) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
@@ -137,7 +137,7 @@ func TestTeamStoreGetByIniviteId(t *testing.T) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
o1.InviteId = model.NewId()
@@ -180,33 +180,32 @@ func TestTeamStoreGetByIniviteId(t *testing.T) {
}
}
func TestTeamStoreGetForEmail(t *testing.T) {
func TestTeamStoreByUserId(t *testing.T) {
Setup()
o1 := model.Team{}
o1 := &model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
Must(store.Team().Save(&o1))
o1.InviteId = model.NewId()
o1 = Must(store.Team().Save(o1)).(*model.Team)
u1 := model.User{}
u1.TeamId = o1.Id
u1.Email = model.NewId()
Must(store.User().Save(&u1))
m1 := &model.TeamMember{TeamId: o1.Id, UserId: model.NewId()}
Must(store.Team().SaveMember(m1))
if r1 := <-store.Team().GetTeamsForEmail(u1.Email); r1.Err != nil {
if r1 := <-store.Team().GetTeamsByUserId(m1.UserId); r1.Err != nil {
t.Fatal(r1.Err)
} else {
teams := r1.Data.([]*model.Team)
if len(teams) == 0 {
t.Fatal("Should return a team")
}
if teams[0].Id != o1.Id {
t.Fatal("failed to lookup by email")
t.Fatal("should be a member")
}
}
if r1 := <-store.Team().GetTeamsForEmail("missing"); r1.Err != nil {
t.Fatal(r1.Err)
}
}
@@ -215,10 +214,10 @@ func TestAllTeamListing(t *testing.T) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
o1.AllowTeamListing = true
o1.AllowOpenInvite = true
Must(store.Team().Save(&o1))
o2 := model.Team{}
@@ -244,10 +243,10 @@ func TestDelete(t *testing.T) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
o1.AllowTeamListing = true
o1.AllowOpenInvite = true
Must(store.Team().Save(&o1))
o2 := model.Team{}
@@ -267,10 +266,10 @@ func TestTeamCount(t *testing.T) {
o1 := model.Team{}
o1.DisplayName = "DisplayName"
o1.Name = "a" + model.NewId() + "b"
o1.Name = "z-z-z" + model.NewId() + "b"
o1.Email = model.NewId() + "@nowhere.com"
o1.Type = model.TEAM_OPEN
o1.AllowTeamListing = true
o1.AllowOpenInvite = true
Must(store.Team().Save(&o1))
if r1 := <-store.Team().AnalyticsTeamCount(); r1.Err != nil {
@@ -281,3 +280,126 @@ func TestTeamCount(t *testing.T) {
}
}
}
func TestTeamMembers(t *testing.T) {
Setup()
teamId1 := model.NewId()
teamId2 := model.NewId()
m1 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
m2 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
m3 := &model.TeamMember{TeamId: teamId2, UserId: model.NewId()}
if r1 := <-store.Team().SaveMember(m1); r1.Err != nil {
t.Fatal(r1.Err)
}
Must(store.Team().SaveMember(m2))
Must(store.Team().SaveMember(m3))
if r1 := <-store.Team().GetMembers(teamId1); r1.Err != nil {
t.Fatal(r1.Err)
} else {
ms := r1.Data.([]*model.TeamMember)
if len(ms) != 2 {
t.Fatal()
}
}
if r1 := <-store.Team().GetMembers(teamId2); r1.Err != nil {
t.Fatal(r1.Err)
} else {
ms := r1.Data.([]*model.TeamMember)
if len(ms) != 1 {
t.Fatal()
}
if ms[0].UserId != m3.UserId {
t.Fatal()
}
}
if r1 := <-store.Team().GetTeamsForUser(m1.UserId); r1.Err != nil {
t.Fatal(r1.Err)
} else {
ms := r1.Data.([]*model.TeamMember)
if len(ms) != 1 {
t.Fatal()
}
if ms[0].TeamId != m1.TeamId {
t.Fatal()
}
}
if r1 := <-store.Team().RemoveMember(teamId1, m1.UserId); r1.Err != nil {
t.Fatal(r1.Err)
}
if r1 := <-store.Team().GetMembers(teamId1); r1.Err != nil {
t.Fatal(r1.Err)
} else {
ms := r1.Data.([]*model.TeamMember)
if len(ms) != 1 {
t.Fatal()
}
if ms[0].UserId != m2.UserId {
t.Fatal()
}
}
Must(store.Team().SaveMember(m1))
if r1 := <-store.Team().RemoveAllMembersByTeam(teamId1); r1.Err != nil {
t.Fatal(r1.Err)
}
if r1 := <-store.Team().GetMembers(teamId1); r1.Err != nil {
t.Fatal(r1.Err)
} else {
ms := r1.Data.([]*model.TeamMember)
if len(ms) != 0 {
t.Fatal()
}
}
uid := model.NewId()
m4 := &model.TeamMember{TeamId: teamId1, UserId: uid}
m5 := &model.TeamMember{TeamId: teamId2, UserId: uid}
Must(store.Team().SaveMember(m4))
Must(store.Team().SaveMember(m5))
if r1 := <-store.Team().GetTeamsForUser(uid); r1.Err != nil {
t.Fatal(r1.Err)
} else {
ms := r1.Data.([]*model.TeamMember)
if len(ms) != 2 {
t.Fatal()
}
}
if r1 := <-store.Team().RemoveAllMembersByUser(uid); r1.Err != nil {
t.Fatal(r1.Err)
}
if r1 := <-store.Team().GetTeamsForUser(m1.UserId); r1.Err != nil {
t.Fatal(r1.Err)
} else {
ms := r1.Data.([]*model.TeamMember)
if len(ms) != 0 {
t.Fatal()
}
}
}

Просмотреть файл

@@ -6,9 +6,10 @@ package store
import (
"database/sql"
"fmt"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"strconv"
"strings"
"github.com/mattermost/platform/model"
)
const (
@@ -26,12 +27,11 @@ func NewSqlUserStore(sqlStore *SqlStore) UserStore {
for _, db := range sqlStore.GetAllConns() {
table := db.AddTableWithName(model.User{}, "Users").SetKeys(false, "Id")
table.ColMap("Id").SetMaxSize(26)
table.ColMap("TeamId").SetMaxSize(26)
table.ColMap("Username").SetMaxSize(64)
table.ColMap("Username").SetMaxSize(64).SetUnique(true)
table.ColMap("Password").SetMaxSize(128)
table.ColMap("AuthData").SetMaxSize(128)
table.ColMap("AuthService").SetMaxSize(32)
table.ColMap("Email").SetMaxSize(128)
table.ColMap("Email").SetMaxSize(128).SetUnique(true)
table.ColMap("Nickname").SetMaxSize(64)
table.ColMap("FirstName").SetMaxSize(64)
table.ColMap("LastName").SetMaxSize(64)
@@ -41,8 +41,6 @@ func NewSqlUserStore(sqlStore *SqlStore) UserStore {
table.ColMap("ThemeProps").SetMaxSize(2000)
table.ColMap("Locale").SetMaxSize(5)
table.ColMap("MfaSecret").SetMaxSize(128)
table.SetUniqueTogether("Email", "TeamId")
table.SetUniqueTogether("Username", "TeamId")
}
return us
@@ -51,13 +49,9 @@ func NewSqlUserStore(sqlStore *SqlStore) UserStore {
func (us SqlUserStore) UpgradeSchemaIfNeeded() {
// ADDED for 2.0 REMOVE for 2.4
us.CreateColumnIfNotExists("Users", "Locale", "varchar(5)", "character varying(5)", model.DEFAULT_LOCALE)
// ADDED for 2.2 REMOVE for 2.6
us.CreateColumnIfNotExists("Users", "MfaActive", "tinyint(1)", "boolean", "0")
us.CreateColumnIfNotExists("Users", "MfaSecret", "varchar(128)", "character varying(128)", "")
}
func (us SqlUserStore) CreateIndexesIfNotExists() {
us.CreateIndexIfNotExists("idx_users_team_id", "Users", "TeamId")
us.CreateIndexIfNotExists("idx_users_email", "Users", "Email")
}
@@ -82,18 +76,6 @@ func (us SqlUserStore) Save(user *model.User) StoreChannel {
return
}
if count, err := us.GetMaster().SelectInt("SELECT COUNT(0) FROM Users WHERE TeamId = :TeamId AND DeleteAt = 0", map[string]interface{}{"TeamId": user.TeamId}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, "teamId="+user.TeamId+", "+err.Error())
storeChannel <- result
close(storeChannel)
return
} else if int(count) > utils.Cfg.TeamSettings.MaxUsersPerTeam {
result.Err = model.NewLocAppError("SqlUserStore.Save", "store.sql_user.save.max_accounts.app_error", nil, "teamId="+user.TeamId)
storeChannel <- result
close(storeChannel)
return
}
if err := us.GetMaster().Insert(user); err != nil {
if IsUniqueConstraintError(err.Error(), "Email", "users_email_teamid_key") {
result.Err = model.NewLocAppError("SqlUserStore.Save", "store.sql_user.save.email_exists.app_error", nil, "user_id="+user.Id+", "+err.Error())
@@ -140,7 +122,6 @@ func (us SqlUserStore) Update(user *model.User, allowActiveUpdate bool) StoreCha
user.Password = oldUser.Password
user.LastPasswordUpdate = oldUser.LastPasswordUpdate
user.LastPictureUpdate = oldUser.LastPictureUpdate
user.TeamId = oldUser.TeamId
user.LastActivityAt = oldUser.LastActivityAt
user.LastPingAt = oldUser.LastPingAt
user.EmailVerified = oldUser.EmailVerified
@@ -153,7 +134,7 @@ func (us SqlUserStore) Update(user *model.User, allowActiveUpdate bool) StoreCha
user.DeleteAt = oldUser.DeleteAt
}
if user.IsSSOUser() {
if user.IsOAuthUser() {
user.Email = oldUser.Email
} else if !user.IsLDAPUser() && user.Email != oldUser.Email {
user.EmailVerified = false
@@ -421,13 +402,76 @@ func (us SqlUserStore) Get(id string) StoreChannel {
return storeChannel
}
func (us SqlUserStore) GetAll() StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
var data []*model.User
if _, err := us.GetReplica().Select(&data, "SELECT * FROM Users"); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetAll", "store.sql_user.get.app_error", nil, err.Error())
}
result.Data = data
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlUserStore) GetEtagForDirectProfiles(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
updateAt, err := s.GetReplica().SelectInt(`
SELECT
UpdateAt
FROM
Users
WHERE
Id IN (SELECT DISTINCT
UserId
FROM
ChannelMembers
WHERE
ChannelMembers.UserId != :UserId
AND ChannelMembers.ChannelId IN (SELECT
Channels.Id
FROM
Channels,
ChannelMembers
WHERE
Channels.Type = 'D'
AND Channels.Id = ChannelMembers.ChannelId
AND ChannelMembers.UserId = :UserId))
`, map[string]interface{}{"UserId": userId})
if err != nil {
result.Data = fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis())
} else {
result.Data = fmt.Sprintf("%v.%v", model.CurrentVersion, updateAt)
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlUserStore) GetEtagForProfiles(teamId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
updateAt, err := s.GetReplica().SelectInt("SELECT UpdateAt FROM Users WHERE TeamId = :TeamId ORDER BY UpdateAt DESC LIMIT 1", map[string]interface{}{"TeamId": teamId})
updateAt, err := s.GetReplica().SelectInt("SELECT UpdateAt FROM Users, TeamMembers WHERE TeamMembers.TeamId = :TeamId AND Users.Id = TeamMembers.UserId ORDER BY UpdateAt DESC LIMIT 1", map[string]interface{}{"TeamId": teamId})
if err != nil {
result.Data = fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis())
} else {
@@ -450,7 +494,7 @@ func (us SqlUserStore) GetProfiles(teamId string) StoreChannel {
var users []*model.User
if _, err := us.GetReplica().Select(&users, "SELECT * FROM Users WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId}); err != nil {
if _, err := us.GetReplica().Select(&users, "SELECT Users.* FROM Users, TeamMembers WHERE TeamMembers.TeamId = :TeamId AND Users.Id = TeamMembers.UserId", map[string]interface{}{"TeamId": teamId}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetProfiles", "store.sql_user.get_profiles.app_error", nil, err.Error())
} else {
@@ -472,6 +516,99 @@ func (us SqlUserStore) GetProfiles(teamId string) StoreChannel {
return storeChannel
}
func (us SqlUserStore) GetDirectProfiles(userId string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
var users []*model.User
if _, err := us.GetReplica().Select(&users, `
SELECT
Users.*
FROM
Users
WHERE
Id IN (SELECT DISTINCT
UserId
FROM
ChannelMembers
WHERE
ChannelMembers.UserId != :UserId
AND ChannelMembers.ChannelId IN (SELECT
Channels.Id
FROM
Channels,
ChannelMembers
WHERE
Channels.Type = 'D'
AND Channels.Id = ChannelMembers.ChannelId
AND ChannelMembers.UserId = :UserId))`, map[string]interface{}{"UserId": userId}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetDirectProfiles", "store.sql_user.get_profiles.app_error", nil, err.Error())
} else {
userMap := make(map[string]*model.User)
for _, u := range users {
u.Password = ""
u.AuthData = ""
userMap[u.Id] = u
}
result.Data = userMap
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (us SqlUserStore) GetProfileByIds(userIds []string) StoreChannel {
storeChannel := make(StoreChannel)
go func() {
result := StoreResult{}
var users []*model.User
props := make(map[string]interface{})
idQuery := ""
for index, userId := range userIds {
if len(idQuery) > 0 {
idQuery += ", "
}
props["userId"+strconv.Itoa(index)] = userId
idQuery += ":userId" + strconv.Itoa(index)
}
if _, err := us.GetReplica().Select(&users, "SELECT * FROM Users WHERE Users.Id IN ("+idQuery+")", props); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetProfileByIds", "store.sql_user.get_profiles.app_error", nil, err.Error())
} else {
userMap := make(map[string]*model.User)
for _, u := range users {
u.Password = ""
u.AuthData = ""
userMap[u.Id] = u
}
result.Data = userMap
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (us SqlUserStore) GetSystemAdminProfiles() StoreChannel {
storeChannel := make(StoreChannel)
@@ -503,7 +640,7 @@ func (us SqlUserStore) GetSystemAdminProfiles() StoreChannel {
return storeChannel
}
func (us SqlUserStore) GetByEmail(teamId string, email string) StoreChannel {
func (us SqlUserStore) GetByEmail(email string) StoreChannel {
storeChannel := make(StoreChannel)
@@ -514,8 +651,8 @@ func (us SqlUserStore) GetByEmail(teamId string, email string) StoreChannel {
user := model.User{}
if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE TeamId = :TeamId AND Email = :Email", map[string]interface{}{"TeamId": teamId, "Email": email}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetByEmail", MISSING_ACCOUNT_ERROR, nil, "teamId="+teamId+", email="+email+", "+err.Error())
if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE Email = :Email", map[string]interface{}{"Email": email}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetByEmail", MISSING_ACCOUNT_ERROR, nil, "email="+email+", "+err.Error())
}
result.Data = &user
@@ -527,7 +664,7 @@ func (us SqlUserStore) GetByEmail(teamId string, email string) StoreChannel {
return storeChannel
}
func (us SqlUserStore) GetByAuth(teamId string, authData string, authService string) StoreChannel {
func (us SqlUserStore) GetByAuth(authData string, authService string) StoreChannel {
storeChannel := make(StoreChannel)
@@ -536,11 +673,11 @@ func (us SqlUserStore) GetByAuth(teamId string, authData string, authService str
user := model.User{}
if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE TeamId = :TeamId AND AuthData = :AuthData AND AuthService = :AuthService", map[string]interface{}{"TeamId": teamId, "AuthData": authData, "AuthService": authService}); err != nil {
if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE AuthData = :AuthData AND AuthService = :AuthService", map[string]interface{}{"AuthData": authData, "AuthService": authService}); err != nil {
if err == sql.ErrNoRows {
result.Err = model.NewLocAppError("SqlUserStore.GetByAuth", MISSING_AUTH_ACCOUNT_ERROR, nil, "teamId="+teamId+", authData="+authData+", authService="+authService+", "+err.Error())
result.Err = model.NewLocAppError("SqlUserStore.GetByAuth", MISSING_AUTH_ACCOUNT_ERROR, nil, "authData="+authData+", authService="+authService+", "+err.Error())
} else {
result.Err = model.NewLocAppError("SqlUserStore.GetByAuth", "store.sql_user.get_by_auth.other.app_error", nil, "teamId="+teamId+", authData="+authData+", authService="+authService+", "+err.Error())
result.Err = model.NewLocAppError("SqlUserStore.GetByAuth", "store.sql_user.get_by_auth.other.app_error", nil, "authData="+authData+", authService="+authService+", "+err.Error())
}
}
@@ -553,7 +690,7 @@ func (us SqlUserStore) GetByAuth(teamId string, authData string, authService str
return storeChannel
}
func (us SqlUserStore) GetByUsername(teamId string, username string) StoreChannel {
func (us SqlUserStore) GetByUsername(username string) StoreChannel {
storeChannel := make(StoreChannel)
@@ -562,9 +699,9 @@ func (us SqlUserStore) GetByUsername(teamId string, username string) StoreChanne
user := model.User{}
if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE TeamId = :TeamId AND Username = :Username", map[string]interface{}{"TeamId": teamId, "Username": username}); err != nil {
if err := us.GetReplica().SelectOne(&user, "SELECT * FROM Users WHERE Username = :Username", map[string]interface{}{"Username": username}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetByUsername", "store.sql_user.get_by_username.app_error",
nil, "teamId="+teamId+", username="+username+", "+err.Error())
nil, err.Error())
}
result.Data = &user
@@ -604,8 +741,8 @@ func (us SqlUserStore) GetForExport(teamId string) StoreChannel {
var users []*model.User
if _, err := us.GetReplica().Select(&users, "SELECT * FROM Users WHERE TeamId = :TeamId", map[string]interface{}{"TeamId": teamId}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetProfiles", "store.sql_user.get_for_export.app_error", nil, err.Error())
if _, err := us.GetReplica().Select(&users, "SELECT Users.* FROM Users, TeamMembers WHERE TeamMembers.TeamId = :TeamId AND Users.Id = TeamMembers.UserId", map[string]interface{}{"TeamId": teamId}); err != nil {
result.Err = model.NewLocAppError("SqlUserStore.GetForExport", "store.sql_user.get_for_export.app_error", nil, err.Error())
} else {
for _, u := range users {
u.Password = ""
@@ -690,7 +827,7 @@ func (us SqlUserStore) AnalyticsUniqueUserCount(teamId string) StoreChannel {
query := "SELECT COUNT(DISTINCT Email) FROM Users"
if len(teamId) > 0 {
query += " WHERE TeamId = :TeamId"
query += ", TeamMembers WHERE TeamMembers.TeamId = :TeamId AND Users.Id = TeamMembers.UserId"
}
v, err := us.GetReplica().SelectInt(query, map[string]interface{}{"TeamId": teamId})

Просмотреть файл

@@ -13,15 +13,18 @@ import (
func TestUserStoreSave(t *testing.T) {
Setup()
teamId := model.NewId()
u1 := model.User{}
u1.Email = model.NewId()
u1.Username = model.NewId()
u1.TeamId = model.NewId()
if err := (<-store.User().Save(&u1)).Err; err != nil {
t.Fatal("couldn't save user", err)
}
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
if err := (<-store.User().Save(&u1)).Err; err == nil {
t.Fatal("shouldn't be able to update user from save")
}
@@ -49,37 +52,44 @@ func TestUserStoreSave(t *testing.T) {
if err := (<-store.User().Save(&u1)).Err; err != nil {
t.Fatal("couldn't save item", err)
}
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
}
u1.Id = ""
u1.Email = model.NewId()
u1.Username = model.NewId()
if err := (<-store.User().Save(&u1)).Err; err == nil {
t.Fatal("should be the limit", err)
if err := (<-store.User().Save(&u1)).Err; err != nil {
t.Fatal("couldn't save item", err)
}
if err := (<-store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id})).Err; err == nil {
t.Fatal("should be the limit")
}
}
func TestUserStoreUpdate(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
time.Sleep(100 * time.Millisecond)
if err := (<-store.User().Update(&u1, false)).Err; err != nil {
if err := (<-store.User().Update(u1, false)).Err; err != nil {
t.Fatal(err)
}
u1.Id = "missing"
if err := (<-store.User().Update(&u1, false)).Err; err == nil {
if err := (<-store.User().Update(u1, false)).Err; err == nil {
t.Fatal("Update should have failed because of missing key")
}
u1.Id = model.NewId()
if err := (<-store.User().Update(&u1, false)).Err; err == nil {
if err := (<-store.User().Update(u1, false)).Err; err == nil {
t.Fatal("Update should have faile because id change")
}
}
@@ -87,10 +97,10 @@ func TestUserStoreUpdate(t *testing.T) {
func TestUserStoreUpdateLastPingAt(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
if err := (<-store.User().UpdateLastPingAt(u1.Id, 1234567890)).Err; err != nil {
t.Fatal(err)
@@ -109,10 +119,10 @@ func TestUserStoreUpdateLastPingAt(t *testing.T) {
func TestUserStoreUpdateLastActivityAt(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
if err := (<-store.User().UpdateLastActivityAt(u1.Id, 1234567890)).Err; err != nil {
t.Fatal(err)
@@ -131,10 +141,10 @@ func TestUserStoreUpdateLastActivityAt(t *testing.T) {
func TestUserStoreUpdateFailedPasswordAttempts(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
if err := (<-store.User().UpdateFailedPasswordAttempts(u1.Id, 3)).Err; err != nil {
t.Fatal(err)
@@ -153,14 +163,13 @@ func TestUserStoreUpdateFailedPasswordAttempts(t *testing.T) {
func TestUserStoreUpdateUserAndSessionActivity(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
s1 := model.Session{}
s1.UserId = u1.Id
s1.TeamId = u1.TeamId
Must(store.Session().Save(&s1))
if err := (<-store.User().UpdateUserAndSessionActivity(u1.Id, s1.Id, 1234567890)).Err; err != nil {
@@ -188,10 +197,10 @@ func TestUserStoreUpdateUserAndSessionActivity(t *testing.T) {
func TestUserStoreGet(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
if r1 := <-store.User().Get(u1.Id); r1.Err != nil {
t.Fatal(r1.Err)
@@ -209,10 +218,10 @@ func TestUserStoreGet(t *testing.T) {
func TestUserCount(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
if result := <-store.User().GetTotalUsersCount(); result.Err != nil {
t.Fatal(result.Err)
@@ -227,10 +236,11 @@ func TestUserCount(t *testing.T) {
func TestActiveUserCount(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
<-store.User().UpdateLastActivityAt(u1.Id, model.GetMillis())
if result := <-store.User().GetTotalActiveUsersCount(); result.Err != nil {
t.Fatal(result.Err)
@@ -245,17 +255,19 @@ func TestActiveUserCount(t *testing.T) {
func TestUserStoreGetProfiles(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
teamId := model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
u2 := model.User{}
u2.TeamId = u1.TeamId
u2 := &model.User{}
u2.Email = model.NewId()
Must(store.User().Save(&u2))
Must(store.User().Save(u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}))
if r1 := <-store.User().GetProfiles(u1.TeamId); r1.Err != nil {
if r1 := <-store.User().GetProfiles(teamId); r1.Err != nil {
t.Fatal(r1.Err)
} else {
users := r1.Data.(map[string]*model.User)
@@ -277,18 +289,104 @@ func TestUserStoreGetProfiles(t *testing.T) {
}
}
func TestUserStoreGetDirectProfiles(t *testing.T) {
Setup()
teamId := model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
u2 := &model.User{}
u2.Email = model.NewId()
Must(store.User().Save(u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}))
if r1 := <-store.User().GetDirectProfiles(u1.Id); r1.Err != nil {
t.Fatal(r1.Err)
} else {
users := r1.Data.(map[string]*model.User)
if len(users) != 0 {
t.Fatal("invalid returned users")
}
}
if r2 := <-store.User().GetDirectProfiles("123"); r2.Err != nil {
t.Fatal(r2.Err)
} else {
if len(r2.Data.(map[string]*model.User)) != 0 {
t.Fatal("should have returned empty map")
}
}
}
func TestUserStoreGetProfilesByIds(t *testing.T) {
Setup()
teamId := model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
u2 := &model.User{}
u2.Email = model.NewId()
Must(store.User().Save(u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}))
if r1 := <-store.User().GetProfileByIds([]string{u1.Id, u2.Id}); r1.Err != nil {
t.Fatal(r1.Err)
} else {
users := r1.Data.(map[string]*model.User)
if len(users) != 2 {
t.Fatal("invalid returned users")
}
if users[u1.Id].Id != u1.Id {
t.Fatal("invalid returned user")
}
}
if r1 := <-store.User().GetProfileByIds([]string{u1.Id}); r1.Err != nil {
t.Fatal(r1.Err)
} else {
users := r1.Data.(map[string]*model.User)
if len(users) != 1 {
t.Fatal("invalid returned users")
}
if users[u1.Id].Id != u1.Id {
t.Fatal("invalid returned user")
}
}
if r2 := <-store.User().GetProfiles("123"); r2.Err != nil {
t.Fatal(r2.Err)
} else {
if len(r2.Data.(map[string]*model.User)) != 0 {
t.Fatal("should have returned empty map")
}
}
}
func TestUserStoreGetSystemAdminProfiles(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
Must(store.User().Save(&u1))
teamId := model.NewId()
u2 := model.User{}
u2.TeamId = u1.TeamId
u1 := &model.User{}
u1.Email = model.NewId()
u1.Roles = model.ROLE_SYSTEM_ADMIN
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
u2 := &model.User{}
u2.Email = model.NewId()
Must(store.User().Save(&u2))
Must(store.User().Save(u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}))
if r1 := <-store.User().GetSystemAdminProfiles(); r1.Err != nil {
t.Fatal(r1.Err)
@@ -303,16 +401,18 @@ func TestUserStoreGetSystemAdminProfiles(t *testing.T) {
func TestUserStoreGetByEmail(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
Must(store.User().Save(&u1))
teamid := model.NewId()
if err := (<-store.User().GetByEmail(u1.TeamId, u1.Email)).Err; err != nil {
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamid, UserId: u1.Id}))
if err := (<-store.User().GetByEmail(u1.Email)).Err; err != nil {
t.Fatal(err)
}
if err := (<-store.User().GetByEmail("", "")).Err; err == nil {
if err := (<-store.User().GetByEmail("")).Err; err == nil {
t.Fatal("Should have failed because of missing email")
}
}
@@ -320,18 +420,20 @@ func TestUserStoreGetByEmail(t *testing.T) {
func TestUserStoreGetByAuthData(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
u1.AuthData = "123"
u1.AuthService = "service"
Must(store.User().Save(&u1))
teamId := model.NewId()
if err := (<-store.User().GetByAuth(u1.TeamId, u1.AuthData, u1.AuthService)).Err; err != nil {
u1 := &model.User{}
u1.Email = model.NewId()
u1.AuthData = "123" + model.NewId()
u1.AuthService = "service"
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
if err := (<-store.User().GetByAuth(u1.AuthData, u1.AuthService)).Err; err != nil {
t.Fatal(err)
}
if err := (<-store.User().GetByAuth("", "", "")).Err; err == nil {
if err := (<-store.User().GetByAuth("", "")).Err; err == nil {
t.Fatal("Should have failed because of missing auth data")
}
}
@@ -339,17 +441,19 @@ func TestUserStoreGetByAuthData(t *testing.T) {
func TestUserStoreGetByUsername(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
teamId := model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
u1.Username = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
if err := (<-store.User().GetByUsername(u1.TeamId, u1.Username)).Err; err != nil {
if err := (<-store.User().GetByUsername(u1.Username)).Err; err != nil {
t.Fatal(err)
}
if err := (<-store.User().GetByUsername("", "")).Err; err == nil {
if err := (<-store.User().GetByUsername("")).Err; err == nil {
t.Fatal("Should have failed because of missing username")
}
}
@@ -357,10 +461,12 @@ func TestUserStoreGetByUsername(t *testing.T) {
func TestUserStoreUpdatePassword(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
teamId := model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
hashedPassword := model.HashPassword("newpwd")
@@ -368,7 +474,7 @@ func TestUserStoreUpdatePassword(t *testing.T) {
t.Fatal(err)
}
if r1 := <-store.User().GetByEmail(u1.TeamId, u1.Email); r1.Err != nil {
if r1 := <-store.User().GetByEmail(u1.Email); r1.Err != nil {
t.Fatal(r1.Err)
} else {
user := r1.Data.(*model.User)
@@ -381,10 +487,10 @@ func TestUserStoreUpdatePassword(t *testing.T) {
func TestUserStoreDelete(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}))
if err := (<-store.User().PermanentDelete(u1.Id)).Err; err != nil {
t.Fatal(err)
@@ -394,10 +500,12 @@ func TestUserStoreDelete(t *testing.T) {
func TestUserStoreUpdateAuthData(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
teamId := model.NewId()
u1 := &model.User{}
u1.Email = model.NewId()
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
service := "someservice"
authData := "1"
@@ -406,7 +514,7 @@ func TestUserStoreUpdateAuthData(t *testing.T) {
t.Fatal(err)
}
if r1 := <-store.User().GetByEmail(u1.TeamId, u1.Email); r1.Err != nil {
if r1 := <-store.User().GetByEmail(u1.Email); r1.Err != nil {
t.Fatal(r1.Err)
} else {
user := r1.Data.(*model.User)
@@ -430,26 +538,26 @@ func TestUserUnreadCount(t *testing.T) {
c1 := model.Channel{}
c1.TeamId = teamId
c1.DisplayName = "Unread Messages"
c1.Name = "unread-messages"
c1.Name = "unread-messages-" + model.NewId()
c1.Type = model.CHANNEL_OPEN
c2 := model.Channel{}
c2.TeamId = teamId
c2.DisplayName = "Unread Direct"
c2.Name = "unread-direct"
c2.Name = "unread-direct-" + model.NewId()
c2.Type = model.CHANNEL_DIRECT
u1 := model.User{}
u1 := &model.User{}
u1.Username = "user1" + model.NewId()
u1.Email = model.NewId()
u1.Username = "user1"
u1.TeamId = teamId
Must(store.User().Save(&u1))
Must(store.User().Save(u1))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))
u2 := model.User{}
u2 := &model.User{}
u2.Email = model.NewId()
u2.Username = "user2"
u2.TeamId = teamId
Must(store.User().Save(&u2))
u2.Username = "user2" + model.NewId()
Must(store.User().Save(u2))
Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}))
if err := (<-store.Channel().Save(&c1)).Err; err != nil {
t.Fatal("couldn't save item", err)
@@ -507,7 +615,6 @@ func TestUserStoreUpdateMfaSecret(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
Must(store.User().Save(&u1))
@@ -527,7 +634,6 @@ func TestUserStoreUpdateMfaActive(t *testing.T) {
Setup()
u1 := model.User{}
u1.TeamId = model.NewId()
u1.Email = model.NewId()
Must(store.User().Save(&u1))

Просмотреть файл

@@ -41,8 +41,10 @@ type Store interface {
Command() CommandStore
Preference() PreferenceStore
License() LicenseStore
PasswordRecovery() PasswordRecoveryStore
MarkSystemRanUnitTests()
Close()
DropAllTables()
}
type TeamStore interface {
@@ -51,12 +53,19 @@ type TeamStore interface {
UpdateDisplayName(name string, teamId string) StoreChannel
Get(id string) StoreChannel
GetByName(name string) StoreChannel
GetTeamsForEmail(domain string) StoreChannel
GetAll() StoreChannel
GetAllTeamListing() StoreChannel
GetTeamsByUserId(userId string) StoreChannel
GetByInviteId(inviteId string) StoreChannel
PermanentDelete(teamId string) StoreChannel
AnalyticsTeamCount() StoreChannel
SaveMember(member *model.TeamMember) StoreChannel
UpdateMember(member *model.TeamMember) StoreChannel
GetMembers(teamId string) StoreChannel
GetTeamsForUser(userId string) StoreChannel
RemoveMember(teamId string, userId string) StoreChannel
RemoveAllMembersByTeam(teamId string) StoreChannel
RemoveAllMembersByUser(userId string) StoreChannel
}
type ChannelStore interface {
@@ -82,6 +91,7 @@ type ChannelStore interface {
PermanentDeleteMembersByUser(userId string) StoreChannel
GetExtraMembers(channelId string, limit int) StoreChannel
CheckPermissionsTo(teamId string, channelId string, userId string) StoreChannel
CheckPermissionsToNoTeam(channelId string, userId string) StoreChannel
CheckOpenChannelPermissions(teamId string, channelId string) StoreChannel
CheckPermissionsToByName(teamId string, channelName string, userId string) StoreChannel
UpdateLastViewedAt(channelId string, userId string) StoreChannel
@@ -120,12 +130,16 @@ type UserStore interface {
UpdateMfaSecret(userId, secret string) StoreChannel
UpdateMfaActive(userId string, active bool) StoreChannel
Get(id string) StoreChannel
GetAll() StoreChannel
GetProfiles(teamId string) StoreChannel
GetByEmail(teamId string, email string) StoreChannel
GetByAuth(teamId string, authData string, authService string) StoreChannel
GetByUsername(teamId string, username string) StoreChannel
GetDirectProfiles(userId string) StoreChannel
GetProfileByIds(userId []string) StoreChannel
GetByEmail(email string) StoreChannel
GetByAuth(authData string, authService string) StoreChannel
GetByUsername(username string) StoreChannel
VerifyEmail(userId string) StoreChannel
GetEtagForProfiles(teamId string) StoreChannel
GetEtagForDirectProfiles(userId string) StoreChannel
UpdateFailedPasswordAttempts(userId string, attempts int) StoreChannel
GetForExport(teamId string) StoreChannel
GetTotalUsersCount() StoreChannel
@@ -133,7 +147,6 @@ type UserStore interface {
GetSystemAdminProfiles() StoreChannel
PermanentDelete(userId string) StoreChannel
AnalyticsUniqueUserCount(teamId string) StoreChannel
GetUnreadCount(userId string) StoreChannel
}
@@ -142,12 +155,12 @@ type SessionStore interface {
Get(sessionIdOrToken string) StoreChannel
GetSessions(userId string) StoreChannel
Remove(sessionIdOrToken string) StoreChannel
RemoveAllSessionsForTeam(teamId string) StoreChannel
RemoveAllSessions() StoreChannel
PermanentDeleteSessionsByUser(teamId string) StoreChannel
UpdateLastActivityAt(sessionId string, time int64) StoreChannel
UpdateRoles(userId string, roles string) StoreChannel
UpdateDeviceId(id string, deviceId string) StoreChannel
AnalyticsSessionCount(teamId string) StoreChannel
AnalyticsSessionCount() StoreChannel
}
type AuditStore interface {
@@ -228,3 +241,10 @@ type LicenseStore interface {
Save(license *model.LicenseRecord) StoreChannel
Get(id string) StoreChannel
}
type PasswordRecoveryStore interface {
SaveOrUpdate(recovery *model.PasswordRecovery) StoreChannel
Delete(userId string) StoreChannel
Get(userId string) StoreChannel
GetByCode(code string) StoreChannel
}