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 TestSessionGetWithDeviceId(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() s1.ExpiresAt = model.GetMillis() + 10000 Must(store.Session().Save(&s1)) s2 := model.Session{} s2.UserId = s1.UserId s2.DeviceId = model.NewId() s2.ExpiresAt = model.GetMillis() + 10000 Must(store.Session().Save(&s2)) s3 := model.Session{} s3.UserId = s1.UserId s3.ExpiresAt = 1 s3.DeviceId = model.NewId() Must(store.Session().Save(&s3)) if rs1 := (<-store.Session().GetSessionsWithActiveDeviceIds(s1.UserId)); rs1.Err != nil { t.Fatal(rs1.Err) } else { if len(rs1.Data.([]*model.Session)) != 1 { t.Fatal("should match len") } } }
func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool { // IMPORTANT: Do not send event if WebConn does not have a session if !webCon.IsAuthenticated() { return false } // If the event is destined to a specific user if len(msg.Broadcast.UserId) > 0 && webCon.UserId != msg.Broadcast.UserId { return false } // if the user is omitted don't send the message if len(msg.Broadcast.OmitUsers) > 0 { if _, ok := msg.Broadcast.OmitUsers[webCon.UserId]; ok { return false } } // Only report events to users who are in the channel for the event if len(msg.Broadcast.ChannelId) > 0 { // Only broadcast typing messages if less than 1K people in channel if msg.Event == model.WEBSOCKET_EVENT_TYPING { if Srv.Store.Channel().GetMemberCountFromCache(msg.Broadcast.ChannelId) > *utils.Cfg.TeamSettings.MaxNotificationsPerChannel { return false } } if model.GetMillis()-webCon.LastAllChannelMembersTime > 1000*60*15 { // 15 minutes webCon.AllChannelMembers = nil webCon.LastAllChannelMembersTime = 0 } if webCon.AllChannelMembers == nil { if result := <-Srv.Store.Channel().GetAllChannelMembersForUser(webCon.UserId, true); result.Err != nil { l4g.Error("webhub.shouldSendEvent: " + result.Err.Error()) return false } else { webCon.AllChannelMembers = result.Data.(map[string]string) webCon.LastAllChannelMembersTime = model.GetMillis() } } if _, ok := webCon.AllChannelMembers[msg.Broadcast.ChannelId]; ok { return true } else { return false } } // Only report events to users who are in the team for the event if len(msg.Broadcast.TeamId) > 0 { return webCon.IsMemberOfTeam(msg.Broadcast.TeamId) } return true }
func TestPostStoreGetWithChildren(t *testing.T) { Setup() o1 := &model.Post{} o1.ChannelId = model.NewId() o1.UserId = model.NewId() o1.Message = "a" + model.NewId() + "b" o1 = (<-store.Post().Save(o1)).Data.(*model.Post) o2 := &model.Post{} o2.ChannelId = o1.ChannelId o2.UserId = model.NewId() o2.Message = "a" + model.NewId() + "b" o2.ParentId = o1.Id o2.RootId = o1.Id o2 = (<-store.Post().Save(o2)).Data.(*model.Post) o3 := &model.Post{} o3.ChannelId = o1.ChannelId o3.UserId = model.NewId() o3.Message = "a" + model.NewId() + "b" o3.ParentId = o2.Id o3.RootId = o1.Id o3 = (<-store.Post().Save(o3)).Data.(*model.Post) if r1 := <-store.Post().Get(o1.Id); r1.Err != nil { t.Fatal(r1.Err) } else { pl := r1.Data.(*model.PostList) if len(pl.Posts) != 3 { t.Fatal("invalid returned post") } } Must(store.Post().Delete(o3.Id, model.GetMillis())) if r2 := <-store.Post().Get(o1.Id); r2.Err != nil { t.Fatal(r2.Err) } else { pl := r2.Data.(*model.PostList) if len(pl.Posts) != 2 { t.Fatal("invalid returned post") } } Must(store.Post().Delete(o2.Id, model.GetMillis())) if r3 := <-store.Post().Get(o1.Id); r3.Err != nil { t.Fatal(r3.Err) } else { pl := r3.Data.(*model.PostList) if len(pl.Posts) != 1 { t.Fatal("invalid returned post") } } }
func TestWebhookStoreDeleteIncoming(t *testing.T) { Setup() o1 := &model.IncomingWebhook{} o1.ChannelId = model.NewId() o1.UserId = model.NewId() o1.TeamId = model.NewId() o1 = (<-store.Webhook().SaveIncoming(o1)).Data.(*model.IncomingWebhook) if r1 := <-store.Webhook().GetIncoming(o1.Id); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.(*model.IncomingWebhook).CreateAt != o1.CreateAt { t.Fatal("invalid returned webhook") } } if r2 := <-store.Webhook().DeleteIncoming(o1.Id, model.GetMillis()); r2.Err != nil { t.Fatal(r2.Err) } if r3 := (<-store.Webhook().GetIncoming(o1.Id)); r3.Err == nil { t.Log(r3.Data) t.Fatal("Missing id should have failed") } }
func TestWebhookStoreDeleteOutgoing(t *testing.T) { Setup() o1 := &model.OutgoingWebhook{} o1.ChannelId = model.NewId() o1.CreatorId = model.NewId() o1.TeamId = model.NewId() o1.CallbackURLs = []string{"http://nowhere.com/"} o1 = (<-store.Webhook().SaveOutgoing(o1)).Data.(*model.OutgoingWebhook) if r1 := <-store.Webhook().GetOutgoing(o1.Id); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.(*model.OutgoingWebhook).CreateAt != o1.CreateAt { t.Fatal("invalid returned webhook") } } if r2 := <-store.Webhook().DeleteOutgoing(o1.Id, model.GetMillis()); r2.Err != nil { t.Fatal(r2.Err) } if r3 := (<-store.Webhook().GetOutgoing(o1.Id)); r3.Err == nil { t.Log(r3.Data) t.Fatal("Missing id should have failed") } }
func PermanentDeleteTeam(c *Context, team *model.Team) *model.AppError { l4g.Warn(utils.T("api.team.permanent_delete_team.attempting.warn"), team.Name, team.Id) c.Path = "/teams/permanent_delete" c.LogAuditWithUserId("", fmt.Sprintf("attempt teamId=%v", team.Id)) team.DeleteAt = model.GetMillis() if result := <-Srv.Store.Team().Update(team); result.Err != nil { return result.Err } if result := <-Srv.Store.User().GetForExport(team.Id); result.Err != nil { return result.Err } else { users := result.Data.([]*model.User) for _, user := range users { PermanentDeleteUser(c, user) } } if result := <-Srv.Store.Channel().PermanentDeleteByTeam(team.Id); result.Err != nil { return result.Err } if result := <-Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil { return result.Err } l4g.Warn(utils.T("api.team.permanent_delete_team.deleted.warn"), team.Name, team.Id) c.LogAuditWithUserId("", fmt.Sprintf("success teamId=%v", team.Id)) return nil }
func (me SqlSessionStore) AnalyticsSessionCount(teamId string) StoreChannel { storeChannel := make(StoreChannel) go func() { result := StoreResult{} query := `SELECT COUNT(*) FROM Sessions WHERE ExpiresAt > :Time` if len(teamId) > 0 { query += " AND TeamId = :TeamId" } if c, err := me.GetReplica().SelectInt(query, map[string]interface{}{"Time": model.GetMillis(), "TeamId": teamId}); err != nil { result.Err = model.NewLocAppError("SqlSessionStore.AnalyticsSessionCount", "store.sql_session.analytics_session_count.app_error", nil, err.Error()) } else { result.Data = c } storeChannel <- result close(storeChannel) }() return storeChannel }
func (s SqlChannelStore) UpdateNotifyLevel(channelId, userId, notifyLevel string) StoreChannel { storeChannel := make(StoreChannel) go func() { result := StoreResult{} updateAt := model.GetMillis() _, err := s.GetMaster().Exec( `UPDATE ChannelMembers SET NotifyLevel = :NotifyLevel, LastUpdateAt = :LastUpdateAt WHERE UserId = :UserId AND ChannelId = :ChannelId`, map[string]interface{}{"ChannelId": channelId, "UserId": userId, "NotifyLevel": notifyLevel, "LastUpdateAt": updateAt}) if err != nil { result.Err = model.NewAppError("SqlChannelStore.UpdateNotifyLevel", "We couldn't update the notify level", "channel_id="+channelId+", user_id="+userId+", "+err.Error()) } storeChannel <- result close(storeChannel) }() return storeChannel }
func TestOAuthStoreGetAccessData(t *testing.T) { Setup() a1 := model.AccessData{} a1.ClientId = model.NewId() a1.UserId = model.NewId() a1.Token = model.NewId() a1.RefreshToken = model.NewId() a1.ExpiresAt = model.GetMillis() Must(store.OAuth().SaveAccessData(&a1)) if result := <-store.OAuth().GetAccessData(a1.Token); result.Err != nil { t.Fatal(result.Err) } else { ra1 := result.Data.(*model.AccessData) if a1.Token != ra1.Token { t.Fatal("tokens didn't match") } } if err := (<-store.OAuth().GetPreviousAccessData(a1.UserId, a1.ClientId)).Err; err != nil { t.Fatal(err) } if err := (<-store.OAuth().GetPreviousAccessData("user", "junk")).Err; err != nil { t.Fatal(err) } }
func NewWebConn(ws *websocket.Conn, teamId string, userId string, sessionId string) *WebConn { go func() { achan := Srv.Store.User().UpdateUserAndSessionActivity(userId, sessionId, model.GetMillis()) pchan := Srv.Store.User().UpdateLastPingAt(userId, model.GetMillis()) if result := <-achan; result.Err != nil { l4g.Error(utils.T("api.web_conn.new_web_conn.last_activity.error"), userId, sessionId, result.Err) } if result := <-pchan; result.Err != nil { l4g.Error(utils.T("api.web_conn.new_web_conn.last_ping.error"), userId, result.Err) } }() return &WebConn{Send: make(chan *model.Message, 64), WebSocket: ws, UserId: userId, TeamId: teamId, ChannelAccessCache: make(map[string]bool)} }
func SetActiveChannel(userId string, channelId string) *model.AppError { status, err := app.GetStatus(userId) if err != nil { status = &model.Status{userId, model.STATUS_ONLINE, false, model.GetMillis(), channelId} } else { status.ActiveChannel = channelId if !status.Manual { status.Status = model.STATUS_ONLINE } status.LastActivityAt = model.GetMillis() } app.AddStatusCache(status) return nil }
func TestSessionCount(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() s1.TeamId = model.NewId() s1.ExpiresAt = model.GetMillis() + 100000 Must(store.Session().Save(&s1)) if r1 := <-store.Session().AnalyticsSessionCount(""); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.(int64) == 0 { t.Fatal("should have at least 1 session") } } if r2 := <-store.Session().AnalyticsSessionCount(s1.TeamId); r2.Err != nil { t.Fatal(r2.Err) } else { if r2.Data.(int64) != 1 { t.Fatal("should have 1 session") } } }
func (s SqlChannelStore) UpdateNotifyLevel(channelId, userId, notifyLevel string) StoreChannel { storeChannel := make(StoreChannel) go func() { result := StoreResult{} updateAt := model.GetMillis() _, err := s.GetMaster().Exec( `UPDATE ChannelMembers SET NotifyLevel = ?, LastUpdateAt = ? WHERE UserId = ? AND ChannelId = ?`, notifyLevel, updateAt, userId, channelId) if err != nil { result.Err = model.NewAppError("SqlChannelStore.UpdateNotifyLevel", "We couldn't update the notify level", "channel_id="+channelId+", user_id="+userId+", "+err.Error()) } storeChannel <- result close(storeChannel) }() return storeChannel }
func NewWebConn(c *Context, ws *websocket.Conn) *WebConn { go func() { achan := Srv.Store.User().UpdateUserAndSessionActivity(c.Session.UserId, c.Session.Token, model.GetMillis()) pchan := Srv.Store.User().UpdateLastPingAt(c.Session.UserId, model.GetMillis()) if result := <-achan; result.Err != nil { l4g.Error(utils.T("api.web_conn.new_web_conn.last_activity.error"), c.Session.UserId, c.Session.Token, result.Err) } if result := <-pchan; result.Err != nil { l4g.Error(utils.T("api.web_conn.new_web_conn.last_ping.error"), c.Session.UserId, result.Err) } }() return &WebConn{ Send: make(chan model.WebSocketMessage, 64), WebSocket: ws, UserId: c.Session.UserId, SessionToken: c.Session.Token, T: c.T, Locale: c.Locale, hasPermissionsToChannel: make(map[string]bool), hasPermissionsToTeam: make(map[string]bool), } }
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) { m := model.MapFromJson(r.Body) email := strings.ToLower(strings.TrimSpace(m["email"])) if len(email) == 0 { c.SetInvalidParam("signupTeam", "email") return } subjectPage := NewServerTemplatePage("signup_team_subject", c.GetSiteURL()) bodyPage := NewServerTemplatePage("signup_team_body", c.GetSiteURL()) bodyPage.Props["TourUrl"] = utils.Cfg.TeamSettings.TourLink props := make(map[string]string) props["email"] = email props["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(props) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt)) bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_team_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash)) if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { c.Err = err return } if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV || utils.Cfg.EmailSettings.ByPassEmail { m["follow_link"] = bodyPage.Props["Link"] } w.Header().Set("Access-Control-Allow-Origin", " *") w.Write([]byte(model.MapToJson(m))) }
func (c *WebConn) readPump() { defer func() { hub.Unregister(c) c.WebSocket.Close() }() c.WebSocket.SetReadLimit(MAX_SIZE) c.WebSocket.SetReadDeadline(time.Now().Add(PONG_WAIT)) c.WebSocket.SetPongHandler(func(string) error { c.WebSocket.SetReadDeadline(time.Now().Add(PONG_WAIT)) go func() { if result := <-Srv.Store.User().UpdateLastPingAt(c.UserId, model.GetMillis()); result.Err != nil { l4g.Error(utils.T("api.web_conn.new_web_conn.last_ping.error"), c.UserId, result.Err) } }() return nil }) for { var msg model.Message if err := c.WebSocket.ReadJSON(&msg); err != nil { return } else { msg.UserId = c.UserId PublishAndForget(&msg) } } }
func ping(c *Context, w http.ResponseWriter, r *http.Request) { m := make(map[string]string) m["version"] = model.CurrentVersion m["server_time"] = fmt.Sprintf("%v", model.GetMillis()) m["node_id"] = "" w.Write([]byte(model.MapToJson(m))) }
func TestCommandStoreDelete(t *testing.T) { Setup() o1 := &model.Command{} o1.CreatorId = model.NewId() o1.Method = model.COMMAND_METHOD_POST o1.TeamId = model.NewId() o1.URL = "http://nowhere.com/" o1.Trigger = "trigger" o1 = (<-store.Command().Save(o1)).Data.(*model.Command) if r1 := <-store.Command().Get(o1.Id); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.(*model.Command).CreateAt != o1.CreateAt { t.Fatal("invalid returned command") } } if r2 := <-store.Command().Delete(o1.Id, model.GetMillis()); r2.Err != nil { t.Fatal(r2.Err) } if r3 := (<-store.Command().Get(o1.Id)); r3.Err == nil { t.Log(r3.Data) t.Fatal("Missing id should have failed") } }
func BenchmarkGetFile(b *testing.B) { team, _, channel := SetupBenchmark() testPoster := NewAutoPostCreator(Client, channel.Id) filenames, err := testPoster.UploadTestFile() if err == false { b.Fatal("Unable to upload file for benchmark") } newProps := make(map[string]string) newProps["filename"] = filenames[0] newProps["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(newProps) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.FileSettings.PublicLinkSalt)) // wait a bit for files to ready time.Sleep(5 * time.Second) // Benchmark Start b.ResetTimer() for i := 0; i < b.N; i++ { if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&h="+url.QueryEscape(hash)+"&t="+team.Id, true); downErr != nil { b.Fatal(downErr) } } }
func (s SqlChannelStore) IncrementMentionCount(channelId string, userId string) StoreChannel { storeChannel := make(StoreChannel, 1) go func() { result := StoreResult{} _, err := s.GetMaster().Exec( `UPDATE ChannelMembers SET MentionCount = MentionCount + 1, LastUpdateAt = :LastUpdateAt WHERE UserId = :UserId AND ChannelId = :ChannelId`, map[string]interface{}{"ChannelId": channelId, "UserId": userId, "LastUpdateAt": model.GetMillis()}) if err != nil { result.Err = model.NewLocAppError("SqlChannelStore.IncrementMentionCount", "store.sql_channel.increment_mention_count.app_error", nil, "channel_id="+channelId+", user_id="+userId+", "+err.Error()) } storeChannel <- result close(storeChannel) }() return storeChannel }
func (c *WebConn) readPump() { defer func() { hub.Unregister(c) c.WebSocket.Close() }() c.WebSocket.SetReadLimit(MAX_SIZE) c.WebSocket.SetReadDeadline(time.Now().Add(PONG_WAIT)) c.WebSocket.SetPongHandler(func(string) error { c.WebSocket.SetReadDeadline(time.Now().Add(PONG_WAIT)) go func() { if result := <-Srv.Store.User().UpdateLastPingAt(c.UserId, model.GetMillis()); result.Err != nil { l4g.Error("Failed to updated LastPingAt for user_id=%v, err=%v", c.UserId, result.Err) } }() return nil }) for { var msg model.Message if err := c.WebSocket.ReadJSON(&msg); err != nil { return } else { msg.TeamId = c.TeamId msg.UserId = c.UserId PublishAndForget(&msg) } } }
func (fs SqlFileInfoStore) DeleteForPost(postId string) StoreChannel { storeChannel := make(StoreChannel, 1) go func() { result := StoreResult{} if _, err := fs.GetMaster().Exec( `UPDATE FileInfo SET DeleteAt = :DeleteAt WHERE PostId = :PostId`, map[string]interface{}{"DeleteAt": model.GetMillis(), "PostId": postId}); err != nil { result.Err = model.NewLocAppError("SqlFileInfoStore.DeleteForPost", "store.sql_file_info.delete_for_post.app_error", nil, "post_id="+postId+", err="+err.Error()) } else { result.Data = postId } storeChannel <- result close(storeChannel) }() return storeChannel }
func PermanentDeleteTeam(c *Context, team *model.Team) *model.AppError { l4g.Warn(utils.T("api.team.permanent_delete_team.attempting.warn"), team.Name, team.Id) c.Path = "/teams/permanent_delete" c.LogAuditWithUserId("", fmt.Sprintf("attempt teamId=%v", team.Id)) team.DeleteAt = model.GetMillis() if result := <-Srv.Store.Team().Update(team); result.Err != nil { return result.Err } if result := <-Srv.Store.Channel().PermanentDeleteByTeam(team.Id); result.Err != nil { return result.Err } if result := <-Srv.Store.Team().RemoveAllMembersByTeam(team.Id); result.Err != nil { return result.Err } if result := <-Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil { return result.Err } l4g.Warn(utils.T("api.team.permanent_delete_team.deleted.warn"), team.Name, team.Id) c.LogAuditWithUserId("", fmt.Sprintf("success teamId=%v", team.Id)) return nil }
func NewWebConn(ws *websocket.Conn, teamId string, userId string, sessionId string) *WebConn { go func() { achan := Srv.Store.User().UpdateUserAndSessionActivity(userId, sessionId, model.GetMillis()) pchan := Srv.Store.User().UpdateLastPingAt(userId, model.GetMillis()) if result := <-achan; result.Err != nil { l4g.Error("Failed to update LastActivityAt for user_id=%v and session_id=%v, err=%v", userId, sessionId, result.Err) } if result := <-pchan; result.Err != nil { l4g.Error("Failed to updated LastPingAt for user_id=%v, err=%v", userId, result.Err) } }() return &WebConn{Send: make(chan *model.Message, 64), WebSocket: ws, UserId: userId, TeamId: teamId, ChannelAccessCache: make(map[string]bool)} }
func TestPostStoreDelete1Level(t *testing.T) { Setup() o1 := &model.Post{} o1.ChannelId = model.NewId() o1.UserId = model.NewId() o1.Message = "a" + model.NewId() + "b" o1 = (<-store.Post().Save(o1)).Data.(*model.Post) o2 := &model.Post{} o2.ChannelId = o1.ChannelId o2.UserId = model.NewId() o2.Message = "a" + model.NewId() + "b" o2.ParentId = o1.Id o2.RootId = o1.Id o2 = (<-store.Post().Save(o2)).Data.(*model.Post) if r2 := <-store.Post().Delete(o1.Id, model.GetMillis()); r2.Err != nil { t.Fatal(r2.Err) } if r3 := (<-store.Post().Get(o1.Id)); r3.Err == nil { t.Fatal("Deleted id should have failed") } if r4 := (<-store.Post().Get(o2.Id)); r4.Err == nil { t.Fatal("Deleted id should have failed") } }
func getTeamIdFromQuery(query url.Values) (string, *model.AppError) { hash := query.Get("h") inviteId := query.Get("id") if len(hash) > 0 { data := query.Get("d") props := model.MapFromJson(strings.NewReader(data)) if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt)) { return "", model.NewLocAppError("getTeamIdFromQuery", "api.oauth.singup_with_oauth.invalid_link.app_error", nil, "") } t, err := strconv.ParseInt(props["time"], 10, 64) if err != nil || model.GetMillis()-t > 1000*60*60*48 { // 48 hours return "", model.NewLocAppError("getTeamIdFromQuery", "api.oauth.singup_with_oauth.expired_link.app_error", nil, "") } return props["id"], nil } else if len(inviteId) > 0 { if result := <-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 { return result.Data.(*model.Team).Id, nil } } return "", nil }
func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) email := props["email"] if len(email) == 0 { c.SetInvalidParam("sendPasswordReset", "email") return } name := props["name"] if len(name) == 0 { c.SetInvalidParam("sendPasswordReset", "name") return } var team *model.Team if result := <-Srv.Store.Team().GetByName(name); result.Err != nil { c.Err = result.Err return } else { team = result.Data.(*model.Team) } var user *model.User if result := <-Srv.Store.User().GetByEmail(team.Id, email); result.Err != nil { c.Err = model.NewAppError("sendPasswordReset", "We couldn’t find an account with that address.", "email="+email+" team_id="+team.Id) return } else { user = result.Data.(*model.User) } if len(user.AuthData) != 0 { c.Err = model.NewAppError("sendPasswordReset", "Cannot reset password for SSO accounts", "userId="+user.Id+", teamId="+team.Id) return } newProps := make(map[string]string) newProps["user_id"] = user.Id newProps["time"] = fmt.Sprintf("%v", model.GetMillis()) data := model.MapToJson(newProps) hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.PasswordResetSalt)) link := fmt.Sprintf("%s/reset_password?d=%s&h=%s", c.GetTeamURLFromTeam(team), url.QueryEscape(data), url.QueryEscape(hash)) subjectPage := NewServerTemplatePage("reset_subject") subjectPage.Props["SiteURL"] = c.GetSiteURL() bodyPage := NewServerTemplatePage("reset_body") bodyPage.Props["SiteURL"] = c.GetSiteURL() bodyPage.Props["ResetUrl"] = link if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil { c.Err = model.NewAppError("sendPasswordReset", "Failed to send password reset email successfully", "err="+err.Message) return } c.LogAuditWithUserId(user.Id, "sent="+email) w.Write([]byte(model.MapToJson(props))) }
func (s SqlPostStore) AnalyticsPostCountsByDay(teamId string) StoreChannel { storeChannel := make(StoreChannel) go func() { result := StoreResult{} query := `SELECT Name, COUNT(Value) AS Value FROM (SELECT DATE(FROM_UNIXTIME(Posts.CreateAt / 1000)) AS Name, '1' AS Value FROM Posts, Channels WHERE Posts.ChannelId = Channels.Id AND Channels.TeamId = :TeamId AND Posts.CreateAt >:Time) AS t1 GROUP BY Name ORDER BY Name DESC LIMIT 30` if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES { query = `SELECT Name, COUNT(Value) AS Value FROM (SELECT TO_CHAR(DATE(TO_TIMESTAMP(Posts.CreateAt / 1000)), 'YYYY-MM-DD') AS Name, '1' AS Value FROM Posts, Channels WHERE Posts.ChannelId = Channels.Id AND Channels.TeamId = :TeamId AND Posts.CreateAt > :Time) AS t1 GROUP BY Name ORDER BY Name DESC LIMIT 30` } var rows model.AnalyticsRows _, err := s.GetReplica().Select( &rows, query, map[string]interface{}{"TeamId": teamId, "Time": model.GetMillis() - 1000*60*60*24*31}) if err != nil { result.Err = model.NewAppError("SqlPostStore.AnalyticsPostCountsByDay", "We couldn't get post counts by day", err.Error()) } else { result.Data = rows } storeChannel <- result close(storeChannel) }() return storeChannel }
func TestGetPostsSince(t *testing.T) { th := Setup().InitBasic() Client := th.BasicClient channel1 := th.BasicChannel time.Sleep(10 * time.Millisecond) post0 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"} post0 = Client.Must(Client.CreatePost(post0)).Data.(*model.Post) time.Sleep(10 * time.Millisecond) post1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"} post1 = Client.Must(Client.CreatePost(post1)).Data.(*model.Post) time.Sleep(10 * time.Millisecond) post1a1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a", RootId: post1.Id} post1a1 = Client.Must(Client.CreatePost(post1a1)).Data.(*model.Post) time.Sleep(10 * time.Millisecond) post2 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"} post2 = Client.Must(Client.CreatePost(post2)).Data.(*model.Post) time.Sleep(10 * time.Millisecond) post3 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a"} post3 = Client.Must(Client.CreatePost(post3)).Data.(*model.Post) time.Sleep(10 * time.Millisecond) post3a1 := &model.Post{ChannelId: channel1.Id, Message: "a" + model.NewId() + "a", RootId: post3.Id} post3a1 = Client.Must(Client.CreatePost(post3a1)).Data.(*model.Post) r1 := Client.Must(Client.GetPostsSince(channel1.Id, post1.CreateAt)).Data.(*model.PostList) if r1.Order[0] != post3a1.Id { t.Fatal("wrong order") } if r1.Order[1] != post3.Id { t.Fatal("wrong order") } if len(r1.Posts) != 5 { t.Fatal("wrong size") } now := model.GetMillis() r2 := Client.Must(Client.GetPostsSince(channel1.Id, now)).Data.(*model.PostList) if len(r2.Posts) != 0 { t.Fatal("should have been empty") } post2.Message = "new message" Client.Must(Client.UpdatePost(post2)) r3 := Client.Must(Client.GetPostsSince(channel1.Id, now)).Data.(*model.PostList) if len(r3.Order) != 2 { // 2 because deleted post is returned as well t.Fatal("missing post update") } }