PLT-4938 Add app package and move logic over from api package (#4931)

* Add app package and move logic over from api package

* Change app package functions to return errors

* Move non-api tests into app package

* Fix merge
Этот коммит содержится в:
Joram Wilander
2017-01-13 13:53:37 -05:00
коммит произвёл GitHub
родитель 07bad4d6d5
Коммит 97558f6a6e
85 изменённых файлов: 3368 добавлений и 2997 удалений

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

@@ -17,6 +17,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
@@ -106,7 +107,7 @@ func getClusterStatus(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getAllAudits(c *Context, w http.ResponseWriter, r *http.Request) {
if result := <-Srv.Store.Audit().Get("", 200); result.Err != nil {
if result := <-app.Srv.Store.Audit().Get("", 200); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -141,7 +142,7 @@ func reloadConfig(c *Context, w http.ResponseWriter, r *http.Request) {
utils.LoadConfig(utils.CfgFileName)
// start/restart email batching job if necessary
InitEmailBatching()
app.InitEmailBatching()
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
ReturnStatusOK(w)
@@ -150,7 +151,7 @@ func reloadConfig(c *Context, w http.ResponseWriter, r *http.Request) {
func invalidateAllCaches(c *Context, w http.ResponseWriter, r *http.Request) {
debug.FreeOSMemory()
InvalidateAllCaches()
app.InvalidateAllCaches()
if einterfaces.GetClusterInterface() != nil {
err := einterfaces.GetClusterInterface().InvalidateAllCaches()
@@ -214,7 +215,7 @@ func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) {
// }
// start/restart email batching job if necessary
InitEmailBatching()
app.InitEmailBatching()
rdata := map[string]string{}
rdata["status"] = "OK"
@@ -222,10 +223,10 @@ func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) {
}
func recycleDatabaseConnection(c *Context, w http.ResponseWriter, r *http.Request) {
oldStore := Srv.Store
oldStore := app.Srv.Store
l4g.Warn(utils.T("api.admin.recycle_db_start.warn"))
Srv.Store = store.NewSqlStore()
app.Srv.Store = store.NewSqlStore()
time.Sleep(20 * time.Second)
oldStore.Close()
@@ -261,7 +262,7 @@ func testEmail(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -282,7 +283,7 @@ func getComplianceReports(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Compliance().GetAll(); result.Err != nil {
if result := <-app.Srv.Store.Compliance().GetAll(); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -306,7 +307,7 @@ func saveComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) {
job.UserId = c.Session.UserId
job.Type = model.COMPLIANCE_TYPE_ADHOC
if result := <-Srv.Store.Compliance().Save(job); result.Err != nil {
if result := <-app.Srv.Store.Compliance().Save(job); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -331,7 +332,7 @@ func downloadComplianceReport(c *Context, w http.ResponseWriter, r *http.Request
return
}
if result := <-Srv.Store.Compliance().Get(id); result.Err != nil {
if result := <-app.Srv.Store.Compliance().Get(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -369,7 +370,7 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
skipIntensiveQueries := false
var systemUserCount int64
if r := <-Srv.Store.User().AnalyticsUniqueUserCount(""); r.Err != nil {
if r := <-app.Srv.Store.User().AnalyticsUniqueUserCount(""); r.Err != nil {
c.Err = r.Err
return
} else {
@@ -391,18 +392,18 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
rows[6] = &model.AnalyticsRow{"total_master_db_connections", 0}
rows[7] = &model.AnalyticsRow{"total_read_db_connections", 0}
openChan := Srv.Store.Channel().AnalyticsTypeCount(teamId, model.CHANNEL_OPEN)
privateChan := Srv.Store.Channel().AnalyticsTypeCount(teamId, model.CHANNEL_PRIVATE)
teamChan := Srv.Store.Team().AnalyticsTeamCount()
openChan := app.Srv.Store.Channel().AnalyticsTypeCount(teamId, model.CHANNEL_OPEN)
privateChan := app.Srv.Store.Channel().AnalyticsTypeCount(teamId, model.CHANNEL_PRIVATE)
teamChan := app.Srv.Store.Team().AnalyticsTeamCount()
var userChan store.StoreChannel
if teamId != "" {
userChan = Srv.Store.User().AnalyticsUniqueUserCount(teamId)
userChan = app.Srv.Store.User().AnalyticsUniqueUserCount(teamId)
}
var postChan store.StoreChannel
if !skipIntensiveQueries {
postChan = Srv.Store.Post().AnalyticsPostCount(teamId, false, false)
postChan = app.Srv.Store.Post().AnalyticsPostCount(teamId, false, false)
}
if r := <-openChan; r.Err != nil {
@@ -456,9 +457,9 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
totalSockets := TotalWebsocketConnections()
totalMasterDb := Srv.Store.TotalMasterDbConnections()
totalReadDb := Srv.Store.TotalReadDbConnections()
totalSockets := app.TotalWebsocketConnections()
totalMasterDb := app.Srv.Store.TotalMasterDbConnections()
totalReadDb := app.Srv.Store.TotalReadDbConnections()
for _, stat := range stats {
totalSockets = totalSockets + stat.TotalWebsocketConnections
@@ -471,9 +472,9 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
rows[7].Value = float64(totalReadDb)
} else {
rows[5].Value = float64(TotalWebsocketConnections())
rows[6].Value = float64(Srv.Store.TotalMasterDbConnections())
rows[7].Value = float64(Srv.Store.TotalReadDbConnections())
rows[5].Value = float64(app.TotalWebsocketConnections())
rows[6].Value = float64(app.Srv.Store.TotalMasterDbConnections())
rows[7].Value = float64(app.Srv.Store.TotalReadDbConnections())
}
w.Write([]byte(rows.ToJson()))
@@ -484,7 +485,7 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if r := <-Srv.Store.Post().AnalyticsPostCountsByDay(teamId); r.Err != nil {
if r := <-app.Srv.Store.Post().AnalyticsPostCountsByDay(teamId); r.Err != nil {
c.Err = r.Err
return
} else {
@@ -497,7 +498,7 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if r := <-Srv.Store.Post().AnalyticsUserCountsWithPostsByDay(teamId); r.Err != nil {
if r := <-app.Srv.Store.Post().AnalyticsUserCountsWithPostsByDay(teamId); r.Err != nil {
c.Err = r.Err
return
} else {
@@ -512,16 +513,16 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
rows[4] = &model.AnalyticsRow{"command_count", 0}
rows[5] = &model.AnalyticsRow{"session_count", 0}
iHookChan := Srv.Store.Webhook().AnalyticsIncomingCount(teamId)
oHookChan := Srv.Store.Webhook().AnalyticsOutgoingCount(teamId)
commandChan := Srv.Store.Command().AnalyticsCommandCount(teamId)
sessionChan := Srv.Store.Session().AnalyticsSessionCount()
iHookChan := app.Srv.Store.Webhook().AnalyticsIncomingCount(teamId)
oHookChan := app.Srv.Store.Webhook().AnalyticsOutgoingCount(teamId)
commandChan := app.Srv.Store.Command().AnalyticsCommandCount(teamId)
sessionChan := app.Srv.Store.Session().AnalyticsSessionCount()
var fileChan store.StoreChannel
var hashtagChan store.StoreChannel
if !skipIntensiveQueries {
fileChan = Srv.Store.Post().AnalyticsPostCount(teamId, true, false)
hashtagChan = Srv.Store.Post().AnalyticsPostCount(teamId, false, true)
fileChan = app.Srv.Store.Post().AnalyticsPostCount(teamId, true, false)
hashtagChan = app.Srv.Store.Post().AnalyticsPostCount(teamId, false, true)
}
if fileChan == nil {
@@ -821,7 +822,7 @@ func samlCertificateStatus(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getRecentlyActiveUsers(c *Context, w http.ResponseWriter, r *http.Request) {
if result := <-Srv.Store.User().GetRecentlyActiveUsersForTeam(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.User().GetRecentlyActiveUsersForTeam(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else {

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

@@ -7,6 +7,7 @@ import (
"strings"
"testing"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -333,7 +334,7 @@ func TestGetPostCount(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
// manually update creation time, since it's always set to 0 upon saving and we only retrieve posts < today
Srv.Store.(*store.SqlStore).GetMaster().Exec("UPDATE Posts SET CreateAt = :CreateAt WHERE ChannelId = :ChannelId",
app.Srv.Store.(*store.SqlStore).GetMaster().Exec("UPDATE Posts SET CreateAt = :CreateAt WHERE ChannelId = :ChannelId",
map[string]interface{}{"ChannelId": th.BasicChannel.Id, "CreateAt": utils.MillisFromTime(utils.Yesterday())})
if _, err := th.BasicClient.GetTeamAnalytics(th.BasicTeam.Id, "post_counts_day"); err == nil {
@@ -375,7 +376,7 @@ func TestUserCountsWithPostsByDay(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
// manually update creation time, since it's always set to 0 upon saving and we only retrieve posts < today
Srv.Store.(*store.SqlStore).GetMaster().Exec("UPDATE Posts SET CreateAt = :CreateAt WHERE ChannelId = :ChannelId",
app.Srv.Store.(*store.SqlStore).GetMaster().Exec("UPDATE Posts SET CreateAt = :CreateAt WHERE ChannelId = :ChannelId",
map[string]interface{}{"ChannelId": th.BasicChannel.Id, "CreateAt": utils.MillisFromTime(utils.Yesterday())})
if _, err := th.BasicClient.GetTeamAnalytics(th.BasicTeam.Id, "user_counts_with_posts_day"); err == nil {
@@ -579,7 +580,7 @@ func TestAdminResetPassword(t *testing.T) {
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
if _, err := Client.AdminResetPassword("", "newpwd1"); err == nil {
t.Fatal("Should have errored - empty user id")
@@ -601,7 +602,7 @@ func TestAdminResetPassword(t *testing.T) {
user2 := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", AuthData: &authData, AuthService: "random"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
LinkUserToTeam(user2, team)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
if _, err := Client.AdminResetPassword(user.Id, "newpwd1"); err != nil {
t.Fatal(err)

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

@@ -7,6 +7,7 @@ import (
"net/http"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
@@ -53,16 +54,20 @@ type Routes struct {
Emoji *mux.Router // 'api/v3/emoji'
Webrtc *mux.Router // 'api/v3/webrtc'
WebSocket *WebSocketRouter // websocket api
}
var BaseRoutes *Routes
func InitRouter() {
app.Srv.Router = mux.NewRouter()
app.Srv.Router.NotFoundHandler = http.HandlerFunc(Handle404)
app.Srv.WebSocketRouter = app.NewWebSocketRouter()
}
func InitApi() {
BaseRoutes = &Routes{}
BaseRoutes.Root = Srv.Router
BaseRoutes.ApiRoot = Srv.Router.PathPrefix(model.API_URL_SUFFIX).Subrouter()
BaseRoutes.Root = app.Srv.Router
BaseRoutes.ApiRoot = app.Srv.Router.PathPrefix(model.API_URL_SUFFIX).Subrouter()
BaseRoutes.Users = BaseRoutes.ApiRoot.PathPrefix("/users").Subrouter()
BaseRoutes.NeedUser = BaseRoutes.Users.PathPrefix("/{user_id:[A-Za-z0-9]+}").Subrouter()
BaseRoutes.Teams = BaseRoutes.ApiRoot.PathPrefix("/teams").Subrouter()
@@ -86,8 +91,6 @@ func InitApi() {
BaseRoutes.Emoji = BaseRoutes.ApiRoot.PathPrefix("/emoji").Subrouter()
BaseRoutes.Webrtc = BaseRoutes.ApiRoot.PathPrefix("/webrtc").Subrouter()
BaseRoutes.WebSocket = NewWebSocketRouter()
InitUser()
InitTeam()
InitChannel()
@@ -108,11 +111,11 @@ func InitApi() {
InitDeprecated()
// 404 on any api route before web.go has a chance to serve it
Srv.Router.Handle("/api/{anything:.*}", http.HandlerFunc(Handle404))
app.Srv.Router.Handle("/api/{anything:.*}", http.HandlerFunc(Handle404))
utils.InitHTML()
InitEmailBatching()
app.InitEmailBatching()
}
func HandleEtag(etag string, routeName string, w http.ResponseWriter, r *http.Request) bool {

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

@@ -6,6 +6,7 @@ package api
import (
"time"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -28,7 +29,7 @@ type TestHelper struct {
}
func SetupEnterprise() *TestHelper {
if Srv == nil {
if app.Srv == nil {
utils.TranslationsPreInit()
utils.LoadConfig("config.json")
utils.InitTranslations(utils.Cfg.LocalizationSettings)
@@ -36,14 +37,14 @@ func SetupEnterprise() *TestHelper {
*utils.Cfg.RateLimitSettings.Enable = false
utils.DisableDebugLogForTest()
utils.License.Features.SetDefaults()
NewServer()
InitStores()
app.NewServer()
app.InitStores()
InitRouter()
StartServer()
app.StartServer()
utils.InitHTML()
InitApi()
utils.EnableDebugLogForTest()
Srv.Store.MarkSystemRanUnitTests()
app.Srv.Store.MarkSystemRanUnitTests()
*utils.Cfg.TeamSettings.EnableOpenServer = true
}
@@ -52,20 +53,20 @@ func SetupEnterprise() *TestHelper {
}
func Setup() *TestHelper {
if Srv == nil {
if app.Srv == nil {
utils.TranslationsPreInit()
utils.LoadConfig("config.json")
utils.InitTranslations(utils.Cfg.LocalizationSettings)
utils.Cfg.TeamSettings.MaxUsersPerTeam = 50
*utils.Cfg.RateLimitSettings.Enable = false
utils.DisableDebugLogForTest()
NewServer()
InitStores()
app.NewServer()
app.InitStores()
InitRouter()
StartServer()
app.StartServer()
InitApi()
utils.EnableDebugLogForTest()
Srv.Store.MarkSystemRanUnitTests()
app.Srv.Store.MarkSystemRanUnitTests()
*utils.Cfg.TeamSettings.EnableOpenServer = true
}
@@ -138,7 +139,7 @@ func (me *TestHelper) CreateUser(client *model.Client) *model.User {
utils.DisableDebugLogForTest()
ruser := client.Must(client.CreateUser(user, "")).Data.(*model.User)
ruser.Password = "Password1"
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
utils.EnableDebugLogForTest()
return ruser
}
@@ -146,7 +147,7 @@ func (me *TestHelper) CreateUser(client *model.Client) *model.User {
func LinkUserToTeam(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
err := JoinUserToTeam(team, user)
err := app.JoinUserToTeam(team, user)
if err != nil {
l4g.Error(err.Error())
l4g.Close()
@@ -161,7 +162,7 @@ func UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.ROLE_TEAM_USER.Id + " " + model.ROLE_TEAM_ADMIN.Id}
if tmr := <-Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
if tmr := <-app.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
utils.EnableDebugLogForTest()
l4g.Error(tmr.Err.Error())
l4g.Close()
@@ -174,10 +175,10 @@ func UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
func MakeUserChannelAdmin(user *model.User, channel *model.Channel) {
utils.DisableDebugLogForTest()
if cmr := <-Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
if cmr := <-app.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
cm := cmr.Data.(model.ChannelMember)
cm.Roles = "channel_admin channel_user"
if sr := <-Srv.Store.Channel().UpdateMember(&cm); sr.Err != nil {
if sr := <-app.Srv.Store.Channel().UpdateMember(&cm); sr.Err != nil {
utils.EnableDebugLogForTest()
panic(sr.Err)
}
@@ -192,10 +193,10 @@ func MakeUserChannelAdmin(user *model.User, channel *model.Channel) {
func MakeUserChannelUser(user *model.User, channel *model.Channel) {
utils.DisableDebugLogForTest()
if cmr := <-Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
if cmr := <-app.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
cm := cmr.Data.(model.ChannelMember)
cm.Roles = "channel_user"
if sr := <-Srv.Store.Channel().UpdateMember(&cm); sr.Err != nil {
if sr := <-app.Srv.Store.Channel().UpdateMember(&cm); sr.Err != nil {
utils.EnableDebugLogForTest()
panic(sr.Err)
}
@@ -264,7 +265,7 @@ func (me *TestHelper) LoginSystemAdmin() {
}
func TearDown() {
if Srv != nil {
StopServer()
if app.Srv != nil {
app.StopServer()
}
}

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

@@ -4,6 +4,7 @@
package api
import (
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
@@ -39,13 +40,13 @@ func doubleCheckPassword(user *model.User, password string) *model.AppError {
func checkUserPassword(user *model.User, password string) *model.AppError {
if !model.ComparePassword(user.Password, password) {
if result := <-Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, user.FailedAttempts+1); result.Err != nil {
if result := <-app.Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, user.FailedAttempts+1); result.Err != nil {
return result.Err
}
return model.NewLocAppError("checkUserPassword", "api.user.check_user_password.invalid.app_error", nil, "user_id="+user.Id)
} else {
if result := <-Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, 0); result.Err != nil {
if result := <-app.Srv.Store.User().UpdateFailedPasswordAttempts(user.Id, 0); result.Err != nil {
return result.Err
}

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

@@ -8,6 +8,7 @@ import (
"strings"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -66,7 +67,7 @@ func HasPermissionToTeam(user *model.User, teamMember *model.TeamMember, permiss
}
func HasPermissionToChannelContext(c *Context, channelId string, permission *model.Permission) bool {
cmc := Srv.Store.Channel().GetAllChannelMembersForUser(c.Session.UserId, true)
cmc := app.Srv.Store.Channel().GetAllChannelMembersForUser(c.Session.UserId, true)
var channelRoles []string
if cmcresult := <-cmc; cmcresult.Err == nil {
@@ -79,7 +80,7 @@ func HasPermissionToChannelContext(c *Context, channelId string, permission *mod
}
}
cc := Srv.Store.Channel().Get(channelId, true)
cc := app.Srv.Store.Channel().Get(channelId, true)
if ccresult := <-cc; ccresult.Err == nil {
channel := ccresult.Data.(*model.Channel)
@@ -117,7 +118,7 @@ func HasPermissionToChannel(user *model.User, teamMember *model.TeamMember, chan
}
func HasPermissionToChannelByPostContext(c *Context, postId string, permission *model.Permission) bool {
cmc := Srv.Store.Channel().GetMemberForPost(postId, c.Session.UserId)
cmc := app.Srv.Store.Channel().GetMemberForPost(postId, c.Session.UserId)
var channelRoles []string
if cmcresult := <-cmc; cmcresult.Err == nil {
@@ -129,7 +130,7 @@ func HasPermissionToChannelByPostContext(c *Context, postId string, permission *
}
}
cc := Srv.Store.Channel().GetForPost(postId)
cc := app.Srv.Store.Channel().GetForPost(postId)
if ccresult := <-cc; ccresult.Err == nil {
channel := ccresult.Data.(*model.Channel)

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

@@ -4,6 +4,7 @@
package api
import (
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -49,8 +50,8 @@ func CreateBasicUser(client *model.Client) *model.AppError {
return err
}
ruser := result.Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(Srv.Store.Team().SaveMember(&model.TeamMember{TeamId: basicteam.Id, UserId: ruser.Id}))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(app.Srv.Store.Team().SaveMember(&model.TeamMember{TeamId: basicteam.Id, UserId: ruser.Id}))
}
return nil
}
@@ -81,14 +82,14 @@ func (cfg *AutoUserCreator) createRandomUser() (*model.User, bool) {
ruser := result.Data.(*model.User)
status := &model.Status{ruser.Id, model.STATUS_ONLINE, false, model.GetMillis(), ""}
if result := <-Srv.Store.Status().SaveOrUpdate(status); result.Err != nil {
if result := <-app.Srv.Store.Status().SaveOrUpdate(status); result.Err != nil {
result.Err.Translate(utils.T)
l4g.Error(result.Err.Error())
return nil, false
}
// We need to cheat to verify the user's email
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
return result.Data.(*model.User), true
}

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

@@ -11,6 +11,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -82,7 +83,7 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
if channel.TeamId == c.TeamId {
// Get total number of channels on current team
if result := <-Srv.Store.Channel().GetTeamChannels(channel.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetTeamChannels(channel.TeamId); result.Err != nil {
c.Err = model.NewLocAppError("createChannel", "api.channel.get_channels.error", nil, result.Err.Message)
return
} else {
@@ -96,38 +97,12 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
channel.CreatorId = c.Session.UserId
if sc, err := CreateChannel(c, channel, true); err != nil {
if sc, err := app.CreateChannel(channel, true); err != nil {
c.Err = err
return
} else {
w.Write([]byte(sc.ToJson()))
}
}
func CreateChannel(c *Context, channel *model.Channel, addMember bool) (*model.Channel, *model.AppError) {
if result := <-Srv.Store.Channel().Save(channel); result.Err != nil {
return nil, result.Err
} else {
sc := result.Data.(*model.Channel)
if addMember {
cm := &model.ChannelMember{
ChannelId: sc.Id,
UserId: c.Session.UserId,
Roles: model.ROLE_CHANNEL_USER.Id + " " + model.ROLE_CHANNEL_ADMIN.Id,
NotifyProps: model.GetDefaultChannelNotifyProps(),
}
if cmresult := <-Srv.Store.Channel().SaveMember(cm); cmresult.Err != nil {
return nil, cmresult.Err
}
InvalidateCacheForUser(c.Session.UserId)
}
c.LogAudit("name=" + channel.Name)
return sc, nil
w.Write([]byte(sc.ToJson()))
}
}
@@ -153,13 +128,13 @@ func createDirectChannel(c *Context, w http.ResponseWriter, r *http.Request) {
}
func CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *model.AppError) {
uc := Srv.Store.User().Get(otherUserId)
uc := app.Srv.Store.User().Get(otherUserId)
if uresult := <-uc; uresult.Err != nil {
return nil, model.NewLocAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, otherUserId)
}
if result := <-Srv.Store.Channel().CreateDirectChannel(userId, otherUserId); result.Err != nil {
if result := <-app.Srv.Store.Channel().CreateDirectChannel(userId, otherUserId); result.Err != nil {
if result.Err.Id == store.CHANNEL_EXISTS_ERROR {
return result.Data.(*model.Channel), nil
} else {
@@ -168,34 +143,17 @@ func CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *mo
} else {
channel := result.Data.(*model.Channel)
InvalidateCacheForUser(userId)
InvalidateCacheForUser(otherUserId)
app.InvalidateCacheForUser(userId)
app.InvalidateCacheForUser(otherUserId)
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_DIRECT_ADDED, "", channel.Id, "", nil)
message.Add("teammate_id", otherUserId)
go Publish(message)
go app.Publish(message)
return channel, nil
}
}
func CreateDefaultChannels(c *Context, teamId string) ([]*model.Channel, *model.AppError) {
townSquare := &model.Channel{DisplayName: c.T("api.channel.create_default_channels.town_square"), Name: "town-square", Type: model.CHANNEL_OPEN, TeamId: teamId}
if _, err := CreateChannel(c, townSquare, false); err != nil {
return nil, err
}
offTopic := &model.Channel{DisplayName: c.T("api.channel.create_default_channels.off_topic"), Name: "off-topic", Type: model.CHANNEL_OPEN, TeamId: teamId}
if _, err := CreateChannel(c, offTopic, false); err != nil {
return nil, err
}
channels := []*model.Channel{townSquare, offTopic}
return channels, nil
}
func CanManageChannel(c *Context, channel *model.Channel) bool {
if channel.Type == model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES) {
return false
@@ -217,8 +175,8 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
sc := Srv.Store.Channel().Get(channel.Id, true)
cmc := Srv.Store.Channel().GetMember(channel.Id, c.Session.UserId)
sc := app.Srv.Store.Channel().Get(channel.Id, true)
cmc := app.Srv.Store.Channel().GetMember(channel.Id, c.Session.UserId)
if cresult := <-sc; cresult.Err != nil {
c.Err = cresult.Err
@@ -265,8 +223,8 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
oldChannel.Type = channel.Type
}
InvalidateCacheForChannel(oldChannel.Id)
if ucresult := <-Srv.Store.Channel().Update(oldChannel); ucresult.Err != nil {
app.InvalidateCacheForChannel(oldChannel.Id)
if ucresult := <-app.Srv.Store.Channel().Update(oldChannel); ucresult.Err != nil {
c.Err = ucresult.Err
return
} else {
@@ -294,8 +252,8 @@ func updateChannelHeader(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
sc := Srv.Store.Channel().Get(channelId, true)
cmc := Srv.Store.Channel().GetMember(channelId, c.Session.UserId)
sc := app.Srv.Store.Channel().Get(channelId, true)
cmc := app.Srv.Store.Channel().GetMember(channelId, c.Session.UserId)
if cresult := <-sc; cresult.Err != nil {
c.Err = cresult.Err
@@ -314,8 +272,8 @@ func updateChannelHeader(c *Context, w http.ResponseWriter, r *http.Request) {
oldChannelHeader := channel.Header
channel.Header = channelHeader
InvalidateCacheForChannel(channel.Id)
if ucresult := <-Srv.Store.Channel().Update(channel); ucresult.Err != nil {
app.InvalidateCacheForChannel(channel.Id)
if ucresult := <-app.Srv.Store.Channel().Update(channel); ucresult.Err != nil {
c.Err = ucresult.Err
return
} else {
@@ -327,7 +285,7 @@ func updateChannelHeader(c *Context, w http.ResponseWriter, r *http.Request) {
}
func PostUpdateChannelHeaderMessage(c *Context, channelId string, oldChannelHeader, newChannelHeader string) {
uc := Srv.Store.User().Get(c.Session.UserId)
uc := app.Srv.Store.User().Get(c.Session.UserId)
if uresult := <-uc; uresult.Err != nil {
l4g.Error(utils.T("api.channel.post_update_channel_header_message_and_forget.retrieve_user.error"), uresult.Err)
@@ -355,14 +313,14 @@ func PostUpdateChannelHeaderMessage(c *Context, channelId string, oldChannelHead
},
}
if _, err := CreatePost(c, post, false); err != nil {
if _, err := app.CreatePost(post, c.TeamId, false); err != nil {
l4g.Error(utils.T("api.channel.post_update_channel_header_message_and_forget.join_leave.error"), err)
}
}
}
func PostUpdateChannelDisplayNameMessage(c *Context, channelId string, oldChannelDisplayName, newChannelDisplayName string) {
uc := Srv.Store.User().Get(c.Session.UserId)
uc := app.Srv.Store.User().Get(c.Session.UserId)
if uresult := <-uc; uresult.Err != nil {
l4g.Error(utils.T("api.channel.post_update_channel_displayname_message_and_forget.retrieve_user.error"), uresult.Err)
@@ -383,7 +341,7 @@ func PostUpdateChannelDisplayNameMessage(c *Context, channelId string, oldChanne
},
}
if _, err := CreatePost(c, post, false); err != nil {
if _, err := app.CreatePost(post, c.TeamId, false); err != nil {
l4g.Error(utils.T("api.channel.post_update_channel_displayname_message_and_forget.create_post.error"), err)
}
}
@@ -403,8 +361,8 @@ func updateChannelPurpose(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
sc := Srv.Store.Channel().Get(channelId, true)
cmc := Srv.Store.Channel().GetMember(channelId, c.Session.UserId)
sc := app.Srv.Store.Channel().Get(channelId, true)
cmc := app.Srv.Store.Channel().GetMember(channelId, c.Session.UserId)
if cresult := <-sc; cresult.Err != nil {
c.Err = cresult.Err
@@ -422,8 +380,8 @@ func updateChannelPurpose(c *Context, w http.ResponseWriter, r *http.Request) {
channel.Purpose = channelPurpose
InvalidateCacheForChannel(channel.Id)
if ucresult := <-Srv.Store.Channel().Update(channel); ucresult.Err != nil {
app.InvalidateCacheForChannel(channel.Id)
if ucresult := <-app.Srv.Store.Channel().Update(channel); ucresult.Err != nil {
c.Err = ucresult.Err
return
} else {
@@ -441,10 +399,11 @@ func getChannels(c *Context, w http.ResponseWriter, r *http.Request) {
}
// user is already in the team
// Get's all channels the user is a member of
if result := <-Srv.Store.Channel().GetChannels(c.TeamId, c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetChannels(c.TeamId, c.Session.UserId); result.Err != nil {
if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" {
// lets make sure the user is valid
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
c.Err = result.Err
c.RemoveSessionCookie(w, r)
l4g.Error(utils.T("api.channel.get_channels.error"), c.Session.UserId)
@@ -482,7 +441,7 @@ func getMoreChannelsPage(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Channel().GetMoreChannels(c.TeamId, c.Session.UserId, offset, limit); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetMoreChannels(c.TeamId, c.Session.UserId, offset, limit); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -496,7 +455,7 @@ func getChannelCounts(c *Context, w http.ResponseWriter, r *http.Request) {
// user is already in the team
if result := <-Srv.Store.Channel().GetChannelCounts(c.TeamId, c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetChannelCounts(c.TeamId, c.Session.UserId); result.Err != nil {
c.Err = model.NewLocAppError("getChannelCounts", "api.channel.get_channel_counts.app_error", nil, result.Err.Message)
return
} else if HandleEtag(result.Data.(*model.ChannelCounts).Etag(), "Get Channel Counts", w, r) {
@@ -539,15 +498,15 @@ func join(c *Context, w http.ResponseWriter, r *http.Request) {
}
func JoinChannelByName(c *Context, userId string, teamId string, channelName string) (*model.AppError, *model.Channel) {
channelChannel := Srv.Store.Channel().GetByName(teamId, channelName)
userChannel := Srv.Store.User().Get(userId)
channelChannel := app.Srv.Store.Channel().GetByName(teamId, channelName)
userChannel := app.Srv.Store.User().Get(userId)
return joinChannel(c, channelChannel, userChannel)
}
func JoinChannelById(c *Context, userId string, channelId string) (*model.AppError, *model.Channel) {
channelChannel := Srv.Store.Channel().Get(channelId, true)
userChannel := Srv.Store.User().Get(userId)
channelChannel := app.Srv.Store.Channel().Get(channelId, true)
userChannel := app.Srv.Store.User().Get(userId)
return joinChannel(c, channelChannel, userChannel)
}
@@ -561,7 +520,7 @@ func joinChannel(c *Context, channelChannel store.StoreChannel, userChannel stor
channel := cresult.Data.(*model.Channel)
user := uresult.Data.(*model.User)
if mresult := <-Srv.Store.Channel().GetMember(channel.Id, user.Id); mresult.Err == nil && mresult.Data != nil {
if mresult := <-app.Srv.Store.Channel().GetMember(channel.Id, user.Id); mresult.Err == nil && mresult.Data != nil {
// the user is already in the channel so just return successful
return nil, channel
}
@@ -571,7 +530,7 @@ func joinChannel(c *Context, channelChannel store.StoreChannel, userChannel stor
}
if channel.Type == model.CHANNEL_OPEN {
if _, err := AddUserToChannel(user, channel); err != nil {
if _, err := app.AddUserToChannel(user, channel); err != nil {
return err, nil
}
go PostUserAddRemoveMessage(c, channel.Id, fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username), model.POST_JOIN_LEAVE)
@@ -589,135 +548,19 @@ func PostUserAddRemoveMessage(c *Context, channelId string, message, postType st
Type: postType,
UserId: c.Session.UserId,
}
if _, err := CreatePost(c, post, false); err != nil {
if _, err := app.CreatePost(post, c.TeamId, false); err != nil {
l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err)
}
}
func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelMember, *model.AppError) {
if channel.DeleteAt > 0 {
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user_to_channel.deleted.app_error", nil, "")
}
if channel.Type != model.CHANNEL_OPEN && channel.Type != model.CHANNEL_PRIVATE {
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "")
}
tmchan := Srv.Store.Team().GetMember(channel.TeamId, user.Id)
cmchan := Srv.Store.Channel().GetMember(channel.Id, user.Id)
if result := <-tmchan; result.Err != nil {
return nil, result.Err
} else {
teamMember := result.Data.(model.TeamMember)
if teamMember.DeleteAt > 0 {
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.deleted.app_error", nil, "")
}
}
if result := <-cmchan; result.Err != nil {
if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR {
return nil, result.Err
}
} else {
channelMember := result.Data.(model.ChannelMember)
return &channelMember, nil
}
newMember := &model.ChannelMember{
ChannelId: channel.Id,
UserId: user.Id,
NotifyProps: model.GetDefaultChannelNotifyProps(),
Roles: model.ROLE_CHANNEL_USER.Id,
}
if result := <-Srv.Store.Channel().SaveMember(newMember); result.Err != nil {
l4g.Error("Failed to add member user_id=%v channel_id=%v err=%v", user.Id, channel.Id, result.Err)
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.app_error", nil, "")
}
InvalidateCacheForUser(user.Id)
InvalidateCacheForChannel(channel.Id)
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ADDED, "", channel.Id, "", nil)
message.Add("user_id", user.Id)
message.Add("team_id", channel.TeamId)
go Publish(message)
return newMember, nil
}
func JoinDefaultChannels(teamId string, user *model.User, channelRole string) *model.AppError {
// We don't call JoinChannel here since c.Session is not populated on user creation
var err *model.AppError = nil
fakeContext := &Context{
Session: model.Session{
UserId: user.Id,
},
TeamId: teamId,
T: utils.TfuncWithFallback(user.Locale),
}
if result := <-Srv.Store.Channel().GetByName(teamId, "town-square"); result.Err != nil {
err = result.Err
} else {
cm := &model.ChannelMember{ChannelId: result.Data.(*model.Channel).Id, UserId: user.Id,
Roles: channelRole, NotifyProps: model.GetDefaultChannelNotifyProps()}
if cmResult := <-Srv.Store.Channel().SaveMember(cm); cmResult.Err != nil {
err = cmResult.Err
}
post := &model.Post{
ChannelId: result.Data.(*model.Channel).Id,
Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username),
Type: model.POST_JOIN_LEAVE,
UserId: user.Id,
}
InvalidateCacheForChannel(result.Data.(*model.Channel).Id)
if _, err := CreatePost(fakeContext, post, false); err != nil {
l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err)
}
}
if result := <-Srv.Store.Channel().GetByName(teamId, "off-topic"); result.Err != nil {
err = result.Err
} else {
cm := &model.ChannelMember{ChannelId: result.Data.(*model.Channel).Id, UserId: user.Id,
Roles: channelRole, NotifyProps: model.GetDefaultChannelNotifyProps()}
if cmResult := <-Srv.Store.Channel().SaveMember(cm); cmResult.Err != nil {
err = cmResult.Err
}
post := &model.Post{
ChannelId: result.Data.(*model.Channel).Id,
Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username),
Type: model.POST_JOIN_LEAVE,
UserId: user.Id,
}
InvalidateCacheForChannel(result.Data.(*model.Channel).Id)
if _, err := CreatePost(fakeContext, post, false); err != nil {
l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err)
}
}
return err
}
func leave(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["channel_id"]
sc := Srv.Store.Channel().Get(id, true)
uc := Srv.Store.User().Get(c.Session.UserId)
ccm := Srv.Store.Channel().GetMemberCount(id, false)
sc := app.Srv.Store.Channel().Get(id, true)
uc := app.Srv.Store.User().Get(c.Session.UserId)
ccm := app.Srv.Store.Channel().GetMemberCount(id, false)
if cresult := <-sc; cresult.Err != nil {
c.Err = cresult.Err
@@ -751,7 +594,7 @@ func leave(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if cmresult := <-Srv.Store.Channel().RemoveMember(channel.Id, c.Session.UserId); cmresult.Err != nil {
if cmresult := <-app.Srv.Store.Channel().RemoveMember(channel.Id, c.Session.UserId); cmresult.Err != nil {
c.Err = cmresult.Err
return
}
@@ -771,12 +614,12 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["channel_id"]
sc := Srv.Store.Channel().Get(id, true)
scm := Srv.Store.Channel().GetMember(id, c.Session.UserId)
cmc := Srv.Store.Channel().GetMemberCount(id, false)
uc := Srv.Store.User().Get(c.Session.UserId)
ihc := Srv.Store.Webhook().GetIncomingByChannel(id)
ohc := Srv.Store.Webhook().GetOutgoingByChannel(id)
sc := app.Srv.Store.Channel().Get(id, true)
scm := app.Srv.Store.Channel().GetMember(id, c.Session.UserId)
cmc := app.Srv.Store.Channel().GetMemberCount(id, false)
uc := app.Srv.Store.User().Get(c.Session.UserId)
ihc := app.Srv.Store.Webhook().GetIncomingByChannel(id)
ohc := app.Srv.Store.Webhook().GetOutgoingByChannel(id)
if cresult := <-sc; cresult.Err != nil {
c.Err = cresult.Err
@@ -834,35 +677,35 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
UserId: c.Session.UserId,
}
if _, err := CreatePost(c, post, false); err != nil {
if _, err := app.CreatePost(post, c.TeamId, false); err != nil {
l4g.Error(utils.T("api.channel.delete_channel.failed_post.error"), err)
}
now := model.GetMillis()
for _, hook := range incomingHooks {
if result := <-Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil {
if result := <-app.Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil {
l4g.Error(utils.T("api.channel.delete_channel.incoming_webhook.error"), hook.Id)
}
}
for _, hook := range outgoingHooks {
if result := <-Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil {
if result := <-app.Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil {
l4g.Error(utils.T("api.channel.delete_channel.outgoing_webhook.error"), hook.Id)
}
}
if dresult := <-Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); dresult.Err != nil {
if dresult := <-app.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); dresult.Err != nil {
c.Err = dresult.Err
return
}
InvalidateCacheForChannel(channel.Id)
app.InvalidateCacheForChannel(channel.Id)
c.LogAudit("name=" + channel.Name)
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_DELETED, c.TeamId, "", "", nil)
message.Add("channel_id", channel.Id)
Publish(message)
app.Publish(message)
result := make(map[string]string)
result["id"] = channel.Id
@@ -874,8 +717,8 @@ func getChannel(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["channel_id"]
cchan := Srv.Store.Channel().Get(id, true)
cmchan := Srv.Store.Channel().GetMember(id, c.Session.UserId)
cchan := app.Srv.Store.Channel().Get(id, true)
cmchan := app.Srv.Store.Channel().GetMember(id, c.Session.UserId)
if cresult := <-cchan; cresult.Err != nil {
c.Err = cresult.Err
@@ -904,7 +747,7 @@ func getChannel(c *Context, w http.ResponseWriter, r *http.Request) {
}
func SetActiveChannel(userId string, channelId string) *model.AppError {
status, err := GetStatus(userId)
status, err := app.GetStatus(userId)
if err != nil {
status = &model.Status{userId, model.STATUS_ONLINE, false, model.GetMillis(), channelId}
} else {
@@ -915,7 +758,7 @@ func SetActiveChannel(userId string, channelId string) *model.AppError {
status.LastActivityAt = model.GetMillis()
}
AddStatusCache(status)
app.AddStatusCache(status)
return nil
}
@@ -924,7 +767,7 @@ func getChannelByName(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
channelName := params["channel_name"]
cchan := Srv.Store.Channel().GetByName(c.TeamId, channelName)
cchan := app.Srv.Store.Channel().GetByName(c.TeamId, channelName)
if cresult := <-cchan; cresult.Err != nil {
c.Err = cresult.Err
@@ -954,7 +797,7 @@ func getChannelStats(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["channel_id"]
sc := Srv.Store.Channel().Get(id, true)
sc := app.Srv.Store.Channel().Get(id, true)
var channel *model.Channel
if result := <-sc; result.Err != nil {
c.Err = result.Err
@@ -963,7 +806,7 @@ func getChannelStats(c *Context, w http.ResponseWriter, r *http.Request) {
channel = result.Data.(*model.Channel)
}
if result := <-Srv.Store.Channel().GetMemberCount(id, true); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetMemberCount(id, true); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -993,7 +836,7 @@ func getChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Channel().GetMember(channelId, userId); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetMember(channelId, userId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1003,7 +846,7 @@ func getChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getMyChannelMembers(c *Context, w http.ResponseWriter, r *http.Request) {
if result := <-Srv.Store.Channel().GetMembersForUser(c.TeamId, c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetMembersForUser(c.TeamId, c.Session.UserId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1024,9 +867,9 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
sc := Srv.Store.Channel().Get(id, true)
ouc := Srv.Store.User().Get(c.Session.UserId)
nuc := Srv.Store.User().Get(userId)
sc := app.Srv.Store.Channel().Get(id, true)
ouc := app.Srv.Store.User().Get(c.Session.UserId)
nuc := app.Srv.Store.User().Get(userId)
if nresult := <-nuc; nresult.Err != nil {
c.Err = model.NewLocAppError("addMember", "api.channel.add_member.find_user.app_error", nil, "")
return
@@ -1051,7 +894,7 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
} else {
oUser := oresult.Data.(*model.User)
cm, err := AddUserToChannel(nUser, channel)
cm, err := app.AddUserToChannel(nUser, channel)
if err != nil {
c.Err = err
return
@@ -1061,7 +904,7 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
go PostUserAddRemoveMessage(c, channel.Id, fmt.Sprintf(utils.T("api.channel.add_member.added"), nUser.Username, oUser.Username), model.POST_ADD_REMOVE)
<-Srv.Store.Channel().UpdateLastViewedAt([]string{id}, oUser.Id)
<-app.Srv.Store.Channel().UpdateLastViewedAt([]string{id}, oUser.Id)
w.Write([]byte(cm.ToJson()))
}
}
@@ -1079,9 +922,9 @@ func removeMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
sc := Srv.Store.Channel().Get(channelId, true)
cmc := Srv.Store.Channel().GetMember(channelId, c.Session.UserId)
ouc := Srv.Store.User().Get(userIdToRemove)
sc := app.Srv.Store.Channel().Get(channelId, true)
cmc := app.Srv.Store.Channel().GetMember(channelId, c.Session.UserId)
ouc := app.Srv.Store.User().Get(userIdToRemove)
if oresult := <-ouc; oresult.Err != nil {
c.Err = model.NewLocAppError("removeMember", "api.channel.remove_member.user.app_error", nil, "")
@@ -1132,23 +975,23 @@ func RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel
return model.NewLocAppError("RemoveUserFromChannel", "api.channel.remove.default.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "")
}
if cmresult := <-Srv.Store.Channel().RemoveMember(channel.Id, userIdToRemove); cmresult.Err != nil {
if cmresult := <-app.Srv.Store.Channel().RemoveMember(channel.Id, userIdToRemove); cmresult.Err != nil {
return cmresult.Err
}
InvalidateCacheForUser(userIdToRemove)
InvalidateCacheForChannel(channel.Id)
app.InvalidateCacheForUser(userIdToRemove)
app.InvalidateCacheForChannel(channel.Id)
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", channel.Id, "", nil)
message.Add("user_id", userIdToRemove)
message.Add("remover_id", removerUserId)
go Publish(message)
go app.Publish(message)
// because the removed user no longer belongs to the channel we need to send a separate websocket event
userMsg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", "", userIdToRemove, nil)
userMsg.Add("channel_id", channel.Id)
userMsg.Add("remover_id", removerUserId)
go Publish(userMsg)
go app.Publish(userMsg)
return nil
}
@@ -1172,7 +1015,7 @@ func updateNotifyProps(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
result := <-Srv.Store.Channel().GetMember(channelId, userId)
result := <-app.Srv.Store.Channel().GetMember(channelId, userId)
if result.Err != nil {
c.Err = result.Err
return
@@ -1189,11 +1032,11 @@ func updateNotifyProps(c *Context, w http.ResponseWriter, r *http.Request) {
member.NotifyProps["desktop"] = desktop
}
if result := <-Srv.Store.Channel().UpdateMember(&member); result.Err != nil {
if result := <-app.Srv.Store.Channel().UpdateMember(&member); result.Err != nil {
c.Err = result.Err
return
} else {
InvalidateCacheForUser(userId)
app.InvalidateCacheForUser(userId)
// return the updated notify properties including any unchanged ones
w.Write([]byte(model.MapToJson(member.NotifyProps)))
@@ -1219,7 +1062,7 @@ func searchMoreChannels(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Channel().SearchMore(c.Session.UserId, c.TeamId, props.Term); result.Err != nil {
if result := <-app.Srv.Store.Channel().SearchMore(c.Session.UserId, c.TeamId, props.Term); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1239,7 +1082,7 @@ func autocompleteChannels(c *Context, w http.ResponseWriter, r *http.Request) {
var channels *model.ChannelList
if result := <-Srv.Store.Channel().SearchInTeam(c.TeamId, term); result.Err != nil {
if result := <-app.Srv.Store.Channel().SearchInTeam(c.TeamId, term); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1269,11 +1112,11 @@ func viewChannel(c *Context, w http.ResponseWriter, r *http.Request) {
channelIds = append(channelIds, view.PrevChannelId)
if *utils.Cfg.EmailSettings.SendPushNotifications && !c.Session.IsMobileApp() {
pchan = Srv.Store.User().GetUnreadCountForChannel(c.Session.UserId, view.ChannelId)
pchan = app.Srv.Store.User().GetUnreadCountForChannel(c.Session.UserId, view.ChannelId)
}
}
uchan := Srv.Store.Channel().UpdateLastViewedAt(channelIds, c.Session.UserId)
uchan := app.Srv.Store.Channel().UpdateLastViewedAt(channelIds, c.Session.UserId)
if pchan != nil {
if result := <-pchan; result.Err != nil {
@@ -1281,7 +1124,7 @@ func viewChannel(c *Context, w http.ResponseWriter, r *http.Request) {
return
} else {
if result.Data.(int64) > 0 {
clearPushNotification(c.Session.UserId, view.ChannelId)
app.ClearPushNotification(c.Session.UserId, view.ChannelId)
}
}
}
@@ -1293,7 +1136,7 @@ func viewChannel(c *Context, w http.ResponseWriter, r *http.Request) {
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, c.TeamId, "", c.Session.UserId, nil)
message.Add("channel_id", view.ChannelId)
go Publish(message)
go app.Publish(message)
ReturnStatusOK(w)
}
@@ -1312,7 +1155,7 @@ func getChannelMembersByIds(c *Context, w http.ResponseWriter, r *http.Request)
return
}
if result := <-Srv.Store.Channel().GetMembersByIds(channelId, userIds); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetMembersByIds(channelId, userIds); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1334,7 +1177,7 @@ func updateChannelMemberRoles(c *Context, w http.ResponseWriter, r *http.Request
return
}
mchan := Srv.Store.Channel().GetMember(channelId, userId)
mchan := app.Srv.Store.Channel().GetMember(channelId, userId)
newRoles := props["new_roles"]
if !(model.IsValidUserRoles(newRoles)) {
@@ -1356,12 +1199,12 @@ func updateChannelMemberRoles(c *Context, w http.ResponseWriter, r *http.Request
member.Roles = newRoles
if result := <-Srv.Store.Channel().UpdateMember(&member); result.Err != nil {
if result := <-app.Srv.Store.Channel().UpdateMember(&member); result.Err != nil {
c.Err = result.Err
return
}
InvalidateCacheForUser(userId)
app.InvalidateCacheForUser(userId)
rdata := map[string]string{}
rdata["status"] = "ok"

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

@@ -9,6 +9,7 @@ import (
"testing"
"time"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -1067,7 +1068,7 @@ func TestJoinChannelByNameDisabledUser(t *testing.T) {
Client.Must(th.BasicClient.RemoveUserFromTeam(th.BasicTeam.Id, th.BasicUser.Id))
if _, err := AddUserToChannel(th.BasicUser, channel1); err == nil {
if _, err := app.AddUserToChannel(th.BasicUser, channel1); err == nil {
t.Fatal("shoudn't be able to join channel")
} else {
if err.Id != "api.channel.add_user.to.channel.failed.deleted.app_error" {
@@ -1832,7 +1833,7 @@ func TestGetChannelByName(t *testing.T) {
user2 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Jabba the Hutt", Password: "passwd1"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
Client.SetTeamId(th.BasicTeam.Id)
@@ -1887,7 +1888,7 @@ func TestViewChannel(t *testing.T) {
func TestGetChannelMembersByIds(t *testing.T) {
th := Setup().InitBasic()
if _, err := AddUserToChannel(th.BasicUser2, th.BasicChannel); err != nil {
if _, err := app.AddUserToChannel(th.BasicUser2, th.BasicChannel); err != nil {
t.Fatal("Could not add second user to channel")
}

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

@@ -7,6 +7,7 @@ import (
"os/exec"
"testing"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -108,7 +109,7 @@ func TestCliCreateUserWithoutTeam(t *testing.T) {
t.Fatal(err)
}
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err != nil {
t.Fatal()
} else {
user := result.Data.(*model.User)
@@ -132,7 +133,7 @@ func TestCliAssignRole(t *testing.T) {
t.Fatal(err)
}
if result := <-Srv.Store.User().GetByEmail(th.BasicUser.Email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(th.BasicUser.Email); result.Err != nil {
t.Fatal()
} else {
user := result.Data.(*model.User)
@@ -370,7 +371,7 @@ func TestCliLeaveTeam(t *testing.T) {
t.Fatal("profile should not be on team")
}
if result := <-Srv.Store.Team().GetTeamsByUserId(th.BasicUser.Id); result.Err != nil {
if result := <-app.Srv.Store.Team().GetTeamsByUserId(th.BasicUser.Id); result.Err != nil {
teamMembers := result.Data.([]*model.TeamMember)
if len(teamMembers) > 0 {
t.Fatal("Shouldn't be in team")

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

@@ -13,6 +13,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -69,7 +70,7 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) {
}
if *utils.Cfg.ServiceSettings.EnableCommands {
if result := <-Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -119,11 +120,11 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
chanChan := Srv.Store.Channel().Get(commandArgs.ChannelId, true)
teamChan := Srv.Store.Team().Get(c.TeamId)
userChan := Srv.Store.User().Get(c.Session.UserId)
chanChan := app.Srv.Store.Channel().Get(commandArgs.ChannelId, true)
teamChan := app.Srv.Store.Team().Get(c.TeamId)
userChan := app.Srv.Store.User().Get(c.Session.UserId)
if result := <-Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -221,6 +222,7 @@ func handleResponse(c *Context, w http.ResponseWriter, response *model.CommandRe
post.ChannelId = commandArgs.ChannelId
post.RootId = commandArgs.RootId
post.ParentId = commandArgs.ParentId
post.UserId = c.Session.UserId
if !builtIn {
post.AddProp("from_webhook", "true")
@@ -246,7 +248,9 @@ func handleResponse(c *Context, w http.ResponseWriter, response *model.CommandRe
}
}
CreateCommandPost(c, post, response)
if _, err := app.CreateCommandPost(post, c.TeamId, response); err != nil {
l4g.Error(err.Error())
}
w.Write([]byte(response.ToJson()))
}
@@ -277,7 +281,7 @@ func createCommand(c *Context, w http.ResponseWriter, r *http.Request) {
cmd.CreatorId = c.Session.UserId
cmd.TeamId = c.TeamId
if result := <-Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -297,7 +301,7 @@ func createCommand(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if result := <-Srv.Store.Command().Save(cmd); result.Err != nil {
if result := <-app.Srv.Store.Command().Save(cmd); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -332,7 +336,7 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) {
cmd.Trigger = strings.ToLower(cmd.Trigger)
var oldCmd *model.Command
if result := <-Srv.Store.Command().Get(cmd.Id); result.Err != nil {
if result := <-app.Srv.Store.Command().Get(cmd.Id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -358,7 +362,7 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) {
cmd.TeamId = oldCmd.TeamId
}
if result := <-Srv.Store.Command().Update(cmd); result.Err != nil {
if result := <-app.Srv.Store.Command().Update(cmd); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -379,7 +383,7 @@ func listTeamCommands(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -412,7 +416,7 @@ func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) {
}
var cmd *model.Command
if result := <-Srv.Store.Command().Get(id); result.Err != nil {
if result := <-app.Srv.Store.Command().Get(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -427,7 +431,7 @@ func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) {
cmd.Token = model.NewId()
if result := <-Srv.Store.Command().Update(cmd); result.Err != nil {
if result := <-app.Srv.Store.Command().Update(cmd); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -458,7 +462,7 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Command().Get(id); result.Err != nil {
if result := <-app.Srv.Store.Command().Get(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -469,7 +473,7 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if err := (<-Srv.Store.Command().Delete(id, model.GetMillis())).Err; err != nil {
if err := (<-app.Srv.Store.Command().Delete(id, model.GetMillis())).Err; err != nil {
c.Err = err
return
}

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

@@ -4,6 +4,7 @@
package api
import (
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -36,7 +37,7 @@ func (me *AwayProvider) DoCommand(c *Context, args *model.CommandArgs, message s
if len(message) > 0 {
rmsg = message + " " + rmsg
}
SetStatusAwayIfNeeded(c.Session.UserId, true)
app.SetStatusAwayIfNeeded(c.Session.UserId, true)
return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: rmsg}
}

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

@@ -9,6 +9,7 @@ import (
"time"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -87,7 +88,7 @@ func (me *EchoProvider) DoCommand(c *Context, args *model.CommandArgs, message s
time.Sleep(time.Duration(delay) * time.Second)
if _, err := CreatePost(c, post, true); err != nil {
if _, err := app.CreatePost(post, c.TeamId, true); err != nil {
l4g.Error(c.T("api.command_echo.create.app_error"), err)
}
}()

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

@@ -6,6 +6,7 @@ package api
import (
"strconv"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -67,13 +68,13 @@ func setCollapsePreference(c *Context, isCollapse bool) *model.CommandResponse {
Value: strconv.FormatBool(isCollapse),
}
if result := <-Srv.Store.Preference().Save(&model.Preferences{pref}); result.Err != nil {
if result := <-app.Srv.Store.Preference().Save(&model.Preferences{pref}); result.Err != nil {
return &model.CommandResponse{Text: c.T("api.command_expand_collapse.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
socketMessage := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_PREFERENCE_CHANGED, "", "", c.Session.UserId, nil)
socketMessage.Add("preference", pref.ToJson())
go Publish(socketMessage)
go app.Publish(socketMessage)
var rmsg string

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

@@ -6,6 +6,7 @@ package api
import (
"strings"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -40,8 +41,8 @@ func (me *InvitePeopleProvider) DoCommand(c *Context, args *model.CommandArgs, m
return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: c.T("api.command.invite_people.email_off")}
}
tchan := Srv.Store.Team().Get(c.TeamId)
uchan := Srv.Store.User().Get(c.Session.UserId)
tchan := app.Srv.Store.Team().Get(c.TeamId)
uchan := app.Srv.Store.User().Get(c.Session.UserId)
emailList := strings.Fields(message)

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

@@ -4,6 +4,7 @@
package api
import (
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -33,7 +34,7 @@ func (me *JoinProvider) GetCommand(c *Context) *model.Command {
}
func (me *JoinProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse {
if result := <-Srv.Store.Channel().GetByName(c.TeamId, message); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetByName(c.TeamId, message); result.Err != nil {
return &model.CommandResponse{Text: c.T("api.command_join.list.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
} else {
channel := result.Data.(*model.Channel)

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

@@ -11,6 +11,7 @@ import (
"strings"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -185,7 +186,7 @@ func (me *LoadTestProvider) SetupCommand(c *Context, channelId string, message s
} else {
var team *model.Team
if tr := <-Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
if tr := <-app.Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
} else {
team = tr.Data.(*model.Team)
@@ -220,7 +221,7 @@ func (me *LoadTestProvider) UsersCommand(c *Context, channelId string, message s
}
var team *model.Team
if tr := <-Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
if tr := <-app.Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
} else {
team = tr.Data.(*model.Team)
@@ -250,7 +251,7 @@ func (me *LoadTestProvider) ChannelsCommand(c *Context, channelId string, messag
}
var team *model.Team
if tr := <-Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
if tr := <-app.Srv.Store.Team().Get(c.TeamId); tr.Err != nil {
return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
} else {
team = tr.Data.(*model.Team)
@@ -289,7 +290,7 @@ func (me *LoadTestProvider) PostsCommand(c *Context, channelId string, message s
}
var usernames []string
if result := <-Srv.Store.User().GetProfiles(c.TeamId, 0, 1000); result.Err == nil {
if result := <-app.Srv.Store.User().GetProfiles(c.TeamId, 0, 1000); result.Err == nil {
profileUsers := result.Data.(map[string]*model.User)
usernames = make([]string, len(profileUsers))
i := 0
@@ -358,7 +359,7 @@ func (me *LoadTestProvider) UrlCommand(c *Context, channelId string, message str
post.ChannelId = channelId
post.UserId = c.Session.UserId
if _, err := CreatePost(c, post, false); err != nil {
if _, err := app.CreatePost(post, c.TeamId, false); err != nil {
return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
}
@@ -397,7 +398,7 @@ func (me *LoadTestProvider) JsonCommand(c *Context, channelId string, message st
post.Message = message
}
if _, err := CreatePost(c, post, false); err != nil {
if _, err := app.CreatePost(post, c.TeamId, false); err != nil {
return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
return &model.CommandResponse{Text: "Loaded data", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}

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

@@ -6,6 +6,7 @@ package api
import (
"strings"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -48,7 +49,7 @@ func (me *msgProvider) DoCommand(c *Context, args *model.CommandArgs, message st
targetUsername = strings.TrimPrefix(targetUsername, "@")
var userProfile *model.User
if result := <-Srv.Store.User().GetByUsername(targetUsername); result.Err != nil {
if result := <-app.Srv.Store.User().GetByUsername(targetUsername); result.Err != nil {
c.Err = result.Err
return &model.CommandResponse{Text: c.T("api.command_msg.missing.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
} else {
@@ -63,7 +64,7 @@ func (me *msgProvider) DoCommand(c *Context, args *model.CommandArgs, message st
channelName := model.GetDMNameFromIds(c.Session.UserId, userProfile.Id)
targetChannelId := ""
if channel := <-Srv.Store.Channel().GetByName(c.TeamId, channelName); channel.Err != nil {
if channel := <-app.Srv.Store.Channel().GetByName(c.TeamId, channelName); channel.Err != nil {
if channel.Err.Id == "store.sql_channel.get_by_name.missing.app_error" {
if directChannel, err := CreateDirectChannel(c.Session.UserId, userProfile.Id); err != nil {
c.Err = err
@@ -79,13 +80,13 @@ func (me *msgProvider) DoCommand(c *Context, args *model.CommandArgs, message st
targetChannelId = channel.Data.(*model.Channel).Id
}
makeDirectChannelVisible(targetChannelId)
app.MakeDirectChannelVisible(targetChannelId)
if len(parsedMessage) > 0 {
post := &model.Post{}
post.Message = parsedMessage
post.ChannelId = targetChannelId
post.UserId = c.Session.UserId
if _, err := CreatePost(c, post, true); err != nil {
if _, err := app.CreatePost(post, c.TeamId, true); err != nil {
return &model.CommandResponse{Text: c.T("api.command_msg.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
}
}

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

@@ -4,6 +4,7 @@
package api
import (
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -36,7 +37,7 @@ func (me *OfflineProvider) DoCommand(c *Context, args *model.CommandArgs, messag
if len(message) > 0 {
rmsg = message + " " + rmsg
}
SetStatusOffline(c.Session.UserId, true)
app.SetStatusOffline(c.Session.UserId, true)
return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: rmsg}
}

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

@@ -4,6 +4,7 @@
package api
import (
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -36,7 +37,7 @@ func (me *OnlineProvider) DoCommand(c *Context, args *model.CommandArgs, message
if len(message) > 0 {
rmsg = message + " " + rmsg
}
SetStatusOnline(c.Session.UserId, c.Session.Id, true)
app.SetStatusOnline(c.Session.UserId, c.Session.Id, true)
return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: rmsg}
}

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

@@ -5,7 +5,6 @@ package api
import (
"fmt"
"net"
"net/http"
"net/url"
"strings"
@@ -15,23 +14,12 @@ import (
"github.com/gorilla/mux"
goi18n "github.com/nicksnyder/go-i18n/i18n"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
)
var sessionCache *utils.Cache = utils.NewLru(model.SESSION_CACHE_SIZE)
var allowedMethods []string = []string{
"POST",
"GET",
"OPTIONS",
"PUT",
"PATCH",
"DELETE",
}
type Context struct {
Session model.Session
RequestId string
@@ -116,7 +104,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := &Context{}
c.T, c.Locale = utils.GetTranslationsAndLocale(w, r)
c.RequestId = model.NewId()
c.IpAddress = GetIpAddress(r)
c.IpAddress = utils.GetIpAddress(r)
c.TeamId = mux.Vars(r)["team_id"]
token := ""
@@ -153,9 +141,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
isTokenFromQueryString = true
}
if *utils.Cfg.ServiceSettings.SiteURL != "" {
c.SetSiteURL(*utils.Cfg.ServiceSettings.SiteURL)
} else {
if utils.GetSiteURL() == "" {
protocol := GetProtocol(r)
c.SetSiteURL(protocol + "://" + r.Host)
}
@@ -180,9 +166,10 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
if len(token) != 0 {
session := GetSession(token)
session, err := app.GetSession(token)
if session == nil || session.IsExpired() {
if err != nil {
l4g.Error(utils.T("api.context.invalid_session.error"), err.Error())
c.RemoveSessionCookie(w, r)
if h.requireUser || h.requireSystemAdmin {
c.Err = model.NewLocAppError("ServeHTTP", "api.context.session_expired.app_error", nil, "token="+token)
@@ -218,7 +205,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
if c.Err == nil && h.isUserActivity && token != "" && len(c.Session.UserId) > 0 {
SetStatusOnline(c.Session.UserId, c.Session.Id, false)
app.SetStatusOnline(c.Session.UserId, c.Session.Id, false)
}
if c.Err == nil && (h.requireUser || h.requireSystemAdmin) {
@@ -269,31 +256,6 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}
func (cw *CorsWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if len(*utils.Cfg.ServiceSettings.AllowCorsFrom) > 0 {
origin := r.Header.Get("Origin")
if *utils.Cfg.ServiceSettings.AllowCorsFrom == "*" || strings.Contains(*utils.Cfg.ServiceSettings.AllowCorsFrom, origin) {
w.Header().Set("Access-Control-Allow-Origin", origin)
if r.Method == "OPTIONS" {
w.Header().Set(
"Access-Control-Allow-Methods",
strings.Join(allowedMethods, ", "))
w.Header().Set(
"Access-Control-Allow-Headers",
r.Header.Get("Access-Control-Request-Headers"))
}
}
}
if r.Method == "OPTIONS" {
return
}
cw.router.ServeHTTP(w, r)
}
func GetProtocol(r *http.Request) string {
if r.Header.Get(model.HEADER_FORWARDED_PROTO) == "https" {
return "https"
@@ -304,7 +266,7 @@ func GetProtocol(r *http.Request) string {
func (c *Context) LogAudit(extraInfo string) {
audit := &model.Audit{UserId: c.Session.UserId, IpAddress: c.IpAddress, Action: c.Path, ExtraInfo: extraInfo, SessionId: c.Session.Id}
if r := <-Srv.Store.Audit().Save(audit); r.Err != nil {
if r := <-app.Srv.Store.Audit().Save(audit); r.Err != nil {
c.LogError(r.Err)
}
}
@@ -316,7 +278,7 @@ func (c *Context) LogAuditWithUserId(userId, extraInfo string) {
}
audit := &model.Audit{UserId: userId, IpAddress: c.IpAddress, Action: c.Path, ExtraInfo: extraInfo, SessionId: c.Session.Id}
if r := <-Srv.Store.Audit().Save(audit); r.Err != nil {
if r := <-app.Srv.Store.Audit().Save(audit); r.Err != nil {
c.LogError(r.Err)
}
}
@@ -356,7 +318,7 @@ func (c *Context) MfaRequired() {
return
}
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
c.Err = model.NewLocAppError("", "api.context.session_expired.app_error", nil, "MfaRequired")
c.Err.StatusCode = http.StatusUnauthorized
return
@@ -422,7 +384,7 @@ func (c *Context) setTeamURL(url string, valid bool) {
}
func (c *Context) SetTeamURLFromSession() {
if result := <-Srv.Store.Team().Get(c.TeamId); result.Err == nil {
if result := <-app.Srv.Store.Team().Get(c.TeamId); result.Err == nil {
c.setTeamURL(c.GetSiteURL()+"/"+result.Data.(*model.Team).Name, true)
}
}
@@ -457,20 +419,6 @@ func IsApiCall(r *http.Request) bool {
return strings.Index(r.URL.Path, "/api/") == 0
}
func GetIpAddress(r *http.Request) string {
address := r.Header.Get(model.HEADER_FORWARDED)
if len(address) == 0 {
address = r.Header.Get(model.HEADER_REAL_IP)
}
if len(address) == 0 {
address, _, _ = net.SplitHostPort(r.RemoteAddr)
}
return address
}
func RenderWebError(err *model.AppError, w http.ResponseWriter, r *http.Request) {
T, _ := utils.GetTranslationsAndLocale(w, r)
@@ -501,7 +449,7 @@ func Handle404(w http.ResponseWriter, r *http.Request) {
err.Translate(utils.T)
err.StatusCode = http.StatusNotFound
l4g.Debug("%v: code=404 ip=%v", r.URL.Path, GetIpAddress(r))
l4g.Debug("%v: code=404 ip=%v", r.URL.Path, utils.GetIpAddress(r))
if IsApiCall(r) {
w.WriteHeader(err.StatusCode)
@@ -512,81 +460,10 @@ func Handle404(w http.ResponseWriter, r *http.Request) {
}
}
func GetSession(token string) *model.Session {
metrics := einterfaces.GetMetricsInterface()
var session *model.Session
if ts, ok := sessionCache.Get(token); ok {
session = ts.(*model.Session)
if metrics != nil {
metrics.IncrementMemCacheHitCounter("Session")
}
} else {
if metrics != nil {
metrics.IncrementMemCacheMissCounter("Session")
}
}
if session == nil {
if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err != nil {
l4g.Error(utils.T("api.context.invalid_token.error"), token, sessionResult.Err.DetailedError)
} else {
session = sessionResult.Data.(*model.Session)
if session.IsExpired() || session.Token != token {
return nil
} else {
AddSessionToCache(session)
return session
}
}
}
return session
}
func RemoveAllSessionsForUserId(userId string) {
RemoveAllSessionsForUserIdSkipClusterSend(userId)
if einterfaces.GetClusterInterface() != nil {
einterfaces.GetClusterInterface().RemoveAllSessionsForUserId(userId)
}
}
func RemoveAllSessionsForUserIdSkipClusterSend(userId string) {
keys := sessionCache.Keys()
for _, key := range keys {
if ts, ok := sessionCache.Get(key); ok {
session := ts.(*model.Session)
if session.UserId == userId {
sessionCache.Remove(key)
}
}
}
InvalidateWebConnSessionCacheForUser(userId)
}
func AddSessionToCache(session *model.Session) {
sessionCache.AddWithExpiresInSecs(session.Token, session, int64(*utils.Cfg.ServiceSettings.SessionCacheInMinutes*60))
}
func InvalidateAllCaches() {
l4g.Info(utils.T("api.context.invalidate_all_caches"))
sessionCache.Purge()
ClearStatusCache()
store.ClearChannelCaches()
store.ClearUserCaches()
store.ClearPostCaches()
}
func (c *Context) CheckTeamId() {
if c.TeamId != "" && c.Session.GetTeamByTeamId(c.TeamId) == nil {
if HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
if result := <-Srv.Store.Team().Get(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Team().Get(c.TeamId); result.Err != nil {
c.Err = result.Err
c.Err.StatusCode = http.StatusBadRequest
return

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

@@ -4,32 +4,9 @@
package api
import (
"github.com/mattermost/platform/model"
"testing"
)
func TestCache(t *testing.T) {
session := &model.Session{
Id: model.NewId(),
Token: model.NewId(),
UserId: model.NewId(),
}
sessionCache.AddWithExpiresInSecs(session.Token, session, 5*60)
keys := sessionCache.Keys()
if len(keys) <= 0 {
t.Fatal("should have items")
}
RemoveAllSessionsForUserId(session.UserId)
rkeys := sessionCache.Keys()
if len(rkeys) != len(keys)-1 {
t.Fatal("should have one less")
}
}
func TestSiteURL(t *testing.T) {
c := &Context{}

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

@@ -8,6 +8,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -35,7 +36,7 @@ func getMoreChannels(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Channel().GetMoreChannels(c.TeamId, c.Session.UserId, 0, 100000); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetMoreChannels(c.TeamId, c.Session.UserId, 0, 100000); result.Err != nil {
c.Err = result.Err
return
} else if HandleEtag(result.Data.(*model.ChannelList).Etag(), "Get More Channels (deprecated)", w, r) {
@@ -61,7 +62,7 @@ func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
doClearPush := false
if *utils.Cfg.EmailSettings.SendPushNotifications && !c.Session.IsMobileApp() && active {
if result := <-Srv.Store.User().GetUnreadCountForChannel(c.Session.UserId, id); result.Err != nil {
if result := <-app.Srv.Store.User().GetUnreadCountForChannel(c.Session.UserId, id); result.Err != nil {
l4g.Error(utils.T("api.channel.update_last_viewed_at.get_unread_count_for_channel.error"), c.Session.UserId, id, result.Err.Error())
} else {
if result.Data.(int64) > 0 {
@@ -76,11 +77,11 @@ func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
}
}()
Srv.Store.Channel().UpdateLastViewedAt([]string{id}, c.Session.UserId)
app.Srv.Store.Channel().UpdateLastViewedAt([]string{id}, c.Session.UserId)
// Must be after update so that unread count is correct
if doClearPush {
go clearPushNotification(c.Session.UserId, id)
go app.ClearPushNotification(c.Session.UserId, id)
}
chanPref := model.Preference{
@@ -97,12 +98,12 @@ func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
Value: c.TeamId,
}
Srv.Store.Preference().Save(&model.Preferences{teamPref, chanPref})
app.Srv.Store.Preference().Save(&model.Preferences{teamPref, chanPref})
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, c.TeamId, "", c.Session.UserId, nil)
message.Add("channel_id", id)
go Publish(message)
go app.Publish(message)
result := make(map[string]string)
result["id"] = id
@@ -116,7 +117,7 @@ func setLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
data := model.StringInterfaceFromJson(r.Body)
newLastViewedAt := int64(data["last_viewed_at"].(float64))
Srv.Store.Channel().SetLastViewedAt(id, c.Session.UserId, newLastViewedAt)
app.Srv.Store.Channel().SetLastViewedAt(id, c.Session.UserId, newLastViewedAt)
chanPref := model.Preference{
UserId: c.Session.UserId,
@@ -132,12 +133,12 @@ func setLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
Value: c.TeamId,
}
Srv.Store.Preference().Save(&model.Preferences{teamPref, chanPref})
app.Srv.Store.Preference().Save(&model.Preferences{teamPref, chanPref})
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, c.TeamId, "", c.Session.UserId, nil)
message.Add("channel_id", id)
go Publish(message)
go app.Publish(message)
result := make(map[string]string)
result["id"] = id

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

@@ -1,252 +0,0 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
"database/sql"
"fmt"
"html/template"
"strconv"
"time"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
l4g "github.com/alecthomas/log4go"
"github.com/nicksnyder/go-i18n/i18n"
)
const (
EMAIL_BATCHING_TASK_NAME = "Email Batching"
)
var emailBatchingJob *EmailBatchingJob
func InitEmailBatching() {
if *utils.Cfg.EmailSettings.EnableEmailBatching {
if emailBatchingJob == nil {
emailBatchingJob = MakeEmailBatchingJob(*utils.Cfg.EmailSettings.EmailBatchingBufferSize)
}
// note that we don't support changing EmailBatchingBufferSize without restarting the server
emailBatchingJob.Start()
}
}
func AddNotificationEmailToBatch(user *model.User, post *model.Post, team *model.Team) *model.AppError {
if !*utils.Cfg.EmailSettings.EnableEmailBatching {
return model.NewLocAppError("AddNotificationEmailToBatch", "api.email_batching.add_notification_email_to_batch.disabled.app_error", nil, "")
}
if !emailBatchingJob.Add(user, post, team) {
l4g.Error(utils.T("api.email_batching.add_notification_email_to_batch.channel_full.app_error"))
return model.NewLocAppError("AddNotificationEmailToBatch", "api.email_batching.add_notification_email_to_batch.channel_full.app_error", nil, "")
}
return nil
}
type batchedNotification struct {
userId string
post *model.Post
teamName string
}
type EmailBatchingJob struct {
newNotifications chan *batchedNotification
pendingNotifications map[string][]*batchedNotification
}
func MakeEmailBatchingJob(bufferSize int) *EmailBatchingJob {
return &EmailBatchingJob{
newNotifications: make(chan *batchedNotification, bufferSize),
pendingNotifications: make(map[string][]*batchedNotification),
}
}
func (job *EmailBatchingJob) Start() {
if task := model.GetTaskByName(EMAIL_BATCHING_TASK_NAME); task != nil {
task.Cancel()
}
l4g.Debug(utils.T("api.email_batching.start.starting"), *utils.Cfg.EmailSettings.EmailBatchingInterval)
model.CreateRecurringTask(EMAIL_BATCHING_TASK_NAME, job.CheckPendingEmails, time.Duration(*utils.Cfg.EmailSettings.EmailBatchingInterval)*time.Second)
}
func (job *EmailBatchingJob) Add(user *model.User, post *model.Post, team *model.Team) bool {
notification := &batchedNotification{
userId: user.Id,
post: post,
teamName: team.Name,
}
select {
case job.newNotifications <- notification:
return true
default:
// return false if we couldn't queue the email notification so that we can send an immediate email
return false
}
}
func (job *EmailBatchingJob) CheckPendingEmails() {
job.handleNewNotifications()
// it's a bit weird to pass the send email function through here, but it makes it so that we can test
// without actually sending emails
job.checkPendingNotifications(time.Now(), sendBatchedEmailNotification)
l4g.Debug(utils.T("api.email_batching.check_pending_emails.finished_running"), len(job.pendingNotifications))
}
func (job *EmailBatchingJob) handleNewNotifications() {
receiving := true
// read in new notifications to send
for receiving {
select {
case notification := <-job.newNotifications:
userId := notification.userId
if _, ok := job.pendingNotifications[userId]; !ok {
job.pendingNotifications[userId] = []*batchedNotification{notification}
} else {
job.pendingNotifications[userId] = append(job.pendingNotifications[userId], notification)
}
default:
receiving = false
}
}
}
func (job *EmailBatchingJob) checkPendingNotifications(now time.Time, handler func(string, []*batchedNotification)) {
// look for users who've acted since pending posts were received
for userId, notifications := range job.pendingNotifications {
schan := Srv.Store.Status().Get(userId)
pchan := Srv.Store.Preference().Get(userId, model.PREFERENCE_CATEGORY_NOTIFICATIONS, model.PREFERENCE_NAME_EMAIL_INTERVAL)
batchStartTime := notifications[0].post.CreateAt
// check if the user has been active and would've seen any new posts
if result := <-schan; result.Err != nil {
l4g.Error(utils.T("api.email_batching.check_pending_emails.status.app_error"), result.Err)
delete(job.pendingNotifications, userId)
continue
} else if status := result.Data.(*model.Status); status.LastActivityAt >= batchStartTime {
delete(job.pendingNotifications, userId)
continue
}
// get how long we need to wait to send notifications to the user
var interval int64
if result := <-pchan; result.Err != nil {
// default to 30 seconds to match the send "immediate" setting
interval, _ = strconv.ParseInt(model.PREFERENCE_DEFAULT_EMAIL_INTERVAL, 10, 64)
} else {
preference := result.Data.(model.Preference)
if value, err := strconv.ParseInt(preference.Value, 10, 64); err != nil {
interval, _ = strconv.ParseInt(model.PREFERENCE_DEFAULT_EMAIL_INTERVAL, 10, 64)
} else {
interval = value
}
}
// send the email notification if it's been long enough
if now.Sub(time.Unix(batchStartTime/1000, 0)) > time.Duration(interval)*time.Second {
go handler(userId, notifications)
delete(job.pendingNotifications, userId)
}
}
}
func sendBatchedEmailNotification(userId string, notifications []*batchedNotification) {
uchan := Srv.Store.User().Get(userId)
pchan := Srv.Store.Preference().Get(userId, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_DISPLAY_NAME_FORMAT)
var user *model.User
if result := <-uchan; result.Err != nil {
l4g.Warn("api.email_batching.send_batched_email_notification.user.app_error")
return
} else {
user = result.Data.(*model.User)
}
translateFunc := utils.GetUserTranslations(user.Locale)
var displayNameFormat string
if result := <-pchan; result.Err != nil && result.Err.DetailedError != sql.ErrNoRows.Error() {
l4g.Warn("api.email_batching.send_batched_email_notification.preferences.app_error")
return
} else if result.Err != nil {
// no display name format saved, so fall back to default
displayNameFormat = model.PREFERENCE_DEFAULT_DISPLAY_NAME_FORMAT
} else {
displayNameFormat = result.Data.(model.Preference).Value
}
var contents string
for _, notification := range notifications {
template := utils.NewHTMLTemplate("post_batched_post", user.Locale)
contents += renderBatchedPost(template, notification.post, notification.teamName, displayNameFormat, translateFunc)
}
tm := time.Unix(notifications[0].post.CreateAt/1000, 0)
subject := translateFunc("api.email_batching.send_batched_email_notification.subject", len(notifications), map[string]interface{}{
"SiteName": utils.Cfg.TeamSettings.SiteName,
"Year": tm.Year(),
"Month": translateFunc(tm.Month().String()),
"Day": tm.Day(),
})
body := utils.NewHTMLTemplate("post_batched_body", user.Locale)
body.Props["SiteURL"] = *utils.Cfg.ServiceSettings.SiteURL
body.Props["Posts"] = template.HTML(contents)
body.Props["BodyText"] = translateFunc("api.email_batching.send_batched_email_notification.body_text", len(notifications))
if err := utils.SendMail(user.Email, subject, body.Render()); err != nil {
l4g.Warn(utils.T("api.email_batchings.send_batched_email_notification.send.app_error"), user.Email, err)
}
}
func renderBatchedPost(template *utils.HTMLTemplate, post *model.Post, teamName string, displayNameFormat string, translateFunc i18n.TranslateFunc) string {
schan := Srv.Store.User().Get(post.UserId)
cchan := Srv.Store.Channel().Get(post.ChannelId, true)
template.Props["Button"] = translateFunc("api.email_batching.render_batched_post.go_to_post")
template.Props["PostMessage"] = getMessageForNotification(post, translateFunc)
template.Props["PostLink"] = *utils.Cfg.ServiceSettings.SiteURL + "/" + teamName + "/pl/" + post.Id
tm := time.Unix(post.CreateAt/1000, 0)
timezone, _ := tm.Zone()
template.Props["Date"] = translateFunc("api.email_batching.render_batched_post.date", map[string]interface{}{
"Year": tm.Year(),
"Month": translateFunc(tm.Month().String()),
"Day": tm.Day(),
"Hour": tm.Hour(),
"Minute": fmt.Sprintf("%02d", tm.Minute()),
"Timezone": timezone,
})
if result := <-schan; result.Err != nil {
l4g.Warn(utils.T("api.email_batching.render_batched_post.sender.app_error"))
return ""
} else {
template.Props["SenderName"] = result.Data.(*model.User).GetDisplayNameForPreference(displayNameFormat)
}
if result := <-cchan; result.Err != nil {
l4g.Warn(utils.T("api.email_batching.render_batched_post.channel.app_error"))
return ""
} else if channel := result.Data.(*model.Channel); channel.Type == model.CHANNEL_DIRECT {
template.Props["ChannelName"] = translateFunc("api.email_batching.render_batched_post.direct_message")
} else {
template.Props["ChannelName"] = channel.DisplayName
}
return template.Render()
}

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

@@ -1,193 +0,0 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
"testing"
"time"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
)
func TestHandleNewNotifications(t *testing.T) {
Setup()
id1 := model.NewId()
id2 := model.NewId()
id3 := model.NewId()
// test queueing of received posts by user
job := MakeEmailBatchingJob(128)
job.handleNewNotifications()
if len(job.pendingNotifications) != 0 {
t.Fatal("shouldn't have added any pending notifications")
}
job.Add(&model.User{Id: id1}, &model.Post{UserId: id1, Message: "test"}, &model.Team{Name: "team"})
if len(job.pendingNotifications) != 0 {
t.Fatal("shouldn't have added any pending notifications")
}
job.handleNewNotifications()
if len(job.pendingNotifications) != 1 {
t.Fatal("should have received posts for 1 user")
} else if len(job.pendingNotifications[id1]) != 1 {
t.Fatal("should have received 1 post for user")
}
job.Add(&model.User{Id: id1}, &model.Post{UserId: id1, Message: "test"}, &model.Team{Name: "team"})
job.handleNewNotifications()
if len(job.pendingNotifications) != 1 {
t.Fatal("should have received posts for 1 user")
} else if len(job.pendingNotifications[id1]) != 2 {
t.Fatal("should have received 2 posts for user1", job.pendingNotifications[id1])
}
job.Add(&model.User{Id: id2}, &model.Post{UserId: id1, Message: "test"}, &model.Team{Name: "team"})
job.handleNewNotifications()
if len(job.pendingNotifications) != 2 {
t.Fatal("should have received posts for 2 users")
} else if len(job.pendingNotifications[id1]) != 2 {
t.Fatal("should have received 2 posts for user1")
} else if len(job.pendingNotifications[id2]) != 1 {
t.Fatal("should have received 1 post for user2")
}
job.Add(&model.User{Id: id2}, &model.Post{UserId: id2, Message: "test"}, &model.Team{Name: "team"})
job.Add(&model.User{Id: id1}, &model.Post{UserId: id3, Message: "test"}, &model.Team{Name: "team"})
job.Add(&model.User{Id: id3}, &model.Post{UserId: id3, Message: "test"}, &model.Team{Name: "team"})
job.Add(&model.User{Id: id2}, &model.Post{UserId: id2, Message: "test"}, &model.Team{Name: "team"})
job.handleNewNotifications()
if len(job.pendingNotifications) != 3 {
t.Fatal("should have received posts for 3 users")
} else if len(job.pendingNotifications[id1]) != 3 {
t.Fatal("should have received 3 posts for user1")
} else if len(job.pendingNotifications[id2]) != 3 {
t.Fatal("should have received 3 posts for user2")
} else if len(job.pendingNotifications[id3]) != 1 {
t.Fatal("should have received 1 post for user3")
}
// test ordering of received posts
job = MakeEmailBatchingJob(128)
job.Add(&model.User{Id: id1}, &model.Post{UserId: id1, Message: "test1"}, &model.Team{Name: "team"})
job.Add(&model.User{Id: id1}, &model.Post{UserId: id1, Message: "test2"}, &model.Team{Name: "team"})
job.Add(&model.User{Id: id2}, &model.Post{UserId: id1, Message: "test3"}, &model.Team{Name: "team"})
job.Add(&model.User{Id: id1}, &model.Post{UserId: id1, Message: "test4"}, &model.Team{Name: "team"})
job.Add(&model.User{Id: id2}, &model.Post{UserId: id1, Message: "test5"}, &model.Team{Name: "team"})
job.handleNewNotifications()
if job.pendingNotifications[id1][0].post.Message != "test1" ||
job.pendingNotifications[id1][1].post.Message != "test2" ||
job.pendingNotifications[id1][2].post.Message != "test4" {
t.Fatal("incorrect order of received posts for user1")
} else if job.pendingNotifications[id2][0].post.Message != "test3" ||
job.pendingNotifications[id2][1].post.Message != "test5" {
t.Fatal("incorrect order of received posts for user2")
}
}
func TestCheckPendingNotifications(t *testing.T) {
Setup()
id1 := model.NewId()
job := MakeEmailBatchingJob(128)
job.pendingNotifications[id1] = []*batchedNotification{
{
post: &model.Post{
UserId: id1,
CreateAt: 10000000,
},
},
}
store.Must(Srv.Store.Status().SaveOrUpdate(&model.Status{
UserId: id1,
LastActivityAt: 9999000,
}))
store.Must(Srv.Store.Preference().Save(&model.Preferences{{
UserId: id1,
Category: model.PREFERENCE_CATEGORY_NOTIFICATIONS,
Name: model.PREFERENCE_NAME_EMAIL_INTERVAL,
Value: "60",
}}))
// test that notifications aren't sent before interval
job.checkPendingNotifications(time.Unix(10001, 0), func(string, []*batchedNotification) {})
if job.pendingNotifications[id1] == nil || len(job.pendingNotifications[id1]) != 1 {
t.Fatal("should'nt have sent queued post")
}
// test that notifications are cleared if the user has acted
store.Must(Srv.Store.Status().SaveOrUpdate(&model.Status{
UserId: id1,
LastActivityAt: 10001000,
}))
job.checkPendingNotifications(time.Unix(10002, 0), func(string, []*batchedNotification) {})
if job.pendingNotifications[id1] != nil && len(job.pendingNotifications[id1]) != 0 {
t.Fatal("should've remove queued post since user acted")
}
// test that notifications are sent if enough time passes since the first message
job.pendingNotifications[id1] = []*batchedNotification{
{
post: &model.Post{
UserId: id1,
CreateAt: 10060000,
Message: "post1",
},
},
{
post: &model.Post{
UserId: id1,
CreateAt: 10090000,
Message: "post2",
},
},
}
received := make(chan *model.Post, 2)
timeout := make(chan bool)
job.checkPendingNotifications(time.Unix(10130, 0), func(s string, notifications []*batchedNotification) {
for _, notification := range notifications {
received <- notification.post
}
})
go func() {
// start a timeout to make sure that we don't get stuck here on a failed test
time.Sleep(5 * time.Second)
timeout <- true
}()
if job.pendingNotifications[id1] != nil && len(job.pendingNotifications[id1]) != 0 {
t.Fatal("should've remove queued posts when sending messages")
}
select {
case post := <-received:
if post.Message != "post1" {
t.Fatal("should've received post1 first")
}
case _ = <-timeout:
t.Fatal("timed out waiting for first post notification")
}
select {
case post := <-received:
if post.Message != "post2" {
t.Fatal("should've received post2 second")
}
case _ = <-timeout:
t.Fatal("timed out waiting for second post notification")
}
}

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

@@ -18,6 +18,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/disintegration/imaging"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
@@ -46,7 +47,7 @@ func getEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Emoji().GetAll(); result.Err != nil {
if result := <-app.Srv.Store.Emoji().GetAll(); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -114,7 +115,7 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Emoji().GetByName(emoji.Name); result.Err == nil && result.Data != nil {
if result := <-app.Srv.Store.Emoji().GetByName(emoji.Name); result.Err == nil && result.Data != nil {
c.Err = model.NewLocAppError("createEmoji", "api.emoji.create.duplicate.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
return
@@ -128,7 +129,7 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Emoji().Save(emoji); result.Err != nil {
if result := <-app.Srv.Store.Emoji().Save(emoji); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -210,7 +211,7 @@ func deleteEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
}
var emoji *model.Emoji
if result := <-Srv.Store.Emoji().Get(id); result.Err != nil {
if result := <-app.Srv.Store.Emoji().Get(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -223,7 +224,7 @@ func deleteEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if err := (<-Srv.Store.Emoji().Delete(id, model.GetMillis())).Err; err != nil {
if err := (<-app.Srv.Store.Emoji().Delete(id, model.GetMillis())).Err; err != nil {
c.Err = err
return
}
@@ -241,7 +242,7 @@ func deleteEmojiImage(id string) {
}
func deleteReactionsForEmoji(emojiName string) {
if result := <-Srv.Store.Reaction().DeleteAllWithEmojiName(emojiName); result.Err != nil {
if result := <-app.Srv.Store.Reaction().DeleteAllWithEmojiName(emojiName); result.Err != nil {
l4g.Warn(utils.T("api.emoji.delete.delete_reactions.app_error"), emojiName)
l4g.Warn(result.Err)
}
@@ -268,7 +269,7 @@ func getEmojiImage(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Emoji().Get(id); result.Err != nil {
if result := <-app.Srv.Store.Emoji().Get(id); result.Err != nil {
c.Err = result.Err
return
} else {

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

@@ -13,6 +13,7 @@ import (
"testing"
"time"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -44,11 +45,11 @@ func TestGetEmoji(t *testing.T) {
}
for i, emoji := range emojis {
emojis[i] = store.Must(Srv.Store.Emoji().Save(emoji)).(*model.Emoji)
emojis[i] = store.Must(app.Srv.Store.Emoji().Save(emoji)).(*model.Emoji)
}
defer func() {
for _, emoji := range emojis {
store.Must(Srv.Store.Emoji().Delete(emoji.Id, time.Now().Unix()))
store.Must(app.Srv.Store.Emoji().Delete(emoji.Id, time.Now().Unix()))
}
}()
@@ -76,7 +77,7 @@ func TestGetEmoji(t *testing.T) {
Name: model.NewId(),
DeleteAt: 1,
}
deleted = store.Must(Srv.Store.Emoji().Save(deleted)).(*model.Emoji)
deleted = store.Must(app.Srv.Store.Emoji().Save(deleted)).(*model.Emoji)
if returnedEmojis, err := Client.ListEmoji(); err != nil {
t.Fatal(err)
@@ -314,10 +315,10 @@ func createTestPng(t *testing.T, width int, height int) []byte {
}
func createTestEmoji(t *testing.T, emoji *model.Emoji, imageData []byte) *model.Emoji {
emoji = store.Must(Srv.Store.Emoji().Save(emoji)).(*model.Emoji)
emoji = store.Must(app.Srv.Store.Emoji().Save(emoji)).(*model.Emoji)
if err := WriteFile(imageData, "emoji/"+emoji.Id+"/image"); err != nil {
store.Must(Srv.Store.Emoji().Delete(emoji.Id, time.Now().Unix()))
store.Must(app.Srv.Store.Emoji().Delete(emoji.Id, time.Now().Unix()))
t.Fatalf("failed to write image: %v", err.Error())
}

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

@@ -27,6 +27,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/disintegration/imaging"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"github.com/rwcarlsen/goexif/exif"
@@ -185,7 +186,7 @@ func doUploadFile(teamId string, channelId string, userId string, rawFilename st
return nil, err
}
if result := <-Srv.Store.FileInfo().Save(info); result.Err != nil {
if result := <-app.Srv.Store.FileInfo().Save(info); result.Err != nil {
return nil, result.Err
}
@@ -436,7 +437,7 @@ func getFileInfoForRequest(c *Context, r *http.Request, requireFileVisible bool)
}
var info *model.FileInfo
if result := <-Srv.Store.FileInfo().Get(fileId); result.Err != nil {
if result := <-app.Srv.Store.FileInfo().Get(fileId); result.Err != nil {
return nil, result.Err
} else {
info = result.Data.(*model.FileInfo)
@@ -497,7 +498,7 @@ func getPublicFileOld(c *Context, w http.ResponseWriter, r *http.Request) {
path := "teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/" + filename
var info *model.FileInfo
if result := <-Srv.Store.FileInfo().GetByPath(path); result.Err != nil {
if result := <-app.Srv.Store.FileInfo().GetByPath(path); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -584,7 +585,7 @@ func migrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo {
return []*model.FileInfo{}
}
cchan := Srv.Store.Channel().Get(post.ChannelId, true)
cchan := app.Srv.Store.Channel().Get(post.ChannelId, true)
// There's a weird bug that rarely happens where a post ends up with duplicate Filenames so remove those
filenames := utils.RemoveDuplicatesFromStringArray(post.Filenames)
@@ -625,12 +626,12 @@ func migrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo {
fileMigrationLock.Lock()
defer fileMigrationLock.Unlock()
if result := <-Srv.Store.Post().Get(post.Id); result.Err != nil {
if result := <-app.Srv.Store.Post().Get(post.Id); result.Err != nil {
l4g.Error(utils.T("api.file.migrate_filenames_to_file_infos.get_post_again.app_error"), post.Id, result.Err)
return []*model.FileInfo{}
} else if newPost := result.Data.(*model.PostList).Posts[post.Id]; len(newPost.Filenames) != len(post.Filenames) {
// Another thread has already created FileInfos for this post, so just return those
if result := <-Srv.Store.FileInfo().GetForPost(post.Id); result.Err != nil {
if result := <-app.Srv.Store.FileInfo().GetForPost(post.Id); result.Err != nil {
l4g.Error(utils.T("api.file.migrate_filenames_to_file_infos.get_post_file_infos_again.app_error"), post.Id, result.Err)
return []*model.FileInfo{}
} else {
@@ -644,7 +645,7 @@ func migrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo {
savedInfos := make([]*model.FileInfo, 0, len(infos))
fileIds := make([]string, 0, len(filenames))
for _, info := range infos {
if result := <-Srv.Store.FileInfo().Save(info); result.Err != nil {
if result := <-app.Srv.Store.FileInfo().Save(info); result.Err != nil {
l4g.Error(utils.T("api.file.migrate_filenames_to_file_infos.save_file_info.app_error"), post.Id, info.Id, info.Path, result.Err)
continue
}
@@ -661,7 +662,7 @@ func migrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo {
newPost.FileIds = fileIds
// Update Posts to clear Filenames and set FileIds
if result := <-Srv.Store.Post().Update(newPost, post); result.Err != nil {
if result := <-app.Srv.Store.Post().Update(newPost, post); result.Err != nil {
l4g.Error(utils.T("api.file.migrate_filenames_to_file_infos.save_post.app_error"), post.Id, newPost.FileIds, post.Filenames, result.Err)
return []*model.FileInfo{}
} else {
@@ -675,7 +676,7 @@ func findTeamIdForFilename(post *model.Post, filename string) string {
name, _ := url.QueryUnescape(split[4])
// This post is in a direct channel so we need to figure out what team the files are stored under.
if result := <-Srv.Store.Team().GetTeamsByUserId(post.UserId); result.Err != nil {
if result := <-app.Srv.Store.Team().GetTeamsByUserId(post.UserId); result.Err != nil {
l4g.Error(utils.T("api.file.migrate_filenames_to_file_infos.teams.app_error"), post.Id, result.Err)
} else if teams := result.Data.([]*model.Team); len(teams) == 1 {
// The user has only one team so the post must've been sent from it

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

@@ -14,6 +14,7 @@ import (
"testing"
"time"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -59,7 +60,7 @@ func TestUploadFile(t *testing.T) {
}
var info *model.FileInfo
if result := <-Srv.Store.FileInfo().Get(uploadInfo.Id); result.Err != nil {
if result := <-app.Srv.Store.FileInfo().Get(uploadInfo.Id); result.Err != nil {
t.Fatal(result.Err)
} else {
info = result.Data.(*model.FileInfo)
@@ -154,7 +155,7 @@ func TestGetFileInfo(t *testing.T) {
}
// Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
store.Must(app.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
// Other user shouldn't be able to get file info for this file if they're not in the channel for it
if _, err := Client.GetFileInfo(fileId); err == nil {
@@ -170,7 +171,7 @@ func TestGetFileInfo(t *testing.T) {
t.Fatal("other user got incorrect file")
}
if err := cleanupTestFile(store.Must(Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
if err := cleanupTestFile(store.Must(app.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
t.Fatal(err)
}
}
@@ -223,7 +224,7 @@ func TestGetFile(t *testing.T) {
}
// Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
store.Must(app.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
// Other user shouldn't be able to get file for this file if they're not in the channel for it
if _, err := Client.GetFile(fileId); err == nil {
@@ -252,7 +253,7 @@ func TestGetFile(t *testing.T) {
body.Close()
}
if err := cleanupTestFile(store.Must(Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
if err := cleanupTestFile(store.Must(app.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
t.Fatal(err)
}
}
@@ -292,7 +293,7 @@ func TestGetFileThumbnail(t *testing.T) {
}
// Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
store.Must(app.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
// Other user shouldn't be able to get thumbnail for this file if they're not in the channel for it
if _, err := Client.GetFileThumbnail(fileId); err == nil {
@@ -308,7 +309,7 @@ func TestGetFileThumbnail(t *testing.T) {
body.Close()
}
if err := cleanupTestFile(store.Must(Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
if err := cleanupTestFile(store.Must(app.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
t.Fatal(err)
}
}
@@ -348,7 +349,7 @@ func TestGetFilePreview(t *testing.T) {
}
// Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
store.Must(app.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
// Other user shouldn't be able to get preview for this file if they're not in the channel for it
if _, err := Client.GetFilePreview(fileId); err == nil {
@@ -364,7 +365,7 @@ func TestGetFilePreview(t *testing.T) {
body.Close()
}
if err := cleanupTestFile(store.Must(Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
if err := cleanupTestFile(store.Must(app.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
t.Fatal(err)
}
}
@@ -397,7 +398,7 @@ func TestGetPublicFile(t *testing.T) {
}
// Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
store.Must(app.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
link := Client.MustGeneric(Client.GetPublicLink(fileId)).(string)
@@ -430,7 +431,7 @@ func TestGetPublicFile(t *testing.T) {
t.Fatal("should've failed to get image with public link after salt changed")
}
if err := cleanupTestFile(store.Must(Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
if err := cleanupTestFile(store.Must(app.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
t.Fatal(err)
}
}
@@ -463,7 +464,7 @@ func TestGetPublicFileOld(t *testing.T) {
}
// Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
store.Must(app.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
// reconstruct old style of link
siteURL := *utils.Cfg.ServiceSettings.SiteURL
@@ -501,7 +502,7 @@ func TestGetPublicFileOld(t *testing.T) {
t.Fatal("should've failed to get image with public link after salt changed")
}
if err := cleanupTestFile(store.Must(Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
if err := cleanupTestFile(store.Must(app.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
t.Fatal(err)
}
}
@@ -540,7 +541,7 @@ func TestGetPublicLink(t *testing.T) {
}
// Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
store.Must(app.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id))
utils.Cfg.FileSettings.EnablePublicLink = false
@@ -575,7 +576,7 @@ func TestGetPublicLink(t *testing.T) {
// Wait a bit for files to ready
time.Sleep(2 * time.Second)
if err := cleanupTestFile(store.Must(Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
if err := cleanupTestFile(store.Must(app.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil {
t.Fatal(err)
}
}
@@ -631,7 +632,7 @@ func TestMigrateFilenamesToFileInfos(t *testing.T) {
}
// Bypass the Client whenever possible since we're trying to simulate a pre-3.5 post
post1 := store.Must(Srv.Store.Post().Save(&model.Post{
post1 := store.Must(app.Srv.Store.Post().Save(&model.Post{
UserId: user1.Id,
ChannelId: channel1.Id,
Message: "test",
@@ -732,7 +733,7 @@ func TestFindTeamIdForFilename(t *testing.T) {
}
// Bypass the Client whenever possible since we're trying to simulate a pre-3.5 post
post1 := store.Must(Srv.Store.Post().Save(&model.Post{
post1 := store.Must(app.Srv.Store.Post().Save(&model.Post{
UserId: user1.Id,
ChannelId: channel1.Id,
Message: "test",
@@ -744,7 +745,7 @@ func TestFindTeamIdForFilename(t *testing.T) {
}
Client.SetTeamId(team2.Id)
post2 := store.Must(Srv.Store.Post().Save(&model.Post{
post2 := store.Must(app.Srv.Store.Post().Save(&model.Post{
UserId: user1.Id,
ChannelId: channel2.Id,
Message: "test",
@@ -781,13 +782,13 @@ func TestGetInfoForFilename(t *testing.T) {
t.Fatal(err)
} else {
fileId1 = Client.MustGeneric(Client.UploadPostAttachment(data, channel1.Id, "test.png")).(*model.FileUploadResponse).FileInfos[0].Id
path = store.Must(Srv.Store.FileInfo().Get(fileId1)).(*model.FileInfo).Path
thumbnailPath = store.Must(Srv.Store.FileInfo().Get(fileId1)).(*model.FileInfo).ThumbnailPath
previewPath = store.Must(Srv.Store.FileInfo().Get(fileId1)).(*model.FileInfo).PreviewPath
path = store.Must(app.Srv.Store.FileInfo().Get(fileId1)).(*model.FileInfo).Path
thumbnailPath = store.Must(app.Srv.Store.FileInfo().Get(fileId1)).(*model.FileInfo).ThumbnailPath
previewPath = store.Must(app.Srv.Store.FileInfo().Get(fileId1)).(*model.FileInfo).PreviewPath
}
// Bypass the Client whenever possible since we're trying to simulate a pre-3.5 post
post1 := store.Must(Srv.Store.Post().Save(&model.Post{
post1 := store.Must(app.Srv.Store.Post().Save(&model.Post{
UserId: user1.Id,
ChannelId: channel1.Id,
Message: "test",

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

@@ -10,6 +10,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -21,7 +22,7 @@ func InitGeneral() {
BaseRoutes.General.Handle("/log_client", ApiAppHandler(logClient)).Methods("POST")
BaseRoutes.General.Handle("/ping", ApiAppHandler(ping)).Methods("GET")
BaseRoutes.WebSocket.Handle("ping", ApiWebSocketHandler(webSocketPing))
app.Srv.WebSocketRouter.Handle("ping", ApiWebSocketHandler(webSocketPing))
}
func getClientConfig(c *Context, w http.ResponseWriter, r *http.Request) {

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

@@ -10,6 +10,7 @@ import (
"unicode/utf8"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -34,12 +35,12 @@ func ImportPost(post *model.Post) {
post.Hashtags, _ = model.ParseHashtags(post.Message)
if result := <-Srv.Store.Post().Save(post); result.Err != nil {
if result := <-app.Srv.Store.Post().Save(post); result.Err != nil {
l4g.Debug(utils.T("api.import.import_post.saving.debug"), post.UserId, post.Message)
}
for _, fileId := range post.FileIds {
if result := <-Srv.Store.FileInfo().AttachToPost(fileId, post.Id); result.Err != nil {
if result := <-app.Srv.Store.FileInfo().AttachToPost(fileId, post.Id); result.Err != nil {
l4g.Error(utils.T("api.import.import_post.attach_files.error"), post.Id, post.FileIds, result.Err)
}
}
@@ -55,17 +56,17 @@ func ImportUser(team *model.Team, user *model.User) *model.User {
user.Roles = model.ROLE_SYSTEM_USER.Id
if result := <-Srv.Store.User().Save(user); result.Err != nil {
if result := <-app.Srv.Store.User().Save(user); result.Err != nil {
l4g.Error(utils.T("api.import.import_user.saving.error"), result.Err)
return nil
} else {
ruser := result.Data.(*model.User)
if cresult := <-Srv.Store.User().VerifyEmail(ruser.Id); cresult.Err != nil {
if cresult := <-app.Srv.Store.User().VerifyEmail(ruser.Id); cresult.Err != nil {
l4g.Error(utils.T("api.import.import_user.set_email.error"), cresult.Err)
}
if err := JoinUserToTeam(team, user); err != nil {
if err := app.JoinUserToTeam(team, user); err != nil {
l4g.Error(utils.T("api.import.import_user.join_team.error"), err)
}
@@ -74,7 +75,7 @@ func ImportUser(team *model.Team, user *model.User) *model.User {
}
func ImportChannel(channel *model.Channel) *model.Channel {
if result := <-Srv.Store.Channel().Save(channel); result.Err != nil {
if result := <-app.Srv.Store.Channel().Save(channel); result.Err != nil {
return nil
} else {
sc := result.Data.(*model.Channel)

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

@@ -10,6 +10,7 @@ import (
"strings"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -29,7 +30,7 @@ func InitLicense() {
func LoadLicense() {
licenseId := ""
if result := <-Srv.Store.System().Get(); result.Err == nil {
if result := <-app.Srv.Store.System().Get(); result.Err == nil {
props := result.Data.(model.StringMap)
licenseId = props[model.SYSTEM_ACTIVE_LICENSE_ID]
}
@@ -39,7 +40,7 @@ func LoadLicense() {
return
}
if result := <-Srv.Store.License().Get(licenseId); result.Err == nil {
if result := <-app.Srv.Store.License().Get(licenseId); result.Err == nil {
record := result.Data.(*model.LicenseRecord)
utils.LoadLicense([]byte(record.Bytes))
} else {
@@ -104,7 +105,7 @@ func SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) {
if success, licenseStr := utils.ValidateLicense(licenseBytes); success {
license = model.LicenseFromJson(strings.NewReader(licenseStr))
if result := <-Srv.Store.User().AnalyticsUniqueUserCount(""); result.Err != nil {
if result := <-app.Srv.Store.User().AnalyticsUniqueUserCount(""); result.Err != nil {
return nil, model.NewLocAppError("addLicense", "api.license.add_license.invalid_count.app_error", nil, result.Err.Error())
} else {
uniqueUserCount := result.Data.(int64)
@@ -121,12 +122,12 @@ func SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) {
record := &model.LicenseRecord{}
record.Id = license.Id
record.Bytes = string(licenseBytes)
rchan := Srv.Store.License().Save(record)
rchan := app.Srv.Store.License().Save(record)
sysVar := &model.System{}
sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
sysVar.Value = license.Id
schan := Srv.Store.System().SaveOrUpdate(sysVar)
schan := app.Srv.Store.System().SaveOrUpdate(sysVar)
if result := <-rchan; result.Err != nil {
RemoveLicense()
@@ -164,7 +165,7 @@ func RemoveLicense() *model.AppError {
sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
sysVar.Value = ""
if result := <-Srv.Store.System().SaveOrUpdate(sysVar); result.Err != nil {
if result := <-app.Srv.Store.System().SaveOrUpdate(sysVar); result.Err != nil {
utils.RemoveLicense()
return result.Err
}

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

@@ -16,6 +16,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
@@ -59,27 +60,27 @@ func registerOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
app := model.OAuthAppFromJson(r.Body)
oauthApp := model.OAuthAppFromJson(r.Body)
if app == nil {
if oauthApp == nil {
c.SetInvalidParam("registerOAuthApp", "app")
return
}
secret := model.NewId()
app.ClientSecret = secret
app.CreatorId = c.Session.UserId
oauthApp.ClientSecret = secret
oauthApp.CreatorId = c.Session.UserId
if result := <-Srv.Store.OAuth().SaveApp(app); result.Err != nil {
if result := <-app.Srv.Store.OAuth().SaveApp(oauthApp); result.Err != nil {
c.Err = result.Err
return
} else {
app = result.Data.(*model.OAuthApp)
oauthApp = result.Data.(*model.OAuthApp)
c.LogAudit("client_id=" + app.Id)
c.LogAudit("client_id=" + oauthApp.Id)
w.Write([]byte(app.ToJson()))
w.Write([]byte(oauthApp.ToJson()))
return
}
@@ -100,10 +101,10 @@ func getOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) {
var ochan store.StoreChannel
if HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
ochan = Srv.Store.OAuth().GetApps()
ochan = app.Srv.Store.OAuth().GetApps()
} else {
c.Err = nil
ochan = Srv.Store.OAuth().GetAppByUser(c.Session.UserId)
ochan = app.Srv.Store.OAuth().GetAppByUser(c.Session.UserId)
}
if result := <-ochan; result.Err != nil {
@@ -126,16 +127,16 @@ func getOAuthAppInfo(c *Context, w http.ResponseWriter, r *http.Request) {
clientId := params["client_id"]
var app *model.OAuthApp
if result := <-Srv.Store.OAuth().GetApp(clientId); result.Err != nil {
var oauthApp *model.OAuthApp
if result := <-app.Srv.Store.OAuth().GetApp(clientId); result.Err != nil {
c.Err = model.NewLocAppError("getOAuthAppInfo", "api.oauth.allow_oauth.database.app_error", nil, "")
return
} else {
app = result.Data.(*model.OAuthApp)
oauthApp = result.Data.(*model.OAuthApp)
}
app.Sanitize()
w.Write([]byte(app.ToJson()))
oauthApp.Sanitize()
w.Write([]byte(oauthApp.ToJson()))
}
func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -177,15 +178,15 @@ func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
scope = model.DEFAULT_SCOPE
}
var app *model.OAuthApp
if result := <-Srv.Store.OAuth().GetApp(clientId); result.Err != nil {
var oauthApp *model.OAuthApp
if result := <-app.Srv.Store.OAuth().GetApp(clientId); result.Err != nil {
c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.database.app_error", nil, "")
return
} else {
app = result.Data.(*model.OAuthApp)
oauthApp = result.Data.(*model.OAuthApp)
}
if !app.IsValidRedirectURL(redirectUri) {
if !oauthApp.IsValidRedirectURL(redirectUri) {
c.LogAudit("fail - redirect_uri did not match registered callback")
c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
@@ -209,13 +210,13 @@ func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
Value: scope,
}
if result := <-Srv.Store.Preference().Save(&model.Preferences{authorizedApp}); result.Err != nil {
if result := <-app.Srv.Store.Preference().Save(&model.Preferences{authorizedApp}); result.Err != nil {
responseData["redirect"] = redirectUri + "?error=server_error&state=" + state
w.Write([]byte(model.MapToJson(responseData)))
return
}
if result := <-Srv.Store.OAuth().SaveAuthData(authData); result.Err != nil {
if result := <-app.Srv.Store.OAuth().SaveAuthData(authData); result.Err != nil {
responseData["redirect"] = redirectUri + "?error=server_error&state=" + state
w.Write([]byte(model.MapToJson(responseData)))
return
@@ -234,7 +235,7 @@ func getAuthorizedApps(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
ochan := Srv.Store.OAuth().GetAuthorizedApps(c.Session.UserId)
ochan := app.Srv.Store.OAuth().GetAuthorizedApps(c.Session.UserId)
if result := <-ochan; result.Err != nil {
c.Err = result.Err
return
@@ -251,14 +252,14 @@ func getAuthorizedApps(c *Context, w http.ResponseWriter, r *http.Request) {
func RevokeAccessToken(token string) *model.AppError {
session := GetSession(token)
schan := Srv.Store.Session().Remove(token)
session, _ := app.GetSession(token)
schan := app.Srv.Store.Session().Remove(token)
if result := <-Srv.Store.OAuth().GetAccessData(token); result.Err != nil {
if result := <-app.Srv.Store.OAuth().GetAccessData(token); result.Err != nil {
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.get.app_error", nil, "")
}
tchan := Srv.Store.OAuth().RemoveAccessData(token)
tchan := app.Srv.Store.OAuth().RemoveAccessData(token)
if result := <-tchan; result.Err != nil {
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.del_token.app_error", nil, "")
@@ -269,14 +270,14 @@ func RevokeAccessToken(token string) *model.AppError {
}
if session != nil {
RemoveAllSessionsForUserId(session.UserId)
app.RemoveAllSessionsForUserId(session.UserId)
}
return nil
}
func GetAuthData(code string) *model.AuthData {
if result := <-Srv.Store.OAuth().GetAuthData(code); result.Err != nil {
if result := <-app.Srv.Store.OAuth().GetAuthData(code); result.Err != nil {
l4g.Error(utils.T("api.oauth.get_auth_data.find.error"), code)
return nil
} else {
@@ -318,7 +319,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
case model.OAUTH_ACTION_LOGIN:
user := LoginByOAuth(c, w, r, service, body)
if len(teamId) > 0 {
c.Err = JoinUserToTeamById(teamId, user)
c.Err = app.JoinUserToTeamById(teamId, user)
}
if c.Err == nil {
if val, ok := props["redirect_to"]; ok {
@@ -372,12 +373,12 @@ func authorizeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
var app *model.OAuthApp
if result := <-Srv.Store.OAuth().GetApp(clientId); result.Err != nil {
var oauthApp *model.OAuthApp
if result := <-app.Srv.Store.OAuth().GetApp(clientId); result.Err != nil {
c.Err = result.Err
return
} else {
app = result.Data.(*model.OAuthApp)
oauthApp = result.Data.(*model.OAuthApp)
}
// here we should check if the user is logged in
@@ -387,13 +388,13 @@ func authorizeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
}
isAuthorized := false
if result := <-Srv.Store.Preference().Get(c.Session.UserId, model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP, clientId); result.Err == nil {
if result := <-app.Srv.Store.Preference().Get(c.Session.UserId, model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP, clientId); result.Err == nil {
// when we support scopes we should check if the scopes match
isAuthorized = true
}
// Automatically allow if the app is trusted
if app.IsTrusted || isAuthorized {
if oauthApp.IsTrusted || isAuthorized {
closeBody := func(r *http.Response) {
if r.Body != nil {
ioutil.ReadAll(r.Body)
@@ -481,16 +482,16 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
var app *model.OAuthApp
achan := Srv.Store.OAuth().GetApp(clientId)
var oauthApp *model.OAuthApp
achan := app.Srv.Store.OAuth().GetApp(clientId)
if result := <-achan; result.Err != nil {
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.credentials.app_error", nil, "")
return
} else {
app = result.Data.(*model.OAuthApp)
oauthApp = result.Data.(*model.OAuthApp)
}
if app.ClientSecret != secret {
if oauthApp.ClientSecret != secret {
c.LogAudit("fail - invalid client credentials")
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.credentials.app_error", nil, "")
return
@@ -510,7 +511,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
}
if authData.IsExpired() {
<-Srv.Store.OAuth().RemoveAuthData(authData.Code)
<-app.Srv.Store.OAuth().RemoveAuthData(authData.Code)
c.LogAudit("fail - auth code expired")
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.expired_code.app_error", nil, "")
return
@@ -528,7 +529,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
uchan := Srv.Store.User().Get(authData.UserId)
uchan := app.Srv.Store.User().Get(authData.UserId)
if result := <-uchan; result.Err != nil {
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.internal_user.app_error", nil, "")
return
@@ -536,14 +537,14 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
user = result.Data.(*model.User)
}
tchan := Srv.Store.OAuth().GetPreviousAccessData(user.Id, clientId)
tchan := app.Srv.Store.OAuth().GetPreviousAccessData(user.Id, clientId)
if result := <-tchan; result.Err != nil {
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.internal.app_error", nil, "")
return
} else if result.Data != nil {
accessData := result.Data.(*model.AccessData)
if accessData.IsExpired() {
if access, err := newSessionUpdateToken(app.Name, accessData, user); err != nil {
if access, err := newSessionUpdateToken(oauthApp.Name, accessData, user); err != nil {
c.Err = err
return
} else {
@@ -560,7 +561,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
} else {
// create a new session and return new access token
var session *model.Session
if result, err := newSession(app.Name, user); err != nil {
if result, err := newSession(oauthApp.Name, user); err != nil {
c.Err = err
return
} else {
@@ -569,7 +570,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
accessData = &model.AccessData{ClientId: clientId, UserId: user.Id, Token: session.Token, RefreshToken: model.NewId(), RedirectUri: redirectUri, ExpiresAt: session.ExpiresAt}
if result := <-Srv.Store.OAuth().SaveAccessData(accessData); result.Err != nil {
if result := <-app.Srv.Store.OAuth().SaveAccessData(accessData); result.Err != nil {
l4g.Error(result.Err)
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.internal_saving.app_error", nil, "")
return
@@ -583,10 +584,10 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
<-Srv.Store.OAuth().RemoveAuthData(authData.Code)
<-app.Srv.Store.OAuth().RemoveAuthData(authData.Code)
} else {
// when grantType is refresh_token
if result := <-Srv.Store.OAuth().GetAccessDataByRefreshToken(refreshToken); result.Err != nil {
if result := <-app.Srv.Store.OAuth().GetAccessDataByRefreshToken(refreshToken); result.Err != nil {
c.LogAudit("fail - refresh token is invalid")
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.refresh_token.app_error", nil, "")
return
@@ -594,7 +595,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
accessData = result.Data.(*model.AccessData)
}
uchan := Srv.Store.User().Get(accessData.UserId)
uchan := app.Srv.Store.User().Get(accessData.UserId)
if result := <-uchan; result.Err != nil {
c.Err = model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.internal_user.app_error", nil, "")
return
@@ -602,7 +603,7 @@ func getAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
user = result.Data.(*model.User)
}
if access, err := newSessionUpdateToken(app.Name, accessData, user); err != nil {
if access, err := newSessionUpdateToken(oauthApp.Name, accessData, user); err != nil {
c.Err = err
return
} else {
@@ -668,7 +669,7 @@ func getTeamIdFromQuery(query url.Values) (string, *model.AppError) {
return props["id"], nil
} else if len(inviteId) > 0 {
if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
// soft fail, so we still create user but don't auto-join team
l4g.Error("%v", result.Err)
} else {
@@ -844,7 +845,7 @@ func CompleteSwitchWithOAuth(c *Context, w http.ResponseWriter, r *http.Request,
}
var user *model.User
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -856,7 +857,7 @@ func CompleteSwitchWithOAuth(c *Context, w http.ResponseWriter, r *http.Request,
return
}
if result := <-Srv.Store.User().UpdateAuthData(user.Id, service, &authData, ssoEmail, true); result.Err != nil {
if result := <-app.Srv.Store.User().UpdateAuthData(user.Id, service, &authData, ssoEmail, true); result.Err != nil {
c.Err = result.Err
return
}
@@ -887,7 +888,7 @@ func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.OAuth().GetApp(id); result.Err != nil {
if result := <-app.Srv.Store.OAuth().GetApp(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -898,7 +899,7 @@ func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if err := (<-Srv.Store.OAuth().DeleteApp(id)).Err; err != nil {
if err := (<-app.Srv.Store.OAuth().DeleteApp(id)).Err; err != nil {
c.Err = err
return
}
@@ -923,7 +924,7 @@ func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
}
// revoke app sessions
if result := <-Srv.Store.OAuth().GetAccessDataByUserForApp(c.Session.UserId, id); result.Err != nil {
if result := <-app.Srv.Store.OAuth().GetAccessDataByUserForApp(c.Session.UserId, id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -935,7 +936,7 @@ func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if rad := <-Srv.Store.OAuth().RemoveAccessData(a.Token); rad.Err != nil {
if rad := <-app.Srv.Store.OAuth().RemoveAccessData(a.Token); rad.Err != nil {
c.Err = rad.Err
return
}
@@ -943,7 +944,7 @@ func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
}
// Deauthorize the app
if err := (<-Srv.Store.Preference().Delete(c.Session.UserId, model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP, id)).Err; err != nil {
if err := (<-app.Srv.Store.Preference().Delete(c.Session.UserId, model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP, id)).Err; err != nil {
c.Err = err
return
}
@@ -967,26 +968,26 @@ func regenerateOAuthSecret(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
var app *model.OAuthApp
if result := <-Srv.Store.OAuth().GetApp(id); result.Err != nil {
var oauthApp *model.OAuthApp
if result := <-app.Srv.Store.OAuth().GetApp(id); result.Err != nil {
c.Err = model.NewLocAppError("regenerateOAuthSecret", "api.oauth.allow_oauth.database.app_error", nil, "")
return
} else {
app = result.Data.(*model.OAuthApp)
oauthApp = result.Data.(*model.OAuthApp)
if app.CreatorId != c.Session.UserId && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
if oauthApp.CreatorId != c.Session.UserId && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
c.Err = model.NewLocAppError("registerOAuthApp", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
app.ClientSecret = model.NewId()
if update := <-Srv.Store.OAuth().UpdateApp(app); update.Err != nil {
oauthApp.ClientSecret = model.NewId()
if update := <-app.Srv.Store.OAuth().UpdateApp(oauthApp); update.Err != nil {
c.Err = update.Err
return
}
w.Write([]byte(app.ToJson()))
w.Write([]byte(oauthApp.ToJson()))
return
}
}
@@ -999,11 +1000,11 @@ func newSession(appName string, user *model.User) (*model.Session, *model.AppErr
session.AddProp(model.SESSION_PROP_OS, "OAuth2")
session.AddProp(model.SESSION_PROP_BROWSER, "OAuth2")
if result := <-Srv.Store.Session().Save(session); result.Err != nil {
if result := <-app.Srv.Store.Session().Save(session); result.Err != nil {
return nil, model.NewLocAppError("getAccessToken", "api.oauth.get_access_token.internal_session.app_error", nil, "")
} else {
session = result.Data.(*model.Session)
AddSessionToCache(session)
app.AddSessionToCache(session)
}
return session, nil
@@ -1011,7 +1012,7 @@ func newSession(appName string, user *model.User) (*model.Session, *model.AppErr
func newSessionUpdateToken(appName string, accessData *model.AccessData, user *model.User) (*model.AccessResponse, *model.AppError) {
var session *model.Session
<-Srv.Store.Session().Remove(accessData.Token) //remove the previous session
<-app.Srv.Store.Session().Remove(accessData.Token) //remove the previous session
if result, err := newSession(appName, user); err != nil {
return nil, err
@@ -1021,7 +1022,7 @@ func newSessionUpdateToken(appName string, accessData *model.AccessData, user *m
accessData.Token = session.Token
accessData.ExpiresAt = session.ExpiresAt
if result := <-Srv.Store.OAuth().UpdateAccessData(accessData); result.Err != nil {
if result := <-app.Srv.Store.OAuth().UpdateAccessData(accessData); result.Err != nil {
l4g.Error(result.Err)
return nil, model.NewLocAppError("getAccessToken", "web.get_access_token.internal_saving.app_error", nil, "")
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@@ -14,6 +14,7 @@ import (
"testing"
"time"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -134,7 +135,7 @@ func TestCreatePost(t *testing.T) {
} else if rpost9 := resp.Data.(*model.Post); len(rpost9.FileIds) != 3 {
t.Fatal("post should have 3 files")
} else {
infos := store.Must(Srv.Store.FileInfo().GetForPost(rpost9.Id)).([]*model.FileInfo)
infos := store.Must(app.Srv.Store.FileInfo().GetForPost(rpost9.Id)).([]*model.FileInfo)
if len(infos) != 3 {
t.Fatal("should've attached all 3 files to post")
@@ -904,7 +905,9 @@ func TestMakeDirectChannelVisible(t *testing.T) {
channel := Client.Must(Client.CreateDirectChannel(user2.Id)).Data.(*model.Channel)
makeDirectChannelVisible(channel.Id)
if err := app.MakeDirectChannelVisible(channel.Id); err != nil {
t.Fatal(err)
}
if result, err := Client.GetPreference(model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, user2.Id); err != nil {
t.Fatal("Errored trying to set direct channel to be visible for user1")
@@ -913,281 +916,6 @@ func TestMakeDirectChannelVisible(t *testing.T) {
}
}
func TestGetMentionKeywords(t *testing.T) {
// user with username or custom mentions enabled
user1 := &model.User{
Id: model.NewId(),
FirstName: "First",
Username: "User",
NotifyProps: map[string]string{
"mention_keys": "User,@User,MENTION",
},
}
profiles := map[string]*model.User{user1.Id: user1}
mentions := getMentionKeywordsInChannel(profiles)
if len(mentions) != 3 {
t.Fatal("should've returned three mention keywords")
} else if ids, ok := mentions["user"]; !ok || ids[0] != user1.Id {
t.Fatal("should've returned mention key of user")
} else if ids, ok := mentions["@user"]; !ok || ids[0] != user1.Id {
t.Fatal("should've returned mention key of @user")
} else if ids, ok := mentions["mention"]; !ok || ids[0] != user1.Id {
t.Fatal("should've returned mention key of mention")
}
// user with first name mention enabled
user2 := &model.User{
Id: model.NewId(),
FirstName: "First",
Username: "User",
NotifyProps: map[string]string{
"first_name": "true",
},
}
profiles = map[string]*model.User{user2.Id: user2}
mentions = getMentionKeywordsInChannel(profiles)
if len(mentions) != 2 {
t.Fatal("should've returned two mention keyword")
} else if ids, ok := mentions["First"]; !ok || ids[0] != user2.Id {
t.Fatal("should've returned mention key of First")
}
// user with @channel/@all mentions enabled
user3 := &model.User{
Id: model.NewId(),
FirstName: "First",
Username: "User",
NotifyProps: map[string]string{
"channel": "true",
},
}
profiles = map[string]*model.User{user3.Id: user3}
mentions = getMentionKeywordsInChannel(profiles)
if len(mentions) != 3 {
t.Fatal("should've returned three mention keywords")
} else if ids, ok := mentions["@channel"]; !ok || ids[0] != user3.Id {
t.Fatal("should've returned mention key of @channel")
} else if ids, ok := mentions["@all"]; !ok || ids[0] != user3.Id {
t.Fatal("should've returned mention key of @all")
}
// user with all types of mentions enabled
user4 := &model.User{
Id: model.NewId(),
FirstName: "First",
Username: "User",
NotifyProps: map[string]string{
"mention_keys": "User,@User,MENTION",
"first_name": "true",
"channel": "true",
},
}
profiles = map[string]*model.User{user4.Id: user4}
mentions = getMentionKeywordsInChannel(profiles)
if len(mentions) != 6 {
t.Fatal("should've returned six mention keywords")
} else if ids, ok := mentions["user"]; !ok || ids[0] != user4.Id {
t.Fatal("should've returned mention key of user")
} else if ids, ok := mentions["@user"]; !ok || ids[0] != user4.Id {
t.Fatal("should've returned mention key of @user")
} else if ids, ok := mentions["mention"]; !ok || ids[0] != user4.Id {
t.Fatal("should've returned mention key of mention")
} else if ids, ok := mentions["First"]; !ok || ids[0] != user4.Id {
t.Fatal("should've returned mention key of First")
} else if ids, ok := mentions["@channel"]; !ok || ids[0] != user4.Id {
t.Fatal("should've returned mention key of @channel")
} else if ids, ok := mentions["@all"]; !ok || ids[0] != user4.Id {
t.Fatal("should've returned mention key of @all")
}
dup_count := func(list []string) map[string]int {
duplicate_frequency := make(map[string]int)
for _, item := range list {
// check if the item/element exist in the duplicate_frequency map
_, exist := duplicate_frequency[item]
if exist {
duplicate_frequency[item] += 1 // increase counter by 1 if already in the map
} else {
duplicate_frequency[item] = 1 // else start counting from 1
}
}
return duplicate_frequency
}
// multiple users
profiles = map[string]*model.User{
user1.Id: user1,
user2.Id: user2,
user3.Id: user3,
user4.Id: user4,
}
mentions = getMentionKeywordsInChannel(profiles)
if len(mentions) != 6 {
t.Fatal("should've returned six mention keywords")
} else if ids, ok := mentions["user"]; !ok || len(ids) != 2 || (ids[0] != user1.Id && ids[1] != user1.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
t.Fatal("should've mentioned user1 and user4 with user")
} else if ids := dup_count(mentions["@user"]); len(ids) != 4 || (ids[user1.Id] != 2) || (ids[user4.Id] != 2) {
t.Fatal("should've mentioned user1 and user4 with @user")
} else if ids, ok := mentions["mention"]; !ok || len(ids) != 2 || (ids[0] != user1.Id && ids[1] != user1.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
t.Fatal("should've mentioned user1 and user4 with mention")
} else if ids, ok := mentions["First"]; !ok || len(ids) != 2 || (ids[0] != user2.Id && ids[1] != user2.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
t.Fatal("should've mentioned user2 and user4 with mention")
} else if ids, ok := mentions["@channel"]; !ok || len(ids) != 2 || (ids[0] != user3.Id && ids[1] != user3.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
t.Fatal("should've mentioned user3 and user4 with @channel")
} else if ids, ok := mentions["@all"]; !ok || len(ids) != 2 || (ids[0] != user3.Id && ids[1] != user3.Id) || (ids[0] != user4.Id && ids[1] != user4.Id) {
t.Fatal("should've mentioned user3 and user4 with @all")
}
}
func TestGetExplicitMentionsAtHere(t *testing.T) {
// test all the boundary cases that we know can break up terms (and those that we know won't)
cases := map[string]bool{
"": false,
"here": false,
"@here": true,
" @here ": true,
"\t@here\t": true,
"\n@here\n": true,
// "!@here!": true,
// "@@here@": true,
// "#@here#": true,
// "$@here$": true,
// "%@here%": true,
// "^@here^": true,
// "&@here&": true,
// "*@here*": true,
"(@here(": true,
")@here)": true,
// "-@here-": true,
// "_@here_": true,
// "=@here=": true,
"+@here+": true,
"[@here[": true,
"{@here{": true,
"]@here]": true,
"}@here}": true,
"\\@here\\": true,
// "|@here|": true,
";@here;": true,
":@here:": true,
// "'@here'": true,
// "\"@here\"": true,
",@here,": true,
"<@here<": true,
".@here.": true,
">@here>": true,
"/@here/": true,
"?@here?": true,
// "`@here`": true,
// "~@here~": true,
}
for message, shouldMention := range cases {
if _, _, hereMentioned, _, _ := getExplicitMentions(message, nil); hereMentioned && !shouldMention {
t.Fatalf("shouldn't have mentioned @here with \"%v\"", message)
} else if !hereMentioned && shouldMention {
t.Fatalf("should've have mentioned @here with \"%v\"", message)
}
}
// mentioning @here and someone
id := model.NewId()
if mentions, potential, hereMentioned, _, _ := getExplicitMentions("@here @user @potential", map[string][]string{"@user": {id}}); !hereMentioned {
t.Fatal("should've mentioned @here with \"@here @user\"")
} else if len(mentions) != 1 || !mentions[id] {
t.Fatal("should've mentioned @user with \"@here @user\"")
} else if len(potential) > 1 {
t.Fatal("should've potential mentions for @potential")
}
}
func TestGetExplicitMentions(t *testing.T) {
id1 := model.NewId()
id2 := model.NewId()
// not mentioning anybody
message := "this is a message"
keywords := map[string][]string{}
if mentions, potential, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 0 || len(potential) != 0 {
t.Fatal("shouldn't have mentioned anybody or have any potencial mentions")
}
// mentioning a user that doesn't exist
message = "this is a message for @user"
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 0 {
t.Fatal("shouldn't have mentioned user that doesn't exist")
}
// mentioning one person
keywords = map[string][]string{"@user": {id1}}
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 1 || !mentions[id1] {
t.Fatal("should've mentioned @user")
}
// mentioning one person without an @mention
message = "this is a message for @user"
keywords = map[string][]string{"this": {id1}}
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 1 || !mentions[id1] {
t.Fatal("should've mentioned this")
}
// mentioning multiple people with one word
message = "this is a message for @user"
keywords = map[string][]string{"@user": {id1, id2}}
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 2 || !mentions[id1] || !mentions[id2] {
t.Fatal("should've mentioned two users with @user")
}
// mentioning only one of multiple people
keywords = map[string][]string{"@user": {id1}, "@mention": {id2}}
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 1 || !mentions[id1] || mentions[id2] {
t.Fatal("should've mentioned @user and not @mention")
}
// mentioning multiple people with multiple words
message = "this is an @mention for @user"
keywords = map[string][]string{"@user": {id1}, "@mention": {id2}}
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 2 || !mentions[id1] || !mentions[id2] {
t.Fatal("should've mentioned two users with @user and @mention")
}
// mentioning @channel (not a special case, but it's good to double check)
message = "this is an message for @channel"
keywords = map[string][]string{"@channel": {id1, id2}}
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 2 || !mentions[id1] || !mentions[id2] {
t.Fatal("should've mentioned two users with @channel")
}
// mentioning @all (not a special case, but it's good to double check)
message = "this is an message for @all"
keywords = map[string][]string{"@all": {id1, id2}}
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 2 || !mentions[id1] || !mentions[id2] {
t.Fatal("should've mentioned two users with @all")
}
// mentioning user.period without mentioning user (PLT-3222)
message = "user.period doesn't complicate things at all by including periods in their username"
keywords = map[string][]string{"user.period": {id1}, "user": {id2}}
if mentions, _, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 1 || !mentions[id1] || mentions[id2] {
t.Fatal("should've mentioned user.period and not user")
}
// mentioning a potential out of channel user
message = "this is an message for @potential and @user"
keywords = map[string][]string{"@user": {id1}}
if mentions, potential, _, _, _ := getExplicitMentions(message, keywords); len(mentions) != 1 || !mentions[id1] || len(potential) != 1 {
t.Fatal("should've mentioned user and have a potential not in channel")
}
}
func TestGetFlaggedPosts(t *testing.T) {
th := Setup().InitBasic()
Client := th.BasicClient
@@ -1226,28 +954,28 @@ func TestGetFlaggedPosts(t *testing.T) {
func TestGetMessageForNotification(t *testing.T) {
Setup().InitBasic()
testPng := store.Must(Srv.Store.FileInfo().Save(&model.FileInfo{
testPng := store.Must(app.Srv.Store.FileInfo().Save(&model.FileInfo{
CreatorId: model.NewId(),
Path: "test1.png",
Name: "test1.png",
MimeType: "image/png",
})).(*model.FileInfo)
testJpg1 := store.Must(Srv.Store.FileInfo().Save(&model.FileInfo{
testJpg1 := store.Must(app.Srv.Store.FileInfo().Save(&model.FileInfo{
CreatorId: model.NewId(),
Path: "test2.jpg",
Name: "test2.jpg",
MimeType: "image/jpeg",
})).(*model.FileInfo)
testFile := store.Must(Srv.Store.FileInfo().Save(&model.FileInfo{
testFile := store.Must(app.Srv.Store.FileInfo().Save(&model.FileInfo{
CreatorId: model.NewId(),
Path: "test1.go",
Name: "test1.go",
MimeType: "text/plain",
})).(*model.FileInfo)
testJpg2 := store.Must(Srv.Store.FileInfo().Save(&model.FileInfo{
testJpg2 := store.Must(app.Srv.Store.FileInfo().Save(&model.FileInfo{
CreatorId: model.NewId(),
Path: "test3.jpg",
Name: "test3.jpg",
@@ -1261,37 +989,37 @@ func TestGetMessageForNotification(t *testing.T) {
Message: "test",
}
if getMessageForNotification(post, translateFunc) != "test" {
if app.GetMessageForNotification(post, translateFunc) != "test" {
t.Fatal("should've returned message text")
}
post.FileIds = model.StringArray{testPng.Id}
store.Must(Srv.Store.FileInfo().AttachToPost(testPng.Id, post.Id))
if getMessageForNotification(post, translateFunc) != "test" {
store.Must(app.Srv.Store.FileInfo().AttachToPost(testPng.Id, post.Id))
if app.GetMessageForNotification(post, translateFunc) != "test" {
t.Fatal("should've returned message text, even with attachments")
}
post.Message = ""
if message := getMessageForNotification(post, translateFunc); message != "1 image sent: test1.png" {
if message := app.GetMessageForNotification(post, translateFunc); message != "1 image sent: test1.png" {
t.Fatal("should've returned number of images:", message)
}
post.FileIds = model.StringArray{testPng.Id, testJpg1.Id}
store.Must(Srv.Store.FileInfo().AttachToPost(testJpg1.Id, post.Id))
if message := getMessageForNotification(post, translateFunc); message != "2 images sent: test1.png, test2.jpg" && message != "2 images sent: test2.jpg, test1.png" {
store.Must(app.Srv.Store.FileInfo().AttachToPost(testJpg1.Id, post.Id))
if message := app.GetMessageForNotification(post, translateFunc); message != "2 images sent: test1.png, test2.jpg" && message != "2 images sent: test2.jpg, test1.png" {
t.Fatal("should've returned number of images:", message)
}
post.Id = model.NewId()
post.FileIds = model.StringArray{testFile.Id}
store.Must(Srv.Store.FileInfo().AttachToPost(testFile.Id, post.Id))
if message := getMessageForNotification(post, translateFunc); message != "1 file sent: test1.go" {
store.Must(app.Srv.Store.FileInfo().AttachToPost(testFile.Id, post.Id))
if message := app.GetMessageForNotification(post, translateFunc); message != "1 file sent: test1.go" {
t.Fatal("should've returned number of files:", message)
}
store.Must(Srv.Store.FileInfo().AttachToPost(testJpg2.Id, post.Id))
store.Must(app.Srv.Store.FileInfo().AttachToPost(testJpg2.Id, post.Id))
post.FileIds = model.StringArray{testFile.Id, testJpg2.Id}
if message := getMessageForNotification(post, translateFunc); message != "2 files sent: test1.go, test3.jpg" && message != "2 files sent: test3.jpg, test1.go" {
if message := app.GetMessageForNotification(post, translateFunc); message != "2 files sent: test1.go, test3.jpg" && message != "2 files sent: test3.jpg, test1.go" {
t.Fatal("should've returned number of mixed files:", message)
}
}
@@ -1334,43 +1062,6 @@ func TestGetFileInfosForPost(t *testing.T) {
}
}
func TestSendNotifications(t *testing.T) {
th := Setup().InitBasic()
Client := th.BasicClient
AddUserToChannel(th.BasicUser2, th.BasicChannel)
mockSession := model.Session{
UserId: th.BasicUser.Id,
TeamMembers: []*model.TeamMember{{TeamId: th.BasicTeam.Id, UserId: th.BasicUser.Id}},
IsOAuth: false,
}
newContext := &Context{
Session: mockSession,
RequestId: model.NewId(),
IpAddress: "",
Path: "fake",
Err: nil,
siteURL: *utils.Cfg.ServiceSettings.SiteURL,
TeamId: th.BasicTeam.Id,
}
post1 := Client.Must(Client.CreatePost(&model.Post{
ChannelId: th.BasicChannel.Id,
Message: "@" + th.BasicUser2.Username,
})).Data.(*model.Post)
mentions := sendNotifications(newContext, post1, th.BasicTeam, th.BasicChannel)
if mentions == nil {
t.Log(mentions)
t.Fatal("user should have been mentioned")
} else if mentions[0] != th.BasicUser2.Id {
t.Log(mentions)
t.Fatal("user should have been mentioned")
}
}
func TestGetPostById(t *testing.T) {
th := Setup().InitBasic()
Client := th.BasicClient

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

@@ -6,6 +6,7 @@ package api
import (
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"net/http"
@@ -22,7 +23,7 @@ func InitPreference() {
}
func getAllPreferences(c *Context, w http.ResponseWriter, r *http.Request) {
if result := <-Srv.Store.Preference().GetAll(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.Preference().GetAll(c.Session.UserId); result.Err != nil {
c.Err = result.Err
} else {
data := result.Data.(model.Preferences)
@@ -49,7 +50,7 @@ func savePreferences(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if result := <-Srv.Store.Preference().Save(&preferences); result.Err != nil {
if result := <-app.Srv.Store.Preference().Save(&preferences); result.Err != nil {
c.Err = result.Err
return
}
@@ -61,7 +62,7 @@ func getPreferenceCategory(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
category := params["category"]
if result := <-Srv.Store.Preference().GetCategory(c.Session.UserId, category); result.Err != nil {
if result := <-app.Srv.Store.Preference().GetCategory(c.Session.UserId, category); result.Err != nil {
c.Err = result.Err
} else {
data := result.Data.(model.Preferences)
@@ -75,7 +76,7 @@ func getPreference(c *Context, w http.ResponseWriter, r *http.Request) {
category := params["category"]
name := params["name"]
if result := <-Srv.Store.Preference().Get(c.Session.UserId, category, name); result.Err != nil {
if result := <-app.Srv.Store.Preference().Get(c.Session.UserId, category, name); result.Err != nil {
c.Err = result.Err
} else {
data := result.Data.(model.Preference)
@@ -101,7 +102,7 @@ func deletePreferences(c *Context, w http.ResponseWriter, r *http.Request) {
}
for _, preference := range preferences {
if result := <-Srv.Store.Preference().Delete(c.Session.UserId, preference.Category, preference.Name); result.Err != nil {
if result := <-app.Srv.Store.Preference().Delete(c.Session.UserId, preference.Category, preference.Name); result.Err != nil {
c.Err = result.Err
return
}

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

@@ -6,6 +6,7 @@ package api
import (
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"net/http"
@@ -50,7 +51,7 @@ func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
pchan := Srv.Store.Post().Get(reaction.PostId)
pchan := app.Srv.Store.Post().Get(reaction.PostId)
var postHadReactions bool
if result := <-pchan; result.Err != nil {
@@ -65,7 +66,7 @@ func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) {
postHadReactions = post.HasReactions
}
if result := <-Srv.Store.Reaction().Save(reaction); result.Err != nil {
if result := <-app.Srv.Store.Reaction().Save(reaction); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -108,7 +109,7 @@ func deleteReaction(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
pchan := Srv.Store.Post().Get(reaction.PostId)
pchan := app.Srv.Store.Post().Get(reaction.PostId)
var postHadReactions bool
if result := <-pchan; result.Err != nil {
@@ -123,7 +124,7 @@ func deleteReaction(c *Context, w http.ResponseWriter, r *http.Request) {
postHadReactions = post.HasReactions
}
if result := <-Srv.Store.Reaction().Delete(reaction); result.Err != nil {
if result := <-app.Srv.Store.Reaction().Delete(reaction); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -139,13 +140,13 @@ func sendReactionEvent(event string, channelId string, reaction *model.Reaction,
message := model.NewWebSocketEvent(event, "", channelId, "", nil)
message.Add("reaction", reaction.ToJson())
Publish(message)
app.Publish(message)
}()
// send out that a post was updated if post.HasReactions has changed
go func() {
var post *model.Post
if result := <-Srv.Store.Post().Get(reaction.PostId); result.Err != nil {
if result := <-app.Srv.Store.Post().Get(reaction.PostId); result.Err != nil {
l4g.Warn(utils.T("api.reaction.send_reaction_event.post.app_error"))
return
} else {
@@ -156,7 +157,7 @@ func sendReactionEvent(event string, channelId string, reaction *model.Reaction,
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_POST_EDITED, "", channelId, "", nil)
message.Add("post", post.ToJson())
Publish(message)
app.Publish(message)
}
}()
}
@@ -176,7 +177,7 @@ func listReactions(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
pchan := Srv.Store.Post().Get(postId)
pchan := app.Srv.Store.Post().Get(postId)
if !HasPermissionToChannelContext(c, channelId, model.PERMISSION_READ_CHANNEL) {
return
@@ -192,7 +193,7 @@ func listReactions(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Reaction().GetForPost(postId); result.Err != nil {
if result := <-app.Srv.Store.Reaction().GetForPost(postId); result.Err != nil {
c.Err = result.Err
return
} else {

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

@@ -1,187 +0,0 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
"crypto/tls"
"net"
"net/http"
"strings"
"time"
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
"github.com/rsc/letsencrypt"
"github.com/tylerb/graceful"
"gopkg.in/throttled/throttled.v2"
"gopkg.in/throttled/throttled.v2/store/memstore"
)
type Server struct {
Store store.Store
Router *mux.Router
GracefulServer *graceful.Server
}
type CorsWrapper struct {
router *mux.Router
}
const TIME_TO_WAIT_FOR_CONNECTIONS_TO_CLOSE_ON_SERVER_SHUTDOWN = time.Second
var Srv *Server
func NewServer() {
l4g.Info(utils.T("api.server.new_server.init.info"))
Srv = &Server{}
}
func InitStores() {
Srv.Store = store.NewSqlStore()
}
func InitRouter() {
Srv.Router = mux.NewRouter()
Srv.Router.NotFoundHandler = http.HandlerFunc(Handle404)
}
type VaryBy struct{}
func (m *VaryBy) Key(r *http.Request) string {
return GetIpAddress(r)
}
func initalizeThrottledVaryBy() *throttled.VaryBy {
vary := throttled.VaryBy{}
if utils.Cfg.RateLimitSettings.VaryByRemoteAddr {
vary.RemoteAddr = true
}
if len(utils.Cfg.RateLimitSettings.VaryByHeader) > 0 {
vary.Headers = strings.Fields(utils.Cfg.RateLimitSettings.VaryByHeader)
if utils.Cfg.RateLimitSettings.VaryByRemoteAddr {
l4g.Warn(utils.T("api.server.start_server.rate.warn"))
vary.RemoteAddr = false
}
}
return &vary
}
func redirectHTTPToHTTPS(w http.ResponseWriter, r *http.Request) {
if r.Host == "" {
http.Error(w, "Not Found", http.StatusNotFound)
}
url := r.URL
url.Host = r.Host
url.Scheme = "https"
http.Redirect(w, r, url.String(), http.StatusFound)
}
func StartServer() {
l4g.Info(utils.T("api.server.start_server.starting.info"))
var handler http.Handler = &CorsWrapper{Srv.Router}
if *utils.Cfg.RateLimitSettings.Enable {
l4g.Info(utils.T("api.server.start_server.rate.info"))
store, err := memstore.New(utils.Cfg.RateLimitSettings.MemoryStoreSize)
if err != nil {
l4g.Critical(utils.T("api.server.start_server.rate_limiting_memory_store"))
return
}
quota := throttled.RateQuota{
MaxRate: throttled.PerSec(utils.Cfg.RateLimitSettings.PerSec),
MaxBurst: *utils.Cfg.RateLimitSettings.MaxBurst,
}
rateLimiter, err := throttled.NewGCRARateLimiter(store, quota)
if err != nil {
l4g.Critical(utils.T("api.server.start_server.rate_limiting_rate_limiter"))
return
}
httpRateLimiter := throttled.HTTPRateLimiter{
RateLimiter: rateLimiter,
VaryBy: &VaryBy{},
DeniedHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
l4g.Error("%v: Denied due to throttling settings code=429 ip=%v", r.URL.Path, GetIpAddress(r))
throttled.DefaultDeniedHandler.ServeHTTP(w, r)
}),
}
handler = httpRateLimiter.RateLimit(handler)
}
Srv.GracefulServer = &graceful.Server{
Timeout: TIME_TO_WAIT_FOR_CONNECTIONS_TO_CLOSE_ON_SERVER_SHUTDOWN,
Server: &http.Server{
Addr: utils.Cfg.ServiceSettings.ListenAddress,
Handler: handlers.RecoveryHandler(handlers.PrintRecoveryStack(true))(handler),
ReadTimeout: time.Duration(*utils.Cfg.ServiceSettings.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(*utils.Cfg.ServiceSettings.WriteTimeout) * time.Second,
},
}
l4g.Info(utils.T("api.server.start_server.listening.info"), utils.Cfg.ServiceSettings.ListenAddress)
if *utils.Cfg.ServiceSettings.Forward80To443 {
go func() {
listener, err := net.Listen("tcp", ":80")
if err != nil {
l4g.Error("Unable to setup forwarding")
return
}
defer listener.Close()
http.Serve(listener, http.HandlerFunc(redirectHTTPToHTTPS))
}()
}
go func() {
var err error
if *utils.Cfg.ServiceSettings.ConnectionSecurity == model.CONN_SECURITY_TLS {
if *utils.Cfg.ServiceSettings.UseLetsEncrypt {
var m letsencrypt.Manager
m.CacheFile(*utils.Cfg.ServiceSettings.LetsEncryptCertificateCacheFile)
tlsConfig := &tls.Config{
GetCertificate: m.GetCertificate,
}
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2")
err = Srv.GracefulServer.ListenAndServeTLSConfig(tlsConfig)
} else {
err = Srv.GracefulServer.ListenAndServeTLS(*utils.Cfg.ServiceSettings.TLSCertFile, *utils.Cfg.ServiceSettings.TLSKeyFile)
}
} else {
err = Srv.GracefulServer.ListenAndServe()
}
if err != nil {
l4g.Critical(utils.T("api.server.start_server.starting.critical"), err)
time.Sleep(time.Second)
}
}()
}
func StopServer() {
l4g.Info(utils.T("api.server.stop_server.stopping.info"))
Srv.GracefulServer.Stop(TIME_TO_WAIT_FOR_CONNECTIONS_TO_CLOSE_ON_SERVER_SHUTDOWN)
Srv.Store.Close()
HubStop()
l4g.Info(utils.T("api.server.stop_server.stopped.info"))
}

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

@@ -16,6 +16,7 @@ import (
"unicode/utf8"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
@@ -137,7 +138,7 @@ func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map
// Need the team
var team *model.Team
if result := <-Srv.Store.Team().Get(teamId); result.Err != nil {
if result := <-app.Srv.Store.Team().Get(teamId); result.Err != nil {
log.WriteString(utils.T("api.slackimport.slack_import.team_fail"))
return addedUsers
} else {
@@ -159,10 +160,10 @@ func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map
password := model.NewId()
// Check for email conflict and use existing user if found
if result := <-Srv.Store.User().GetByEmail(email); result.Err == nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err == nil {
existingUser := result.Data.(*model.User)
addedUsers[sUser.Id] = existingUser
if err := JoinUserToTeam(team, addedUsers[sUser.Id]); err != nil {
if err := app.JoinUserToTeam(team, addedUsers[sUser.Id]); err != nil {
log.WriteString(utils.T("api.slackimport.slack_add_users.merge_existing_failed", map[string]interface{}{"Email": existingUser.Email, "Username": existingUser.Username}))
} else {
log.WriteString(utils.T("api.slackimport.slack_add_users.merge_existing", map[string]interface{}{"Email": existingUser.Email, "Username": existingUser.Username}))
@@ -191,7 +192,7 @@ func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map
func SlackAddBotUser(teamId string, log *bytes.Buffer) *model.User {
var team *model.Team
if result := <-Srv.Store.Team().Get(teamId); result.Err != nil {
if result := <-app.Srv.Store.Team().Get(teamId); result.Err != nil {
log.WriteString(utils.T("api.slackimport.slack_import.team_fail"))
return nil
} else {
@@ -244,7 +245,7 @@ func SlackAddPosts(teamId string, channel *model.Channel, posts []SlackPost, use
}
ImportPost(&newPost)
for _, fileId := range newPost.FileIds {
if result := <-Srv.Store.FileInfo().AttachToPost(fileId, newPost.Id); result.Err != nil {
if result := <-app.Srv.Store.FileInfo().AttachToPost(fileId, newPost.Id); result.Err != nil {
l4g.Error(utils.T("api.slackimport.slack_add_posts.attach_files.error"), newPost.Id, newPost.FileIds, result.Err)
}
}
@@ -375,7 +376,7 @@ func addSlackUsersToChannel(members []string, users map[string]*model.User, chan
if user, ok := users[member]; !ok {
log.WriteString(utils.T("api.slackimport.slack_add_channels.failed_to_add_user", map[string]interface{}{"Username": "?"}))
} else {
if _, err := AddUserToChannel(user, channel); err != nil {
if _, err := app.AddUserToChannel(user, channel); err != nil {
log.WriteString(utils.T("api.slackimport.slack_add_channels.failed_to_add_user", map[string]interface{}{"Username": user.Username}))
}
}
@@ -425,7 +426,7 @@ func SlackAddChannels(teamId string, slackchannels []SlackChannel, posts map[str
mChannel := ImportChannel(&newChannel)
if mChannel == nil {
// Maybe it already exists?
if result := <-Srv.Store.Channel().GetByName(teamId, sChannel.Name); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetByName(teamId, sChannel.Name); result.Err != nil {
l4g.Warn(utils.T("api.slackimport.slack_add_channels.import_failed.warn"), newChannel.DisplayName)
log.WriteString(utils.T("api.slackimport.slack_add_channels.import_failed", map[string]interface{}{"DisplayName": newChannel.DisplayName}))
continue
@@ -560,7 +561,7 @@ func SlackImport(fileData multipart.File, fileSize int64, teamID string) (*model
deactivateSlackBotUser(botUser)
}
InvalidateAllCaches()
app.InvalidateAllCaches()
log.WriteString(utils.T("api.slackimport.slack_import.notes"))
log.WriteString("=======\r\n\r\n")

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

@@ -8,67 +8,30 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
)
var statusCache *utils.Cache = utils.NewLru(model.STATUS_CACHE_SIZE)
func ClearStatusCache() {
statusCache.Purge()
}
func AddStatusCacheSkipClusterSend(status *model.Status) {
statusCache.Add(status.UserId, status)
}
func AddStatusCache(status *model.Status) {
AddStatusCacheSkipClusterSend(status)
if einterfaces.GetClusterInterface() != nil {
einterfaces.GetClusterInterface().UpdateStatus(status)
}
}
func InitStatus() {
l4g.Debug(utils.T("api.status.init.debug"))
BaseRoutes.Users.Handle("/status", ApiUserRequired(getStatusesHttp)).Methods("GET")
BaseRoutes.Users.Handle("/status/ids", ApiUserRequired(getStatusesByIdsHttp)).Methods("POST")
BaseRoutes.WebSocket.Handle("get_statuses", ApiWebSocketHandler(getStatusesWebSocket))
BaseRoutes.WebSocket.Handle("get_statuses_by_ids", ApiWebSocketHandler(getStatusesByIdsWebSocket))
app.Srv.WebSocketRouter.Handle("get_statuses", ApiWebSocketHandler(getStatusesWebSocket))
app.Srv.WebSocketRouter.Handle("get_statuses_by_ids", ApiWebSocketHandler(getStatusesByIdsWebSocket))
}
func getStatusesHttp(c *Context, w http.ResponseWriter, r *http.Request) {
statusMap := model.StatusMapToInterfaceMap(GetAllStatuses())
statusMap := model.StatusMapToInterfaceMap(app.GetAllStatuses())
w.Write([]byte(model.StringInterfaceToJson(statusMap)))
}
func getStatusesWebSocket(req *model.WebSocketRequest) (map[string]interface{}, *model.AppError) {
statusMap := GetAllStatuses()
statusMap := app.GetAllStatuses()
return model.StatusMapToInterfaceMap(statusMap), nil
}
func GetAllStatuses() map[string]*model.Status {
userIds := statusCache.Keys()
statusMap := map[string]*model.Status{}
for _, userId := range userIds {
if id, ok := userId.(string); !ok {
continue
} else {
status := GetStatusFromCache(id)
if status != nil {
statusMap[id] = status
}
}
}
return statusMap
}
func getStatusesByIdsHttp(c *Context, w http.ResponseWriter, r *http.Request) {
userIds := model.ArrayFromJson(r.Body)
@@ -77,7 +40,7 @@ func getStatusesByIdsHttp(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
statusMap, err := GetStatusesByIds(userIds)
statusMap, err := app.GetStatusesByIds(userIds)
if err != nil {
c.Err = err
return
@@ -93,216 +56,10 @@ func getStatusesByIdsWebSocket(req *model.WebSocketRequest) (map[string]interfac
return nil, NewInvalidWebSocketParamError(req.Action, "user_ids")
}
statusMap, err := GetStatusesByIds(userIds)
statusMap, err := app.GetStatusesByIds(userIds)
if err != nil {
return nil, err
}
return statusMap, nil
}
func GetStatusesByIds(userIds []string) (map[string]interface{}, *model.AppError) {
statusMap := map[string]interface{}{}
metrics := einterfaces.GetMetricsInterface()
missingUserIds := []string{}
for _, userId := range userIds {
if result, ok := statusCache.Get(userId); ok {
statusMap[userId] = result.(*model.Status).Status
if metrics != nil {
metrics.IncrementMemCacheHitCounter("Status")
}
} else {
missingUserIds = append(missingUserIds, userId)
if metrics != nil {
metrics.IncrementMemCacheMissCounter("Status")
}
}
}
if len(missingUserIds) > 0 {
if result := <-Srv.Store.Status().GetByIds(missingUserIds); result.Err != nil {
return nil, result.Err
} else {
statuses := result.Data.([]*model.Status)
for _, s := range statuses {
AddStatusCache(s)
statusMap[s.UserId] = s.Status
}
}
}
// For the case where the user does not have a row in the Status table and cache
for _, userId := range missingUserIds {
if _, ok := statusMap[userId]; !ok {
statusMap[userId] = model.STATUS_OFFLINE
}
}
return statusMap, nil
}
func SetStatusOnline(userId string, sessionId string, manual bool) {
broadcast := false
var oldStatus string = model.STATUS_OFFLINE
var oldTime int64 = 0
var oldManual bool = false
var status *model.Status
var err *model.AppError
if status, err = GetStatus(userId); err != nil {
status = &model.Status{userId, model.STATUS_ONLINE, false, model.GetMillis(), ""}
broadcast = true
} else {
if status.Manual && !manual {
return // manually set status always overrides non-manual one
}
if status.Status != model.STATUS_ONLINE {
broadcast = true
}
oldStatus = status.Status
oldTime = status.LastActivityAt
oldManual = status.Manual
status.Status = model.STATUS_ONLINE
status.Manual = false // for "online" there's no manual setting
status.LastActivityAt = model.GetMillis()
}
AddStatusCache(status)
// Only update the database if the status has changed, the status has been manually set,
// or enough time has passed since the previous action
if status.Status != oldStatus || status.Manual != oldManual || status.LastActivityAt-oldTime > model.STATUS_MIN_UPDATE_TIME {
achan := Srv.Store.Session().UpdateLastActivityAt(sessionId, status.LastActivityAt)
var schan store.StoreChannel
if broadcast {
schan = Srv.Store.Status().SaveOrUpdate(status)
} else {
schan = Srv.Store.Status().UpdateLastActivityAt(status.UserId, status.LastActivityAt)
}
if result := <-achan; result.Err != nil {
l4g.Error(utils.T("api.status.last_activity.error"), userId, sessionId, result.Err)
}
if result := <-schan; result.Err != nil {
l4g.Error(utils.T("api.status.save_status.error"), userId, result.Err)
}
}
if broadcast {
event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_STATUS_CHANGE, "", "", status.UserId, nil)
event.Add("status", model.STATUS_ONLINE)
event.Add("user_id", status.UserId)
go Publish(event)
}
}
func SetStatusOffline(userId string, manual bool) {
status, err := GetStatus(userId)
if err == nil && status.Manual && !manual {
return // manually set status always overrides non-manual one
}
status = &model.Status{userId, model.STATUS_OFFLINE, manual, model.GetMillis(), ""}
AddStatusCache(status)
if result := <-Srv.Store.Status().SaveOrUpdate(status); result.Err != nil {
l4g.Error(utils.T("api.status.save_status.error"), userId, result.Err)
}
event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_STATUS_CHANGE, "", "", status.UserId, nil)
event.Add("status", model.STATUS_OFFLINE)
event.Add("user_id", status.UserId)
go Publish(event)
}
func SetStatusAwayIfNeeded(userId string, manual bool) {
status, err := GetStatus(userId)
if err != nil {
status = &model.Status{userId, model.STATUS_OFFLINE, manual, 0, ""}
}
if !manual && status.Manual {
return // manually set status always overrides non-manual one
}
if !manual {
if status.Status == model.STATUS_AWAY {
return
}
if !IsUserAway(status.LastActivityAt) {
return
}
}
status.Status = model.STATUS_AWAY
status.Manual = manual
status.ActiveChannel = ""
AddStatusCache(status)
if result := <-Srv.Store.Status().SaveOrUpdate(status); result.Err != nil {
l4g.Error(utils.T("api.status.save_status.error"), userId, result.Err)
}
event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_STATUS_CHANGE, "", "", status.UserId, nil)
event.Add("status", model.STATUS_AWAY)
event.Add("user_id", status.UserId)
go Publish(event)
}
func GetStatusFromCache(userId string) *model.Status {
if result, ok := statusCache.Get(userId); ok {
status := result.(*model.Status)
statusCopy := &model.Status{}
*statusCopy = *status
return statusCopy
}
return nil
}
func GetStatus(userId string) (*model.Status, *model.AppError) {
status := GetStatusFromCache(userId)
if status != nil {
return status, nil
}
if result := <-Srv.Store.Status().Get(userId); result.Err != nil {
return nil, result.Err
} else {
return result.Data.(*model.Status), nil
}
}
func IsUserAway(lastActivityAt int64) bool {
return model.GetMillis()-lastActivityAt >= *utils.Cfg.TeamSettings.UserStatusAwayTimeout*1000
}
func DoesStatusAllowPushNotification(user *model.User, status *model.Status, channelId string) bool {
props := user.NotifyProps
if props["push"] == "none" {
return false
}
if pushStatus, ok := props["push_status"]; (pushStatus == model.STATUS_ONLINE || !ok) && (status.ActiveChannel != channelId || model.GetMillis()-status.LastActivityAt > model.STATUS_CHANNEL_TIMEOUT) {
return true
} else if pushStatus == model.STATUS_AWAY && (status.Status == model.STATUS_AWAY || status.Status == model.STATUS_OFFLINE) {
return true
} else if pushStatus == model.STATUS_OFFLINE && status.Status == model.STATUS_OFFLINE {
return true
}
return false
}

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

@@ -8,6 +8,7 @@ import (
"testing"
"time"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -34,12 +35,12 @@ func TestStatuses(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
LinkUserToTeam(ruser, rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
user2 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser2 := Client.Must(Client.CreateUser(&user2, "")).Data.(*model.User)
LinkUserToTeam(ruser2, rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser2.Id))
Client.Login(user.Email, user.Password)
Client.SetTeamId(team.Id)
@@ -137,7 +138,7 @@ func TestStatuses(t *testing.T) {
WebSocketClient2.Close()
SetStatusAwayIfNeeded(th.BasicUser.Id, false)
app.SetStatusAwayIfNeeded(th.BasicUser.Id, false)
awayTimeout := *utils.Cfg.TeamSettings.UserStatusAwayTimeout
defer func() {
@@ -147,8 +148,8 @@ func TestStatuses(t *testing.T) {
time.Sleep(1500 * time.Millisecond)
SetStatusAwayIfNeeded(th.BasicUser.Id, false)
SetStatusOnline(th.BasicUser.Id, "junk", false)
app.SetStatusAwayIfNeeded(th.BasicUser.Id, false)
app.SetStatusOnline(th.BasicUser.Id, "junk", false)
time.Sleep(1500 * time.Millisecond)

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

@@ -16,6 +16,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -61,7 +62,7 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
var user *model.User
if len(c.Session.UserId) > 0 {
uchan := Srv.Store.User().Get(c.Session.UserId)
uchan := app.Srv.Store.User().Get(c.Session.UserId)
if result := <-uchan; result.Err != nil {
c.Err = result.Err
@@ -76,13 +77,14 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
rteam := CreateTeam(c, team)
if c.Err != nil {
rteam, err := app.CreateTeam(team)
if err != nil {
c.Err = err
return
}
if user != nil {
err := JoinUserToTeam(team, user)
err := app.JoinUserToTeam(team, user)
if err != nil {
c.Err = err
return
@@ -92,84 +94,11 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(rteam.ToJson()))
}
func CreateTeam(c *Context, team *model.Team) *model.Team {
if result := <-Srv.Store.Team().Save(team); result.Err != nil {
c.Err = result.Err
return nil
} else {
rteam := result.Data.(*model.Team)
if _, err := CreateDefaultChannels(c, rteam.Id); err != nil {
c.Err = err
return nil
}
return rteam
}
}
func JoinUserToTeamById(teamId string, user *model.User) *model.AppError {
if result := <-Srv.Store.Team().Get(teamId); result.Err != nil {
return result.Err
} else {
return JoinUserToTeam(result.Data.(*model.Team), user)
}
}
func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError {
tm := &model.TeamMember{
TeamId: team.Id,
UserId: user.Id,
Roles: model.ROLE_TEAM_USER.Id,
}
channelRole := model.ROLE_CHANNEL_USER.Id
if team.Email == user.Email {
tm.Roles = model.ROLE_TEAM_USER.Id + " " + model.ROLE_TEAM_ADMIN.Id
channelRole = model.ROLE_CHANNEL_USER.Id + " " + model.ROLE_CHANNEL_ADMIN.Id
}
if etmr := <-Srv.Store.Team().GetMember(team.Id, user.Id); etmr.Err == nil {
// Membership alredy exists. Check if deleted and and update, otherwise do nothing
rtm := etmr.Data.(model.TeamMember)
// Do nothing if already added
if rtm.DeleteAt == 0 {
return nil
}
if tmr := <-Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
return tmr.Err
}
} else {
// Membership appears to be missing. Lets try to add.
if tmr := <-Srv.Store.Team().SaveMember(tm); tmr.Err != nil {
return tmr.Err
}
}
if uua := <-Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil {
return uua.Err
}
// Soft error if there is an issue joining the default channels
if err := JoinDefaultChannels(team.Id, user, channelRole); err != nil {
l4g.Error(utils.T("api.user.create_user.joining.error"), user.Id, team.Id, err)
}
RemoveAllSessionsForUserId(user.Id)
InvalidateCacheForUser(user.Id)
return nil
}
func LeaveTeam(team *model.Team, user *model.User) *model.AppError {
var teamMember model.TeamMember
if result := <-Srv.Store.Team().GetMember(team.Id, user.Id); result.Err != nil {
if result := <-app.Srv.Store.Team().GetMember(team.Id, user.Id); result.Err != nil {
return model.NewLocAppError("RemoveUserFromTeam", "api.team.remove_user_from_team.missing.app_error", nil, result.Err.Error())
} else {
teamMember = result.Data.(model.TeamMember)
@@ -177,7 +106,7 @@ func LeaveTeam(team *model.Team, user *model.User) *model.AppError {
var channelList *model.ChannelList
if result := <-Srv.Store.Channel().GetChannels(team.Id, user.Id); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetChannels(team.Id, user.Id); result.Err != nil {
if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" {
channelList = &model.ChannelList{}
} else {
@@ -190,8 +119,8 @@ func LeaveTeam(team *model.Team, user *model.User) *model.AppError {
for _, channel := range *channelList {
if channel.Type != model.CHANNEL_DIRECT {
InvalidateCacheForChannel(channel.Id)
if result := <-Srv.Store.Channel().RemoveMember(channel.Id, user.Id); result.Err != nil {
app.InvalidateCacheForChannel(channel.Id)
if result := <-app.Srv.Store.Channel().RemoveMember(channel.Id, user.Id); result.Err != nil {
return result.Err
}
}
@@ -201,26 +130,26 @@ func LeaveTeam(team *model.Team, user *model.User) *model.AppError {
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_LEAVE_TEAM, team.Id, "", "", nil)
message.Add("user_id", user.Id)
message.Add("team_id", team.Id)
Publish(message)
app.Publish(message)
teamMember.Roles = ""
teamMember.DeleteAt = model.GetMillis()
if result := <-Srv.Store.Team().UpdateMember(&teamMember); result.Err != nil {
if result := <-app.Srv.Store.Team().UpdateMember(&teamMember); result.Err != nil {
return result.Err
}
if uua := <-Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil {
if uua := <-app.Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil {
return uua.Err
}
// delete the preferences that set the last channel used in the team and other team specific preferences
if result := <-Srv.Store.Preference().DeleteCategory(user.Id, team.Id); result.Err != nil {
if result := <-app.Srv.Store.Preference().DeleteCategory(user.Id, team.Id); result.Err != nil {
return result.Err
}
RemoveAllSessionsForUserId(user.Id)
InvalidateCacheForUser(user.Id)
app.RemoveAllSessionsForUserId(user.Id)
app.InvalidateCacheForUser(user.Id)
return nil
}
@@ -235,7 +164,7 @@ func isTeamCreationAllowed(c *Context, email string) bool {
}
c.Err = nil
if result := <-Srv.Store.User().GetByEmail(email); result.Err == nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err == nil {
user := result.Data.(*model.User)
if len(user.AuthService) > 0 && len(*user.AuthData) > 0 {
return true
@@ -263,7 +192,7 @@ func isTeamCreationAllowed(c *Context, email string) bool {
}
func GetAllTeamListings(c *Context, w http.ResponseWriter, r *http.Request) {
if result := <-Srv.Store.Team().GetAllTeamListing(); result.Err != nil {
if result := <-app.Srv.Store.Team().GetAllTeamListing(); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -286,10 +215,10 @@ func GetAllTeamListings(c *Context, w http.ResponseWriter, r *http.Request) {
func getAll(c *Context, w http.ResponseWriter, r *http.Request) {
var tchan store.StoreChannel
if HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
tchan = Srv.Store.Team().GetAll()
tchan = app.Srv.Store.Team().GetAll()
} else {
c.Err = nil
tchan = Srv.Store.Team().GetTeamsByUserId(c.Session.UserId)
tchan = app.Srv.Store.Team().GetTeamsByUserId(c.Session.UserId)
}
if result := <-tchan; result.Err != nil {
@@ -310,7 +239,7 @@ func revokeAllSessions(c *Context, w http.ResponseWriter, r *http.Request) {
props := model.MapFromJson(r.Body)
id := props["id"]
if result := <-Srv.Store.Session().Get(id); result.Err != nil {
if result := <-app.Srv.Store.Session().Get(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -321,11 +250,11 @@ func revokeAllSessions(c *Context, w http.ResponseWriter, r *http.Request) {
if session.IsOAuth {
RevokeAccessToken(session.Token)
} else {
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
if result := <-app.Srv.Store.Session().Remove(session.Id); result.Err != nil {
c.Err = result.Err
return
} else {
RemoveAllSessionsForUserId(session.UserId)
app.RemoveAllSessionsForUserId(session.UserId)
w.Write([]byte(model.MapToJson(props)))
return
}
@@ -354,8 +283,8 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
tchan := Srv.Store.Team().Get(c.TeamId)
uchan := Srv.Store.User().Get(c.Session.UserId)
tchan := app.Srv.Store.Team().Get(c.TeamId)
uchan := app.Srv.Store.User().Get(c.Session.UserId)
var team *model.Team
if result := <-tchan; result.Err != nil {
@@ -392,8 +321,8 @@ func addUserToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
tchan := Srv.Store.Team().Get(c.TeamId)
uchan := Srv.Store.User().Get(userId)
tchan := app.Srv.Store.Team().Get(c.TeamId)
uchan := app.Srv.Store.User().Get(userId)
var team *model.Team
if result := <-tchan; result.Err != nil {
@@ -415,7 +344,7 @@ func addUserToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
err := JoinUserToTeam(team, user)
err := app.JoinUserToTeam(team, user)
if err != nil {
c.Err = err
return
@@ -433,8 +362,8 @@ func removeUserFromTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
tchan := Srv.Store.Team().Get(c.TeamId)
uchan := Srv.Store.User().Get(userId)
tchan := app.Srv.Store.Team().Get(c.TeamId)
uchan := app.Srv.Store.User().Get(userId)
var team *model.Team
if result := <-tchan; result.Err != nil {
@@ -494,7 +423,7 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request)
teamId = props["id"]
// try to load the team to make sure it exists
if result := <-Srv.Store.Team().Get(teamId); result.Err != nil {
if result := <-app.Srv.Store.Team().Get(teamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -503,7 +432,7 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request)
}
if len(inviteId) > 0 {
if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -517,7 +446,7 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request)
return
}
uchan := Srv.Store.User().Get(c.Session.UserId)
uchan := app.Srv.Store.User().Get(c.Session.UserId)
var user *model.User
if result := <-uchan; result.Err != nil {
@@ -530,7 +459,7 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request)
tm := c.Session.GetTeamByTeamId(teamId)
if tm == nil {
err := JoinUserToTeam(team, user)
err := app.JoinUserToTeam(team, user)
if err != nil {
c.Err = err
return
@@ -543,7 +472,7 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request)
}
func FindTeamByName(name string) bool {
if result := <-Srv.Store.Team().GetByName(name); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(name); result.Err != nil {
return false
} else {
return true
@@ -568,7 +497,7 @@ func getTeamByName(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
teamname := params["team_name"]
if result := <-Srv.Store.Team().GetByName(teamname); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(teamname); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -589,7 +518,7 @@ func getMyTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
if len(c.Session.TeamMembers) > 0 {
w.Write([]byte(model.TeamMembersToJson(c.Session.TeamMembers)))
} else {
if result := <-Srv.Store.Team().GetTeamsForUser(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.Team().GetTeamsForUser(c.Session.UserId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -602,7 +531,7 @@ func getMyTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
func getMyTeamsUnread(c *Context, w http.ResponseWriter, r *http.Request) {
teamId := r.URL.Query().Get("id")
if result := <-Srv.Store.Team().GetTeamsUnreadForUser(teamId, c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.Team().GetTeamsUnreadForUser(teamId, c.Session.UserId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -696,7 +625,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
}
var oldTeam *model.Team
if result := <-Srv.Store.Team().Get(team.Id); result.Err != nil {
if result := <-app.Srv.Store.Team().Get(team.Id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -711,7 +640,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
oldTeam.AllowedDomains = team.AllowedDomains
//oldTeam.Type = team.Type
if result := <-Srv.Store.Team().Update(oldTeam); result.Err != nil {
if result := <-app.Srv.Store.Team().Update(oldTeam); result.Err != nil {
c.Err = result.Err
return
}
@@ -720,7 +649,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_UPDATE_TEAM, "", "", "", nil)
message.Add("team", oldTeam.ToJson())
go Publish(message)
go app.Publish(message)
w.Write([]byte(oldTeam.ToJson()))
}
@@ -734,7 +663,7 @@ func updateMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
mchan := Srv.Store.Team().GetTeamsForUser(userId)
mchan := app.Srv.Store.Team().GetTeamsForUser(userId)
teamId := c.TeamId
@@ -769,12 +698,12 @@ func updateMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
member.Roles = newRoles
if result := <-Srv.Store.Team().UpdateMember(member); result.Err != nil {
if result := <-app.Srv.Store.Team().UpdateMember(member); result.Err != nil {
c.Err = result.Err
return
}
RemoveAllSessionsForUserId(userId)
app.RemoveAllSessionsForUserId(userId)
rdata := map[string]string{}
rdata["status"] = "ok"
@@ -783,19 +712,19 @@ func updateMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
func PermanentDeleteTeam(team *model.Team) *model.AppError {
team.DeleteAt = model.GetMillis()
if result := <-Srv.Store.Team().Update(team); result.Err != nil {
if result := <-app.Srv.Store.Team().Update(team); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Channel().PermanentDeleteByTeam(team.Id); result.Err != nil {
if result := <-app.Srv.Store.Channel().PermanentDeleteByTeam(team.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Team().RemoveAllMembersByTeam(team.Id); result.Err != nil {
if result := <-app.Srv.Store.Team().RemoveAllMembersByTeam(team.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil {
if result := <-app.Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil {
return result.Err
}
@@ -808,7 +737,7 @@ func getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Team().Get(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Team().Get(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else if HandleEtag(result.Data.(*model.Team).Etag(), "Get My Team", w, r) {
@@ -827,8 +756,8 @@ func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
tchan := Srv.Store.Team().GetTotalMemberCount(c.TeamId)
achan := Srv.Store.Team().GetActiveMemberCount(c.TeamId)
tchan := app.Srv.Store.Team().GetTotalMemberCount(c.TeamId)
achan := app.Srv.Store.Team().GetActiveMemberCount(c.TeamId)
stats := &model.TeamStats{}
stats.TeamId = c.TeamId
@@ -925,7 +854,7 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
m := model.MapFromJson(r.Body)
inviteId := m["invite_id"]
if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -965,7 +894,7 @@ func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if result := <-Srv.Store.Team().GetMembers(c.TeamId, offset, limit); result.Err != nil {
if result := <-app.Srv.Store.Team().GetMembers(c.TeamId, offset, limit); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -990,7 +919,7 @@ func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if result := <-Srv.Store.Team().GetMember(c.TeamId, userId); result.Err != nil {
if result := <-app.Srv.Store.Team().GetMember(c.TeamId, userId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1013,7 +942,7 @@ func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if result := <-Srv.Store.Team().GetMembersByIds(c.TeamId, userIds); result.Err != nil {
if result := <-app.Srv.Store.Team().GetMembersByIds(c.TeamId, userIds); result.Err != nil {
c.Err = result.Err
return
} else {

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

@@ -6,6 +6,7 @@ package api
import (
"testing"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -25,7 +26,7 @@ func TestCreateTeam(t *testing.T) {
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
Client.Login(user.Email, "passwd1")
Client.SetTeamId(rteam.Data.(*model.Team).Id)
@@ -140,7 +141,7 @@ func TestGetAllTeams(t *testing.T) {
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
Client.Login(user.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -173,7 +174,7 @@ func TestGetAllTeamListings(t *testing.T) {
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
Client.Login(user.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -219,7 +220,7 @@ func TestTeamPermDelete(t *testing.T) {
user1 := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
LinkUserToTeam(user1, team)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user1.Id))
Client.Login(user1.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -263,7 +264,7 @@ func TestInviteMembers(t *testing.T) {
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
Client.Login(user.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -347,12 +348,12 @@ func TestUpdateTeamDisplayName(t *testing.T) {
user := &model.User{Email: team.Email, Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
user2 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
LinkUserToTeam(user2, team)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
Client.Login(user2.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -413,7 +414,7 @@ func TestGetMyTeam(t *testing.T) {
user := model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
Client.Login(user.Email, user.Password)
Client.SetTeamId(team.Id)
@@ -658,7 +659,7 @@ func TestGetTeamStats(t *testing.T) {
user := model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
Client.Login(user.Email, user.Password)
@@ -678,12 +679,12 @@ func TestUpdateTeamDescription(t *testing.T) {
user := &model.User{Email: team.Email, Nickname: "My Testing", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
user2 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Jabba the Hutt", Password: "passwd1"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
LinkUserToTeam(user2, team)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
Client.Login(user2.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -721,7 +722,7 @@ func TestGetTeamByName(t *testing.T) {
user := &model.User{Email: team.Email, Nickname: "My Testing", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
Client.Login(user.Email, "passwd1")
if _, err := Client.GetTeamByName(team.Name); err != nil {
@@ -740,7 +741,7 @@ func TestGetTeamByName(t *testing.T) {
user2 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Jabba the Hutt", Password: "passwd1"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
Client.Login(user2.Email, "passwd1")

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

@@ -27,6 +27,7 @@ import (
"github.com/disintegration/imaging"
"github.com/golang/freetype"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
@@ -84,7 +85,7 @@ func InitUser() {
BaseRoutes.Root.Handle("/login/sso/saml", AppHandlerIndependent(loginWithSaml)).Methods("GET")
BaseRoutes.Root.Handle("/login/sso/saml", AppHandlerIndependent(completeSaml)).Methods("POST")
BaseRoutes.WebSocket.Handle("user_typing", ApiWebSocketHandler(userTyping))
app.Srv.WebSocketRouter.Handle("user_typing", ApiWebSocketHandler(userTyping))
}
func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -125,7 +126,7 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
teamId = props["id"]
// try to load the team to make sure it exists
if result := <-Srv.Store.Team().Get(teamId); result.Err != nil {
if result := <-app.Srv.Store.Team().Get(teamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -139,7 +140,7 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
inviteId := r.URL.Query().Get("iid")
if len(inviteId) > 0 {
if result := <-Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -149,8 +150,8 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
}
firstAccount := false
if sessionCache.Len() == 0 {
if cr := <-Srv.Store.User().GetTotalUsersCount(); cr.Err != nil {
if app.SessionCacheLength() == 0 {
if cr := <-app.Srv.Store.User().GetTotalUsersCount(); cr.Err != nil {
c.Err = cr.Err
return
} else {
@@ -171,14 +172,14 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
ruser, err := CreateUser(user)
ruser, err := app.CreateUser(user)
if err != nil {
c.Err = err
return
}
if len(teamId) > 0 {
err := JoinUserToTeam(team, ruser)
err := app.JoinUserToTeam(team, ruser)
if err != nil {
c.Err = err
return
@@ -238,56 +239,6 @@ func IsVerifyHashRequired(user *model.User, team *model.Team, hash string) bool
return shouldVerifyHash
}
func CreateUser(user *model.User) (*model.User, *model.AppError) {
user.Roles = model.ROLE_SYSTEM_USER.Id
// Below is a special case where the first user in the entire
// system is granted the system_admin role
if result := <-Srv.Store.User().GetTotalUsersCount(); result.Err != nil {
return nil, result.Err
} else {
count := result.Data.(int64)
if count <= 0 {
user.Roles = model.ROLE_SYSTEM_ADMIN.Id + " " + model.ROLE_SYSTEM_USER.Id
}
}
user.MakeNonNil()
user.Locale = *utils.Cfg.LocalizationSettings.DefaultClientLocale
if err := utils.IsPasswordValid(user.Password); user.AuthService == "" && err != nil {
return nil, err
}
if result := <-Srv.Store.User().Save(user); result.Err != nil {
l4g.Error(utils.T("api.user.create_user.save.error"), result.Err)
return nil, result.Err
} else {
ruser := result.Data.(*model.User)
if user.EmailVerified {
if cresult := <-Srv.Store.User().VerifyEmail(ruser.Id); cresult.Err != nil {
l4g.Error(utils.T("api.user.create_user.verified.error"), cresult.Err)
}
}
pref := model.Preference{UserId: ruser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: ruser.Id, Value: "0"}
if presult := <-Srv.Store.Preference().Save(&model.Preferences{pref}); presult.Err != nil {
l4g.Error(utils.T("api.user.create_user.tutorial.error"), presult.Err.Message)
}
ruser.Sanitize(map[string]bool{})
// This message goes to everyone, so the teamId, channelId and userId are irrelevant
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_NEW_USER, "", "", "", nil)
message.Add("user_id", ruser.Id)
go Publish(message)
return ruser, nil
}
}
func CreateOAuthUser(c *Context, w http.ResponseWriter, r *http.Request, service string, userData io.Reader, teamId string) *model.User {
var user *model.User
provider := einterfaces.GetOauthProvider(service)
@@ -303,8 +254,8 @@ func CreateOAuthUser(c *Context, w http.ResponseWriter, r *http.Request, service
return nil
}
suchan := Srv.Store.User().GetByAuth(user.AuthData, service)
euchan := Srv.Store.User().GetByEmail(user.Email)
suchan := app.Srv.Store.User().GetByAuth(user.AuthData, service)
euchan := app.Srv.Store.User().GetByEmail(user.Email)
found := true
count := 0
@@ -335,14 +286,14 @@ func CreateOAuthUser(c *Context, w http.ResponseWriter, r *http.Request, service
user.EmailVerified = true
ruser, err := CreateUser(user)
ruser, err := app.CreateUser(user)
if err != nil {
c.Err = err
return nil
}
if len(teamId) > 0 {
err = JoinUserToTeamById(teamId, user)
err = app.JoinUserToTeamById(teamId, user)
if err != nil {
c.Err = err
return nil
@@ -390,7 +341,7 @@ func sendWelcomeEmail(c *Context, userId string, email string, siteURL string, v
func addDirectChannels(teamId string, user *model.User) {
var profiles map[string]*model.User
if result := <-Srv.Store.User().GetProfiles(teamId, 0, 100); result.Err != nil {
if result := <-app.Srv.Store.User().GetProfiles(teamId, 0, 100); result.Err != nil {
l4g.Error(utils.T("api.user.add_direct_channels_and_forget.failed.error"), user.Id, teamId, result.Err.Error())
return
} else {
@@ -420,7 +371,7 @@ func addDirectChannels(teamId string, user *model.User) {
}
}
if result := <-Srv.Store.Preference().Save(&preferences); result.Err != nil {
if result := <-app.Srv.Store.Preference().Save(&preferences); result.Err != nil {
l4g.Error(utils.T("api.user.add_direct_channels_and_forget.failed.error"), user.Id, teamId, result.Err.Error())
}
}
@@ -467,7 +418,7 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) {
if len(id) != 0 {
c.LogAuditWithUserId(id, "attempt")
if result := <-Srv.Store.User().Get(id); result.Err != nil {
if result := <-app.Srv.Store.User().Get(id); result.Err != nil {
c.LogAuditWithUserId(id, "failure")
c.Err = result.Err
c.Err.StatusCode = http.StatusBadRequest
@@ -521,7 +472,7 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) {
func getUserForLogin(loginId string, onlyLdap bool) (*model.User, *model.AppError) {
ldapAvailable := *utils.Cfg.LdapSettings.Enable && einterfaces.GetLdapInterface() != nil && utils.IsLicensed && *utils.License.Features.LDAP
if result := <-Srv.Store.User().GetForLogin(
if result := <-app.Srv.Store.User().GetForLogin(
loginId,
*utils.Cfg.EmailSettings.EnableSignInWithUsername && !onlyLdap,
*utils.Cfg.EmailSettings.EnableSignInWithEmail && !onlyLdap,
@@ -570,7 +521,7 @@ func LoginByOAuth(c *Context, w http.ResponseWriter, r *http.Request, service st
}
var user *model.User
if result := <-Srv.Store.User().GetByAuth(&authData, service); result.Err != nil {
if result := <-app.Srv.Store.User().GetByAuth(&authData, service); result.Err != nil {
if result.Err.Id == store.MISSING_AUTH_ACCOUNT_ERROR {
return CreateOAuthUser(c, w, r, service, bytes.NewReader(buf.Bytes()), "")
}
@@ -598,7 +549,7 @@ func doLogin(c *Context, w http.ResponseWriter, r *http.Request, user *model.Use
maxAge = *utils.Cfg.ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
// A special case where we logout of all other sessions with the same Id
if result := <-Srv.Store.Session().GetSessions(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Session().GetSessions(user.Id); result.Err != nil {
c.Err = result.Err
c.Err.StatusCode = http.StatusInternalServerError
return
@@ -648,13 +599,13 @@ func doLogin(c *Context, w http.ResponseWriter, r *http.Request, user *model.Use
session.AddProp(model.SESSION_PROP_OS, os)
session.AddProp(model.SESSION_PROP_BROWSER, fmt.Sprintf("%v/%v", bname, bversion))
if result := <-Srv.Store.Session().Save(session); result.Err != nil {
if result := <-app.Srv.Store.Session().Save(session); result.Err != nil {
c.Err = result.Err
c.Err.StatusCode = http.StatusInternalServerError
return
} else {
session = result.Data.(*model.Session)
AddSessionToCache(session)
app.AddSessionToCache(session)
}
w.Header().Set(model.HEADER_TOKEN, session.Token)
@@ -702,7 +653,7 @@ func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
}
// A special case where we logout of all other sessions with the same Id
if result := <-Srv.Store.Session().GetSessions(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.Session().GetSessions(c.Session.UserId); result.Err != nil {
c.Err = result.Err
c.Err.StatusCode = http.StatusInternalServerError
return
@@ -720,7 +671,7 @@ func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
RemoveAllSessionsForUserId(c.Session.UserId)
app.RemoveAllSessionsForUserId(c.Session.UserId)
c.Session.SetExpireInDays(*utils.Cfg.ServiceSettings.SessionLengthMobileInDays)
maxAge := *utils.Cfg.ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
@@ -743,7 +694,7 @@ func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
http.SetCookie(w, sessionCookie)
if result := <-Srv.Store.Session().UpdateDeviceId(c.Session.Id, deviceId, c.Session.ExpiresAt); result.Err != nil {
if result := <-app.Srv.Store.Session().UpdateDeviceId(c.Session.Id, deviceId, c.Session.ExpiresAt); result.Err != nil {
c.Err = result.Err
return
}
@@ -752,7 +703,7 @@ func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
}
func RevokeSessionById(c *Context, sessionId string) {
if result := <-Srv.Store.Session().Get(sessionId); result.Err != nil {
if result := <-app.Srv.Store.Session().Get(sessionId); result.Err != nil {
c.Err = result.Err
} else {
session := result.Data.(*model.Session)
@@ -761,19 +712,19 @@ func RevokeSessionById(c *Context, sessionId string) {
if session.IsOAuth {
RevokeAccessToken(session.Token)
} else {
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
if result := <-app.Srv.Store.Session().Remove(session.Id); result.Err != nil {
c.Err = result.Err
}
}
RevokeWebrtcToken(session.Id)
RemoveAllSessionsForUserId(session.UserId)
app.RemoveAllSessionsForUserId(session.UserId)
}
}
// IF YOU UPDATE THIS PLEASE UPDATE BELOW
func RevokeAllSession(c *Context, userId string) {
if result := <-Srv.Store.Session().GetSessions(userId); result.Err != nil {
if result := <-app.Srv.Store.Session().GetSessions(userId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -784,7 +735,7 @@ func RevokeAllSession(c *Context, userId string) {
if session.IsOAuth {
RevokeAccessToken(session.Token)
} else {
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
if result := <-app.Srv.Store.Session().Remove(session.Id); result.Err != nil {
c.Err = result.Err
return
}
@@ -794,13 +745,13 @@ func RevokeAllSession(c *Context, userId string) {
}
}
RemoveAllSessionsForUserId(userId)
app.RemoveAllSessionsForUserId(userId)
}
// UGH...
// If you update this please update above
func RevokeAllSessionsNoContext(userId string) *model.AppError {
if result := <-Srv.Store.Session().GetSessions(userId); result.Err != nil {
if result := <-app.Srv.Store.Session().GetSessions(userId); result.Err != nil {
return result.Err
} else {
sessions := result.Data.([]*model.Session)
@@ -809,7 +760,7 @@ func RevokeAllSessionsNoContext(userId string) *model.AppError {
if session.IsOAuth {
RevokeAccessToken(session.Token)
} else {
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
if result := <-app.Srv.Store.Session().Remove(session.Id); result.Err != nil {
return result.Err
}
}
@@ -818,7 +769,7 @@ func RevokeAllSessionsNoContext(userId string) *model.AppError {
}
}
RemoveAllSessionsForUserId(userId)
app.RemoveAllSessionsForUserId(userId)
return nil
}
@@ -832,7 +783,7 @@ func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Session().GetSessions(id); result.Err != nil {
if result := <-app.Srv.Store.Session().GetSessions(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -865,7 +816,7 @@ func Logout(c *Context, w http.ResponseWriter, r *http.Request) {
func getMe(c *Context, w http.ResponseWriter, r *http.Request) {
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
c.Err = result.Err
c.RemoveSessionCookie(w, r)
l4g.Error(utils.T("api.user.get_me.getting.error"), c.Session.UserId)
@@ -886,17 +837,17 @@ func getInitialLoad(c *Context, w http.ResponseWriter, r *http.Request) {
var cchan store.StoreChannel
if sessionCache.Len() == 0 {
if app.SessionCacheLength() == 0 {
// Below is a special case when intializating a new server
// Lets check to make sure the server is really empty
cchan = Srv.Store.User().GetTotalUsersCount()
cchan = app.Srv.Store.User().GetTotalUsersCount()
}
if len(c.Session.UserId) != 0 {
uchan := Srv.Store.User().Get(c.Session.UserId)
pchan := Srv.Store.Preference().GetAll(c.Session.UserId)
tchan := Srv.Store.Team().GetTeamsByUserId(c.Session.UserId)
uchan := app.Srv.Store.User().Get(c.Session.UserId)
pchan := app.Srv.Store.Preference().GetAll(c.Session.UserId)
tchan := app.Srv.Store.Team().GetTeamsByUserId(c.Session.UserId)
il.TeamMembers = c.Session.TeamMembers
@@ -954,7 +905,7 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["user_id"]
if result := <-Srv.Store.User().Get(id); result.Err != nil {
if result := <-app.Srv.Store.User().Get(id); result.Err != nil {
c.Err = result.Err
return
} else if HandleEtag(result.Data.(*model.User).Etag(utils.Cfg.PrivacySettings.ShowFullName, utils.Cfg.PrivacySettings.ShowEmailAddress), "Get User", w, r) {
@@ -972,7 +923,7 @@ func getByUsername(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
username := params["username"]
if result := <-Srv.Store.User().GetByUsername(username); result.Err != nil {
if result := <-app.Srv.Store.User().GetByUsername(username); result.Err != nil {
c.Err = result.Err
return
} else if HandleEtag(result.Data.(*model.User).Etag(utils.Cfg.PrivacySettings.ShowFullName, utils.Cfg.PrivacySettings.ShowEmailAddress), "Get By Username", w, r) {
@@ -990,7 +941,7 @@ func getByEmail(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
email := params["email"]
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err != nil {
c.Err = result.Err
return
} else if HandleEtag(result.Data.(*model.User).Etag(utils.Cfg.PrivacySettings.ShowFullName, utils.Cfg.PrivacySettings.ShowEmailAddress), "Get By Email", w, r) {
@@ -1019,12 +970,12 @@ func getProfiles(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
etag := (<-Srv.Store.User().GetEtagForAllProfiles()).Data.(string)
etag := (<-app.Srv.Store.User().GetEtagForAllProfiles()).Data.(string)
if HandleEtag(etag, "Get Profiles", w, r) {
return
}
if result := <-Srv.Store.User().GetAllProfiles(offset, limit); result.Err != nil {
if result := <-app.Srv.Store.User().GetAllProfiles(offset, limit); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1061,12 +1012,12 @@ func getProfilesInTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
etag := (<-Srv.Store.User().GetEtagForProfiles(teamId)).Data.(string)
etag := (<-app.Srv.Store.User().GetEtagForProfiles(teamId)).Data.(string)
if HandleEtag(etag, "Get Profiles In Team", w, r) {
return
}
if result := <-Srv.Store.User().GetProfiles(teamId, offset, limit); result.Err != nil {
if result := <-app.Srv.Store.User().GetProfiles(teamId, offset, limit); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1107,7 +1058,7 @@ func getProfilesInChannel(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.User().GetProfilesInChannel(channelId, offset, limit, false); result.Err != nil {
if result := <-app.Srv.Store.User().GetProfilesInChannel(channelId, offset, limit, false); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1147,7 +1098,7 @@ func getProfilesNotInChannel(c *Context, w http.ResponseWriter, r *http.Request)
return
}
if result := <-Srv.Store.User().GetProfilesNotInChannel(c.TeamId, channelId, offset, limit); result.Err != nil {
if result := <-app.Srv.Store.User().GetProfilesNotInChannel(c.TeamId, channelId, offset, limit); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1169,8 +1120,8 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
userChan := Srv.Store.User().Get(id)
auditChan := Srv.Store.Audit().Get(id, 20)
userChan := app.Srv.Store.User().Get(id)
auditChan := app.Srv.Store.Audit().Get(id, 20)
if c.Err = (<-userChan).Err; c.Err != nil {
return
@@ -1278,7 +1229,7 @@ func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
var etag string
if result := <-Srv.Store.User().Get(id); result.Err != nil {
if result := <-app.Srv.Store.User().Get(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1407,9 +1358,9 @@ func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
Srv.Store.User().UpdateLastPictureUpdate(c.Session.UserId)
app.Srv.Store.User().UpdateLastPictureUpdate(c.Session.UserId)
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
l4g.Error(utils.T("api.user.get_me.getting.error"), c.Session.UserId)
} else {
user := result.Data.(*model.User)
@@ -1419,7 +1370,7 @@ func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", omitUsers)
message.Add("user", user)
go Publish(message)
go app.Publish(message)
}
c.LogAudit("")
@@ -1445,7 +1396,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.User().Update(user, false); result.Err != nil {
if result := <-app.Srv.Store.User().Update(user, false); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1465,7 +1416,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) {
go sendEmailChangeUsername(c, rusers[1].Username, rusers[0].Username, rusers[0].Email, c.GetSiteURL())
}
InvalidateCacheForUser(user.Id)
app.InvalidateCacheForUser(user.Id)
updatedUser := rusers[0]
updatedUser = sanitizeProfile(c, updatedUser)
@@ -1474,7 +1425,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) {
omitUsers[user.Id] = true
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", omitUsers)
message.Add("user", updatedUser)
go Publish(message)
go app.Publish(message)
rusers[0].Password = ""
rusers[0].AuthData = new(string)
@@ -1514,7 +1465,7 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
var result store.StoreResult
if result = <-Srv.Store.User().Get(userId); result.Err != nil {
if result = <-app.Srv.Store.User().Get(userId); result.Err != nil {
c.Err = result.Err
return
}
@@ -1544,7 +1495,7 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if uresult := <-Srv.Store.User().UpdatePassword(c.Session.UserId, model.HashPassword(newPassword)); uresult.Err != nil {
if uresult := <-app.Srv.Store.User().UpdatePassword(c.Session.UserId, model.HashPassword(newPassword)); uresult.Err != nil {
c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.failed.app_error", nil, uresult.Err.Error())
return
} else {
@@ -1579,7 +1530,7 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
}
var user *model.User
if result := <-Srv.Store.User().Get(userId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(userId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1600,8 +1551,8 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
func UpdateUserRoles(user *model.User, newRoles string) (*model.User, *model.AppError) {
user.Roles = newRoles
uchan := Srv.Store.User().Update(user, true)
schan := Srv.Store.Session().UpdateRoles(user.Id, newRoles)
uchan := app.Srv.Store.User().Update(user, true)
schan := app.Srv.Store.Session().UpdateRoles(user.Id, newRoles)
var ruser *model.User
if result := <-uchan; result.Err != nil {
@@ -1615,7 +1566,7 @@ func UpdateUserRoles(user *model.User, newRoles string) (*model.User, *model.App
l4g.Error(result.Err)
}
RemoveAllSessionsForUserId(user.Id)
app.RemoveAllSessionsForUserId(user.Id)
return ruser, nil
}
@@ -1632,7 +1583,7 @@ func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
active := props["active"] == "true"
var user *model.User
if result := <-Srv.Store.User().Get(user_id); result.Err != nil {
if result := <-app.Srv.Store.User().Get(user_id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -1658,7 +1609,7 @@ func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = err
} else {
if !active {
SetStatusOffline(ruser.Id, false)
app.SetStatusOffline(ruser.Id, false)
}
c.LogAuditWithUserId(ruser.Id, fmt.Sprintf("active=%v", active))
@@ -1673,14 +1624,14 @@ func UpdateActive(user *model.User, active bool) (*model.User, *model.AppError)
user.DeleteAt = model.GetMillis()
}
if result := <-Srv.Store.User().Update(user, true); result.Err != nil {
if result := <-app.Srv.Store.User().Update(user, true); result.Err != nil {
return nil, result.Err
} else {
if user.DeleteAt > 0 {
RevokeAllSessionsNoContext(user.Id)
}
if extra := <-Srv.Store.Channel().ExtraUpdateByUser(user.Id, model.GetMillis()); extra.Err != nil {
if extra := <-app.Srv.Store.Channel().ExtraUpdateByUser(user.Id, model.GetMillis()); extra.Err != nil {
return nil, extra.Err
}
@@ -1702,51 +1653,51 @@ func PermanentDeleteUser(user *model.User) *model.AppError {
return err
}
if result := <-Srv.Store.Session().PermanentDeleteSessionsByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Session().PermanentDeleteSessionsByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.OAuth().PermanentDeleteAuthDataByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.OAuth().PermanentDeleteAuthDataByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Webhook().PermanentDeleteIncomingByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Webhook().PermanentDeleteIncomingByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Webhook().PermanentDeleteOutgoingByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Webhook().PermanentDeleteOutgoingByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Command().PermanentDeleteByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Command().PermanentDeleteByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Preference().PermanentDeleteByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Preference().PermanentDeleteByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Channel().PermanentDeleteMembersByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Channel().PermanentDeleteMembersByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Post().PermanentDeleteByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Post().PermanentDeleteByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.User().PermanentDelete(user.Id); result.Err != nil {
if result := <-app.Srv.Store.User().PermanentDelete(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Audit().PermanentDeleteByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Audit().PermanentDeleteByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.Team().RemoveAllMembersByUser(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Team().RemoveAllMembersByUser(user.Id); result.Err != nil {
return result.Err
}
if result := <-Srv.Store.PasswordRecovery().Delete(user.Id); result.Err != nil {
if result := <-app.Srv.Store.PasswordRecovery().Delete(user.Id); result.Err != nil {
return result.Err
}
@@ -1756,7 +1707,7 @@ func PermanentDeleteUser(user *model.User) *model.AppError {
}
func PermanentDeleteAllUsers() *model.AppError {
if result := <-Srv.Store.User().GetAll(); result.Err != nil {
if result := <-app.Srv.Store.User().GetAll(); result.Err != nil {
return result.Err
} else {
users := result.Data.([]*model.User)
@@ -1778,7 +1729,7 @@ func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
}
var user *model.User
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err != nil {
w.Write([]byte(model.MapToJson(props)))
return
} else {
@@ -1793,7 +1744,7 @@ func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
recovery := &model.PasswordRecovery{}
recovery.UserId = user.Id
if result := <-Srv.Store.PasswordRecovery().SaveOrUpdate(recovery); result.Err != nil {
if result := <-app.Srv.Store.PasswordRecovery().SaveOrUpdate(recovery); result.Err != nil {
c.Err = result.Err
return
}
@@ -1838,7 +1789,7 @@ func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
userId := ""
if result := <-Srv.Store.PasswordRecovery().GetByCode(code); result.Err != nil {
if result := <-app.Srv.Store.PasswordRecovery().GetByCode(code); result.Err != nil {
c.LogAuditWithUserId(userId, "fail - bad code")
c.Err = model.NewLocAppError("resetPassword", "api.user.reset_password.invalid_link.app_error", nil, result.Err.Error())
return
@@ -1854,7 +1805,7 @@ func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
}
go func() {
if result := <-Srv.Store.PasswordRecovery().Delete(userId); result.Err != nil {
if result := <-app.Srv.Store.PasswordRecovery().Delete(userId); result.Err != nil {
l4g.Error("%v", result.Err)
}
}()
@@ -1874,7 +1825,7 @@ func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
func ResetPassword(c *Context, userId, newPassword string) *model.AppError {
var user *model.User
if result := <-Srv.Store.User().Get(userId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(userId); result.Err != nil {
return result.Err
} else {
user = result.Data.(*model.User)
@@ -1885,7 +1836,7 @@ func ResetPassword(c *Context, userId, newPassword string) *model.AppError {
}
if result := <-Srv.Store.User().UpdatePassword(userId, model.HashPassword(newPassword)); result.Err != nil {
if result := <-app.Srv.Store.User().UpdatePassword(userId, model.HashPassword(newPassword)); result.Err != nil {
return result.Err
}
@@ -1992,7 +1943,7 @@ func updateUserNotify(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
uchan := Srv.Store.User().Get(user_id)
uchan := app.Srv.Store.User().Get(user_id)
if !HasPermissionToUser(c, user_id) {
return
@@ -2034,12 +1985,12 @@ func updateUserNotify(c *Context, w http.ResponseWriter, r *http.Request) {
user.NotifyProps = props
if result := <-Srv.Store.User().Update(user, false); result.Err != nil {
if result := <-app.Srv.Store.User().Update(user, false); result.Err != nil {
c.Err = result.Err
return
} else {
c.LogAuditWithUserId(user.Id, "")
InvalidateCacheForUser(user.Id)
app.InvalidateCacheForUser(user.Id)
ruser := result.Data.([2]*model.User)[0]
options := utils.Cfg.GetSanitizeOptions()
@@ -2056,7 +2007,7 @@ func IsUsernameTaken(name string) bool {
return false
}
if result := <-Srv.Store.User().GetByUsername(name); result.Err != nil {
if result := <-app.Srv.Store.User().GetByUsername(name); result.Err != nil {
return false
} else {
return true
@@ -2091,7 +2042,7 @@ func emailToOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("attempt")
var user *model.User
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err != nil {
c.LogAudit("fail - couldn't get user")
c.Err = result.Err
return
@@ -2144,7 +2095,7 @@ func oauthToEmail(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("attempt")
var user *model.User
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err != nil {
c.LogAudit("fail - couldn't get user")
c.Err = result.Err
return
@@ -2159,7 +2110,7 @@ func oauthToEmail(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.User().UpdatePassword(c.Session.UserId, model.HashPassword(password)); result.Err != nil {
if result := <-app.Srv.Store.User().UpdatePassword(c.Session.UserId, model.HashPassword(password)); result.Err != nil {
c.LogAudit("fail - database issue")
c.Err = result.Err
return
@@ -2212,7 +2163,7 @@ func emailToLdap(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("attempt")
var user *model.User
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err != nil {
c.LogAudit("fail - couldn't get user")
c.Err = result.Err
return
@@ -2280,7 +2231,7 @@ func ldapToEmail(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("attempt")
var user *model.User
if result := <-Srv.Store.User().GetByEmail(email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(email); result.Err != nil {
c.LogAudit("fail - couldn't get user")
c.Err = result.Err
return
@@ -2312,7 +2263,7 @@ func ldapToEmail(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(emailPassword)); result.Err != nil {
if result := <-app.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(emailPassword)); result.Err != nil {
c.LogAudit("fail - database issue")
c.Err = result.Err
return
@@ -2364,7 +2315,7 @@ func verifyEmail(c *Context, w http.ResponseWriter, r *http.Request) {
}
if model.ComparePassword(hashedId, userId+utils.Cfg.EmailSettings.InviteSalt) {
if c.Err = (<-Srv.Store.User().VerifyEmail(userId)).Err; c.Err != nil {
if c.Err = (<-app.Srv.Store.User().VerifyEmail(userId)).Err; c.Err != nil {
return
} else {
c.LogAudit("Email Verified")
@@ -2389,7 +2340,7 @@ func resendVerification(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = error
return
} else {
if _, err := GetStatus(user.Id); err != nil {
if _, err := app.GetStatus(user.Id); err != nil {
go SendVerifyEmail(c, user.Id, user.Email, c.GetSiteURL())
} else {
go SendEmailChangeVerifyEmail(c, user.Id, user.Email, c.GetSiteURL())
@@ -2398,7 +2349,7 @@ func resendVerification(c *Context, w http.ResponseWriter, r *http.Request) {
}
func generateMfaSecret(c *Context, w http.ResponseWriter, r *http.Request) {
uchan := Srv.Store.User().Get(c.Session.UserId)
uchan := app.Srv.Store.User().Get(c.Session.UserId)
var user *model.User
if result := <-uchan; result.Err != nil {
@@ -2467,7 +2418,7 @@ func updateMfa(c *Context, w http.ResponseWriter, r *http.Request) {
go func() {
var user *model.User
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
l4g.Warn(result.Err)
} else {
user = result.Data.(*model.User)
@@ -2490,7 +2441,7 @@ func ActivateMfa(userId, token string) *model.AppError {
}
var user *model.User
if result := <-Srv.Store.User().Get(userId); result.Err != nil {
if result := <-app.Srv.Store.User().Get(userId); result.Err != nil {
return result.Err
} else {
user = result.Data.(*model.User)
@@ -2540,7 +2491,7 @@ func checkMfa(c *Context, w http.ResponseWriter, r *http.Request) {
// we don't need to worry about contacting the ldap server to get this user because
// only users already in the system could have MFA enabled
uchan := Srv.Store.User().GetForLogin(
uchan := app.Srv.Store.User().GetForLogin(
loginId,
*utils.Cfg.EmailSettings.EnableSignInWithUsername,
*utils.Cfg.EmailSettings.EnableSignInWithEmail,
@@ -2680,7 +2631,7 @@ func userTyping(req *model.WebSocketRequest) (map[string]interface{}, *model.App
event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_TYPING, "", channelId, "", omitUsers)
event.Add("parent_id", parentId)
event.Add("user_id", req.Session.UserId)
go Publish(event)
go app.Publish(event)
return nil, nil
}
@@ -2740,11 +2691,11 @@ func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
var uchan store.StoreChannel
if props.InChannelId != "" {
uchan = Srv.Store.User().SearchInChannel(props.InChannelId, props.Term, searchOptions)
uchan = app.Srv.Store.User().SearchInChannel(props.InChannelId, props.Term, searchOptions)
} else if props.NotInChannelId != "" {
uchan = Srv.Store.User().SearchNotInChannel(props.TeamId, props.NotInChannelId, props.Term, searchOptions)
uchan = app.Srv.Store.User().SearchNotInChannel(props.TeamId, props.NotInChannelId, props.Term, searchOptions)
} else {
uchan = Srv.Store.User().Search(props.TeamId, props.Term, searchOptions)
uchan = app.Srv.Store.User().Search(props.TeamId, props.Term, searchOptions)
}
if result := <-uchan; result.Err != nil {
@@ -2769,7 +2720,7 @@ func getProfilesByIds(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.User().GetProfileByIds(userIds, true); result.Err != nil {
if result := <-app.Srv.Store.User().GetProfileByIds(userIds, true); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -2810,8 +2761,8 @@ func autocompleteUsersInChannel(c *Context, w http.ResponseWriter, r *http.Reque
searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY] = true
}
uchan := Srv.Store.User().SearchInChannel(channelId, term, searchOptions)
nuchan := Srv.Store.User().SearchNotInChannel(teamId, channelId, term, searchOptions)
uchan := app.Srv.Store.User().SearchInChannel(channelId, term, searchOptions)
nuchan := app.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, searchOptions)
autocomplete := &model.UserAutocompleteInChannel{}
@@ -2866,7 +2817,7 @@ func autocompleteUsersInTeam(c *Context, w http.ResponseWriter, r *http.Request)
searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY] = true
}
uchan := Srv.Store.User().Search(teamId, term, searchOptions)
uchan := app.Srv.Store.User().Search(teamId, term, searchOptions)
autocomplete := &model.UserAutocompleteInTeam{}
@@ -2899,7 +2850,7 @@ func autocompleteUsers(c *Context, w http.ResponseWriter, r *http.Request) {
searchOptions[store.USER_SEARCH_OPTION_NAMES_ONLY] = true
}
uchan := Srv.Store.User().Search("", term, searchOptions)
uchan := app.Srv.Store.User().Search("", term, searchOptions)
var profiles []*model.User

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

@@ -16,6 +16,7 @@ import (
"testing"
"time"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -148,7 +149,7 @@ func TestLogin(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Username: "corey" + model.NewId(), Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
if result, err := Client.LoginById(ruser.Data.(*model.User).Id, user.Password); err != nil {
t.Fatal(err)
@@ -242,7 +243,7 @@ func TestLogin(t *testing.T) {
AuthService: model.USER_AUTH_SERVICE_LDAP,
}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user3.Id))
if _, err := Client.Login(user3.Id, user3.Password); err == nil {
t.Fatal("AD/LDAP user should not be able to log in with AD/LDAP disabled")
@@ -259,7 +260,7 @@ func TestLoginByLdap(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Username: "corey" + model.NewId(), Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
if _, err := Client.LoginByLdap(ruser.Data.(*model.User).Id, user.Password); err == nil {
t.Fatal("should have failed to log in with non AD/LDAP user")
@@ -286,7 +287,7 @@ func TestLoginWithDeviceId(t *testing.T) {
t.Fatal(err)
}
if sresult := <-Srv.Store.Session().Get(sessions[0].Id); sresult.Err == nil {
if sresult := <-app.Srv.Store.Session().Get(sessions[0].Id); sresult.Err == nil {
t.Fatal("session should have been removed")
}
}
@@ -387,12 +388,12 @@ func TestGetUser(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
user2 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1", FirstName: "Corey", LastName: "Hulen"}
ruser2, _ := Client.CreateUser(&user2, "")
LinkUserToTeam(ruser2.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser2.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser2.Data.(*model.User).Id))
team2 := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam2, _ := Client.CreateTeam(&team2)
@@ -400,7 +401,7 @@ func TestGetUser(t *testing.T) {
user3 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser3, _ := Client.CreateUser(&user3, "")
LinkUserToTeam(ruser3.Data.(*model.User), rteam2.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser3.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser3.Data.(*model.User).Id))
Client.Login(user.Email, user.Password)
@@ -653,7 +654,7 @@ func TestGetAudits(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
time.Sleep(100 * time.Millisecond)
@@ -708,7 +709,7 @@ func TestUserCreateImage(t *testing.T) {
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
Client.Login(user.Email, "passwd1")
@@ -753,7 +754,7 @@ func TestUserUploadProfileImage(t *testing.T) {
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
if utils.Cfg.FileSettings.DriverName != "" {
@@ -862,7 +863,7 @@ func TestUserUpdate(t *testing.T) {
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1", Roles: ""}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
if _, err := Client.UpdateUser(user); err == nil {
t.Fatal("Should have errored")
@@ -892,7 +893,7 @@ func TestUserUpdate(t *testing.T) {
user2 := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
LinkUserToTeam(user2, team)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
Client.Login(user2.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -915,7 +916,7 @@ func TestUserUpdatePassword(t *testing.T) {
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
if _, err := Client.UpdateUserPassword(user.Id, "passwd1", "newpasswd1"); err == nil {
t.Fatal("Should have errored")
@@ -997,12 +998,12 @@ func TestUserUpdateRoles(t *testing.T) {
user := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
user2 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
LinkUserToTeam(user2, team)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
if _, err := Client.UpdateUserRoles(user.Id, ""); err == nil {
t.Fatal("Should have errored, not logged in")
@@ -1021,7 +1022,7 @@ func TestUserUpdateRoles(t *testing.T) {
user3 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
LinkUserToTeam(user3, team2)
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user3.Id))
Client.Login(user3.Email, "passwd1")
Client.SetTeamId(team2.Id)
@@ -1116,7 +1117,7 @@ func TestUserUpdateDeviceId(t *testing.T) {
user := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
Client.Login(user.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -1126,7 +1127,7 @@ func TestUserUpdateDeviceId(t *testing.T) {
t.Fatal(err)
}
if result := <-Srv.Store.Session().GetSessions(user.Id); result.Err != nil {
if result := <-app.Srv.Store.Session().GetSessions(user.Id); result.Err != nil {
t.Fatal(result.Err)
} else {
sessions := result.Data.([]*model.Session)
@@ -1148,12 +1149,12 @@ func TestUserUpdateActive(t *testing.T) {
user := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
user2 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
LinkUserToTeam(user2, team)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
if _, err := Client.UpdateActive(user.Id, false); err == nil {
t.Fatal("Should have errored, not logged in")
@@ -1174,7 +1175,7 @@ func TestUserUpdateActive(t *testing.T) {
user3 := &model.User{Email: "success+" + model.NewId() + "@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user3 = Client.Must(Client.CreateUser(user3, "")).Data.(*model.User)
LinkUserToTeam(user2, team2)
store.Must(Srv.Store.User().VerifyEmail(user3.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user3.Id))
Client.Login(user3.Email, "passwd1")
Client.SetTeamId(team2.Id)
@@ -1194,13 +1195,13 @@ func TestUserUpdateActive(t *testing.T) {
t.Fatal("Should have errored, bad id")
}
SetStatusOnline(user3.Id, "", false)
app.SetStatusOnline(user3.Id, "", false)
if _, err := SystemAdminClient.UpdateActive(user3.Id, false); err != nil {
t.Fatal(err)
}
if status, err := GetStatus(user3.Id); err != nil {
if status, err := app.GetStatus(user3.Id); err != nil {
t.Fatal(err)
} else if status.Status != model.STATUS_OFFLINE {
t.Fatal("status should have been set to offline")
@@ -1217,7 +1218,7 @@ func TestUserPermDelete(t *testing.T) {
user1 := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
LinkUserToTeam(user1, team)
store.Must(Srv.Store.User().VerifyEmail(user1.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user1.Id))
Client.Login(user1.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -1259,7 +1260,7 @@ func TestSendPasswordReset(t *testing.T) {
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
if result, err := Client.SendPasswordReset(user.Email); err != nil {
t.Fatal(err)
@@ -1282,7 +1283,7 @@ func TestSendPasswordReset(t *testing.T) {
user2 := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", AuthData: &authData, AuthService: "random"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
LinkUserToTeam(user2, team)
store.Must(Srv.Store.User().VerifyEmail(user2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user2.Id))
if _, err := Client.SendPasswordReset(user2.Email); err == nil {
t.Fatal("should have errored - SSO user can't send reset password link")
@@ -1297,12 +1298,12 @@ func TestResetPassword(t *testing.T) {
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
Client.Must(Client.SendPasswordReset(user.Email))
var recovery *model.PasswordRecovery
if result := <-Srv.Store.PasswordRecovery().Get(user.Id); result.Err != nil {
if result := <-app.Srv.Store.PasswordRecovery().Get(user.Id); result.Err != nil {
t.Fatal(result.Err)
} else {
recovery = result.Data.(*model.PasswordRecovery)
@@ -1342,14 +1343,14 @@ func TestResetPassword(t *testing.T) {
Client.Must(Client.SendPasswordReset(user.Email))
if result := <-Srv.Store.PasswordRecovery().Get(user.Id); result.Err != nil {
if result := <-app.Srv.Store.PasswordRecovery().Get(user.Id); result.Err != nil {
t.Fatal(result.Err)
} else {
recovery = result.Data.(*model.PasswordRecovery)
}
authData := model.NewId()
if result := <-Srv.Store.User().UpdateAuthData(user.Id, "random", &authData, "", true); result.Err != nil {
if result := <-app.Srv.Store.User().UpdateAuthData(user.Id, "random", &authData, "", true); result.Err != nil {
t.Fatal(result.Err)
}
@@ -1368,7 +1369,7 @@ func TestUserUpdateNotify(t *testing.T) {
user := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1", Roles: ""}
user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
LinkUserToTeam(user, team)
store.Must(Srv.Store.User().VerifyEmail(user.Id))
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
data := make(map[string]string)
data["user_id"] = user.Id
@@ -1479,7 +1480,7 @@ func TestEmailToOAuth(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
LinkUserToTeam(ruser, rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
m := map[string]string{}
if _, err := Client.EmailToOAuth(m); err == nil {
@@ -1530,12 +1531,12 @@ func TestOAuthToEmail(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
LinkUserToTeam(ruser, rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
user2 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser2 := Client.Must(Client.CreateUser(&user2, "")).Data.(*model.User)
LinkUserToTeam(ruser2, rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser2.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser2.Id))
m := map[string]string{}
if _, err := Client.OAuthToEmail(m); err == nil {
@@ -1581,7 +1582,7 @@ func TestLDAPToEmail(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
LinkUserToTeam(ruser, rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
Client.Login(user.Email, user.Password)
@@ -1634,7 +1635,7 @@ func TestEmailToLDAP(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser := Client.Must(Client.CreateUser(&user, "")).Data.(*model.User)
LinkUserToTeam(ruser, rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
Client.Login(user.Email, user.Password)
@@ -1765,7 +1766,7 @@ func TestGenerateMfaSecret(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
Client.Logout()
@@ -1803,7 +1804,7 @@ func TestUpdateMfa(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
Client.Logout()
@@ -1842,7 +1843,7 @@ func TestCheckMfa(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
ruser, _ := Client.CreateUser(&user, "")
LinkUserToTeam(ruser.Data.(*model.User), rteam.Data.(*model.Team))
store.Must(Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Data.(*model.User).Id))
if result, err := Client.CheckMfa(user.Email); err != nil {
t.Fatal(err)

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

@@ -1,252 +0,0 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
"fmt"
"time"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/websocket"
goi18n "github.com/nicksnyder/go-i18n/i18n"
)
const (
WRITE_WAIT = 30 * time.Second
PONG_WAIT = 100 * time.Second
PING_PERIOD = (PONG_WAIT * 6) / 10
AUTH_TIMEOUT = 5 * time.Second
)
type WebConn struct {
WebSocket *websocket.Conn
Send chan model.WebSocketMessage
SessionToken string
SessionExpiresAt int64
UserId string
T goi18n.TranslateFunc
Locale string
AllChannelMembers map[string]string
LastAllChannelMembersTime int64
}
func NewWebConn(c *Context, ws *websocket.Conn) *WebConn {
if len(c.Session.UserId) > 0 {
go SetStatusOnline(c.Session.UserId, c.Session.Id, false)
}
return &WebConn{
Send: make(chan model.WebSocketMessage, 256),
WebSocket: ws,
UserId: c.Session.UserId,
SessionToken: c.Session.Token,
SessionExpiresAt: c.Session.ExpiresAt,
T: c.T,
Locale: c.Locale,
}
}
func (c *WebConn) readPump() {
defer func() {
HubUnregister(c)
c.WebSocket.Close()
}()
c.WebSocket.SetReadLimit(SOCKET_MAX_MESSAGE_SIZE_KB)
c.WebSocket.SetReadDeadline(time.Now().Add(PONG_WAIT))
c.WebSocket.SetPongHandler(func(string) error {
c.WebSocket.SetReadDeadline(time.Now().Add(PONG_WAIT))
if c.isAuthenticated() {
go SetStatusAwayIfNeeded(c.UserId, false)
}
return nil
})
for {
var req model.WebSocketRequest
if err := c.WebSocket.ReadJSON(&req); err != nil {
// browsers will appear as CloseNoStatusReceived
if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) {
l4g.Debug(fmt.Sprintf("websocket.read: client side closed socket userId=%v", c.UserId))
} else {
l4g.Debug(fmt.Sprintf("websocket.read: closing websocket for userId=%v error=%v", c.UserId, err.Error()))
}
return
} else {
BaseRoutes.WebSocket.ServeWebSocket(c, &req)
}
}
}
func (c *WebConn) writePump() {
ticker := time.NewTicker(PING_PERIOD)
authTicker := time.NewTicker(AUTH_TIMEOUT)
defer func() {
ticker.Stop()
authTicker.Stop()
c.WebSocket.Close()
}()
for {
select {
case msg, ok := <-c.Send:
if !ok {
c.WebSocket.SetWriteDeadline(time.Now().Add(WRITE_WAIT))
c.WebSocket.WriteMessage(websocket.CloseMessage, []byte{})
return
}
c.WebSocket.SetWriteDeadline(time.Now().Add(WRITE_WAIT))
if err := c.WebSocket.WriteMessage(websocket.TextMessage, msg.GetPreComputeJson()); err != nil {
// browsers will appear as CloseNoStatusReceived
if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) {
l4g.Debug(fmt.Sprintf("websocket.send: client side closed socket userId=%v", c.UserId))
} else {
l4g.Debug(fmt.Sprintf("websocket.send: closing websocket for userId=%v, error=%v", c.UserId, err.Error()))
}
return
}
if msg.EventType() == model.WEBSOCKET_EVENT_POSTED {
if einterfaces.GetMetricsInterface() != nil {
einterfaces.GetMetricsInterface().IncrementPostBroadcast()
}
}
case <-ticker.C:
c.WebSocket.SetWriteDeadline(time.Now().Add(WRITE_WAIT))
if err := c.WebSocket.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
// browsers will appear as CloseNoStatusReceived
if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) {
l4g.Debug(fmt.Sprintf("websocket.ticker: client side closed socket userId=%v", c.UserId))
} else {
l4g.Debug(fmt.Sprintf("websocket.ticker: closing websocket for userId=%v error=%v", c.UserId, err.Error()))
}
return
}
case <-authTicker.C:
if c.SessionToken == "" {
l4g.Debug(fmt.Sprintf("websocket.authTicker: did not authenticate ip=%v", c.WebSocket.RemoteAddr()))
return
}
authTicker.Stop()
}
}
}
func (webCon *WebConn) InvalidateCache() {
webCon.AllChannelMembers = nil
webCon.LastAllChannelMembersTime = 0
webCon.SessionExpiresAt = 0
}
func (webCon *WebConn) isAuthenticated() bool {
// Check the expiry to see if we need to check for a new session
if webCon.SessionExpiresAt < model.GetMillis() {
if webCon.SessionToken == "" {
return false
}
session := GetSession(webCon.SessionToken)
if session == nil || session.IsExpired() {
webCon.SessionToken = ""
webCon.SessionExpiresAt = 0
return false
}
webCon.SessionToken = session.Token
webCon.SessionExpiresAt = session.ExpiresAt
}
return true
}
func (webCon *WebConn) SendHello() {
msg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_HELLO, "", "", webCon.UserId, nil)
msg.Add("server_version", fmt.Sprintf("%v.%v.%v", model.CurrentVersion, model.BuildNumber, utils.CfgHash))
msg.DoPreComputeJson()
webCon.Send <- msg
}
func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
// IMPORTANT: Do not send event if WebConn does not have a session
if !webCon.isAuthenticated() {
return false
}
// If the event is destined to a specific user
if len(msg.Broadcast.UserId) > 0 && webCon.UserId != msg.Broadcast.UserId {
return false
}
// if the user is omitted don't send the message
if len(msg.Broadcast.OmitUsers) > 0 {
if _, ok := msg.Broadcast.OmitUsers[webCon.UserId]; ok {
return false
}
}
// Only report events to users who are in the channel for the event
if len(msg.Broadcast.ChannelId) > 0 {
// Only broadcast typing messages if less than 1K people in channel
if msg.Event == model.WEBSOCKET_EVENT_TYPING {
if Srv.Store.Channel().GetMemberCountFromCache(msg.Broadcast.ChannelId) > *utils.Cfg.TeamSettings.MaxNotificationsPerChannel {
return false
}
}
if model.GetMillis()-webCon.LastAllChannelMembersTime > 1000*60*15 { // 15 minutes
webCon.AllChannelMembers = nil
webCon.LastAllChannelMembersTime = 0
}
if webCon.AllChannelMembers == nil {
if result := <-Srv.Store.Channel().GetAllChannelMembersForUser(webCon.UserId, true); result.Err != nil {
l4g.Error("webhub.shouldSendEvent: " + result.Err.Error())
return false
} else {
webCon.AllChannelMembers = result.Data.(map[string]string)
webCon.LastAllChannelMembersTime = model.GetMillis()
}
}
if _, ok := webCon.AllChannelMembers[msg.Broadcast.ChannelId]; ok {
return true
} else {
return false
}
}
// Only report events to users who are in the team for the event
if len(msg.Broadcast.TeamId) > 0 {
return webCon.IsMemberOfTeam(msg.Broadcast.TeamId)
}
return true
}
func (webCon *WebConn) IsMemberOfTeam(teamId string) bool {
session := GetSession(webCon.SessionToken)
if session == nil {
return false
} else {
member := session.GetTeamByTeamId(teamId)
if member != nil {
return true
} else {
return false
}
}
}

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

@@ -1,241 +0,0 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
"fmt"
"hash/fnv"
"runtime"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
type Hub struct {
connections map[*WebConn]bool
register chan *WebConn
unregister chan *WebConn
broadcast chan *model.WebSocketEvent
stop chan string
invalidateUser chan string
}
var hubs []*Hub = make([]*Hub, 0)
func NewWebHub() *Hub {
return &Hub{
register: make(chan *WebConn),
unregister: make(chan *WebConn),
connections: make(map[*WebConn]bool, model.SESSION_CACHE_SIZE),
broadcast: make(chan *model.WebSocketEvent, 4096),
stop: make(chan string),
invalidateUser: make(chan string),
}
}
func TotalWebsocketConnections() int {
// This is racy, but it's only used for reporting information
// so it's probably OK
count := 0
for _, hub := range hubs {
count = count + len(hub.connections)
}
return count
}
func HubStart() {
l4g.Info(utils.T("api.web_hub.start.starting.debug"), runtime.NumCPU()*2)
// Total number of hubs is twice the number of CPUs.
hubs = make([]*Hub, runtime.NumCPU()*2)
for i := 0; i < len(hubs); i++ {
hubs[i] = NewWebHub()
hubs[i].Start()
}
}
func HubStop() {
l4g.Info(utils.T("api.web_hub.start.stopping.debug"))
for _, hub := range hubs {
hub.Stop()
}
hubs = make([]*Hub, 0)
}
func GetHubForUserId(userId string) *Hub {
hash := fnv.New32a()
hash.Write([]byte(userId))
index := hash.Sum32() % uint32(len(hubs))
return hubs[index]
}
func HubRegister(webConn *WebConn) {
GetHubForUserId(webConn.UserId).Register(webConn)
}
func HubUnregister(webConn *WebConn) {
GetHubForUserId(webConn.UserId).Unregister(webConn)
}
func Publish(message *model.WebSocketEvent) {
message.DoPreComputeJson()
for _, hub := range hubs {
hub.Broadcast(message)
}
if einterfaces.GetClusterInterface() != nil {
einterfaces.GetClusterInterface().Publish(message)
}
}
func PublishSkipClusterSend(message *model.WebSocketEvent) {
message.DoPreComputeJson()
for _, hub := range hubs {
hub.Broadcast(message)
}
}
func InvalidateCacheForChannel(channelId string) {
InvalidateCacheForChannelSkipClusterSend(channelId)
if cluster := einterfaces.GetClusterInterface(); cluster != nil {
cluster.InvalidateCacheForChannel(channelId)
}
}
func InvalidateCacheForChannelSkipClusterSend(channelId string) {
Srv.Store.User().InvalidateProfilesInChannelCache(channelId)
Srv.Store.Channel().InvalidateMemberCount(channelId)
Srv.Store.Channel().InvalidateChannel(channelId)
}
func InvalidateCacheForChannelPosts(channelId string) {
InvalidateCacheForChannelPostsSkipClusterSend(channelId)
if cluster := einterfaces.GetClusterInterface(); cluster != nil {
cluster.InvalidateCacheForChannelPosts(channelId)
}
}
func InvalidateCacheForChannelPostsSkipClusterSend(channelId string) {
Srv.Store.Post().InvalidateLastPostTimeCache(channelId)
}
func InvalidateCacheForUser(userId string) {
InvalidateCacheForUserSkipClusterSend(userId)
if einterfaces.GetClusterInterface() != nil {
einterfaces.GetClusterInterface().InvalidateCacheForUser(userId)
}
}
func InvalidateCacheForUserSkipClusterSend(userId string) {
Srv.Store.Channel().InvalidateAllChannelMembersForUser(userId)
Srv.Store.User().InvalidateProfilesInChannelCacheByUser(userId)
Srv.Store.User().InvalidatProfileCacheForUser(userId)
if len(hubs) != 0 {
GetHubForUserId(userId).InvalidateUser(userId)
}
}
func InvalidateWebConnSessionCacheForUser(userId string) {
if len(hubs) != 0 {
GetHubForUserId(userId).InvalidateUser(userId)
}
}
func (h *Hub) Register(webConn *WebConn) {
h.register <- webConn
if webConn.isAuthenticated() {
webConn.SendHello()
}
}
func (h *Hub) Unregister(webConn *WebConn) {
h.unregister <- webConn
}
func (h *Hub) Broadcast(message *model.WebSocketEvent) {
if message != nil {
h.broadcast <- message
}
}
func (h *Hub) InvalidateUser(userId string) {
h.invalidateUser <- userId
}
func (h *Hub) Stop() {
h.stop <- "all"
}
func (h *Hub) Start() {
go func() {
for {
select {
case webCon := <-h.register:
h.connections[webCon] = true
case webCon := <-h.unregister:
userId := webCon.UserId
if _, ok := h.connections[webCon]; ok {
delete(h.connections, webCon)
close(webCon.Send)
}
if len(userId) == 0 {
continue
}
found := false
for webCon := range h.connections {
if userId == webCon.UserId {
found = true
break
}
}
if !found {
go SetStatusOffline(userId, false)
}
case userId := <-h.invalidateUser:
for webCon := range h.connections {
if webCon.UserId == userId {
webCon.InvalidateCache()
}
}
case msg := <-h.broadcast:
for webCon := range h.connections {
if webCon.ShouldSendEvent(msg) {
select {
case webCon.Send <- msg:
default:
l4g.Error(fmt.Sprintf("webhub.broadcast: cannot send, closing websocket for userId=%v", webCon.UserId))
close(webCon.Send)
delete(h.connections, webCon)
}
}
}
case <-h.stop:
for webCon := range h.connections {
webCon.WebSocket.Close()
}
return
}
}
}()
}

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

@@ -11,6 +11,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -31,7 +32,7 @@ func InitWebhook() {
BaseRoutes.Hooks.Handle("/{id:[A-Za-z0-9]+}", ApiAppHandler(incomingWebhook)).Methods("POST")
// Old route. Remove eventually.
mr := Srv.Router
mr := app.Srv.Router
mr.Handle("/hooks/{id:[A-Za-z0-9]+}", ApiAppHandler(incomingWebhook)).Methods("POST")
}
@@ -55,7 +56,7 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().Get(hook.ChannelId, true)
cchan := app.Srv.Store.Channel().Get(hook.ChannelId, true)
hook.UserId = c.Session.UserId
hook.TeamId = c.TeamId
@@ -73,7 +74,7 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Webhook().SaveIncoming(hook); result.Err != nil {
if result := <-app.Srv.Store.Webhook().SaveIncoming(hook); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -106,7 +107,7 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Webhook().GetIncoming(id); result.Err != nil {
if result := <-app.Srv.Store.Webhook().GetIncoming(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -117,7 +118,7 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if err := (<-Srv.Store.Webhook().DeleteIncoming(id, model.GetMillis())).Err; err != nil {
if err := (<-app.Srv.Store.Webhook().DeleteIncoming(id, model.GetMillis())).Err; err != nil {
c.Err = err
return
}
@@ -139,7 +140,7 @@ func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Webhook().GetIncomingByTeam(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Webhook().GetIncomingByTeam(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -174,7 +175,7 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
hook.TeamId = c.TeamId
if len(hook.ChannelId) != 0 {
cchan := Srv.Store.Channel().Get(hook.ChannelId, true)
cchan := app.Srv.Store.Channel().Get(hook.ChannelId, true)
var channel *model.Channel
if result := <-cchan; result.Err != nil {
@@ -200,7 +201,7 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Webhook().GetOutgoingByTeam(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Webhook().GetOutgoingByTeam(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -217,7 +218,7 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if result := <-Srv.Store.Webhook().SaveOutgoing(hook); result.Err != nil {
if result := <-app.Srv.Store.Webhook().SaveOutgoing(hook); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -240,7 +241,7 @@ func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Webhook().GetOutgoingByTeam(c.TeamId); result.Err != nil {
if result := <-app.Srv.Store.Webhook().GetOutgoingByTeam(c.TeamId); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -272,7 +273,7 @@ func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if result := <-Srv.Store.Webhook().GetOutgoing(id); result.Err != nil {
if result := <-app.Srv.Store.Webhook().GetOutgoing(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -283,7 +284,7 @@ func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if err := (<-Srv.Store.Webhook().DeleteOutgoing(id, model.GetMillis())).Err; err != nil {
if err := (<-app.Srv.Store.Webhook().DeleteOutgoing(id, model.GetMillis())).Err; err != nil {
c.Err = err
return
}
@@ -316,7 +317,7 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request)
}
var hook *model.OutgoingWebhook
if result := <-Srv.Store.Webhook().GetOutgoing(id); result.Err != nil {
if result := <-app.Srv.Store.Webhook().GetOutgoing(id); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -331,7 +332,7 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request)
hook.Token = model.NewId()
if result := <-Srv.Store.Webhook().UpdateOutgoing(hook); result.Err != nil {
if result := <-app.Srv.Store.Webhook().UpdateOutgoing(hook); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -349,7 +350,7 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["id"]
hchan := Srv.Store.Webhook().GetIncoming(id)
hchan := app.Srv.Store.Webhook().GetIncoming(id)
r.ParseForm()
@@ -434,7 +435,7 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
if len(channelName) != 0 {
if channelName[0] == '@' {
if result := <-Srv.Store.User().GetByUsername(channelName[1:]); result.Err != nil {
if result := <-app.Srv.Store.User().GetByUsername(channelName[1:]); result.Err != nil {
c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.user.app_error", nil, "err="+result.Err.Message)
return
} else {
@@ -445,9 +446,9 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
channelName = channelName[1:]
}
cchan = Srv.Store.Channel().GetByName(hook.TeamId, channelName)
cchan = app.Srv.Store.Channel().GetByName(hook.TeamId, channelName)
} else {
cchan = Srv.Store.Channel().Get(hook.ChannelId, true)
cchan = app.Srv.Store.Channel().Get(hook.ChannelId, true)
}
overrideUsername := parsedRequest.Username
@@ -455,14 +456,14 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
result := <-cchan
if result.Err != nil && result.Err.Id == store.MISSING_CHANNEL_ERROR && directUserId != "" {
newChanResult := <-Srv.Store.Channel().CreateDirectChannel(directUserId, hook.UserId)
newChanResult := <-app.Srv.Store.Channel().CreateDirectChannel(directUserId, hook.UserId)
if newChanResult.Err != nil {
c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.channel.app_error", nil, "err="+newChanResult.Err.Message)
return
} else {
channel = newChanResult.Data.(*model.Channel)
InvalidateCacheForUser(directUserId)
InvalidateCacheForUser(hook.UserId)
app.InvalidateCacheForUser(directUserId)
app.InvalidateCacheForUser(hook.UserId)
}
} else if result.Err != nil {
c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.channel.app_error", nil, "err="+result.Err.Message)
@@ -490,7 +491,7 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
}
c.Err = nil
if _, err := CreateWebhookPost(c, channel.Id, text, overrideUsername, overrideIconUrl, parsedRequest.Props, webhookType); err != nil {
if _, err := app.CreateWebhookPost(hook.UserId, hook.TeamId, channel.Id, text, overrideUsername, overrideIconUrl, parsedRequest.Props, webhookType); err != nil {
c.Err = err
return
}

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

@@ -8,14 +8,16 @@ import (
"crypto/sha1"
"crypto/tls"
"encoding/base64"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"io/ioutil"
"net/http"
"strconv"
"strings"
"time"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
func InitWebrtc() {
@@ -23,7 +25,7 @@ func InitWebrtc() {
BaseRoutes.Webrtc.Handle("/token", ApiUserRequired(webrtcToken)).Methods("POST")
BaseRoutes.WebSocket.Handle("webrtc", ApiWebSocketHandler(webrtcMessage))
app.Srv.WebSocketRouter.Handle("webrtc", ApiWebSocketHandler(webrtcMessage))
}
func webrtcToken(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -60,7 +62,7 @@ func webrtcMessage(req *model.WebSocketRequest) (map[string]interface{}, *model.
event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_WEBRTC, "", "", toUserId, nil)
event.Data = req.Data
go Publish(event)
go app.Publish(event)
return nil, nil
}

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

@@ -4,27 +4,25 @@
package api
import (
"net/http"
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/websocket"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"net/http"
)
const (
SOCKET_MAX_MESSAGE_SIZE_KB = 8 * 1024 // 8KB
)
func InitWebSocket() {
l4g.Debug(utils.T("api.web_socket.init.debug"))
BaseRoutes.Users.Handle("/websocket", ApiAppHandlerTrustRequester(connect)).Methods("GET")
HubStart()
app.HubStart()
}
func connect(c *Context, w http.ResponseWriter, r *http.Request) {
upgrader := websocket.Upgrader{
ReadBufferSize: SOCKET_MAX_MESSAGE_SIZE_KB,
WriteBufferSize: SOCKET_MAX_MESSAGE_SIZE_KB,
ReadBufferSize: model.SOCKET_MAX_MESSAGE_SIZE_KB,
WriteBufferSize: model.SOCKET_MAX_MESSAGE_SIZE_KB,
CheckOrigin: func(r *http.Request) bool {
return true
},
@@ -37,8 +35,8 @@ func connect(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
wc := NewWebConn(c, ws)
HubRegister(wc)
go wc.writePump()
wc.readPump()
wc := app.NewWebConn(ws, c.Session, c.T, c.Locale)
app.HubRegister(wc)
go wc.WritePump()
wc.ReadPump()
}

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

@@ -6,22 +6,34 @@ package api
import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
func ApiWebSocketHandler(wh func(*model.WebSocketRequest) (map[string]interface{}, *model.AppError)) *webSocketHandler {
return &webSocketHandler{wh}
func ApiWebSocketHandler(wh func(*model.WebSocketRequest) (map[string]interface{}, *model.AppError)) webSocketHandler {
return webSocketHandler{wh}
}
type webSocketHandler struct {
handlerFunc func(*model.WebSocketRequest) (map[string]interface{}, *model.AppError)
}
func (wh *webSocketHandler) ServeWebSocket(conn *WebConn, r *model.WebSocketRequest) {
func (wh webSocketHandler) ServeWebSocket(conn *app.WebConn, r *model.WebSocketRequest) {
l4g.Debug("/api/v3/users/websocket:%s", r.Action)
r.Session = *GetSession(conn.SessionToken)
session, sessionErr := app.GetSession(conn.SessionToken)
if sessionErr != nil {
l4g.Error(utils.T("api.web_socket_handler.log.error"), "/api/v3/users/websocket", r.Action, r.Seq, conn.UserId, sessionErr.SystemMessage(utils.T), sessionErr.Error())
sessionErr.DetailedError = ""
errResp := model.NewWebSocketError(r.Seq, sessionErr)
errResp.DoPreComputeJson()
conn.Send <- errResp
return
}
r.Session = *session
r.T = conn.T
r.Locale = conn.Locale

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

@@ -1,92 +0,0 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
type WebSocketRouter struct {
handlers map[string]*webSocketHandler
}
func NewWebSocketRouter() *WebSocketRouter {
router := &WebSocketRouter{}
router.handlers = make(map[string]*webSocketHandler)
return router
}
func (wr *WebSocketRouter) Handle(action string, handler *webSocketHandler) {
wr.handlers[action] = handler
}
func (wr *WebSocketRouter) ServeWebSocket(conn *WebConn, r *model.WebSocketRequest) {
if r.Action == "" {
err := model.NewLocAppError("ServeWebSocket", "api.web_socket_router.no_action.app_error", nil, "")
wr.ReturnWebSocketError(conn, r, err)
return
}
if r.Seq <= 0 {
err := model.NewLocAppError("ServeWebSocket", "api.web_socket_router.bad_seq.app_error", nil, "")
wr.ReturnWebSocketError(conn, r, err)
return
}
if r.Action == model.WEBSOCKET_AUTHENTICATION_CHALLENGE {
token, ok := r.Data["token"].(string)
if !ok {
conn.WebSocket.Close()
return
}
session := GetSession(token)
if session == nil || session.IsExpired() {
conn.WebSocket.Close()
} else {
go SetStatusOnline(session.UserId, session.Id, false)
conn.SessionToken = session.Token
conn.UserId = session.UserId
resp := model.NewWebSocketResponse(model.STATUS_OK, r.Seq, nil)
resp.DoPreComputeJson()
conn.Send <- resp
conn.SendHello()
}
return
}
if !conn.isAuthenticated() {
err := model.NewLocAppError("ServeWebSocket", "api.web_socket_router.not_authenticated.app_error", nil, "")
wr.ReturnWebSocketError(conn, r, err)
return
}
var handler *webSocketHandler
if h, ok := wr.handlers[r.Action]; !ok {
err := model.NewLocAppError("ServeWebSocket", "api.web_socket_router.bad_action.app_error", nil, "")
wr.ReturnWebSocketError(conn, r, err)
return
} else {
handler = h
}
handler.ServeWebSocket(conn, r)
}
func (wr *WebSocketRouter) ReturnWebSocketError(conn *WebConn, r *model.WebSocketRequest, err *model.AppError) {
l4g.Error(utils.T("api.web_socket_router.log.error"), r.Seq, conn.UserId, err.SystemMessage(utils.T), err.DetailedError)
err.DetailedError = ""
errorResp := model.NewWebSocketError(r.Seq, err)
errorResp.DoPreComputeJson()
conn.Send <- errorResp
}

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

@@ -10,6 +10,7 @@ import (
"time"
//"github.com/gorilla/websocket"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -192,7 +193,7 @@ func TestWebSocketEvent(t *testing.T) {
omitUser["somerandomid"] = true
evt1 := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_TYPING, "", th.BasicChannel.Id, "", omitUser)
evt1.Add("user_id", "somerandomid")
Publish(evt1)
app.Publish(evt1)
time.Sleep(300 * time.Millisecond)
@@ -221,7 +222,7 @@ func TestWebSocketEvent(t *testing.T) {
}
evt2 := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_TYPING, "", "somerandomid", "", nil)
go Publish(evt2)
go app.Publish(evt2)
time.Sleep(300 * time.Millisecond)
eventHit = false