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

* Add app package and move logic over from api package

* Change app package functions to return errors

* Move non-api tests into app package

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

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

@@ -184,17 +184,19 @@ test-server: start-docker prepare-enterprise
echo "mode: count" > cover.out
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=650s -covermode=count -coverprofile=capi.out ./api || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=60s -covermode=count -coverprofile=capp.out ./app || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=60s -covermode=count -coverprofile=cmodel.out ./model || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s -covermode=count -coverprofile=cstore.out ./store || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s -covermode=count -coverprofile=cutils.out ./utils || exit 1
$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s -covermode=count -coverprofile=cweb.out ./web || exit 1
tail -n +2 capi.out >> cover.out
tail -n +2 capp.out >> cover.out
tail -n +2 cmodel.out >> cover.out
tail -n +2 cstore.out >> cover.out
tail -n +2 cutils.out >> cover.out
tail -n +2 cweb.out >> cover.out
rm -f capi.out cmodel.out cstore.out cutils.out cweb.out
rm -f capi.out capp.out cmodel.out cstore.out cutils.out cweb.out
ifeq ($(BUILD_ENTERPRISE_READY),true)
@echo Running Enterprise tests

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -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

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

@@ -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

191
app/apptestlib.go Обычный файл
Просмотреть файл

@@ -0,0 +1,191 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"time"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
l4g "github.com/alecthomas/log4go"
)
type TestHelper struct {
BasicTeam *model.Team
BasicUser *model.User
BasicUser2 *model.User
BasicChannel *model.Channel
BasicPost *model.Post
}
func SetupEnterprise() *TestHelper {
if 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()
utils.License.Features.SetDefaults()
NewServer()
InitStores()
StartServer()
utils.InitHTML()
utils.EnableDebugLogForTest()
Srv.Store.MarkSystemRanUnitTests()
*utils.Cfg.TeamSettings.EnableOpenServer = true
}
return &TestHelper{}
}
func Setup() *TestHelper {
if 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()
StartServer()
utils.EnableDebugLogForTest()
Srv.Store.MarkSystemRanUnitTests()
*utils.Cfg.TeamSettings.EnableOpenServer = true
}
return &TestHelper{}
}
func (me *TestHelper) InitBasic() *TestHelper {
me.BasicTeam = me.CreateTeam()
me.BasicUser = me.CreateUser()
LinkUserToTeam(me.BasicUser, me.BasicTeam)
me.BasicUser2 = me.CreateUser()
LinkUserToTeam(me.BasicUser2, me.BasicTeam)
me.BasicChannel = me.CreateChannel(me.BasicTeam)
me.BasicPost = me.CreatePost(me.BasicChannel)
return me
}
func (me *TestHelper) CreateTeam() *model.Team {
id := model.NewId()
team := &model.Team{
DisplayName: "dn_" + id,
Name: "name" + id,
Email: "success+" + id + "@simulator.amazonses.com",
Type: model.TEAM_OPEN,
}
utils.DisableDebugLogForTest()
var err *model.AppError
if team, err = CreateTeam(team); err != nil {
l4g.Error(err.Error())
l4g.Close()
time.Sleep(time.Second)
panic(err)
}
utils.EnableDebugLogForTest()
return team
}
func (me *TestHelper) CreateUser() *model.User {
id := model.NewId()
user := &model.User{
Email: "success+" + id + "@simulator.amazonses.com",
Username: "un_" + id,
Nickname: "nn_" + id,
Password: "Password1",
EmailVerified: true,
}
utils.DisableDebugLogForTest()
var err *model.AppError
if user, err = CreateUser(user); err != nil {
l4g.Error(err.Error())
l4g.Close()
time.Sleep(time.Second)
panic(err)
}
utils.EnableDebugLogForTest()
return user
}
func (me *TestHelper) CreateChannel(team *model.Team) *model.Channel {
return me.createChannel(team, model.CHANNEL_OPEN)
}
func (me *TestHelper) CreatePrivateChannel(team *model.Team) *model.Channel {
return me.createChannel(team, model.CHANNEL_PRIVATE)
}
func (me *TestHelper) createChannel(team *model.Team, channelType string) *model.Channel {
id := model.NewId()
channel := &model.Channel{
DisplayName: "dn_" + id,
Name: "name_" + id,
Type: channelType,
TeamId: team.Id,
CreatorId: me.BasicUser.Id,
}
utils.DisableDebugLogForTest()
var err *model.AppError
if channel, err = CreateChannel(channel, true); err != nil {
l4g.Error(err.Error())
l4g.Close()
time.Sleep(time.Second)
panic(err)
}
utils.EnableDebugLogForTest()
return channel
}
func (me *TestHelper) CreatePost(channel *model.Channel) *model.Post {
id := model.NewId()
post := &model.Post{
UserId: me.BasicUser.Id,
ChannelId: channel.Id,
Message: "message_" + id,
}
utils.DisableDebugLogForTest()
var err *model.AppError
if post, err = CreatePost(post, channel.TeamId, false); err != nil {
l4g.Error(err.Error())
l4g.Close()
time.Sleep(time.Second)
panic(err)
}
utils.EnableDebugLogForTest()
return post
}
func LinkUserToTeam(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
err := JoinUserToTeam(team, user)
if err != nil {
l4g.Error(err.Error())
l4g.Close()
time.Sleep(time.Second)
panic(err)
}
utils.EnableDebugLogForTest()
}
func TearDown() {
if Srv != nil {
StopServer()
}
}

216
app/channel.go Обычный файл
Просмотреть файл

@@ -0,0 +1,216 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"fmt"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
)
func MakeDirectChannelVisible(channelId string) *model.AppError {
var members []model.ChannelMember
if result := <-Srv.Store.Channel().GetMembers(channelId); result.Err != nil {
return result.Err
} else {
members = result.Data.([]model.ChannelMember)
}
if len(members) != 2 {
return model.NewLocAppError("MakeDirectChannelVisible", "api.post.make_direct_channel_visible.get_2_members.error", map[string]interface{}{"ChannelId": channelId}, "")
}
// make sure the channel is visible to both members
for i, member := range members {
otherUserId := members[1-i].UserId
if result := <-Srv.Store.Preference().Get(member.UserId, model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, otherUserId); result.Err != nil {
// create a new preference since one doesn't exist yet
preference := &model.Preference{
UserId: member.UserId,
Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW,
Name: otherUserId,
Value: "true",
}
if saveResult := <-Srv.Store.Preference().Save(&model.Preferences{*preference}); saveResult.Err != nil {
return saveResult.Err
} else {
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_PREFERENCE_CHANGED, "", "", member.UserId, nil)
message.Add("preference", preference.ToJson())
go Publish(message)
}
} else {
preference := result.Data.(model.Preference)
if preference.Value != "true" {
// update the existing preference to make the channel visible
preference.Value = "true"
if updateResult := <-Srv.Store.Preference().Save(&model.Preferences{preference}); updateResult.Err != nil {
return updateResult.Err
} else {
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_PREFERENCE_CHANGED, "", "", member.UserId, nil)
message.Add("preference", preference.ToJson())
go Publish(message)
}
}
}
}
return nil
}
func CreateDefaultChannels(teamId string) ([]*model.Channel, *model.AppError) {
townSquare := &model.Channel{DisplayName: utils.T("api.channel.create_default_channels.town_square"), Name: "town-square", Type: model.CHANNEL_OPEN, TeamId: teamId}
if _, err := CreateChannel(townSquare, false); err != nil {
return nil, err
}
offTopic := &model.Channel{DisplayName: utils.T("api.channel.create_default_channels.off_topic"), Name: "off-topic", Type: model.CHANNEL_OPEN, TeamId: teamId}
if _, err := CreateChannel(offTopic, false); err != nil {
return nil, err
}
channels := []*model.Channel{townSquare, offTopic}
return channels, nil
}
func JoinDefaultChannels(teamId string, user *model.User, channelRole string) *model.AppError {
var err *model.AppError = nil
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(post, teamId, 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(post, teamId, false); err != nil {
l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err)
}
}
return err
}
func CreateChannel(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: channel.CreatorId,
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(channel.CreatorId)
}
return sc, nil
}
}
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
}

31
app/command.go Обычный файл
Просмотреть файл

@@ -0,0 +1,31 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"github.com/mattermost/platform/model"
)
func CreateCommandPost(post *model.Post, teamId string, response *model.CommandResponse) (*model.Post, *model.AppError) {
post.Message = parseSlackLinksToMarkdown(response.Text)
post.CreateAt = model.GetMillis()
if response.Attachments != nil {
parseSlackAttachment(post, response.Attachments)
}
switch response.ResponseType {
case model.COMMAND_RESPONSE_TYPE_IN_CHANNEL:
return CreatePost(post, teamId, true)
case model.COMMAND_RESPONSE_TYPE_EPHEMERAL:
if response.Text == "" {
return post, nil
}
post.ParentId = ""
SendEphemeralPost(teamId, post.UserId, post)
}
return post, nil
}

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

