// Contacts retrieves contacts presences since n seconds func (*UsersController) Contacts(ctx *gin.Context) { sinceSeconds, err := GetParam(ctx, "sinceSeconds") if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "Error while getting seconds parameter"}) return } seconds, err := strconv.ParseInt(sinceSeconds, 10, 64) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "Invalid since parameter : must be an interger"}) return } var user = models.User{} err = user.FindByUsername(utils.GetCtxUsername(ctx)) if err != nil { ctx.JSON(http.StatusInternalServerError, errors.New("Error while fetching user")) return } criteria := models.PresenceCriteria{} for _, contact := range user.Contacts { criteria.Username = criteria.Username + "," + contact.Username } criteria.DateMinPresence = strconv.FormatInt(time.Now().Unix()-seconds, 10) count, presences, _ := models.ListPresences(&criteria) out := &contactsJSON{ Contacts: user.Contacts, CountContactsPresences: count, ContactsPresences: &presences, } ctx.JSON(http.StatusOK, out) }
// ResetSystemUser reset password for a system user func (*UsersController) ResetSystemUser(ctx *gin.Context) { var systemUserJSON resetSystemUserJSON ctx.Bind(&systemUserJSON) if !strings.HasPrefix(systemUserJSON.Username, "tat.system") { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("Username does not begin with tat.system (%s), it's not possible to reset password for this user", systemUserJSON.Username)) return } var systemUserToReset = models.User{} err := systemUserToReset.FindByUsername(systemUserJSON.Username) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s does not exist", systemUserJSON.Username)) return } if !systemUserToReset.IsSystem { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s is not a system user", systemUserJSON.Username)) return } newPassword, err := systemUserToReset.ResetSystemUserPassword() if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("Reset password for %s (system user) failed", systemUserJSON.Username)) return } ctx.JSON(http.StatusOK, gin.H{ "message": "Reset password successfull", "username": systemUserToReset.Username, "password": newPassword, "url": fmt.Sprintf("%s://%s:%s%s", viper.GetString("exposed_scheme"), viper.GetString("exposed_host"), viper.GetString("exposed_port"), viper.GetString("exposed_path")), }) }
// Delete deletes requested topic only if user is Tat admin, or admin on topic func (t *TopicsController) Delete(ctx *gin.Context) { topicRequest, err := GetParam(ctx, "topic") if err != nil { return } var user = models.User{} err = user.FindByUsername(utils.GetCtxUsername(ctx)) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Error while fetching user."}) return } paramJSON := paramTopicUserJSON{ Topic: topicRequest, Username: user.Username, Recursive: false, } topic, e := t.preCheckUser(ctx, ¶mJSON) if e != nil { return } err = topic.Delete(&user) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, errors.New(err.Error())) return } ctx.JSON(http.StatusOK, "") }
// OneTopic returns only requested topic, and only if user has read access func (t *TopicsController) OneTopic(ctx *gin.Context) { topicRequest, err := GetParam(ctx, "topic") if err != nil { return } var user = models.User{} err = user.FindByUsername(utils.GetCtxUsername(ctx)) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Error while fetching user."}) return } topic := &models.Topic{} errfinding := topic.FindByTopic(topicRequest, user.IsAdmin) if errfinding != nil { ctx.JSON(http.StatusInternalServerError, errfinding) return } isReadAccess := topic.IsUserReadAccess(user) if !isReadAccess { ctx.JSON(http.StatusInternalServerError, errors.New("No Read Access to this topic: "+user.Username+" "+topic.Topic)) return } out := &topicJSON{Topic: topic} ctx.JSON(http.StatusOK, out) }
// Convert a "normal" user to a "system" user func (*UsersController) Convert(ctx *gin.Context) { var convertJSON convertUserJSON ctx.Bind(&convertJSON) if !strings.HasPrefix(convertJSON.Username, "tat.system") { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("Username does not begin with tat.system (%s), it's not possible to convert this user", convertJSON.Username)) return } var userToConvert = models.User{} err := userToConvert.FindByUsername(convertJSON.Username) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s does not exist", convertJSON.Username)) return } if userToConvert.IsSystem { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s is already a system user", convertJSON.Username)) return } newPassword, err := userToConvert.ConvertToSystem(utils.GetCtxUsername(ctx), convertJSON.CanWriteNotifications) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("Convert %s to system user failed", convertJSON.Username)) return } ctx.JSON(http.StatusOK, gin.H{ "message": "Verification successfull", "username": userToConvert.Username, "password": newPassword, "url": fmt.Sprintf("%s://%s:%s%s", viper.GetString("exposed_scheme"), viper.GetString("exposed_host"), viper.GetString("exposed_port"), viper.GetString("exposed_path")), }) }
// Me retrieves all information about me (exception information about Authentication) func (*UsersController) Me(ctx *gin.Context) { var user = models.User{} err := user.FindByUsername(utils.GetCtxUsername(ctx)) if err != nil { AbortWithReturnError(ctx, http.StatusInternalServerError, errors.New("Error while fetching user")) return } out := &userJSON{User: &user} ctx.JSON(http.StatusOK, out) }
func (*PresencesController) preCheckUser(ctx *gin.Context) (models.User, error) { var user = models.User{} err := user.FindByUsername(utils.GetCtxUsername(ctx)) if err != nil { e := errors.New("Error while fetching user.") ctx.AbortWithError(http.StatusInternalServerError, e) return user, e } return user, nil }
// Create a new message on one topic func (m *MessagesController) Create(ctx *gin.Context) { messageIn, messageReference, topic, e := m.preCheckTopic(ctx) if e != nil { return } user, e := PreCheckUser(ctx) if e != nil { return } isRw := topic.IsUserRW(&user) if !isRw { ctx.JSON(http.StatusForbidden, gin.H{"error": fmt.Sprintf("No RW Access to topic " + messageIn.Topic)}) return } var message = models.Message{} info := "" if messageIn.Action == "bookmark" { var originalUser = models.User{} err := originalUser.FindByUsername(utils.GetCtxUsername(ctx)) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, errors.New("Error while fetching original user.")) return } err = message.Insert(originalUser, topic, messageReference.Text, "", -1) if err != nil { log.Errorf("Error while InsertMessage with action %s : %s", messageIn.Action, err) ctx.AbortWithError(http.StatusInternalServerError, errors.New(err.Error())) return } info = fmt.Sprintf("New Bookmark created in %s", topic.Topic) } else { err := message.Insert(user, topic, messageIn.Text, messageIn.IDReference, messageIn.DateCreation) if err != nil { log.Errorf("Error while InsertMessage %s", err) ctx.AbortWithError(http.StatusInternalServerError, errors.New(err.Error())) return } go models.WSMessageNew(&models.WSMessageNewJSON{Topic: topic.Topic}) info = fmt.Sprintf("Message created in %s", topic.Topic) } out := &messageJSONOut{Message: message, Info: info} go models.WSMessage(&models.WSMessageJSON{Action: "create", Username: user.Username, Message: message}) ctx.JSON(http.StatusCreated, out) }
// validateTatHeaders fetch user in db and check Password func validateTatHeaders(tatHeaders tatHeaders) (models.User, error) { user := models.User{} if tatHeaders.trustUsername != "" && tatHeaders.trustUsername != "null" { err := user.TrustUsername(tatHeaders.trustUsername) if err != nil { return user, fmt.Errorf("User %s does not exist. Please register before. Err:%s", tatHeaders.trustUsername, err.Error()) } } else { err := user.FindByUsernameAndPassword(tatHeaders.username, tatHeaders.password) if err != nil { return user, fmt.Errorf("Invalid Tat credentials for username %s, err:%s", tatHeaders.username, err.Error()) } } return user, nil }
// Rename a username of one user func (*UsersController) Rename(ctx *gin.Context) { var renameJSON renameUserJSON ctx.Bind(&renameJSON) var userToRename = models.User{} err := userToRename.FindByUsername(renameJSON.Username) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s does not exist", renameJSON.Username)) return } err = userToRename.Rename(renameJSON.NewUsername) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("Rename %s user to %s failed", renameJSON.Username, renameJSON.NewUsername)) return } ctx.JSON(http.StatusCreated, "") }
// Create creates a new topic func (*TopicsController) Create(ctx *gin.Context) { var topicIn topicCreateJSON ctx.Bind(&topicIn) var user = models.User{} err := user.FindByUsername(utils.GetCtxUsername(ctx)) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Error while fetching user."}) return } var topic models.Topic topic.Topic = topicIn.Topic topic.Description = topicIn.Description err = topic.Insert(&user) if err != nil { log.Errorf("Error while InsertTopic %s", err) ctx.JSON(http.StatusInternalServerError, err) return } ctx.JSON(http.StatusCreated, topic) }
// Update changes fullname and email func (*UsersController) Update(ctx *gin.Context) { var updateJSON updateUserJSON ctx.Bind(&updateJSON) var userToUpdate = models.User{} err := userToUpdate.FindByUsername(updateJSON.Username) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("user with username %s does not exist", updateJSON.Username)}) return } if strings.TrimSpace(updateJSON.NewFullname) == "" || strings.TrimSpace(updateJSON.NewEmail) == "" { ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("Invalid Fullname %s or Email %s", updateJSON.NewFullname, updateJSON.NewEmail)}) return } err = userToUpdate.Update(strings.TrimSpace(updateJSON.NewFullname), strings.TrimSpace(updateJSON.NewEmail)) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Update %s user to fullname %s and email %s failed : %s", updateJSON.Username, updateJSON.NewFullname, updateJSON.NewEmail, err.Error())}) return } ctx.JSON(http.StatusCreated, "") }
// Archive a user func (*UsersController) Archive(ctx *gin.Context) { var archiveJSON usernameUserJSON ctx.Bind(&archiveJSON) var userToArchive = models.User{} err := userToArchive.FindByUsername(archiveJSON.Username) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s does not exist", archiveJSON.Username)) return } if userToArchive.IsArchived { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s is already archived", archiveJSON.Username)) return } err = userToArchive.Archive(utils.GetCtxUsername(ctx)) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("archive user %s failed", archiveJSON.Username)) return } ctx.JSON(http.StatusCreated, "") }
// SetAdmin a "normal" user to an admin user func (*UsersController) SetAdmin(ctx *gin.Context) { var convertJSON convertUserJSON ctx.Bind(&convertJSON) var userToGrant = models.User{} err := userToGrant.FindByUsername(convertJSON.Username) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s does not exist", convertJSON.Username)) return } if userToGrant.IsAdmin { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s is already an admin user", convertJSON.Username)) return } err = userToGrant.ConvertToAdmin(utils.GetCtxUsername(ctx)) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("Convert %s to admin user failed", convertJSON.Username)) return } ctx.JSON(http.StatusCreated, "") }
// Reset send a mail asking user to confirm reset password func (u *UsersController) Reset(ctx *gin.Context) { var userJSON userResetJSON ctx.Bind(&userJSON) var userIn models.User userIn.Username = strings.TrimSpace(userJSON.Username) userIn.Email = strings.TrimSpace(userJSON.Email) callback := strings.TrimSpace(userJSON.Callback) if len(userIn.Username) < 3 || len(userIn.Email) < 7 { err := fmt.Errorf("Invalid username (%s) or email (%s)", userIn.Username, userIn.Email) AbortWithReturnError(ctx, http.StatusInternalServerError, err) return } tokenVerify, err := userIn.AskReset() if err != nil { log.Errorf("Error while AskReset %s", err) ctx.AbortWithError(http.StatusInternalServerError, err) return } go utils.SendAskResetEmail(userIn.Username, userIn.Email, tokenVerify, callback) ctx.JSON(http.StatusCreated, gin.H{"info": "please check your mail to validate your account"}) }
// AddContact add a contact to user func (*UsersController) AddContact(ctx *gin.Context) { contactIn, err := GetParam(ctx, "username") if err != nil { return } user, err := PreCheckUser(ctx) if err != nil { return } var contact = models.User{} err = contact.FindByUsername(contactIn) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, fmt.Errorf("user with username %s does not exist", contactIn)) return } err = user.AddContact(contact.Username, contact.Fullname) if err != nil { AbortWithReturnError(ctx, http.StatusInternalServerError, fmt.Errorf("Error while add contact %s to user:%s", contact.Username, user.Username)) return } ctx.JSON(http.StatusCreated, "") }
func (m *MessagesController) checkDMTopic(ctx *gin.Context, topicName string) (models.Topic, string, error) { var topic = models.Topic{} topicParentName := "/Private/" + utils.GetCtxUsername(ctx) + "/DM" if !strings.HasPrefix(topicName, topicParentName+"/") { log.Errorf("wrong topic name for DM:" + topicName) return topic, "", errors.New("Wrong tpic name for DM:" + topicName) } // /Private/usernameFrom/DM/usernameTO part := strings.Split(topicName, "/") if len(part) != 5 { log.Errorf("wrong topic name for DM") return topic, "", errors.New("Wrong topic name for DM:" + topicName) } var userFrom = models.User{} err := userFrom.FindByUsername(utils.GetCtxUsername(ctx)) if err != nil { return topic, "", errors.New("Error while fetching user.") } var userTo = models.User{} usernameTo := part[4] err = userTo.FindByUsername(usernameTo) if err != nil { return topic, "", errors.New("Error while fetching user.") } err = m.checkTopicParentDM(userFrom) if err != nil { return topic, "", errors.New(err.Error()) } err = m.checkTopicParentDM(userTo) if err != nil { return topic, "", errors.New(err.Error()) } topic, err = m.insertTopicDM(userFrom, userTo) if err != nil { return topic, "", errors.New(err.Error()) } _, err = m.insertTopicDM(userTo, userFrom) if err != nil { return topic, "", errors.New(err.Error()) } topicCriteria := topicName + "," + "/Private/" + usernameTo + "/DM/" + userFrom.Username return topic, topicCriteria, nil }
// Create a new user, record Username, Fullname and Email // A mail is sent to ask user for validation func (u *UsersController) Create(ctx *gin.Context) { var userJSON userCreateJSON ctx.Bind(&userJSON) var userIn models.User userIn.Username = u.computeUsername(userJSON) userIn.Fullname = strings.TrimSpace(userJSON.Fullname) userIn.Email = strings.TrimSpace(userJSON.Email) callback := strings.TrimSpace(userJSON.Callback) if len(userIn.Username) < 3 || len(userIn.Fullname) < 3 || len(userIn.Email) < 7 { err := fmt.Errorf("Invalid username (%s) or fullname (%s) or email (%s)", userIn.Username, userIn.Fullname, userIn.Email) AbortWithReturnError(ctx, http.StatusInternalServerError, err) return } err := u.checkAllowedDomains(userJSON) if err != nil { ctx.JSON(http.StatusForbidden, gin.H{"error": err.Error()}) return } if models.IsEmailExists(userJSON.Email) || models.IsUsernameExists(userJSON.Username) || models.IsFullnameExists(userJSON.Fullname) { e := fmt.Errorf("Please check your username, email or fullname. If you are already registered, please reset your password") AbortWithReturnError(ctx, http.StatusBadRequest, e) return } tokenVerify, err := userIn.Insert() if err != nil { log.Errorf("Error while InsertUser %s", err) ctx.AbortWithError(http.StatusInternalServerError, err) return } go utils.SendVerifyEmail(userIn.Username, userIn.Email, tokenVerify, callback) go models.WSUser(&models.WSUserJSON{Action: "create", Username: userIn.Username}) info := "" if viper.GetBool("username_from_email") { info = fmt.Sprintf(" Note that configuration of Tat forced your username to %s", userIn.Username) } ctx.JSON(http.StatusCreated, gin.H{"info": fmt.Sprintf("please check your mail to validate your account.%s", info)}) }