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 handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks bool) { go func() { tchan := Srv.Store.Team().Get(c.Session.TeamId) cchan := Srv.Store.Channel().Get(post.ChannelId) uchan := Srv.Store.User().Get(post.UserId) pchan := Srv.Store.User().GetProfiles(c.Session.TeamId) mchan := Srv.Store.Channel().GetMembers(post.ChannelId) var team *model.Team if result := <-tchan; result.Err != nil { l4g.Error(utils.T("api.post.handle_post_events_and_forget.team.error"), c.Session.TeamId, result.Err) return } else { team = result.Data.(*model.Team) } var channel *model.Channel if result := <-cchan; result.Err != nil { l4g.Error(utils.T("api.post.handle_post_events_and_forget.channel.error"), post.ChannelId, result.Err) return } else { channel = result.Data.(*model.Channel) } var profiles map[string]*model.User if result := <-pchan; result.Err != nil { l4g.Error(utils.T("api.post.handle_post_events_and_forget.profiles.error"), c.Session.TeamId, result.Err) return } else { profiles = result.Data.(map[string]*model.User) } var members []model.ChannelMember if result := <-mchan; result.Err != nil { l4g.Error(utils.T("api.post.handle_post_events_and_forget.members.error"), post.ChannelId, result.Err) return } else { members = result.Data.([]model.ChannelMember) } go sendNotifications(c, post, team, channel, profiles, members) go checkForOutOfChannelMentions(c, post, channel, profiles, members) var user *model.User if result := <-uchan; result.Err != nil { l4g.Error(utils.T("api.post.handle_post_events_and_forget.user.error"), post.UserId, result.Err) return } else { user = result.Data.(*model.User) } if triggerWebhooks { handleWebhookEventsAndForget(c, post, team, channel, user) } if channel.Type == model.CHANNEL_DIRECT { go makeDirectChannelVisible(c.Session.TeamId, post.ChannelId) } }() }
func PostUpdateChannelDisplayNameMessage(c *Context, channelId string, oldChannelDisplayName, newChannelDisplayName string) { uc := 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) return } else { user := uresult.Data.(*model.User) message := fmt.Sprintf(utils.T("api.channel.post_update_channel_displayname_message_and_forget.updated_from"), user.Username, oldChannelDisplayName, newChannelDisplayName) post := &model.Post{ ChannelId: channelId, Message: message, Type: model.POST_DISPLAYNAME_CHANGE, UserId: c.Session.UserId, Props: model.StringInterface{ "old_displayname": oldChannelDisplayName, "new_displayname": newChannelDisplayName, }, } if _, err := CreatePost(c, post, false); err != nil { l4g.Error(utils.T("api.channel.post_update_channel_displayname_message_and_forget.create_post.error"), err) } } }
func SlackUploadFile(sPost SlackPost, uploads map[string]*zip.File, teamId string, channelId string, userId string) (*model.FileInfo, bool) { if sPost.File != nil { if file, ok := uploads[sPost.File.Id]; ok == true { openFile, err := file.Open() if err != nil { l4g.Warn(utils.T("api.slackimport.slack_add_posts.upload_file_open_failed.warn", map[string]interface{}{"FileId": sPost.File.Id, "Error": err.Error()})) return nil, false } defer openFile.Close() uploadedFile, err := ImportFile(openFile, teamId, channelId, userId, filepath.Base(file.Name)) if err != nil { l4g.Warn(utils.T("api.slackimport.slack_add_posts.upload_file_upload_failed.warn", map[string]interface{}{"FileId": sPost.File.Id, "Error": err.Error()})) return nil, false } return uploadedFile, true } else { l4g.Warn(utils.T("api.slackimport.slack_add_posts.upload_file_not_found.warn", map[string]interface{}{"FileId": sPost.File.Id})) return nil, false } } else { l4g.Warn(utils.T("api.slackimport.slack_add_posts.upload_file_not_in_json.warn")) return nil, false } }
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 { return err } } return nil }
func SlackAddChannels(teamId string, slackchannels []SlackChannel, posts map[string][]SlackPost, users map[string]*model.User, log *bytes.Buffer) map[string]*model.Channel { // Write Header log.WriteString(utils.T("api.slackimport.slack_add_channels.added")) log.WriteString("=================\r\n\r\n") addedChannels := make(map[string]*model.Channel) for _, sChannel := range slackchannels { newChannel := model.Channel{ TeamId: teamId, Type: model.CHANNEL_OPEN, DisplayName: sChannel.Name, Name: SlackConvertChannelName(sChannel.Name), Purpose: sChannel.Topic["value"], } mChannel := ImportChannel(&newChannel) if mChannel == nil { // Maybe it already exists? if result := <-Srv.Store.Channel().GetByName(teamId, sChannel.Name); result.Err != nil { l4g.Debug(utils.T("api.slackimport.slack_add_channels.import_failed.debug"), newChannel.DisplayName) log.WriteString(utils.T("api.slackimport.slack_add_channels.import_failed", map[string]interface{}{"DisplayName": newChannel.DisplayName})) continue } else { mChannel = result.Data.(*model.Channel) log.WriteString(utils.T("api.slackimport.slack_add_channels.merge", map[string]interface{}{"DisplayName": newChannel.DisplayName})) } } log.WriteString(newChannel.DisplayName + "\r\n") addedChannels[sChannel.Id] = mChannel SlackAddPosts(mChannel, posts[sChannel.Name], users) } return addedChannels }
func PostUpdateChannelPurposeMessage(userId string, channelId string, teamId string, oldChannelPurpose string, newChannelPurpose string) *model.AppError { uc := Srv.Store.User().Get(userId) if uresult := <-uc; uresult.Err != nil { return model.NewLocAppError("PostUpdateChannelPurposeMessage", "app.channel.post_update_channel_purpose_message.retrieve_user.error", nil, uresult.Err.Error()) } else { user := uresult.Data.(*model.User) var message string if oldChannelPurpose == "" { message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_to"), user.Username, newChannelPurpose) } else if newChannelPurpose == "" { message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.removed"), user.Username, oldChannelPurpose) } else { message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_from"), user.Username, oldChannelPurpose, newChannelPurpose) } post := &model.Post{ ChannelId: channelId, Message: message, Type: model.POST_PURPOSE_CHANGE, UserId: userId, Props: model.StringInterface{ "old_purpose": oldChannelPurpose, "new_purpose": newChannelPurpose, }, } if _, err := CreatePost(post, teamId, false); err != nil { return model.NewLocAppError("", "app.channel.post_update_channel_purpose_message.post.error", nil, err.Error()) } } return nil }
func generateThumbnailImage(img image.Image, thumbnailPath string, width int, height int) { thumbWidth := float64(utils.Cfg.FileSettings.ThumbnailWidth) thumbHeight := float64(utils.Cfg.FileSettings.ThumbnailHeight) imgWidth := float64(width) imgHeight := float64(height) var thumbnail image.Image if imgHeight < thumbHeight && imgWidth < thumbWidth { thumbnail = img } else if imgHeight/imgWidth < thumbHeight/thumbWidth { thumbnail = imaging.Resize(img, 0, utils.Cfg.FileSettings.ThumbnailHeight, imaging.Lanczos) } else { thumbnail = imaging.Resize(img, utils.Cfg.FileSettings.ThumbnailWidth, 0, imaging.Lanczos) } buf := new(bytes.Buffer) if err := jpeg.Encode(buf, thumbnail, &jpeg.Options{Quality: 90}); err != nil { l4g.Error(utils.T("api.file.handle_images_forget.encode_jpeg.error"), thumbnailPath, err) return } if err := WriteFile(buf.Bytes(), thumbnailPath); err != nil { l4g.Error(utils.T("api.file.handle_images_forget.upload_thumb.error"), thumbnailPath, err) return } }
func UpgradeDatabase(sqlStore *SqlStore) { UpgradeDatabaseToVersion31(sqlStore) UpgradeDatabaseToVersion32(sqlStore) UpgradeDatabaseToVersion33(sqlStore) UpgradeDatabaseToVersion34(sqlStore) UpgradeDatabaseToVersion35(sqlStore) UpgradeDatabaseToVersion36(sqlStore) UpgradeDatabaseToVersion37(sqlStore) // If the SchemaVersion is empty this this is the first time it has ran // so lets set it to the current version. if sqlStore.SchemaVersion == "" { if result := <-sqlStore.system.Save(&model.System{Name: "Version", Value: model.CurrentVersion}); result.Err != nil { l4g.Critical(result.Err.Error()) time.Sleep(time.Second) os.Exit(EXIT_VERSION_SAVE_MISSING) } sqlStore.SchemaVersion = model.CurrentVersion l4g.Info(utils.T("store.sql.schema_set.info"), model.CurrentVersion) } // If we're not on the current version then it's too old to be upgraded if sqlStore.SchemaVersion != model.CurrentVersion { l4g.Critical(utils.T("store.sql.schema_version.critical"), sqlStore.SchemaVersion) time.Sleep(time.Second) os.Exit(EXIT_TOO_OLD) } }
func ImportPost(post *model.Post) { // Workaround for empty messages, which may be the case if they are webhook posts. firstIteration := true for messageRuneCount := utf8.RuneCountInString(post.Message); messageRuneCount > 0 || firstIteration; messageRuneCount = utf8.RuneCountInString(post.Message) { firstIteration = false var remainder string if messageRuneCount > model.POST_MESSAGE_MAX_RUNES { remainder = string(([]rune(post.Message))[model.POST_MESSAGE_MAX_RUNES:]) post.Message = truncateRunes(post.Message, model.POST_MESSAGE_MAX_RUNES) } else { remainder = "" } post.Hashtags, _ = model.ParseHashtags(post.Message) 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 := <-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) } } post.Id = "" post.CreateAt++ post.Message = remainder } }
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 (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, mySqlColType string, postgresColType string, defaultValue string) bool { if ss.DoesColumnExist(tableName, columnName) { return false } if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES { _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " ADD " + columnName + " " + postgresColType + " DEFAULT '" + defaultValue + "'") if err != nil { l4g.Critical(utils.T("store.sql.create_column.critical"), err) time.Sleep(time.Second) os.Exit(EXIT_CREATE_COLUMN_POSTGRES) } return true } else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL { _, err := ss.GetMaster().Exec("ALTER TABLE " + tableName + " ADD " + columnName + " " + mySqlColType + " DEFAULT '" + defaultValue + "'") if err != nil { l4g.Critical(utils.T("store.sql.create_column.critical"), err) time.Sleep(time.Second) os.Exit(EXIT_CREATE_COLUMN_MYSQL) } return true } else { l4g.Critical(utils.T("store.sql.create_column_missing_driver.critical")) time.Sleep(time.Second) os.Exit(EXIT_CREATE_COLUMN_MISSING) return false } }
func PostUpdateChannelHeaderMessage(c *Context, channelId string, oldChannelHeader, newChannelHeader string) { uc := 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) return } else { user := uresult.Data.(*model.User) var message string if oldChannelHeader == "" { message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_to"), user.Username, newChannelHeader) } else if newChannelHeader == "" { message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.removed"), user.Username, oldChannelHeader) } else { message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_from"), user.Username, oldChannelHeader, newChannelHeader) } post := &model.Post{ ChannelId: channelId, Message: message, Type: model.POST_HEADER_CHANGE, UserId: c.Session.UserId, Props: model.StringInterface{ "old_header": oldChannelHeader, "new_header": newChannelHeader, }, } if _, err := CreatePost(c, post, false); err != nil { l4g.Error(utils.T("api.channel.post_update_channel_header_message_and_forget.join_leave.error"), err) } } }
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 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 SlackAddBotUser(teamId string, log *bytes.Buffer) *model.User { var team *model.Team if result := <-Srv.Store.Team().Get(teamId); result.Err != nil { log.WriteString(utils.T("api.slackimport.slack_import.team_fail")) return nil } else { team = result.Data.(*model.Team) } password := model.NewId() username := "******" + model.NewId() email := username + "@localhost" botUser := model.User{ Username: username, FirstName: "", LastName: "", Email: email, Password: password, } if mUser := ImportUser(team, &botUser); mUser != nil { log.WriteString(utils.T("api.slackimport.slack_add_bot_user.email_pwd", map[string]interface{}{"Email": botUser.Email, "Password": password})) return mUser } else { log.WriteString(utils.T("api.slackimport.slack_add_bot_user.unable_import", map[string]interface{}{"Username": username})) return 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, } 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, } 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 (ss *SqlStore) createIndexIfNotExists(indexName string, tableName string, columnName string, indexType string, unique bool) { uniqueStr := "" if unique { uniqueStr = "UNIQUE " } if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES { _, err := ss.GetMaster().SelectStr("SELECT $1::regclass", indexName) // It should fail if the index does not exist if err == nil { return } query := "" if indexType == INDEX_TYPE_FULL_TEXT { postgresColumnNames := convertMySQLFullTextColumnsToPostgres(columnName) query = "CREATE INDEX " + indexName + " ON " + tableName + " USING gin(to_tsvector('english', " + postgresColumnNames + "))" } else { query = "CREATE " + uniqueStr + "INDEX " + indexName + " ON " + tableName + " (" + columnName + ")" } _, err = ss.GetMaster().Exec(query) if err != nil { l4g.Critical(utils.T("store.sql.create_index.critical"), err) time.Sleep(time.Second) os.Exit(EXIT_CREATE_INDEX_POSTGRES) } } else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL { count, err := ss.GetMaster().SelectInt("SELECT COUNT(0) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name = ? AND index_name = ?", tableName, indexName) if err != nil { l4g.Critical(utils.T("store.sql.check_index.critical"), err) time.Sleep(time.Second) os.Exit(EXIT_CREATE_INDEX_MYSQL) } if count > 0 { return } fullTextIndex := "" if indexType == INDEX_TYPE_FULL_TEXT { fullTextIndex = " FULLTEXT " } _, err = ss.GetMaster().Exec("CREATE " + uniqueStr + fullTextIndex + " INDEX " + indexName + " ON " + tableName + " (" + columnName + ")") if err != nil { l4g.Critical(utils.T("store.sql.create_index.critical"), err) time.Sleep(time.Second) os.Exit(EXIT_CREATE_INDEX_FULL_MYSQL) } } else { l4g.Critical(utils.T("store.sql.create_index_missing_driver.critical")) time.Sleep(time.Second) os.Exit(EXIT_CREATE_INDEX_MISSING) } }
func SlackAddUsers(teamId string, slackusers []SlackUser, log *bytes.Buffer) map[string]*model.User { // Log header log.WriteString(utils.T("api.slackimport.slack_add_users.created")) log.WriteString("===============\r\n\r\n") addedUsers := make(map[string]*model.User) // Need the team var team *model.Team if result := <-Srv.Store.Team().Get(teamId); result.Err != nil { log.WriteString(utils.T("api.slackimport.slack_import.team_fail")) return addedUsers } else { team = result.Data.(*model.Team) } for _, sUser := range slackusers { firstName := "" lastName := "" if name, ok := sUser.Profile["first_name"]; ok { firstName = name } if name, ok := sUser.Profile["last_name"]; ok { lastName = name } email := sUser.Profile["email"] password := model.NewId() // Check for email conflict and use existing user if found if result := <-Srv.Store.User().GetByEmail(email); result.Err == nil { existingUser := result.Data.(*model.User) addedUsers[sUser.Id] = existingUser log.WriteString(utils.T("api.slackimport.slack_add_users.merge_existing", map[string]interface{}{"Email": existingUser.Email, "Username": existingUser.Username})) continue } newUser := model.User{ Username: sUser.Username, FirstName: firstName, LastName: lastName, Email: email, Password: password, } if mUser := ImportUser(team, &newUser); mUser != nil { addedUsers[sUser.Id] = mUser log.WriteString(utils.T("api.slackimport.slack_add_users.email_pwd", map[string]interface{}{"Email": newUser.Email, "Password": password})) } else { log.WriteString(utils.T("api.slackimport.slack_add_users.unable_import", map[string]interface{}{"Username": sUser.Username})) } } return addedUsers }
func StopServer() { l4g.Info(utils.T("api.server.stop_server.stopping.info")) manners.Close() Srv.Store.Close() hub.Stop() l4g.Info(utils.T("api.server.stop_server.stopped.info")) }
func StopServer() { l4g.Info(utils.T("api.server.stop_server.stopping.info")) Srv.GracefulServer.Stop(TIME_TO_WAIT_FOR_CONNECTIONS_TO_CLOSE_ON_SERVER_SHUTDOWN) Srv.Store.Close() HubStop() l4g.Info(utils.T("api.server.stop_server.stopped.info")) }
func shouldPerformUpgrade(sqlStore *SqlStore, currentSchemaVersion string, expectedSchemaVersion string) bool { if sqlStore.SchemaVersion == currentSchemaVersion { l4g.Warn(utils.T("store.sql.schema_out_of_date.warn"), currentSchemaVersion) l4g.Warn(utils.T("store.sql.schema_upgrade_attempt.warn"), expectedSchemaVersion) return true } return false }
func makeDirectChannelVisible(teamId string, channelId string) { var members []model.ChannelMember if result := <-Srv.Store.Channel().GetMembers(channelId); result.Err != nil { l4g.Error(utils.T("api.post.make_direct_channel_visible.get_members.error"), channelId, result.Err.Message) return } else { members = result.Data.([]model.ChannelMember) } if len(members) != 2 { l4g.Error(utils.T("api.post.make_direct_channel_visible.get_2_members.error"), channelId) return } // 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 { l4g.Error(utils.T("api.post.make_direct_channel_visible.save_pref.error"), member.UserId, otherUserId, saveResult.Err.Message) } else { message := model.NewMessage(teamId, channelId, member.UserId, model.ACTION_PREFERENCE_CHANGED) message.Add("preference", preference.ToJson()) PublishAndForget(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 { l4g.Error(utils.T("api.post.make_direct_channel_visible.update_pref.error"), member.UserId, otherUserId, updateResult.Err.Message) } else { message := model.NewMessage(teamId, channelId, member.UserId, model.ACTION_PREFERENCE_CHANGED) message.Add("preference", preference.ToJson()) PublishAndForget(message) } } } } }
func claimAccount(c *api.Context, w http.ResponseWriter, r *http.Request) { if !CheckBrowserCompatability(c, r) { return } params := mux.Vars(r) teamName := params["team"] email := r.URL.Query().Get("email") newType := r.URL.Query().Get("new_type") var team *model.Team if tResult := <-api.Srv.Store.Team().GetByName(teamName); tResult.Err != nil { l4g.Error(utils.T("web.claim_account.team.error"), teamName, tResult.Err.Message) http.Redirect(w, r, api.GetProtocol(r)+"://"+r.Host, http.StatusTemporaryRedirect) return } else { team = tResult.Data.(*model.Team) } authType := "" if len(email) != 0 { if uResult := <-api.Srv.Store.User().GetByEmail(team.Id, email); uResult.Err != nil { l4g.Error(utils.T("web.claim_account.user.error"), team.Id, email, uResult.Err.Message) http.Redirect(w, r, api.GetProtocol(r)+"://"+r.Host, http.StatusTemporaryRedirect) return } else { user := uResult.Data.(*model.User) authType = user.AuthService // if user is not logged in to their SSO account, ask them to log in if len(authType) != 0 && user.Id != c.Session.UserId { stateProps := map[string]string{} stateProps["action"] = model.OAUTH_ACTION_SSO_TO_EMAIL stateProps["email"] = email if authUrl, err := api.GetAuthorizationCode(c, authType, team.Name, stateProps, ""); err != nil { c.Err = err return } else { http.Redirect(w, r, authUrl, http.StatusFound) } } } } page := NewHtmlTemplatePage("claim_account", c.T("web.claim_account.title"), c.Locale) page.Props["Email"] = email page.Props["CurrentType"] = authType page.Props["NewType"] = newType page.Props["TeamDisplayName"] = team.DisplayName page.Props["TeamName"] = team.Name page.Render(c, w) }
func (ss SqlStore) DoesColumnExist(tableName string, columnName string) bool { if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES { count, err := ss.GetMaster().SelectInt( `SELECT COUNT(0) FROM pg_attribute WHERE attrelid = $1::regclass AND attname = $2 AND NOT attisdropped`, strings.ToLower(tableName), strings.ToLower(columnName), ) if err != nil { if err.Error() == "pq: relation \""+strings.ToLower(tableName)+"\" does not exist" { return false } l4g.Critical(utils.T("store.sql.column_exists.critical"), err) time.Sleep(time.Second) os.Exit(EXIT_DOES_COLUMN_EXISTS_POSTGRES) } return count > 0 } else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL { count, err := ss.GetMaster().SelectInt( `SELECT COUNT(0) AS column_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`, tableName, columnName, ) if err != nil { l4g.Critical(utils.T("store.sql.column_exists.critical"), err) time.Sleep(time.Second) os.Exit(EXIT_DOES_COLUMN_EXISTS_MYSQL) } return count > 0 } else { l4g.Critical(utils.T("store.sql.column_exists_missing_driver.critical")) time.Sleep(time.Second) os.Exit(EXIT_DOES_COLUMN_EXISTS_MISSING) return false } }
func sendPushNotification(post *model.Post, user *model.User, channel *model.Channel, senderName string, wasMentioned bool) { sessions := getMobileAppSessions(user.Id) if sessions == nil { return } 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.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) sendToPushProxy(tmpMessage) } }
func addSlackUsersToChannel(members []string, users map[string]*model.User, channel *model.Channel, log *bytes.Buffer) { for _, member := range members { 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 { log.WriteString(utils.T("api.slackimport.slack_add_channels.failed_to_add_user", map[string]interface{}{"Username": user.Username})) } } } }
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 (me mattermConverter) FromDb(target interface{}) (gorp.CustomScanner, bool) { switch target.(type) { case *model.StringMap: binder := func(holder, target interface{}) error { s, ok := holder.(*string) if !ok { return errors.New(utils.T("store.sql.convert_string_map")) } b := []byte(*s) return json.Unmarshal(b, target) } return gorp.CustomScanner{new(string), target, binder}, true case *model.StringArray: binder := func(holder, target interface{}) error { s, ok := holder.(*string) if !ok { return errors.New(utils.T("store.sql.convert_string_array")) } b := []byte(*s) return json.Unmarshal(b, target) } return gorp.CustomScanner{new(string), target, binder}, true case *model.EncryptStringMap: binder := func(holder, target interface{}) error { s, ok := holder.(*string) if !ok { return errors.New(utils.T("store.sql.convert_encrypt_string_map")) } ue, err := decrypt([]byte(utils.Cfg.SqlSettings.AtRestEncryptKey), *s) if err != nil { return err } b := []byte(ue) return json.Unmarshal(b, target) } return gorp.CustomScanner{new(string), target, binder}, true case *model.StringInterface: binder := func(holder, target interface{}) error { s, ok := holder.(*string) if !ok { return errors.New(utils.T("store.sql.convert_string_interface")) } b := []byte(*s) return json.Unmarshal(b, target) } return gorp.CustomScanner{new(string), target, binder}, true } return gorp.CustomScanner{}, false }
func (ss SqlStore) GetColumnDataType(tableName, columnName string) string { dataType, err := ss.GetMaster().SelectStr("SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS where table_name = :Tablename AND column_name = :Columnname", map[string]interface{}{ "Tablename": tableName, "Columnname": columnName, }) if err != nil { l4g.Critical(utils.T("store.sql.table_column_type.critical"), columnName, tableName, err.Error()) time.Sleep(time.Second) panic(fmt.Sprintf(utils.T("store.sql.table_column_type.critical"), columnName, tableName, err.Error())) } return dataType }