@@ -1,7 +1,7 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
package app
import (
"database/sql"
@@ -217,7 +217,7 @@ func renderBatchedPost(template *utils.HTMLTemplate, post *model.Post, teamName
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["PostMessage"] = GetMessageForNotification(post, translateFunc)
template.Props["PostLink"] = *utils.Cfg.ServiceSettings.SiteURL + "/" + teamName + "/pl/" + post.Id
tm := time.Unix(post.CreateAt/1000, 0)

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

@@ -1,7 +1,7 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
package app
import (
"testing"

732
app/notification.go Обычный файл
Просмотреть файл

@@ -0,0 +1,732 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"crypto/tls"
"fmt"
"html"
"html/template"
"io/ioutil"
"net/http"
"net/url"
"path/filepath"
"sort"
"strings"
"time"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
"github.com/nicksnyder/go-i18n/i18n"
)
func SendNotifications(post *model.Post, team *model.Team, channel *model.Channel) ([]string, *model.AppError) {
mentionedUsersList := make([]string, 0)
var fchan store.StoreChannel
var senderUsername string
if post.IsSystemMessage() {
senderUsername = utils.T("system.message.name")
} else {
pchan := Srv.Store.User().GetProfilesInChannel(channel.Id, -1, -1, true)
fchan = Srv.Store.FileInfo().GetForPost(post.Id)
var profileMap map[string]*model.User
if result := <-pchan; result.Err != nil {
return nil, result.Err
} else {
profileMap = result.Data.(map[string]*model.User)
}
// If the user who made the post isn't in the channel don't send a notification
if _, ok := profileMap[post.UserId]; !ok {
l4g.Debug(utils.T("api.post.send_notifications.user_id.debug"), post.Id, channel.Id, post.UserId)
return []string{}, nil
}
mentionedUserIds := make(map[string]bool)
allActivityPushUserIds := []string{}
hereNotification := false
channelNotification := false
allNotification := false
updateMentionChans := []store.StoreChannel{}
if channel.Type == model.CHANNEL_DIRECT {
var otherUserId string
if userIds := strings.Split(channel.Name, "__"); userIds[0] == post.UserId {
otherUserId = userIds[1]
} else {
otherUserId = userIds[0]
}
mentionedUserIds[otherUserId] = true
if post.Props["from_webhook"] == "true" {
mentionedUserIds[post.UserId] = true
}
} else {
keywords := GetMentionKeywordsInChannel(profileMap)
var potentialOtherMentions []string
mentionedUserIds, potentialOtherMentions, hereNotification, channelNotification, allNotification = GetExplicitMentions(post.Message, keywords)
// get users that have comment thread mentions enabled
if len(post.RootId) > 0 {
if result := <-Srv.Store.Post().Get(post.RootId); result.Err != nil {
return nil, result.Err
} else {
list := result.Data.(*model.PostList)
for _, threadPost := range list.Posts {
if profile, ok := profileMap[threadPost.UserId]; ok {
if profile.NotifyProps["comments"] == "any" || (profile.NotifyProps["comments"] == "root" && threadPost.Id == list.Order[0]) {
mentionedUserIds[threadPost.UserId] = true
}
}
}
}
}
// prevent the user from mentioning themselves
if post.Props["from_webhook"] != "true" {
delete(mentionedUserIds, post.UserId)
}
if len(potentialOtherMentions) > 0 {
if result := <-Srv.Store.User().GetProfilesByUsernames(potentialOtherMentions, team.Id); result.Err == nil {
outOfChannelMentions := result.Data.(map[string]*model.User)
go sendOutOfChannelMentions(post, team.Id, outOfChannelMentions)
}
}
// find which users in the channel are set up to always receive mobile notifications
for _, profile := range profileMap {
if profile.NotifyProps["push"] == model.USER_NOTIFY_ALL &&
(post.UserId != profile.Id || post.Props["from_webhook"] == "true") {
allActivityPushUserIds = append(allActivityPushUserIds, profile.Id)
}
}
}
mentionedUsersList = make([]string, 0, len(mentionedUserIds))
for id := range mentionedUserIds {
mentionedUsersList = append(mentionedUsersList, id)
updateMentionChans = append(updateMentionChans, Srv.Store.Channel().IncrementMentionCount(post.ChannelId, id))
}
var sender *model.User
senderName := make(map[string]string)
for _, id := range mentionedUsersList {
senderName[id] = ""
if profile, ok := profileMap[post.UserId]; ok {
if value, ok := post.Props["override_username"]; ok && post.Props["from_webhook"] == "true" {
senderName[id] = value.(string)
} else {
//Get the Display name preference from the receiver
if result := <-Srv.Store.Preference().Get(id, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, "name_format"); result.Err != nil {
// Show default sender's name if user doesn't set display settings.
senderName[id] = profile.Username
} else {
senderName[id] = profile.GetDisplayNameForPreference(result.Data.(model.Preference).Value)
}
}
sender = profile
}
}
if value, ok := post.Props["override_username"]; ok && post.Props["from_webhook"] == "true" {
senderUsername = value.(string)
} else {
senderUsername = profileMap[post.UserId].Username
}
if utils.Cfg.EmailSettings.SendEmailNotifications {
for _, id := range mentionedUsersList {
userAllowsEmails := profileMap[id].NotifyProps["email"] != "false"
var status *model.Status
var err *model.AppError
if status, err = GetStatus(id); err != nil {
status = &model.Status{
UserId: id,
Status: model.STATUS_OFFLINE,
Manual: false,
LastActivityAt: 0,
ActiveChannel: "",
}
}
if userAllowsEmails && status.Status != model.STATUS_ONLINE && profileMap[id].DeleteAt == 0 {
if err := sendNotificationEmail(post, profileMap[id], channel, team, senderName[id], sender); err != nil {
l4g.Error(err.Error())
}
}
}
}
T := utils.GetUserTranslations(profileMap[post.UserId].Locale)
// If the channel has more than 1K users then @here is disabled
if hereNotification && int64(len(profileMap)) > *utils.Cfg.TeamSettings.MaxNotificationsPerChannel {
hereNotification = false
SendEphemeralPost(
team.Id,
post.UserId,
&model.Post{
ChannelId: post.ChannelId,
Message: T("api.post.disabled_here", map[string]interface{}{"Users": *utils.Cfg.TeamSettings.MaxNotificationsPerChannel}),
CreateAt: post.CreateAt + 1,
},
)
}
// If the channel has more than 1K users then @channel is disabled
if channelNotification && int64(len(profileMap)) > *utils.Cfg.TeamSettings.MaxNotificationsPerChannel {
SendEphemeralPost(
team.Id,
post.UserId,
&model.Post{
ChannelId: post.ChannelId,
Message: T("api.post.disabled_channel", map[string]interface{}{"Users": *utils.Cfg.TeamSettings.MaxNotificationsPerChannel}),
CreateAt: post.CreateAt + 1,
},
)
}
// If the channel has more than 1K users then @all is disabled
if allNotification && int64(len(profileMap)) > *utils.Cfg.TeamSettings.MaxNotificationsPerChannel {
SendEphemeralPost(
team.Id,
post.UserId,
&model.Post{
ChannelId: post.ChannelId,
Message: T("api.post.disabled_all", map[string]interface{}{"Users": *utils.Cfg.TeamSettings.MaxNotificationsPerChannel}),
CreateAt: post.CreateAt + 1,
},
)
}
if hereNotification {
statuses := GetAllStatuses()
for _, status := range statuses {
if status.UserId == post.UserId {
continue
}
_, profileFound := profileMap[status.UserId]
_, alreadyMentioned := mentionedUserIds[status.UserId]
if status.Status == model.STATUS_ONLINE && profileFound && !alreadyMentioned {
mentionedUsersList = append(mentionedUsersList, status.UserId)
updateMentionChans = append(updateMentionChans, Srv.Store.Channel().IncrementMentionCount(post.ChannelId, status.UserId))
}
}
}
// Make sure all mention updates are complete to prevent race
// Probably better to batch these DB updates in the future
// MUST be completed before push notifications send
for _, uchan := range updateMentionChans {
if result := <-uchan; result.Err != nil {
l4g.Warn(utils.T("api.post.update_mention_count_and_forget.update_error"), post.Id, post.ChannelId, result.Err)
}
}
sendPushNotifications := false
if *utils.Cfg.EmailSettings.SendPushNotifications {
pushServer := *utils.Cfg.EmailSettings.PushNotificationServer
if pushServer == model.MHPNS && (!utils.IsLicensed || !*utils.License.Features.MHPNS) {
l4g.Warn(utils.T("api.post.send_notifications_and_forget.push_notification.mhpnsWarn"))
sendPushNotifications = false
} else {
sendPushNotifications = true
}
}
if sendPushNotifications {
for _, id := range mentionedUsersList {
var status *model.Status
var err *model.AppError
if status, err = GetStatus(id); err != nil {
status = &model.Status{id, model.STATUS_OFFLINE, false, 0, ""}
}
if DoesStatusAllowPushNotification(profileMap[id], status, post.ChannelId) {
if err := sendPushNotification(post, profileMap[id], channel, senderName[id], true); err != nil {
l4g.Error(err.Error())
}
}
}
for _, id := range allActivityPushUserIds {
if _, ok := mentionedUserIds[id]; !ok {
var status *model.Status
var err *model.AppError
if status, err = GetStatus(id); err != nil {
status = &model.Status{id, model.STATUS_OFFLINE, false, 0, ""}
}
if DoesStatusAllowPushNotification(profileMap[id], status, post.ChannelId) {
if err := sendPushNotification(post, profileMap[id], channel, senderName[id], false); err != nil {
l4g.Error(err.Error())
}
}
}
}
}
}
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_POSTED, "", post.ChannelId, "", nil)
message.Add("post", post.ToJson())
message.Add("channel_type", channel.Type)
message.Add("channel_display_name", channel.DisplayName)
message.Add("channel_name", channel.Name)
message.Add("sender_name", senderUsername)
message.Add("team_id", team.Id)
if len(post.FileIds) != 0 && fchan != nil {
message.Add("otherFile", "true")
var infos []*model.FileInfo
if result := <-fchan; result.Err != nil {
l4g.Warn(utils.T("api.post.send_notifications.files.error"), post.Id, result.Err)
} else {
infos = result.Data.([]*model.FileInfo)
}
for _, info := range infos {
if info.IsImage() {
message.Add("image", "true")
break
}
}
}
if len(mentionedUsersList) != 0 {
message.Add("mentions", model.ArrayToJson(mentionedUsersList))
}
Publish(message)
return mentionedUsersList, nil
}
func sendNotificationEmail(post *model.Post, user *model.User, channel *model.Channel, team *model.Team, senderName string, sender *model.User) *model.AppError {
if channel.Type == model.CHANNEL_DIRECT && channel.TeamId != team.Id {
// this message is a cross-team DM so it we need to find a team that the recipient is on to use in the link
if result := <-Srv.Store.Team().GetTeamsByUserId(user.Id); result.Err != nil {
return result.Err
} else {
// if the recipient isn't in the current user's team, just pick one
teams := result.Data.([]*model.Team)
found := false
for i := range teams {
if teams[i].Id == team.Id {
found = true
team = teams[i]
break
}
}
if !found {
if len(teams) > 0 {
team = teams[0]
} else {
// in case the user hasn't joined any teams we send them to the select_team page
team = &model.Team{Name: "select_team", DisplayName: utils.Cfg.TeamSettings.SiteName}
}
}
}
}
if *utils.Cfg.EmailSettings.EnableEmailBatching {
var sendBatched bool
if result := <-Srv.Store.Preference().Get(user.Id, model.PREFERENCE_CATEGORY_NOTIFICATIONS, model.PREFERENCE_NAME_EMAIL_INTERVAL); result.Err != nil {
// if the call fails, assume it hasn't been set and use the default
sendBatched = false
} else {
// default to not using batching if the setting is set to immediate
sendBatched = result.Data.(model.Preference).Value != model.PREFERENCE_DEFAULT_EMAIL_INTERVAL
}
if sendBatched {
if err := AddNotificationEmailToBatch(user, post, team); err == nil {
return nil
}
}
// fall back to sending a single email if we can't batch it for some reason
}
var channelName string
var bodyText string
var subjectText string
var mailTemplate string
var mailParameters map[string]interface{}
teamURL := utils.GetSiteURL() + "/" + team.Name
tm := time.Unix(post.CreateAt/1000, 0)
userLocale := utils.GetUserTranslations(user.Locale)
month := userLocale(tm.Month().String())
day := fmt.Sprintf("%d", tm.Day())
year := fmt.Sprintf("%d", tm.Year())
zone, _ := tm.Zone()
if channel.Type == model.CHANNEL_DIRECT {
bodyText = userLocale("api.post.send_notifications_and_forget.message_body")
subjectText = userLocale("api.post.send_notifications_and_forget.message_subject")
senderDisplayName := senderName
mailTemplate = "api.templates.post_subject_in_direct_message"
mailParameters = map[string]interface{}{"SubjectText": subjectText, "TeamDisplayName": team.DisplayName,
"SenderDisplayName": senderDisplayName, "Month": month, "Day": day, "Year": year}
} else {
bodyText = userLocale("api.post.send_notifications_and_forget.mention_body")
subjectText = userLocale("api.post.send_notifications_and_forget.mention_subject")
channelName = channel.DisplayName
mailTemplate = "api.templates.post_subject_in_channel"
mailParameters = map[string]interface{}{"SubjectText": subjectText, "TeamDisplayName": team.DisplayName,
"ChannelName": channelName, "Month": month, "Day": day, "Year": year}
}
subject := fmt.Sprintf("[%v] %v", utils.Cfg.TeamSettings.SiteName, userLocale(mailTemplate, mailParameters))
bodyPage := utils.NewHTMLTemplate("post_body", user.Locale)
bodyPage.Props["SiteURL"] = utils.GetSiteURL()
bodyPage.Props["PostMessage"] = GetMessageForNotification(post, userLocale)
if team.Name != "select_team" {
bodyPage.Props["TeamLink"] = teamURL + "/pl/" + post.Id
} else {
bodyPage.Props["TeamLink"] = teamURL
}
bodyPage.Props["BodyText"] = bodyText
bodyPage.Props["Button"] = userLocale("api.templates.post_body.button")
bodyPage.Html["Info"] = template.HTML(userLocale("api.templates.post_body.info",
map[string]interface{}{"ChannelName": channelName, "SenderName": senderName,
"Hour": fmt.Sprintf("%02d", tm.Hour()), "Minute": fmt.Sprintf("%02d", tm.Minute()),
"TimeZone": zone, "Month": month, "Day": day}))
if err := utils.SendMail(user.Email, html.UnescapeString(subject), bodyPage.Render()); err != nil {
return err
}
if einterfaces.GetMetricsInterface() != nil {
einterfaces.GetMetricsInterface().IncrementPostSentEmail()
}
return nil
}
func GetMessageForNotification(post *model.Post, translateFunc i18n.TranslateFunc) string {
if len(strings.TrimSpace(post.Message)) != 0 || len(post.FileIds) == 0 {
return post.Message
}
// extract the filenames from their paths and determine what type of files are attached
var infos []*model.FileInfo
if result := <-Srv.Store.FileInfo().GetForPost(post.Id); result.Err != nil {
l4g.Warn(utils.T("api.post.get_message_for_notification.get_files.error"), post.Id, result.Err)
} else {
infos = result.Data.([]*model.FileInfo)
}
filenames := make([]string, len(infos))
onlyImages := true
for i, info := range infos {
if escaped, err := url.QueryUnescape(filepath.Base(info.Name)); err != nil {
// this should never error since filepath was escaped using url.QueryEscape
filenames[i] = escaped
} else {
filenames[i] = info.Name
}
onlyImages = onlyImages && info.IsImage()
}
props := map[string]interface{}{"Filenames": strings.Join(filenames, ", ")}
if onlyImages {
return translateFunc("api.post.get_message_for_notification.images_sent", len(filenames), props)
} else {
return translateFunc("api.post.get_message_for_notification.files_sent", len(filenames), props)
}
}
func sendPushNotification(post *model.Post, user *model.User, channel *model.Channel, senderName string, wasMentioned bool) *model.AppError {
sessions, err := getMobileAppSessions(user.Id)
if err != nil {
return err
}
var channelName string
if channel.Type == model.CHANNEL_DIRECT {
channelName = senderName
} else {
channelName = channel.DisplayName
}
userLocale := utils.GetUserTranslations(user.Locale)
msg := model.PushNotification{}
if badge := <-Srv.Store.User().GetUnreadCount(user.Id); badge.Err != nil {
msg.Badge = 1
l4g.Error(utils.T("store.sql_user.get_unread_count.app_error"), user.Id, badge.Err)
} else {
msg.Badge = int(badge.Data.(int64))
}
msg.Type = model.PUSH_TYPE_MESSAGE
msg.TeamId = channel.TeamId
msg.ChannelId = channel.Id
msg.ChannelName = channel.Name
if *utils.Cfg.EmailSettings.PushNotificationContents == model.FULL_NOTIFICATION {
if channel.Type == model.CHANNEL_DIRECT {
msg.Category = model.CATEGORY_DM
msg.Message = "@" + senderName + ": " + model.ClearMentionTags(post.Message)
} else {
msg.Message = senderName + userLocale("api.post.send_notifications_and_forget.push_in") + channelName + ": " + model.ClearMentionTags(post.Message)
}
} else {
if channel.Type == model.CHANNEL_DIRECT {
msg.Category = model.CATEGORY_DM
msg.Message = senderName + userLocale("api.post.send_notifications_and_forget.push_message")
} else if wasMentioned {
msg.Message = senderName + userLocale("api.post.send_notifications_and_forget.push_mention") + channelName
} else {
msg.Message = senderName + userLocale("api.post.send_notifications_and_forget.push_non_mention") + channelName
}
}
l4g.Debug(utils.T("api.post.send_notifications_and_forget.push_notification.debug"), msg.DeviceId, msg.Message)
for _, session := range sessions {
tmpMessage := *model.PushNotificationFromJson(strings.NewReader(msg.ToJson()))
tmpMessage.SetDeviceIdAndPlatform(session.DeviceId)
if err := sendToPushProxy(tmpMessage); err != nil {
l4g.Error(err.Error)
}
if einterfaces.GetMetricsInterface() != nil {
einterfaces.GetMetricsInterface().IncrementPostSentPush()
}
}
return nil
}
func ClearPushNotification(userId string, channelId string) *model.AppError {
sessions, err := getMobileAppSessions(userId)
if err != nil {
return err
}
msg := model.PushNotification{}
msg.Type = model.PUSH_TYPE_CLEAR
msg.ChannelId = channelId
msg.ContentAvailable = 0
if badge := <-Srv.Store.User().GetUnreadCount(userId); badge.Err != nil {
msg.Badge = 0
l4g.Error(utils.T("store.sql_user.get_unread_count.app_error"), userId, badge.Err)
} else {
msg.Badge = int(badge.Data.(int64))
}
l4g.Debug(utils.T("api.post.send_notifications_and_forget.clear_push_notification.debug"), msg.DeviceId, msg.ChannelId)
for _, session := range sessions {
tmpMessage := *model.PushNotificationFromJson(strings.NewReader(msg.ToJson()))
tmpMessage.SetDeviceIdAndPlatform(session.DeviceId)
if err := sendToPushProxy(tmpMessage); err != nil {
l4g.Error(err.Error)
}
}
return nil
}
func sendToPushProxy(msg model.PushNotification) *model.AppError {
msg.ServerId = utils.CfgDiagnosticId
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections},
}
httpClient := &http.Client{Transport: tr}
request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+model.API_URL_SUFFIX_V1+"/send_push", strings.NewReader(msg.ToJson()))
if resp, err := httpClient.Do(request); err != nil {
return model.NewLocAppError("sendToPushProxy", "api.post.send_notifications_and_forget.push_notification.error", map[string]interface{}{"DeviceId": msg.DeviceId, "Error": err.Error()}, "")
} else {
ioutil.ReadAll(resp.Body)
resp.Body.Close()
}
return nil
}
func getMobileAppSessions(userId string) ([]*model.Session, *model.AppError) {
if result := <-Srv.Store.Session().GetSessionsWithActiveDeviceIds(userId); result.Err != nil {
return nil, result.Err
} else {
return result.Data.([]*model.Session), nil
}
}
func sendOutOfChannelMentions(post *model.Post, teamId string, profiles map[string]*model.User) *model.AppError {
if len(profiles) == 0 {
return nil
}
var usernames []string
for _, user := range profiles {
usernames = append(usernames, user.Username)
}
sort.Strings(usernames)
T := utils.GetUserTranslations(profiles[post.UserId].Locale)
var message string
if len(usernames) == 1 {
message = T("api.post.check_for_out_of_channel_mentions.message.one", map[string]interface{}{
"Username": usernames[0],
})
} else {
message = T("api.post.check_for_out_of_channel_mentions.message.multiple", map[string]interface{}{
"Usernames": strings.Join(usernames[:len(usernames)-1], ", "),
"LastUsername": usernames[len(usernames)-1],
})
}
SendEphemeralPost(
teamId,
post.UserId,
&model.Post{
ChannelId: post.ChannelId,
Message: message,
CreateAt: post.CreateAt + 1,
},
)
return nil
}
// Given a message and a map mapping mention keywords to the users who use them, returns a map of mentioned
// users and a slice of potential mention users not in the channel and whether or not @here was mentioned.
func GetExplicitMentions(message string, keywords map[string][]string) (map[string]bool, []string, bool, bool, bool) {
mentioned := make(map[string]bool)
potentialOthersMentioned := make([]string, 0)
systemMentions := map[string]bool{"@here": true, "@channel": true, "@all": true}
hereMentioned := false
allMentioned := false
channelMentioned := false
addMentionedUsers := func(ids []string) {
for _, id := range ids {
mentioned[id] = true
}
}
for _, word := range strings.Fields(message) {
isMention := false
if word == "@here" {
hereMentioned = true
}
if word == "@channel" {
channelMentioned = true
}
if word == "@all" {
allMentioned = true
}
// Non-case-sensitive check for regular keys
if ids, match := keywords[strings.ToLower(word)]; match {
addMentionedUsers(ids)
isMention = true
}
// Case-sensitive check for first name
if ids, match := keywords[word]; match {
addMentionedUsers(ids)
isMention = true
}
if !isMention {
// No matches were found with the string split just on whitespace so try further splitting
// the message on punctuation
splitWords := strings.FieldsFunc(word, func(c rune) bool {
return model.SplitRunes[c]
})
for _, splitWord := range splitWords {
if splitWord == "@here" {
hereMentioned = true
}
if splitWord == "@all" {
allMentioned = true
}
if splitWord == "@channel" {
channelMentioned = true
}
// Non-case-sensitive check for regular keys
if ids, match := keywords[strings.ToLower(splitWord)]; match {
addMentionedUsers(ids)
}
// Case-sensitive check for first name
if ids, match := keywords[splitWord]; match {
addMentionedUsers(ids)
} else if _, ok := systemMentions[word]; !ok && strings.HasPrefix(word, "@") {
username := word[1:len(splitWord)]
potentialOthersMentioned = append(potentialOthersMentioned, username)
}
}
}
}
return mentioned, potentialOthersMentioned, hereMentioned, channelMentioned, allMentioned
}
// Given a map of user IDs to profiles, returns a list of mention
// keywords for all users in the channel.
func GetMentionKeywordsInChannel(profiles map[string]*model.User) map[string][]string {
keywords := make(map[string][]string)
for id, profile := range profiles {
userMention := "@" + strings.ToLower(profile.Username)
keywords[userMention] = append(keywords[userMention], id)
if len(profile.NotifyProps["mention_keys"]) > 0 {
// Add all the user's mention keys
splitKeys := strings.Split(profile.NotifyProps["mention_keys"], ",")
for _, k := range splitKeys {
// note that these are made lower case so that we can do a case insensitive check for them
key := strings.ToLower(k)
keywords[key] = append(keywords[key], id)
}
}
// If turned on, add the user's case sensitive first name
if profile.NotifyProps["first_name"] == "true" {
keywords[profile.FirstName] = append(keywords[profile.FirstName], profile.Id)
}
// Add @channel and @all to keywords if user has them turned on
if int64(len(profiles)) < *utils.Cfg.TeamSettings.MaxNotificationsPerChannel && profile.NotifyProps["channel"] == "true" {
keywords["@channel"] = append(keywords["@channel"], profile.Id)
keywords["@all"] = append(keywords["@all"], profile.Id)
}
}
return keywords
}

