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
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
07bad4d6d5
Коммит
97558f6a6e
63
api/admin.go
63
api/admin.go
@@ -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)
|
||||
|
||||
19
api/api.go
19
api/api.go
@@ -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
|
||||
}
|
||||
|
||||
333
api/channel.go
333
api/channel.go
@@ -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}
|
||||
}
|
||||
|
||||
149
api/context.go
149
api/context.go
@@ -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")
|
||||
}
|
||||
}
|
||||
15
api/emoji.go
15
api/emoji.go
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
19
api/file.go
19
api/file.go
@@ -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
|
||||
}
|
||||
|
||||
135
api/oauth.go
135
api/oauth.go
@@ -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, "")
|
||||
}
|
||||
|
||||
1176
api/post.go
1176
api/post.go
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
347
api/post_test.go
347
api/post_test.go
@@ -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 {
|
||||
|
||||
187
api/server.go
187
api/server.go
@@ -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")
|
||||
|
||||
257
api/status.go
257
api/status.go
@@ -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)
|
||||
|
||||
|
||||
181
api/team.go
181
api/team.go
@@ -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")
|
||||
|
||||
|
||||
271
api/user.go
271
api/user.go
@@ -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)
|
||||
|
||||
252
api/web_conn.go
252
api/web_conn.go
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
241
api/web_hub.go
241
api/web_hub.go
@@ -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
|
||||
|
||||
Ссылка в новой задаче
Block a user