func changeUsernameOnPrivateTopics(oldUsername, newUsername string) error { var topics []tat.Topic err := store.Tat().CTopics.Find( bson.M{ "topic": bson.RegEx{ Pattern: "^/Private/" + oldUsername + ".*$", Options: "i", }}).All(&topics) if err != nil { log.Errorf("Error while getting topic with username %s for rename to %s on Topics %s", oldUsername, newUsername, err) } for _, topic := range topics { newTopicName := strings.Replace(topic.Topic, oldUsername, newUsername, 1) errUpdate := store.Tat().CTopics.Update( bson.M{"_id": topic.ID}, bson.M{"$set": bson.M{"topic": newTopicName}}, ) if errUpdate != nil { log.Errorf("Error while update Topic name from %s to %s :%s", topic.Topic, newTopicName, errUpdate) } } return err }
func actionOnSetParameter(topic *tat.Topic, operand, set, admin string, newParam tat.TopicParameter, recursive bool, history string) error { var selector bson.M if recursive { selector = bson.M{"topic": bson.RegEx{Pattern: "^" + topic.Topic + ".*$"}} } else { selector = bson.M{"_id": topic.ID} } var err error if operand == "$pull" { _, err = store.Tat().CTopics.UpdateAll( selector, bson.M{operand: bson.M{set: bson.M{"key": newParam.Key}}}, ) } else { _, err = store.Tat().CTopics.UpdateAll( selector, bson.M{operand: bson.M{set: bson.M{"key": newParam.Key, "value": newParam.Value}}}, ) } if err != nil { return err } return addToHistory(topic, selector, admin, history+" "+newParam.Key+":"+newParam.Value) }
// FindAllTopicsWithCollections returns the total number of topics in db func FindAllTopicsWithCollections() ([]tat.Topic, error) { var topics []tat.Topic err := store.Tat().CTopics.Find(bson.M{"collection": bson.M{"$exists": true, "$ne": ""}}). Select(bson.M{"_id": 1, "collection": 1, "topic": 1}). All(&topics) return topics, err }
func listTopicsCursor(criteria *tat.TopicCriteria, user *tat.User) (*mgo.Query, error) { c, err := buildTopicCriteria(criteria, user) if err != nil { return nil, err } return store.Tat().CTopics.Find(c), nil }
// Insert a new user, return tokenVerify to user, in order to // validate account after check email func Insert(user *tat.User) (string, error) { user.ID = bson.NewObjectId().Hex() user.DateCreation = time.Now().Unix() user.Auth.DateAskReset = time.Now().Unix() user.Auth.EmailVerified = false user.IsSystem = false user.IsArchived = false user.CanWriteNotifications = false user.CanListUsersAsAdmin = false nbUsers, err := CountUsers() if err != nil { log.Errorf("Error while count all users%s", err) return "", err } if nbUsers > 0 { user.IsAdmin = false } else { log.Infof("user %s is the first user, he is now admin", user.Username) user.IsAdmin = true } tokenVerify := "" tokenVerify, user.Auth.HashedTokenVerify, err = generateUserPassword() if err != nil { log.Errorf("Error while generate Token Verify for new user %s", err) return tokenVerify, err } if err = store.Tat().CUsers.Insert(user); err != nil { log.Errorf("Error while inserting new user %s", err) } return tokenVerify, err }
func addToHistory(group *tat.Group, user string, historyToAdd string) error { toAdd := strconv.FormatInt(time.Now().Unix(), 10) + " " + user + " " + historyToAdd return store.Tat().CGroups.Update( bson.M{"_id": group.ID}, bson.M{"$addToSet": bson.M{"history": toAdd}}, ) }
// FindByUsernameAndPassword search username, use user's salt to generates tokenVerify // and check username + hashedTokenVerify in DB func findByUsernameAndTokenVerify(user *tat.User, username, tokenVerify string) (bool, error) { var tmpUser = tat.User{} err := store.Tat().CUsers. Find(bson.M{"username": username}). Select(bson.M{"auth.emailVerify": 1, "auth.hashedTokenVerify": 1, "auth.saltTokenVerify": 1, "auth.dateAskReset": 1}). One(&tmpUser) if err != nil { return false, fmt.Errorf("findByUsernameAndTokenVerify > Error while fetching hashed Token Verify with username %s", username) } // dateAskReset more than 30 min, expire token if time.Since(time.Unix(tmpUser.Auth.DateAskReset, 0)).Minutes() > 30 { return false, fmt.Errorf("Token Validation expired. Please ask a reset of your password with username %s", username) } if !isCheckValid(tokenVerify, tmpUser.Auth.HashedTokenVerify) { return false, fmt.Errorf("Error while checking user %s with given token", username) } // ok, user is checked, get all fields now found, err := FindByUsername(user, username) if !found || err != nil { return false, err } return tmpUser.Auth.EmailVerified, nil }
// AllTopicsSetParam computes Tags on all topics func AllTopicsSetParam(key, value string) (string, error) { var topics []tat.Topic err := store.Tat().CTopics.Find(bson.M{}). Select(GetTopicSelectedFields(true, false, false, false)). All(&topics) if err != nil { log.Errorf("Error while getting all topics for set a param") return "", err } errTxt := "" nOk := 1 for _, topic := range topics { if err := setAParam(&topic, key, value); err != nil { log.Errorf("Error while set param %s on topic %s: %s", key, topic.Topic, err.Error()) errTxt += fmt.Sprintf(" Error set param %s on topic %s", key, topic.Topic) } else { log.Infof(" %s param setted on topic %s", key, topic.Topic) nOk++ } } if errTxt != "" { return "", fmt.Errorf(errTxt) } return fmt.Sprintf("Param setted on %d topics", nOk), nil }
// AskReset generate a new saltTokenVerify / hashedTokenVerify // return tokenVerify (to be sent to user by mail) func AskReset(user *tat.User) (string, error) { err := FindByUsernameAndEmail(user, user.Username, user.Email) if err != nil { return "", err } tokenVerify, hashedTokenVerify, err := generateUserPassword() if err != nil { log.Errorf("Error while generate Token for reset password %s", err) return tokenVerify, err } err = store.Tat().CUsers.Update( bson.M{"_id": user.ID}, bson.M{"$set": bson.M{ "auth.hashedTokenVerify": hashedTokenVerify, "auth.dateAskReset": time.Now().Unix(), }}) if err != nil { log.Errorf("Error while ask reset user %s", err) } return tokenVerify, err }
func listUsersCursor(criteria *tat.UserCriteria, isAdmin bool) (*mgo.Query, error) { c, err := buildUserCriteria(criteria) if err != nil { return nil, err } return store.Tat().CUsers.Find(c), nil }
func listGroupsCursor(criteria *tat.GroupCriteria, user *tat.User) (*mgo.Query, error) { c, err := buildGroupCriteria(criteria, user) if err != nil { return nil, err } return store.Tat().CGroups.Find(c), nil }
// AllTopicsComputeTags computes Tags on all topics func AllTopicsComputeTags() (string, error) { var topics []tat.Topic err := store.Tat().CTopics.Find(bson.M{}). Select(GetTopicSelectedFields(true, false, false, false)). All(&topics) if err != nil { log.Errorf("Error while getting all topics for compute tags") return "", err } errTxt := "" infoTxt := "" for _, topic := range topics { if topic.IsAutoComputeTags { n, err := ComputeTags(&topic) if err != nil { log.Errorf("Error while compute tags on topic %s: %s", topic.Topic, err.Error()) errTxt += fmt.Sprintf(" Error compute tags on topic %s", topic.Topic) } else { infoTxt += fmt.Sprintf(" %d tags computed on topic %s", n, topic.Topic) log.Infof(infoTxt) } } } if errTxt != "" { return infoTxt, fmt.Errorf(errTxt) } return infoTxt, nil }
// UpdateTopicLabels updates labels on topic func UpdateTopicLabels(topic *tat.Topic, labels []tat.Label) { if !topic.IsAutoComputeLabels || len(labels) == 0 { return } update := false newLabels := topic.Labels for _, label := range labels { find := false for _, tlabel := range topic.Labels { if label.Text == tlabel.Text { find = true continue } } if !find { newLabels = append(newLabels, label) update = true } } if update { err := store.Tat().CTopics.Update( bson.M{"_id": topic.ID}, bson.M{"$set": bson.M{"labels": newLabels}}) if err != nil { log.Errorf("UpdateTopicLabels> Error while updating labels on topic") } else { log.Debugf("UpdateTopicLabels> Topic %s ", topic.Topic) } cache.CleanTopicByName(topic.Topic) } }
// UpdateTopicTags updates tags on topic func UpdateTopicTags(topic *tat.Topic, tags []string) { if !topic.IsAutoComputeTags || len(tags) == 0 { return } update := false newTags := topic.Tags for _, tag := range tags { if !tat.ArrayContains(topic.Tags, tag) { update = true newTags = append(newTags, tag) } } if update { err := store.Tat().CTopics.Update( bson.M{"_id": topic.ID}, bson.M{"$set": bson.M{"tags": newTags}}) if err != nil { log.Errorf("UpdateTopicTags> Error while updating tags on topic") } else { log.Debugf("UpdateTopicTags> Topic %s ", topic.Topic) } cache.CleanTopicByName(topic.Topic) } }
func listPresencesCursor(criteria *tat.PresenceCriteria, allFields bool) (*mgo.Query, error) { c, err := buildPresenceCriteria(criteria) if err != nil { return nil, err } return store.Tat().CPresences.Find(c), nil }
func addToHistory(topic *tat.Topic, selector bson.M, user string, historyToAdd string) error { toAdd := strconv.FormatInt(time.Now().Unix(), 10) + " " + user + " " + historyToAdd _, err := store.Tat().CTopics.UpdateAll( selector, bson.M{"$addToSet": bson.M{"history": toAdd}}, ) return err }
// RemoveFilter add a user filter to the topic func RemoveFilter(topic *tat.Topic, filter *tat.Filter) error { err := store.Tat().CTopics.Update( bson.M{"_id": topic.ID}, bson.M{"$pull": bson.M{"filters": bson.M{"_id": filter.ID}}}, ) cache.CleanTopicByName(topic.Topic) return err }
// UpdateFilter add a user filter to the topic func UpdateFilter(topic *tat.Topic, filter *tat.Filter) error { err := store.Tat().CTopics.Update( bson.M{"_id": topic.ID, "filters._id": filter.ID}, bson.M{"$set": bson.M{"filters.$": filter}}, ) cache.CleanTopicByName(topic.Topic) return err }
// TruncateLabels clears "cached" labels on a topic func TruncateLabels(topic *tat.Topic) error { err := store.Tat().CTopics.Update( bson.M{"_id": topic.ID}, bson.M{"$unset": bson.M{"labels": ""}}) cache.CleanTopicByName(topic.Topic) return err }
// UpdateSystemUser updates flags CanWriteNotifications and CanListUsersAsAdmin func UpdateSystemUser(user *tat.User, canWriteNotifications, canListUsersAsAdmin bool) error { return store.Tat().CUsers.Update( bson.M{"_id": user.ID}, bson.M{"$set": bson.M{ "canWriteNotifications": canWriteNotifications, "canListUsersAsAdmin": canListUsersAsAdmin, }}) }
// AddFavoriteTag Add a favorite tag to user func AddFavoriteTag(user *tat.User, tag string) error { if containsFavoriteTag(user, tag) { return fmt.Errorf("AddFavoriteTag not possible, %s is already a favorite tag", tag) } cache.CleanUsernames(user.Username) return store.Tat().CUsers.Update( bson.M{"_id": user.ID}, bson.M{"$push": bson.M{"favoritesTags": tag}}) }
//FindByUsernameAndEmail retrieve information from user with username func FindByUsernameAndEmail(user *tat.User, username, email string) error { err := store.Tat().CUsers. Find(bson.M{"username": username, "email": email}). Select(fieldsExceptAuth). One(&user) if err != nil { log.Errorf("Error while fetching user with username %s", username) } return err }
// DisableNotificationsTopic add topic to user list offNotificationsTopics func DisableNotificationsTopic(user *tat.User, topic string) error { if containsOffNotificationsTopic(user, topic) { return fmt.Errorf("DisableNotificationsTopic not possible, notifications are already off on topic %s", topic) } cache.CleanUsernames(user.Username) return store.Tat().CUsers.Update( bson.M{"_id": user.ID}, bson.M{"$push": bson.M{"offNotificationsTopics": topic}}) }
func actionOnSet(group *tat.Group, operand, set, groupname, admin, history string) error { err := store.Tat().CGroups.Update( bson.M{"_id": group.ID}, bson.M{operand: bson.M{set: groupname}}, ) if err != nil { return err } cache.CleanAllGroups() return addToHistory(group, admin, history+" "+groupname) }
func changeNameOnSet(typeChange, set, oldname, newname string) error { _, err := store.Tat().CTopics.UpdateAll( bson.M{set: oldname}, bson.M{"$set": bson.M{set + ".$": newname}}) if err != nil { log.Errorf("Error while changes %s from %s to %s on Topics (%s) %s", typeChange, oldname, newname, set, err) return fmt.Errorf("Error while changes %s from %s to %s on Topics (%s)", typeChange, oldname, newname, set) } return nil }
// ChangeAuthorUsernameOnPresences changes username on presences collection func ChangeAuthorUsernameOnPresences(oldUsername, newUsername string) error { _, err := store.Tat().CPresences.UpdateAll( bson.M{"userPresence.username": oldUsername}, bson.M{"$set": bson.M{"userPresence.username": newUsername}}) if err != nil { log.Errorf("Error while update username from %s to %s on Presences %s", oldUsername, newUsername, err) } return err }
func workOnTopicsLastMsgUpdate() { for topic, dateUpdate := range topicsLastMsgUpdate { err := store.Tat().CTopics.Update( bson.M{"topic": topic}, bson.M{"$set": bson.M{"dateLastMessage": dateUpdate}}) if err != nil { log.Errorf("Error while update last date message on topic %s, err:%s", topic, err) } } topicsLastMsgUpdate = make(map[string]int64) }
// RemoveContact removes a contact from user func RemoveContact(user *tat.User, contactUsername string) error { l, err := getContact(user, contactUsername) if err != nil { return fmt.Errorf("Remove Contact is not possible, %s is not a contact of this user", contactUsername) } cache.CleanUsernames(user.Username) return store.Tat().CUsers.Update( bson.M{"_id": user.ID}, bson.M{"$pull": bson.M{"contacts": l}}) }
// AddContact add a contact to user func AddContact(user *tat.User, contactUsername string, contactFullname string) error { if containsContact(user, contactUsername) { return fmt.Errorf("AddContact not possible, %s is already a contact of this user", contactUsername) } var newContact = &tat.Contact{Username: contactUsername, Fullname: contactFullname} cache.CleanUsernames(user.Username) return store.Tat().CUsers.Update( bson.M{"_id": user.ID}, bson.M{"$push": bson.M{"contacts": newContact}}) }
// RemoveFavoriteTag remove a favorite tag from user func RemoveFavoriteTag(user *tat.User, tag string) error { t, err := getFavoriteTag(user, tag) if err != nil { return fmt.Errorf("Remove favorite tag is not possible, %s is not a favorite of this user", tag) } cache.CleanUsernames(user.Username) return store.Tat().CUsers.Update( bson.M{"_id": user.ID}, bson.M{"$pull": bson.M{"favoritesTags": t}}) }