312
app/notification_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,312 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"testing"
"github.com/mattermost/platform/model"
)
func TestSendNotifications(t *testing.T) {
th := Setup().InitBasic()
AddUserToChannel(th.BasicUser2, th.BasicChannel)
post1, postErr := CreatePost(&model.Post{
UserId: th.BasicUser.Id,
ChannelId: th.BasicChannel.Id,
Message: "@" + th.BasicUser2.Username,
}, th.BasicTeam.Id, true)
if postErr != nil {
t.Fatal(postErr)
}
mentions, err := SendNotifications(post1, th.BasicTeam, th.BasicChannel)
if err != nil {
t.Fatal(err)
} else 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 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 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 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")
}
}

196
app/post.go Обычный файл
Просмотреть файл

@@ -0,0 +1,196 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"regexp"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
)
func CreatePost(post *model.Post, teamId string, triggerWebhooks bool) (*model.Post, *model.AppError) {
var pchan store.StoreChannel
if len(post.RootId) > 0 {
pchan = Srv.Store.Post().Get(post.RootId)
}
// Verify the parent/child relationships are correct
if pchan != nil {
if presult := <-pchan; presult.Err != nil {
return nil, model.NewLocAppError("createPost", "api.post.create_post.root_id.app_error", nil, "")
} else {
list := presult.Data.(*model.PostList)
if len(list.Posts) == 0 || !list.IsChannelId(post.ChannelId) {
return nil, model.NewLocAppError("createPost", "api.post.create_post.channel_root_id.app_error", nil, "")
}
if post.ParentId == "" {
post.ParentId = post.RootId
}
if post.RootId != post.ParentId {
parent := list.Posts[post.ParentId]
if parent == nil {
return nil, model.NewLocAppError("createPost", "api.post.create_post.parent_id.app_error", nil, "")
}
}
}
}
post.Hashtags, _ = model.ParseHashtags(post.Message)
var rpost *model.Post
if result := <-Srv.Store.Post().Save(post); result.Err != nil {
return nil, result.Err
} else {
rpost = result.Data.(*model.Post)
}
if einterfaces.GetMetricsInterface() != nil {
einterfaces.GetMetricsInterface().IncrementPostCreate()
}
if len(post.FileIds) > 0 {
// There's a rare bug where the client sends up duplicate FileIds so protect against that
post.FileIds = utils.RemoveDuplicatesFromStringArray(post.FileIds)
for _, fileId := range post.FileIds {
if result := <-Srv.Store.FileInfo().AttachToPost(fileId, post.Id); result.Err != nil {
l4g.Error(utils.T("api.post.create_post.attach_files.error"), post.Id, post.FileIds, post.UserId, result.Err)
}
}
if einterfaces.GetMetricsInterface() != nil {
einterfaces.GetMetricsInterface().IncrementPostFileAttachment(len(post.FileIds))
}
}
InvalidateCacheForChannel(rpost.ChannelId)
InvalidateCacheForChannelPosts(rpost.ChannelId)
if err := handlePostEvents(rpost, teamId, triggerWebhooks); err != nil {
return nil, err
}
return rpost, nil
}
func handlePostEvents(post *model.Post, teamId string, triggerWebhooks bool) *model.AppError {
tchan := Srv.Store.Team().Get(teamId)
cchan := Srv.Store.Channel().Get(post.ChannelId, true)
uchan := Srv.Store.User().Get(post.UserId)
var team *model.Team
if result := <-tchan; result.Err != nil {
return result.Err
} else {
team = result.Data.(*model.Team)
}
var channel *model.Channel
if result := <-cchan; result.Err != nil {
return result.Err
} else {
channel = result.Data.(*model.Channel)
}
if _, err := SendNotifications(post, team, channel); err != nil {
return err
}
var user *model.User
if result := <-uchan; result.Err != nil {
return result.Err
} else {
user = result.Data.(*model.User)
}
if triggerWebhooks {
go func() {
if err := handleWebhookEvents(post, team, channel, user); err != nil {
l4g.Error(err.Error())
}
}()
}
if channel.Type == model.CHANNEL_DIRECT {
go func() {
if err := MakeDirectChannelVisible(post.ChannelId); err != nil {
l4g.Error(err.Error())
}
}()
}
return nil
}
var linkWithTextRegex *regexp.Regexp = regexp.MustCompile(`<([^<\|]+)\|([^>]+)>`)
// This method only parses and processes the attachments,
// all else should be set in the post which is passed
func parseSlackAttachment(post *model.Post, attachments interface{}) {
post.Type = model.POST_SLACK_ATTACHMENT
if list, success := attachments.([]interface{}); success {
for i, aInt := range list {
attachment := aInt.(map[string]interface{})
if aText, ok := attachment["text"].(string); ok {
aText = linkWithTextRegex.ReplaceAllString(aText, "[${2}](${1})")
attachment["text"] = aText
list[i] = attachment
}
if aText, ok := attachment["pretext"].(string); ok {
aText = linkWithTextRegex.ReplaceAllString(aText, "[${2}](${1})")
attachment["pretext"] = aText
list[i] = attachment
}
if fVal, ok := attachment["fields"]; ok {
if fields, ok := fVal.([]interface{}); ok {
// parse attachment field links into Markdown format
for j, fInt := range fields {
field := fInt.(map[string]interface{})
if fValue, ok := field["value"].(string); ok {
fValue = linkWithTextRegex.ReplaceAllString(fValue, "[${2}](${1})")
field["value"] = fValue
fields[j] = field
}
}
attachment["fields"] = fields
list[i] = attachment
}
}
}
post.AddProp("attachments", list)
}
}
func parseSlackLinksToMarkdown(text string) string {
return linkWithTextRegex.ReplaceAllString(text, "[${2}](${1})")
}
func SendEphemeralPost(teamId, userId string, post *model.Post) *model.Post {
post.Type = model.POST_EPHEMERAL
// fill in fields which haven't been specified which have sensible defaults
if post.Id == "" {
post.Id = model.NewId()
}
if post.CreateAt == 0 {
post.CreateAt = model.GetMillis()
}
if post.Props == nil {
post.Props = model.StringInterface{}
}
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_EPHEMERAL_MESSAGE, "", post.ChannelId, userId, nil)
message.Add("post", post.ToJson())
go Publish(message)
return post
}

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

@@ -1,7 +1,7 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
package app
import (
"crypto/tls"
@@ -23,15 +23,50 @@ import (
)
type Server struct {
Store store.Store
Router *mux.Router
GracefulServer *graceful.Server
Store store.Store
WebSocketRouter *WebSocketRouter
Router *mux.Router
GracefulServer *graceful.Server
}
var allowedMethods []string = []string{
"POST",
"GET",
"OPTIONS",
"PUT",
"PATCH",
"DELETE",
}
type CorsWrapper struct {
router *mux.Router
}
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)
}
const TIME_TO_WAIT_FOR_CONNECTIONS_TO_CLOSE_ON_SERVER_SHUTDOWN = time.Second
var Srv *Server
@@ -46,15 +81,10 @@ 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)
return utils.GetIpAddress(r)
}
func initalizeThrottledVaryBy() *throttled.VaryBy {
@@ -116,7 +146,7 @@ func StartServer() {
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))
l4g.Error("%v: Denied due to throttling settings code=429 ip=%v", r.URL.Path, utils.GetIpAddress(r))
throttled.DefaultDeniedHandler.ServeHTTP(w, r)
}),
}

94
app/session.go Обычный файл
Просмотреть файл

@@ -0,0 +1,94 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
l4g "github.com/alecthomas/log4go"
)
var sessionCache *utils.Cache = utils.NewLru(model.SESSION_CACHE_SIZE)
func GetSession(token string) (*model.Session, *model.AppError) {
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 {
return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token, "Error": sessionResult.Err.DetailedError}, "")
} else {
session = sessionResult.Data.(*model.Session)
if session.IsExpired() || session.Token != token {
return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token, "Error": sessionResult.Err.DetailedError}, "")
} else {
AddSessionToCache(session)
return session, nil
}
}
}
if session == nil || session.IsExpired() {
return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token}, "")
}
return session, nil
}
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 SessionCacheLength() int {
return sessionCache.Len()
}

31
app/session_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,31 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
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")
}
}

255
app/status.go Обычный файл
Просмотреть файл

@@ -0,0 +1,255 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/einterfaces"
"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 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 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
}

82
app/team.go Обычный файл
Просмотреть файл

@@ -0,0 +1,82 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
func CreateTeam(team *model.Team) (*model.Team, *model.AppError) {
if result := <-Srv.Store.Team().Save(team); result.Err != nil {
return nil, result.Err
} else {
rteam := result.Data.(*model.Team)
if _, err := CreateDefaultChannels(rteam.Id); err != nil {
return nil, err
}
return rteam, nil
}
}
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
}

60
app/user.go Обычный файл
Просмотреть файл

@@ -0,0 +1,60 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
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
}
}

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

@@ -1,7 +1,7 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
package app
import (
"fmt"
@@ -35,32 +35,32 @@ type WebConn struct {
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)
func NewWebConn(ws *websocket.Conn, session model.Session, t goi18n.TranslateFunc, locale string) *WebConn {
if len(session.UserId) > 0 {
go SetStatusOnline(session.UserId, 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,
UserId: session.UserId,
SessionToken: session.Token,
SessionExpiresAt: session.ExpiresAt,
T: t,
Locale: locale,
}
}
func (c *WebConn) readPump() {
func (c *WebConn) ReadPump() {
defer func() {
HubUnregister(c)
c.WebSocket.Close()
}()
c.WebSocket.SetReadLimit(SOCKET_MAX_MESSAGE_SIZE_KB)
c.WebSocket.SetReadLimit(model.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() {
if c.IsAuthenticated() {
go SetStatusAwayIfNeeded(c.UserId, false)
}
return nil
@@ -78,12 +78,12 @@ func (c *WebConn) readPump() {
return
} else {
BaseRoutes.WebSocket.ServeWebSocket(c, &req)
Srv.WebSocketRouter.ServeWebSocket(c, &req)
}
}
}
func (c *WebConn) writePump() {
func (c *WebConn) WritePump() {
ticker := time.NewTicker(PING_PERIOD)
authTicker := time.NewTicker(AUTH_TIMEOUT)
@@ -149,15 +149,16 @@ func (webCon *WebConn) InvalidateCache() {
webCon.SessionExpiresAt = 0
}
func (webCon *WebConn) isAuthenticated() bool {
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() {
session, err := GetSession(webCon.SessionToken)
if err != nil {
l4g.Error(utils.T("api.websocket.invalid_session.error"), err.Error())
webCon.SessionToken = ""
webCon.SessionExpiresAt = 0
return false
@@ -179,7 +180,7 @@ func (webCon *WebConn) SendHello() {
func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
// IMPORTANT: Do not send event if WebConn does not have a session
if !webCon.isAuthenticated() {
if !webCon.IsAuthenticated() {
return false
}
@@ -237,8 +238,9 @@ func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
}
func (webCon *WebConn) IsMemberOfTeam(teamId string) bool {
session := GetSession(webCon.SessionToken)
if session == nil {
session, err := GetSession(webCon.SessionToken)
if err != nil {
l4g.Error(utils.T("api.websocket.invalid_session.error"), err.Error())
return false
} else {
member := session.GetTeamByTeamId(teamId)

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

@@ -1,7 +1,7 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
package app
import (
"fmt"
@@ -156,7 +156,7 @@ func InvalidateWebConnSessionCacheForUser(userId string) {
func (h *Hub) Register(webConn *WebConn) {
h.register <- webConn
if webConn.isAuthenticated() {
if webConn.IsAuthenticated() {
webConn.SendHello()
}
}

155
app/webhook.go Обычный файл
Просмотреть файл

@@ -0,0 +1,155 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"crypto/tls"
"io"
"io/ioutil"
"net/http"
"strings"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
const (
TRIGGERWORDS_FULL = 0
TRIGGERWORDS_STARTSWITH = 1
)
func handleWebhookEvents(post *model.Post, team *model.Team, channel *model.Channel, user *model.User) *model.AppError {
if !utils.Cfg.ServiceSettings.EnableOutgoingWebhooks {
return nil
}
if channel.Type != model.CHANNEL_OPEN {
return nil
}
hchan := Srv.Store.Webhook().GetOutgoingByTeam(team.Id)
result := <-hchan
if result.Err != nil {
return result.Err
}
hooks := result.Data.([]*model.OutgoingWebhook)
if len(hooks) == 0 {
return nil
}
splitWords := strings.Fields(post.Message)
if len(splitWords) == 0 {
return nil
}
firstWord := splitWords[0]
relevantHooks := []*model.OutgoingWebhook{}
for _, hook := range hooks {
if hook.ChannelId == post.ChannelId || len(hook.ChannelId) == 0 {
if hook.ChannelId == post.ChannelId && len(hook.TriggerWords) == 0 {
relevantHooks = append(relevantHooks, hook)
} else if hook.TriggerWhen == TRIGGERWORDS_FULL && hook.HasTriggerWord(firstWord) {
relevantHooks = append(relevantHooks, hook)
} else if hook.TriggerWhen == TRIGGERWORDS_STARTSWITH && hook.TriggerWordStartsWith(firstWord) {
relevantHooks = append(relevantHooks, hook)
}
}
}
for _, hook := range relevantHooks {
go func(hook *model.OutgoingWebhook) {
payload := &model.OutgoingWebhookPayload{
Token: hook.Token,
TeamId: hook.TeamId,
TeamDomain: team.Name,
ChannelId: post.ChannelId,
ChannelName: channel.Name,
Timestamp: post.CreateAt,
UserId: post.UserId,
UserName: user.Username,
PostId: post.Id,
Text: post.Message,
TriggerWord: firstWord,
}
var body io.Reader
var contentType string
if hook.ContentType == "application/json" {
body = strings.NewReader(payload.ToJSON())
contentType = "application/json"
} else {
body = strings.NewReader(payload.ToFormValues())
contentType = "application/x-www-form-urlencoded"
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections},
}
client := &http.Client{Transport: tr}
for _, url := range hook.CallbackURLs {
go func(url string) {
req, _ := http.NewRequest("POST", url, body)
req.Header.Set("Content-Type", contentType)
req.Header.Set("Accept", "application/json")
if resp, err := client.Do(req); err != nil {
l4g.Error(utils.T("api.post.handle_webhook_events_and_forget.event_post.error"), err.Error())
} else {
defer func() {
ioutil.ReadAll(resp.Body)
resp.Body.Close()
}()
respProps := model.MapFromJson(resp.Body)
if text, ok := respProps["text"]; ok {
if _, err := CreateWebhookPost(hook.CreatorId, hook.TeamId, post.ChannelId, text, respProps["username"], respProps["icon_url"], post.Props, post.Type); err != nil {
l4g.Error(utils.T("api.post.handle_webhook_events_and_forget.create_post.error"), err)
}
}
}
}(url)
}
}(hook)
}
return nil
}
func CreateWebhookPost(userId, teamId, channelId, text, overrideUsername, overrideIconUrl string, props model.StringInterface, postType string) (*model.Post, *model.AppError) {
post := &model.Post{UserId: userId, ChannelId: channelId, Message: text, Type: postType}
post.AddProp("from_webhook", "true")
if utils.Cfg.ServiceSettings.EnablePostUsernameOverride {
if len(overrideUsername) != 0 {
post.AddProp("override_username", overrideUsername)
} else {
post.AddProp("override_username", model.DEFAULT_WEBHOOK_USERNAME)
}
}
if utils.Cfg.ServiceSettings.EnablePostIconOverride {
if len(overrideIconUrl) != 0 {
post.AddProp("override_icon_url", overrideIconUrl)
}
}
post.Message = parseSlackLinksToMarkdown(post.Message)
if len(props) > 0 {
for key, val := range props {
if key == "attachments" {
parseSlackAttachment(post, val)
} else if key != "override_icon_url" && key != "override_username" && key != "from_webhook" {
post.AddProp(key, val)
}
}
}
if _, err := CreatePost(post, teamId, false); err != nil {
return nil, model.NewLocAppError("CreateWebhookPost", "api.post.create_webhook_post.creating.app_error", nil, "err="+err.Message)
}
return post, nil
}

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

@@ -1,7 +1,7 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
package app
import (
l4g "github.com/alecthomas/log4go"
@@ -10,30 +10,34 @@ import (
"github.com/mattermost/platform/utils"
)
type webSocketHandler interface {
ServeWebSocket(*WebConn, *model.WebSocketRequest)
}
type WebSocketRouter struct {
handlers map[string]*webSocketHandler
handlers map[string]webSocketHandler
}
func NewWebSocketRouter() *WebSocketRouter {
router := &WebSocketRouter{}
router.handlers = make(map[string]*webSocketHandler)
router.handlers = make(map[string]webSocketHandler)
return router
}
func (wr *WebSocketRouter) Handle(action string, handler *webSocketHandler) {
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)
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)
ReturnWebSocketError(conn, r, err)
return
}
@@ -44,9 +48,9 @@ func (wr *WebSocketRouter) ServeWebSocket(conn *WebConn, r *model.WebSocketReque
return
}
session := GetSession(token)
session, err := GetSession(token)
if session == nil || session.IsExpired() {
if err != nil {
conn.WebSocket.Close()
} else {
go SetStatusOnline(session.UserId, session.Id, false)
@@ -63,16 +67,16 @@ func (wr *WebSocketRouter) ServeWebSocket(conn *WebConn, r *model.WebSocketReque
return
}
if !conn.isAuthenticated() {
if !conn.IsAuthenticated() {
err := model.NewLocAppError("ServeWebSocket", "api.web_socket_router.not_authenticated.app_error", nil, "")
wr.ReturnWebSocketError(conn, r, err)
ReturnWebSocketError(conn, r, err)
return
}
var handler *webSocketHandler
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)
ReturnWebSocketError(conn, r, err)
return
} else {
handler = h
@@ -81,7 +85,7 @@ func (wr *WebSocketRouter) ServeWebSocket(conn *WebConn, r *model.WebSocketReque
handler.ServeWebSocket(conn, r)
}
func (wr *WebSocketRouter) ReturnWebSocketError(conn *WebConn, r *model.WebSocketRequest, err *model.AppError) {
func 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 = ""

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

@@ -6,6 +6,7 @@ import (
"errors"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"github.com/spf13/cobra"
@@ -117,6 +118,8 @@ func createChannelCmdF(cmd *cobra.Command, args []string) error {
team := getTeamFromTeamArg(teamArg)
c := getMockContext()
channel := &model.Channel{
TeamId: team.Id,
Name: name,
@@ -124,10 +127,10 @@ func createChannelCmdF(cmd *cobra.Command, args []string) error {
Header: header,
Purpose: purpose,
Type: channelType,
CreatorId: c.Session.UserId,
}
c := getMockContext()
if _, err := api.CreateChannel(c, channel, false); err != nil {
if _, err := app.CreateChannel(channel, false); err != nil {
return err
}
@@ -197,7 +200,7 @@ func addUserToChannel(channel *model.Channel, user *model.User, userArg string)
CommandPrintErrorln("Can't find user '" + userArg + "'")
return
}
if _, err := api.AddUserToChannel(user, channel); err != nil {
if _, err := app.AddUserToChannel(user, channel); err != nil {
CommandPrintErrorln("Unable to add '" + userArg + "' from " + channel.Name + ". Error: " + err.Error())
}
}
@@ -215,7 +218,7 @@ func deleteChannelsCmdF(cmd *cobra.Command, args []string) error {
CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
continue
}
if result := <-api.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); result.Err != nil {
if result := <-app.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); result.Err != nil {
CommandPrintErrorln("Unable to delete channel '" + channel.Name + "' error: " + result.Err.Error())
}
}
@@ -240,7 +243,7 @@ func listChannelsCmdF(cmd *cobra.Command, args []string) error {
CommandPrintErrorln("Unable to find team '" + args[i] + "'")
continue
}
if result := <-api.Srv.Store.Channel().GetAll(team.Id); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetAll(team.Id); result.Err != nil {
CommandPrintErrorln("Unable to list channels for '" + args[i] + "'")
} else {
channels := result.Data.([]*model.Channel)
@@ -275,7 +278,7 @@ func restoreChannelsCmdF(cmd *cobra.Command, args []string) error {
CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
continue
}
if result := <-api.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil {
if result := <-app.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil {
CommandPrintErrorln("Unable to restore channel '" + args[i] + "'")
}
}

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

@@ -6,7 +6,7 @@ import (
"fmt"
"strings"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -42,7 +42,7 @@ func getChannelFromChannelArg(channelArg string) *model.Channel {
return nil
}
if result := <-api.Srv.Store.Channel().GetByNameIncludeDeleted(team.Id, channelPart); result.Err == nil {
if result := <-app.Srv.Store.Channel().GetByNameIncludeDeleted(team.Id, channelPart); result.Err == nil {
channel = result.Data.(*model.Channel)
} else {
fmt.Println(result.Err.Error())
@@ -50,7 +50,7 @@ func getChannelFromChannelArg(channelArg string) *model.Channel {
}
if channel == nil {
if result := <-api.Srv.Store.Channel().Get(channelPart, true); result.Err == nil {
if result := <-app.Srv.Store.Channel().Get(channelPart, true); result.Err == nil {
channel = result.Data.(*model.Channel)
}
}

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

@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"github.com/spf13/cobra"
@@ -37,8 +38,8 @@ func initDBCommandContext(configFileLocation string) {
utils.ConfigureCmdLineLog()
api.NewServer()
api.InitStores()
app.NewServer()
app.InitStores()
if model.BuildEnterpriseReady == "true" {
api.LoadLicense()
}

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

@@ -9,7 +9,7 @@ import (
"fmt"
"os"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/spf13/cobra"
// Plugins
@@ -79,7 +79,7 @@ func resetCmdF(cmd *cobra.Command, args []string) error {
}
}
api.Srv.Store.DropAllTables()
app.Srv.Store.DropAllTables()
CommandPrettyPrintln("Database sucessfully reset")
return nil

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

@@ -13,6 +13,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
@@ -69,8 +70,8 @@ func doLegacyCommands() {
doLoadConfig(flagConfigFile)
utils.InitTranslations(utils.Cfg.LocalizationSettings)
utils.ConfigureCmdLineLog()
api.NewServer()
api.InitStores()
app.NewServer()
app.InitStores()
api.InitRouter()
api.InitApi()
web.InitWeb()
@@ -187,9 +188,9 @@ func runCmds() {
func cmdRunClientTests() {
if flagCmdRunWebClientTests {
setupClientTests()
api.StartServer()
app.StartServer()
runWebClientTests()
api.StopServer()
app.StopServer()
}
}
@@ -220,9 +221,8 @@ func cmdCreateTeam() {
team.Email = flagEmail
team.Type = model.TEAM_OPEN
api.CreateTeam(c, team)
if c.Err != nil {
if c.Err.Id != "store.sql_team.save.domain_exists.app_error" {
if _, err := app.CreateTeam(team); err != nil {
if err.Id != "store.sql_team.save.domain_exists.app_error" {
l4g.Error("%v", c.Err)
flushLogAndExit(1)
}
@@ -257,7 +257,7 @@ func cmdCreateUser() {
}
if len(flagTeamName) > 0 {
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -265,7 +265,7 @@ func cmdCreateUser() {
}
}
ruser, err := api.CreateUser(user)
ruser, err := app.CreateUser(user)
if err != nil {
if err.Id != "store.sql_user.save.email_exists.app_error" {
l4g.Error("%v", err)
@@ -274,7 +274,7 @@ func cmdCreateUser() {
}
if team != nil {
err = api.JoinUserToTeam(team, ruser)
err = app.JoinUserToTeam(team, ruser)
if err != nil {
l4g.Error("%v", err)
flushLogAndExit(1)
@@ -303,7 +303,7 @@ func cmdInviteUser() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -311,7 +311,7 @@ func cmdInviteUser() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(team.Email); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(team.Email); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -333,7 +333,7 @@ func cmdVersion() {
fmt.Fprintln(os.Stderr, "Build Date: "+model.BuildDate)
fmt.Fprintln(os.Stderr, "Build Hash: "+model.BuildHash)
fmt.Fprintln(os.Stderr, "Build Enterprise Ready: "+model.BuildEnterpriseReady)
fmt.Fprintln(os.Stderr, "DB Version: "+api.Srv.Store.(*store.SqlStore).SchemaVersion)
fmt.Fprintln(os.Stderr, "DB Version: "+app.Srv.Store.(*store.SqlStore).SchemaVersion)
os.Exit(0)
}
@@ -361,7 +361,7 @@ func cmdAssignRole() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -404,7 +404,7 @@ func cmdCreateChannel() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v %v", utils.T(result.Err.Message), result.Err.DetailedError)
flushLogAndExit(1)
} else {
@@ -412,7 +412,7 @@ func cmdCreateChannel() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v %v", utils.T(result.Err.Message), result.Err.DetailedError)
flushLogAndExit(1)
} else {
@@ -431,7 +431,7 @@ func cmdCreateChannel() {
channel.Header = flagChannelHeader
channel.Purpose = flagChannelPurpose
if _, err := api.CreateChannel(c, channel, true); err != nil {
if _, err := app.CreateChannel(channel, true); err != nil {
l4g.Error("%v %v", utils.T(err.Message), err.DetailedError)
flushLogAndExit(1)
}
@@ -463,7 +463,7 @@ func cmdJoinChannel() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -471,7 +471,7 @@ func cmdJoinChannel() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -479,14 +479,14 @@ func cmdJoinChannel() {
}
var channel *model.Channel
if result := <-api.Srv.Store.Channel().GetByName(team.Id, flagChannelName); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetByName(team.Id, flagChannelName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
channel = result.Data.(*model.Channel)
}
_, err := api.AddUserToChannel(user, channel)
_, err := app.AddUserToChannel(user, channel)
if err != nil {
l4g.Error("%v", err)
flushLogAndExit(1)
@@ -524,7 +524,7 @@ func cmdLeaveChannel() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -532,7 +532,7 @@ func cmdLeaveChannel() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -540,7 +540,7 @@ func cmdLeaveChannel() {
}
var channel *model.Channel
if result := <-api.Srv.Store.Channel().GetByName(team.Id, flagChannelName); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetByName(team.Id, flagChannelName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -570,14 +570,14 @@ func cmdListChannels() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
team = result.Data.(*model.Team)
}
if result := <-api.Srv.Store.Channel().GetAll(team.Id); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetAll(team.Id); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -615,7 +615,7 @@ func cmdRestoreChannel() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -623,7 +623,7 @@ func cmdRestoreChannel() {
}
var channel *model.Channel
if result := <-api.Srv.Store.Channel().GetAll(team.Id); result.Err != nil {
if result := <-app.Srv.Store.Channel().GetAll(team.Id); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -637,7 +637,7 @@ func cmdRestoreChannel() {
}
}
if result := <-api.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil {
if result := <-app.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
}
@@ -659,7 +659,7 @@ func cmdJoinTeam() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -667,14 +667,14 @@ func cmdJoinTeam() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
user = result.Data.(*model.User)
}
err := api.JoinUserToTeam(team, user)
err := app.JoinUserToTeam(team, user)
if err != nil {
l4g.Error("%v", err)
flushLogAndExit(1)
@@ -697,7 +697,7 @@ func cmdLeaveTeam() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -705,7 +705,7 @@ func cmdLeaveTeam() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -741,14 +741,14 @@ func cmdResetPassword() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
user = result.Data.(*model.User)
}
if result := <-api.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(flagPassword)); result.Err != nil {
if result := <-app.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(flagPassword)); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
}
@@ -766,14 +766,14 @@ func cmdResetMfa() {
var user *model.User
if len(flagEmail) > 0 {
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
user = result.Data.(*model.User)
}
} else {
if result := <-api.Srv.Store.User().GetByUsername(flagUsername); result.Err != nil {
if result := <-app.Srv.Store.User().GetByUsername(flagUsername); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -798,7 +798,7 @@ func cmdPermDeleteUser() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -841,7 +841,7 @@ func cmdPermDeleteTeam() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -927,7 +927,7 @@ func cmdResetDatabase() {
flushLogAndExit(1)
}
api.Srv.Store.DropAllTables()
app.Srv.Store.DropAllTables()
fmt.Print("SUCCESS: Database reset.")
flushLogAndExit(0)
}
@@ -1022,7 +1022,7 @@ func cmdActivateUser() {
}
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {
@@ -1054,7 +1054,7 @@ func cmdSlackImport() {
}
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
if result := <-app.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
l4g.Error("%v", result.Err)
flushLogAndExit(1)
} else {

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

@@ -16,6 +16,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/manualtesting"
"github.com/mattermost/platform/model"
@@ -63,8 +64,8 @@ func runServer(configFileLocation string) {
cmdUpdateDb30()
api.NewServer()
api.InitStores()
app.NewServer()
app.InitStores()
api.InitRouter()
api.InitApi()
web.InitWeb()
@@ -84,7 +85,7 @@ func runServer(configFileLocation string) {
resetStatuses()
api.StartServer()
app.StartServer()
// If we allow testing then listen for manual testing URL hits
if utils.Cfg.ServiceSettings.EnableTesting {
@@ -120,7 +121,7 @@ func runServer(configFileLocation string) {
einterfaces.GetMetricsInterface().StopServer()
}
api.StopServer()
app.StopServer()
}
func runSecurityAndDiagnosticsJob() {
@@ -129,20 +130,20 @@ func runSecurityAndDiagnosticsJob() {
}
func resetStatuses() {
if result := <-api.Srv.Store.Status().ResetAll(); result.Err != nil {
if result := <-app.Srv.Store.Status().ResetAll(); result.Err != nil {
l4g.Error(utils.T("mattermost.reset_status.error"), result.Err.Error())
}
}
func setDiagnosticId() {
if result := <-api.Srv.Store.System().Get(); result.Err == nil {
if result := <-app.Srv.Store.System().Get(); result.Err == nil {
props := result.Data.(model.StringMap)
id := props[model.SYSTEM_DIAGNOSTIC_ID]
if len(id) == 0 {
id = model.NewId()
systemId := &model.System{Name: model.SYSTEM_DIAGNOSTIC_ID, Value: id}
<-api.Srv.Store.System().Save(systemId)
<-app.Srv.Store.System().Save(systemId)
}
utils.CfgDiagnosticId = id
@@ -151,7 +152,7 @@ func setDiagnosticId() {
func doSecurityAndDiagnostics() {
if *utils.Cfg.ServiceSettings.EnableSecurityFixAlert {
if result := <-api.Srv.Store.System().Get(); result.Err == nil {
if result := <-app.Srv.Store.System().Get(); result.Err == nil {
props := result.Data.(model.StringMap)
lastSecurityTime, _ := strconv.ParseInt(props[model.SYSTEM_LAST_SECURITY_TIME], 10, 0)
currentTime := model.GetMillis()
@@ -176,20 +177,20 @@ func doSecurityAndDiagnostics() {
systemSecurityLastTime := &model.System{Name: model.SYSTEM_LAST_SECURITY_TIME, Value: strconv.FormatInt(currentTime, 10)}
if lastSecurityTime == 0 {
<-api.Srv.Store.System().Save(systemSecurityLastTime)
<-app.Srv.Store.System().Save(systemSecurityLastTime)
} else {
<-api.Srv.Store.System().Update(systemSecurityLastTime)
<-app.Srv.Store.System().Update(systemSecurityLastTime)
}
if ucr := <-api.Srv.Store.User().GetTotalUsersCount(); ucr.Err == nil {
if ucr := <-app.Srv.Store.User().GetTotalUsersCount(); ucr.Err == nil {
v.Set(utils.PROP_DIAGNOSTIC_USER_COUNT, strconv.FormatInt(ucr.Data.(int64), 10))
}
if ucr := <-api.Srv.Store.Status().GetTotalActiveUsersCount(); ucr.Err == nil {
if ucr := <-app.Srv.Store.Status().GetTotalActiveUsersCount(); ucr.Err == nil {
v.Set(utils.PROP_DIAGNOSTIC_ACTIVE_USER_COUNT, strconv.FormatInt(ucr.Data.(int64), 10))
}
if tcr := <-api.Srv.Store.Team().AnalyticsTeamCount(); tcr.Err == nil {
if tcr := <-app.Srv.Store.Team().AnalyticsTeamCount(); tcr.Err == nil {
v.Set(utils.PROP_DIAGNOSTIC_TEAM_COUNT, strconv.FormatInt(tcr.Data.(int64), 10))
}
@@ -206,7 +207,7 @@ func doSecurityAndDiagnostics() {
for _, bulletin := range bulletins {
if bulletin.AppliesToVersion == model.CurrentVersion {
if props["SecurityBulletin_"+bulletin.Id] == "" {
if results := <-api.Srv.Store.User().GetSystemAdminProfiles(); results.Err != nil {
if results := <-app.Srv.Store.User().GetSystemAdminProfiles(); results.Err != nil {
l4g.Error(utils.T("mattermost.system_admins.error"))
return
} else {
@@ -232,7 +233,7 @@ func doSecurityAndDiagnostics() {
}
bulletinSeen := &model.System{Name: "SecurityBulletin_" + bulletin.Id, Value: bulletin.Id}
<-api.Srv.Store.System().Save(bulletinSeen)
<-app.Srv.Store.System().Save(bulletinSeen)
}
}
}
@@ -251,15 +252,15 @@ func sendServerDiagnostics() {
var activeUserCount int64
var teamCount int64
if ucr := <-api.Srv.Store.User().GetTotalUsersCount(); ucr.Err == nil {
if ucr := <-app.Srv.Store.User().GetTotalUsersCount(); ucr.Err == nil {
userCount = ucr.Data.(int64)
}
if ucr := <-api.Srv.Store.Status().GetTotalActiveUsersCount(); ucr.Err == nil {
if ucr := <-app.Srv.Store.Status().GetTotalActiveUsersCount(); ucr.Err == nil {
activeUserCount = ucr.Data.(int64)
}
if tcr := <-api.Srv.Store.Team().AnalyticsTeamCount(); tcr.Err == nil {
if tcr := <-app.Srv.Store.Team().AnalyticsTeamCount(); tcr.Err == nil {
teamCount = tcr.Data.(int64)
}

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

@@ -7,6 +7,7 @@ import (
"fmt"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/spf13/cobra"
)
@@ -92,10 +93,8 @@ func createTeamCmdF(cmd *cobra.Command, args []string) error {
Type: teamType,
}
c := getMockContext()
api.CreateTeam(c, team)
if c.Err != nil {
return errors.New("Team creation failed: " + c.Err.Error())
if _, err := app.CreateTeam(team); err != nil {
return errors.New("Team creation failed: " + err.Error())
}
return nil
@@ -156,7 +155,7 @@ func addUserToTeam(team *model.Team, user *model.User, userArg string) {
CommandPrintErrorln("Can't find user '" + userArg + "'")
return
}
if err := api.JoinUserToTeam(team, user); err != nil {
if err := app.JoinUserToTeam(team, user); err != nil {
CommandPrintErrorln("Unable to add '" + userArg + "' to " + team.Name)
}
}

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

@@ -3,7 +3,7 @@
package main
import (
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -18,12 +18,12 @@ func getTeamsFromTeamArgs(teamArgs []string) []*model.Team {
func getTeamFromTeamArg(teamArg string) *model.Team {
var team *model.Team
if result := <-api.Srv.Store.Team().GetByName(teamArg); result.Err == nil {
if result := <-app.Srv.Store.Team().GetByName(teamArg); result.Err == nil {
team = result.Data.(*model.Team)
}
if team == nil {
if result := <-api.Srv.Store.Team().Get(teamArg); result.Err == nil {
if result := <-app.Srv.Store.Team().Get(teamArg); result.Err == nil {
team = result.Data.(*model.Team)
}
}

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

@@ -10,6 +10,7 @@ import (
"os/exec"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/utils"
"github.com/spf13/cobra"
)
@@ -38,9 +39,9 @@ func webClientTestsCmdF(cmd *cobra.Command, args []string) error {
api.InitRouter()
api.InitApi()
setupClientTests()
api.StartServer()
app.StartServer()
runWebClientTests()
api.StopServer()
app.StopServer()
return nil
}

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

@@ -7,6 +7,7 @@ import (
"fmt"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
@@ -220,7 +221,7 @@ func userCreateCmdF(cmd *cobra.Command, args []string) error {
Locale: locale,
}
ruser, err := api.CreateUser(user)
ruser, err := app.CreateUser(user)
if err != nil {
return errors.New("Unable to create user. Error: " + err.Error())
}
@@ -277,7 +278,7 @@ func resetUserPasswordCmdF(cmd *cobra.Command, args []string) error {
}
password := args[1]
if result := <-api.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(password)); result.Err != nil {
if result := <-app.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(password)); result.Err != nil {
return result.Err
}
@@ -423,7 +424,7 @@ func verifyUserCmdF(cmd *cobra.Command, args []string) error {
if user == nil {
CommandPrintErrorln("Unable to find user '" + args[i] + "'")
}
if cresult := <-api.Srv.Store.User().VerifyEmail(user.Id); cresult.Err != nil {
if cresult := <-app.Srv.Store.User().VerifyEmail(user.Id); cresult.Err != nil {
CommandPrintErrorln("Unable to verify '" + args[i] + "' email. Error: " + cresult.Err.Error())
}
}

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

@@ -3,7 +3,7 @@
package main
import (
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
)
@@ -18,18 +18,18 @@ func getUsersFromUserArgs(userArgs []string) []*model.User {
func getUserFromUserArg(userArg string) *model.User {
var user *model.User
if result := <-api.Srv.Store.User().GetByEmail(userArg); result.Err == nil {
if result := <-app.Srv.Store.User().GetByEmail(userArg); result.Err == nil {
user = result.Data.(*model.User)
}
if user == nil {
if result := <-api.Srv.Store.User().GetByUsername(userArg); result.Err == nil {
if result := <-app.Srv.Store.User().GetByUsername(userArg); result.Err == nil {
user = result.Data.(*model.User)
}
}
if user == nil {
if result := <-api.Srv.Store.User().Get(userArg); result.Err == nil {
if result := <-app.Srv.Store.User().Get(userArg); result.Err == nil {
user = result.Data.(*model.User)
}
}

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

@@ -3,7 +3,7 @@
package main
import (
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/spf13/cobra"
@@ -26,5 +26,5 @@ func printVersion() {
CommandPrintln("Build Date: " + model.BuildDate)
CommandPrintln("Build Hash: " + model.BuildHash)
CommandPrintln("Build Enterprise Ready: " + model.BuildEnterpriseReady)
CommandPrintln("DB Version: " + api.Srv.Store.(*store.SqlStore).SchemaVersion)
CommandPrintln("DB Version: " + app.Srv.Store.(*store.SqlStore).SchemaVersion)
}

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

@@ -805,7 +805,15 @@
},
{
"id": "api.context.invalid_token.error",
"translation": "Invalid session token=%v, err=%v"
"translation": "Invalid session token={{.Token}}, err={{.Error}}"
},
{
"id": "api.context.invalid_session.error",
"translation": "Invalid session err=%v"
},
{
"id": "api.websocket.invalid_session.error",
"translation": "Invalid session err=%v"
},
{
"id": "api.context.invalidate_all_caches",
@@ -1467,26 +1475,10 @@
"id": "api.post.get_post.permissions.app_error",
"translation": "You do not have the appropriate permissions"
},
{
"id": "api.post.handle_post_events_and_forget.channel.error",
"translation": "Encountered error getting channel, channel_id=%s, err=%v"
},
{
"id": "api.post.handle_post_events_and_forget.members.error",
"translation": "Failed to get channel members channel_id=%v err=%v"
},
{
"id": "api.post.handle_post_events_and_forget.profiles.error",
"translation": "Failed to retrieve user profiles team_id=%v, err=%v"
},
{
"id": "api.post.handle_post_events_and_forget.team.error",
"translation": "Encountered error getting team, team_id=%s, err=%v"
},
{
"id": "api.post.handle_post_events_and_forget.user.error",
"translation": "Encountered error getting user, user_id=%s, err=%v"
},
{
"id": "api.post.handle_webhook_events_and_forget.create_post.error",
"translation": "Failed to create response post, err=%v"
@@ -1495,17 +1487,13 @@
"id": "api.post.handle_webhook_events_and_forget.event_post.error",
"translation": "Event POST failed, err=%s"
},
{
"id": "api.post.handle_webhook_events_and_forget.getting.error",
"translation": "Encountered error getting webhooks by team, err=%v"
},
{
"id": "api.post.init.debug",
"translation": "Initializing post API routes"
},
{
"id": "api.post.make_direct_channel_visible.get_2_members.error",
"translation": "Failed to get 2 members for a direct channel channel_id=%v"
"translation": "Failed to get 2 members for a direct channel channel_id={{.ChannelId}}"
},
{
"id": "api.post.make_direct_channel_visible.get_members.error",
@@ -1519,10 +1507,6 @@
"id": "api.post.make_direct_channel_visible.update_pref.error",
"translation": "Failed to update direct channel preference user_id=%v other_user_id=%v err=%v"
},
{
"id": "api.post.notification.here.warn",
"translation": "Unable to send notification to online users with @here, err=%v"
},
{
"id": "api.post.notification.member_profile.warn",
"translation": "Unable to get profile for channel member, user_id=%v"
@@ -1531,10 +1515,6 @@
"id": "api.post.send_notifications_and_forget.clear_push_notification.debug",
"translation": "Clearing push notification to %v with channel_id %v"
},
{
"id": "api.post.send_notifications_and_forget.comment_thread.error",
"translation": "Failed to retrieve comment thread posts in notifications root_post_id=%v, err=%v"
},
{
"id": "api.post.send_notifications_and_forget.files.error",
"translation": "Failed to get files for post notification post_id=%v, err=%v"
@@ -1581,23 +1561,15 @@
},
{
"id": "api.post.send_notifications_and_forget.push_notification.error",
"translation": "Failed to send push device_id=%v, err=%v"
},
{
"id": "api.post.send_notifications_and_forget.send.error",
"translation": "Failed to send mention email successfully email=%v err=%v"
"translation": "Failed to send push device_id={{.DeviceId}}, err={{.Error}}"
},
{
"id": "api.post.send_notifications_and_forget.sent",
"translation": "{{.Prefix}} {{.Filenames}} sent"
},
{
"id": "api.post.send_notifications_and_forget.sessions.error",
"translation": "Failed to retrieve sessions in notifications id=%v, err=%v"
},
{
"id": "api.post.send_notifications_and_forget.user_id.error",
"translation": "Post user_id not returned by GetProfiles user_id=%v"
"id": "api.post.send_notifications.user_id.debug",
"translation": "Post creator not in channel for the post, no notification sent post_id=%v channel_id=%v user_id=%v"
},
{
"id": "api.post.update_mention_count_and_forget.update_error",

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

@@ -4,16 +4,18 @@
package manualtesting
import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"hash/fnv"
"math/rand"
"net/http"
"net/url"
"strconv"
"time"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
)
type TestEnvironment struct {
@@ -27,7 +29,7 @@ type TestEnvironment struct {
}
func InitManualTesting() {
api.Srv.Router.Handle("/manualtest", api.AppHandler(manualTest)).Methods("GET")
app.Srv.Router.Handle("/manualtest", api.AppHandler(manualTest)).Methods("GET")
}
func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
@@ -70,7 +72,7 @@ func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
Type: model.TEAM_OPEN,
}
if result := <-api.Srv.Store.Team().Save(team); result.Err != nil {
if result := <-app.Srv.Store.Team().Save(team); result.Err != nil {
c.Err = result.Err
return
} else {
@@ -78,7 +80,7 @@ func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
createdTeam := result.Data.(*model.Team)
channel := &model.Channel{DisplayName: "Town Square", Name: "town-square", Type: model.CHANNEL_OPEN, TeamId: createdTeam.Id}
if _, err := api.CreateChannel(c, channel, false); err != nil {
if _, err := app.CreateChannel(channel, false); err != nil {
c.Err = err
return
}
@@ -98,8 +100,8 @@ func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
return
}
<-api.Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id)
<-api.Srv.Store.Team().SaveMember(&model.TeamMember{TeamId: teamID, UserId: result.Data.(*model.User).Id})
<-app.Srv.Store.User().VerifyEmail(result.Data.(*model.User).Id)
<-app.Srv.Store.Team().SaveMember(&model.TeamMember{TeamId: teamID, UserId: result.Data.(*model.User).Id})
newuser := result.Data.(*model.User)
userID = newuser.Id
@@ -153,7 +155,7 @@ func manualTest(c *api.Context, w http.ResponseWriter, r *http.Request) {
func getChannelID(channelname string, teamid string, userid string) (id string, err bool) {
// Grab all the channels
result := <-api.Srv.Store.Channel().GetChannels(teamid, userid)
result := <-app.Srv.Store.Channel().GetChannels(teamid, userid)
if result.Err != nil {
l4g.Debug(utils.T("manaultesting.get_channel_id.unable.debug"))
return "", false

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

@@ -8,6 +8,10 @@ import (
"github.com/gorilla/websocket"
)
const (
SOCKET_MAX_MESSAGE_SIZE_KB = 8 * 1024 // 8KB
)
type WebSocketClient struct {
Url string // The location of the server like "ws://localhost:8065"
ApiUrl string // The api location of the server like "ws://localhost:8065/api/v3"

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

@@ -32,6 +32,15 @@ var CfgHash = ""
var CfgFileName string = ""
var ClientCfg map[string]string = map[string]string{}
var originalDisableDebugLvl l4g.Level = l4g.DEBUG
var siteURL = ""
func GetSiteURL() string {
return siteURL
}
func SetSiteURL(url string) {
siteURL = url
}
func FindConfigFile(fileName string) string {
if _, err := os.Stat("./config/" + fileName); err == nil {
@@ -215,6 +224,7 @@ func LoadConfig(fileName string) {
}
SetDefaultRolesBasedOnConfig()
SetSiteURL(*Cfg.ServiceSettings.SiteURL)
}
func RegenerateClientConfig() {

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

@@ -4,7 +4,11 @@
package utils
import (
"net"
"net/http"
"os"
"github.com/mattermost/platform/model"
)
func StringArrayIntersection(arr1, arr2 []string) []string {
@@ -48,3 +52,17 @@ func RemoveDuplicatesFromStringArray(arr []string) []string {
return result
}
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
}

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

@@ -11,6 +11,7 @@ import (
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
"github.com/mssola/user_agent"
@@ -19,7 +20,7 @@ import (
func InitWeb() {
l4g.Debug(utils.T("web.init.debug"))
mainrouter := api.Srv.Router
mainrouter := app.Srv.Router
if *utils.Cfg.ServiceSettings.WebserverMode != "disabled" {
staticDir := utils.FindDir(model.CLIENT_DIR)

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

@@ -10,6 +10,7 @@ import (
"time"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -19,28 +20,28 @@ var ApiClient *model.Client
var URL string
func Setup() {
if api.Srv == nil {
if app.Srv == nil {
utils.TranslationsPreInit()
utils.LoadConfig("config.json")
utils.InitTranslations(utils.Cfg.LocalizationSettings)
api.NewServer()
api.InitStores()
app.NewServer()
app.InitStores()
api.InitRouter()
api.StartServer()
app.StartServer()
api.InitApi()
InitWeb()
URL = "http://localhost" + utils.Cfg.ServiceSettings.ListenAddress
ApiClient = model.NewClient(URL)
api.Srv.Store.MarkSystemRanUnitTests()
app.Srv.Store.MarkSystemRanUnitTests()
*utils.Cfg.TeamSettings.EnableOpenServer = true
}
}
func TearDown() {
if api.Srv != nil {
api.StopServer()
if app.Srv != nil {
app.StopServer()
}
}
@@ -69,13 +70,13 @@ func TestGetAccessToken(t *testing.T) {
user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Password: "passwd1"}
ruser := ApiClient.Must(ApiClient.CreateUser(&user, "")).Data.(*model.User)
api.JoinUserToTeam(rteam.Data.(*model.Team), ruser)
store.Must(api.Srv.Store.User().VerifyEmail(ruser.Id))
app.JoinUserToTeam(rteam.Data.(*model.Team), ruser)
store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id))
app := &model.OAuthApp{Name: "TestApp" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
oauthApp := &model.OAuthApp{Name: "TestApp" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
utils.Cfg.ServiceSettings.EnableOAuthServiceProvider = false
data := url.Values{"grant_type": []string{"junk"}, "client_id": []string{"12345678901234567890123456"}, "client_secret": []string{"12345678901234567890123456"}, "code": []string{"junk"}, "redirect_uri": []string{app.CallbackUrls[0]}}
data := url.Values{"grant_type": []string{"junk"}, "client_id": []string{"12345678901234567890123456"}, "client_secret": []string{"12345678901234567890123456"}, "code": []string{"junk"}, "redirect_uri": []string{oauthApp.CallbackUrls[0]}}
if _, err := ApiClient.GetAccessToken(data); err == nil {
t.Fatal("should have failed - oauth providing turned off")
@@ -86,18 +87,18 @@ func TestGetAccessToken(t *testing.T) {
ApiClient.SetTeamId(rteam.Data.(*model.Team).Id)
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
app = ApiClient.Must(ApiClient.RegisterApp(app)).Data.(*model.OAuthApp)
oauthApp = ApiClient.Must(ApiClient.RegisterApp(oauthApp)).Data.(*model.OAuthApp)
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
redirect := ApiClient.Must(ApiClient.AllowOAuth(model.AUTHCODE_RESPONSE_TYPE, app.Id, app.CallbackUrls[0], "all", "123")).Data.(map[string]string)["redirect"]
redirect := ApiClient.Must(ApiClient.AllowOAuth(model.AUTHCODE_RESPONSE_TYPE, oauthApp.Id, oauthApp.CallbackUrls[0], "all", "123")).Data.(map[string]string)["redirect"]
rurl, _ := url.Parse(redirect)
teamId := rteam.Data.(*model.Team).Id
ApiClient.Logout()
data = url.Values{"grant_type": []string{"junk"}, "client_id": []string{app.Id}, "client_secret": []string{app.ClientSecret}, "code": []string{rurl.Query().Get("code")}, "redirect_uri": []string{app.CallbackUrls[0]}}
data = url.Values{"grant_type": []string{"junk"}, "client_id": []string{oauthApp.Id}, "client_secret": []string{oauthApp.ClientSecret}, "code": []string{rurl.Query().Get("code")}, "redirect_uri": []string{oauthApp.CallbackUrls[0]}}
if _, err := ApiClient.GetAccessToken(data); err == nil {
t.Fatal("should have failed - bad grant type")
@@ -113,7 +114,7 @@ func TestGetAccessToken(t *testing.T) {
t.Fatal("should have failed - bad client id")
}
data.Set("client_id", app.Id)
data.Set("client_id", oauthApp.Id)
data.Set("client_secret", "")
if _, err := ApiClient.GetAccessToken(data); err == nil {
t.Fatal("should have failed - missing client secret")
@@ -124,7 +125,7 @@ func TestGetAccessToken(t *testing.T) {
t.Fatal("should have failed - bad client secret")
}
data.Set("client_secret", app.ClientSecret)
data.Set("client_secret", oauthApp.ClientSecret)
data.Set("code", "")
if _, err := ApiClient.GetAccessToken(data); err == nil {
t.Fatal("should have failed - missing code")
@@ -143,10 +144,10 @@ func TestGetAccessToken(t *testing.T) {
// reset data for successful request
data.Set("grant_type", model.ACCESS_TOKEN_GRANT_TYPE)
data.Set("client_id", app.Id)
data.Set("client_secret", app.ClientSecret)
data.Set("client_id", oauthApp.Id)
data.Set("client_secret", oauthApp.ClientSecret)
data.Set("code", rurl.Query().Get("code"))
data.Set("redirect_uri", app.CallbackUrls[0])
data.Set("redirect_uri", oauthApp.CallbackUrls[0])
token := ""
if result, err := ApiClient.GetAccessToken(data); err != nil {
@@ -205,8 +206,8 @@ func TestIncomingWebhook(t *testing.T) {
user := &model.User{Email: model.NewId() + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user = ApiClient.Must(ApiClient.CreateUser(user, "")).Data.(*model.User)
store.Must(api.Srv.Store.User().VerifyEmail(user.Id))
api.JoinUserToTeam(team, user)
store.Must(app.Srv.Store.User().VerifyEmail(user.Id))
app.JoinUserToTeam(team, user)
api.UpdateUserRoles(user, model.ROLE_SYSTEM_ADMIN.Id)
ApiClient.Login(user.Email, "passwd1")