// EnableNotificationsTopic enable notication on one topic func (*UsersController) EnableNotificationsTopic(ctx *gin.Context) { topicIn, err := GetParam(ctx, "topic") if err != nil { return } user, err := PreCheckUser(ctx) if err != nil { return } var topic = models.Topic{} err = topic.FindByTopic(topicIn, true) if err != nil { AbortWithReturnError(ctx, http.StatusBadRequest, errors.New("topic "+topicIn+" does not exist")) return } isReadAccess := topic.IsUserReadAccess(user) if !isReadAccess { AbortWithReturnError(ctx, http.StatusForbidden, errors.New("No Read Access to this topic")) return } err = user.EnableNotificationsTopic(topic.Topic) if err != nil { AbortWithReturnError(ctx, http.StatusInternalServerError, fmt.Errorf("Error while enable notication on topic %s to user:%s", topic.Topic, user.Username)) return } ctx.JSON(http.StatusCreated, gin.H{"info": fmt.Sprintf("Notications enabled on Topic %s", topic.Topic)}) }
func (m *MessagesController) likeOrUnlike(ctx *gin.Context, action string, message models.Message, topic models.Topic, user models.User) { isReadAccess := topic.IsUserReadAccess(user) if !isReadAccess { ctx.AbortWithError(http.StatusInternalServerError, errors.New("No Read Access to topic "+message.Topics[0])) return } info := "" if action == "like" { err := message.Like(user) if err != nil { log.Errorf("Error while like a message %s", err) ctx.AbortWithError(http.StatusInternalServerError, err) return } info = "like added" } else if action == "unlike" { err := message.Unlike(user) if err != nil { log.Errorf("Error while like a message %s", err) ctx.AbortWithError(http.StatusInternalServerError, err) return } info = "like removed" } else { ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Invalid action : " + action)}) return } go models.WSMessage(&models.WSMessageJSON{Action: action, Username: user.Username, Message: message}) ctx.JSON(http.StatusCreated, gin.H{"info": info}) }
func (t *TopicsController) preCheckUserAdminOnTopic(ctx *gin.Context, topicName string) (models.Topic, error) { topic := models.Topic{} errfinding := topic.FindByTopic(topicName, true) if errfinding != nil { e := errors.New(errfinding.Error()) ctx.AbortWithError(http.StatusInternalServerError, e) return topic, e } if utils.IsTatAdmin(ctx) { // if Tat admin, ok return topic, nil } user, err := PreCheckUser(ctx) if err != nil { return models.Topic{}, err } if !topic.IsUserAdmin(&user) { e := fmt.Errorf("user %s is not admin on topic %s", user.Username, topic.Topic) ctx.AbortWithError(http.StatusForbidden, e) return models.Topic{}, e } return topic, nil }
func (*MessagesController) insertTopicDM(userFrom, userTo models.User) (models.Topic, error) { var topic = models.Topic{} topicName := "/Private/" + userFrom.Username + "/DM/" + userTo.Username topic.Topic = topicName topic.Description = userTo.Fullname err := topic.Insert(&userFrom) if err != nil { log.Errorf("Error while InsertTopic %s", err) return topic, err } return topic, nil }
func (m *PresencesController) listWithCriteria(ctx *gin.Context, criteria *models.PresenceCriteria) { user, e := m.preCheckUser(ctx) if e != nil { return } var topic = models.Topic{} err := topic.FindByTopic(criteria.Topic, true) if err != nil { ctx.AbortWithError(http.StatusBadRequest, errors.New("topic "+criteria.Topic+" does not exist")) return } isReadAccess := topic.IsUserReadAccess(user) if !isReadAccess { ctx.AbortWithError(http.StatusForbidden, errors.New("No Read Access to this topic.")) return } // add / if search on topic // as topic is in path, it can't start with a / if criteria.Topic != "" && string(criteria.Topic[0]) != "/" { criteria.Topic = "/" + criteria.Topic } topicDM := "/Private/" + utils.GetCtxUsername(ctx) + "/DM/" if strings.HasPrefix(criteria.Topic, topicDM) { part := strings.Split(criteria.Topic, "/") if len(part) != 5 { log.Errorf("wrong topic name for DM") ctx.AbortWithError(http.StatusInternalServerError, errors.New("Wrong topic name for DM:"+criteria.Topic)) return } topicInverse := "/Private/" + part[4] + "/DM/" + utils.GetCtxUsername(ctx) criteria.Topic = criteria.Topic + "," + topicInverse } count, presences, err := models.ListPresences(criteria) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, err) return } out := &presencesJSON{ Count: count, Presences: presences, } ctx.JSON(http.StatusOK, out) }
func (m *PresencesController) preCheckTopic(ctx *gin.Context) (presenceJSON, models.Topic, error) { var topic = models.Topic{} var presenceIn presenceJSON ctx.Bind(&presenceIn) topicIn, err := GetParam(ctx, "topic") if err != nil { return presenceIn, topic, err } presenceIn.Topic = topicIn err = topic.FindByTopic(presenceIn.Topic, true) if err != nil { e := errors.New("Topic " + presenceIn.Topic + " does not exist") ctx.AbortWithError(http.StatusInternalServerError, e) return presenceIn, topic, e } return presenceIn, topic, nil }
// 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) }
// SetParam update Topic Parameters : MaxLength, CanForeceDate, CanUpdateMsg, CanDeleteMsg, CanUpdateAllMsg, CanDeleteAllMsg, IsROPublic // admin only, except on Private topic func (t *TopicsController) SetParam(ctx *gin.Context) { var paramJSON paramJSON ctx.Bind(¶mJSON) topic := models.Topic{} var err error if strings.HasPrefix(paramJSON.Topic, "/Private/"+utils.GetCtxUsername(ctx)) { err := topic.FindByTopic(paramJSON.Topic, false) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Error while fetching topic /Private/" + utils.GetCtxUsername(ctx)}) return } } else { topic, err = t.preCheckUserAdminOnTopic(ctx, paramJSON.Topic) if err != nil { ctx.JSON(http.StatusInternalServerError, err) return } } err = topic.SetParam(utils.GetCtxUsername(ctx), paramJSON.Recursive, paramJSON.MaxLength, paramJSON.CanForceDate, paramJSON.CanUpdateMsg, paramJSON.CanDeleteMsg, paramJSON.CanUpdateAllMsg, paramJSON.CanDeleteAllMsg, paramJSON.IsROPublic) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, errors.New(err.Error())) return } ctx.JSON(http.StatusCreated, "") }
func (*MessagesController) checkTopicParentDM(user models.User) error { topicName := "/Private/" + user.Username + "/DM" var topicParent = models.Topic{} err := topicParent.FindByTopic(topicName, false) if err != nil { topicParent.Topic = topicName topicParent.Description = "DM Topics" err = topicParent.Insert(&user) if err != nil { log.Errorf("Error while InsertTopic Parent %s", err) return err } } return nil }
// List messages on one topic, with given criterias func (m *MessagesController) List(ctx *gin.Context) { var criteria = m.buildCriteria(ctx) presenceArg := ctx.Query("presence") topicIn, err := GetParam(ctx, "topic") if err != nil { return } criteria.Topic = topicIn // add / if search on topic // as topic is in path, it can't start with a / if criteria.Topic != "" && string(criteria.Topic[0]) != "/" { criteria.Topic = "/" + criteria.Topic } var topic = models.Topic{} err = topic.FindByTopic(criteria.Topic, true) if err != nil { topicCriteria := "" _, topicCriteria, err = m.checkDMTopic(ctx, criteria.Topic) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "topic " + criteria.Topic + " does not exist"}) return } // hack to get new created DM Topic err := topic.FindByTopic(criteria.Topic, true) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "topic " + criteria.Topic + " does not exist (2)"}) return } criteria.Topic = topicCriteria } out := &messagesJSON{} var user models.User var e error if utils.GetCtxUsername(ctx) != "" { user, e = PreCheckUser(ctx) if e != nil { return } isReadAccess := topic.IsUserReadAccess(user) if !isReadAccess { ctx.JSON(http.StatusForbidden, gin.H{"error": "No Read Access to this topic"}) return } out.IsTopicRw = topic.IsUserRW(&user) } else if !topic.IsROPublic { ctx.JSON(http.StatusForbidden, gin.H{"error": "No Public Read Access Public to this topic"}) return } else if topic.IsROPublic && strings.HasPrefix(topic.Topic, "/Private") { ctx.JSON(http.StatusForbidden, gin.H{"error": "No Public Read Access to this topic"}) return } // send presence if presenceArg != "" && !user.IsSystem { go func() { var presence = models.Presence{} err := presence.Upsert(user, topic, presenceArg) if err != nil { log.Errorf("Error while InsertPresence %s", err) } go models.WSPresence(&models.WSPresenceJSON{Action: "create", Presence: presence}) }() } messages, err := models.ListMessages(criteria) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } out.Messages = messages ctx.JSON(http.StatusOK, out) }
// Delete a message, works only on /Private/username/... topics func (m *MessagesController) Delete(ctx *gin.Context) { idMessageIn, err := GetParam(ctx, "idMessage") if err != nil { return } message := models.Message{} err = message.FindByID(idMessageIn) if err != nil { ctx.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("Message %s does not exist", idMessageIn)}) return } user, e := PreCheckUser(ctx) if e != nil { return } topic := models.Topic{} err = topic.FindByTopic(message.Topics[0], true) if err != nil { ctx.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("Topic %s does not exist", message.Topics[0])}) return } isRw := topic.IsUserRW(&user) if !isRw { ctx.JSON(http.StatusForbidden, gin.H{"error": fmt.Sprintf("No RW Access to topic %s", message.Topics[0])}) return } if !strings.HasPrefix(message.Topics[0], "/Private/"+user.Username) && !topic.CanDeleteMsg && !topic.CanDeleteAllMsg { if !topic.CanDeleteMsg && !topic.CanDeleteAllMsg { ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("You can't delete a message on this topic %s", topic.Topic)}) return } ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Could not delete a message in a non private topic %s", message.Topics[0])}) return } if !topic.CanDeleteAllMsg && message.Author.Username != user.Username { ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Could not delete a message from another user %s than you %s", message.Author.Username, user.Username)}) return } for _, topicName := range message.Topics { // if msg is only in tasks topic, ok to delete it if strings.HasPrefix(topicName, "/Private/") && strings.HasSuffix(topicName, "/Tasks") && len(message.Topics) > 1 { ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Could not delete a message in a tasks topic")}) return } } err = message.Delete() if err != nil { log.Errorf("Error while delete a message %s", err) ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } go models.WSMessage(&models.WSMessageJSON{Action: "delete", Username: user.Username, Message: message}) ctx.JSON(http.StatusOK, gin.H{"info": fmt.Sprintf("Message deleted from %s", topic.Topic)}) }
func (m *MessagesController) preCheckTopic(ctx *gin.Context) (messageJSON, models.Message, models.Topic, error) { var topic = models.Topic{} var message = models.Message{} var messageIn messageJSON ctx.Bind(&messageIn) topicIn, err := GetParam(ctx, "topic") if err != nil { return messageIn, message, topic, err } messageIn.Topic = topicIn if messageIn.IDReference == "" || messageIn.Action == "" { err := topic.FindByTopic(messageIn.Topic, true) if err != nil { topic, _, err = m.checkDMTopic(ctx, messageIn.Topic) if err != nil { e := errors.New("Topic " + messageIn.Topic + " does not exist") ctx.JSON(http.StatusNotFound, gin.H{"error": e.Error()}) return messageIn, message, topic, e } } } else if messageIn.IDReference != "" { err := message.FindByID(messageIn.IDReference) if err != nil { e := errors.New("Message " + messageIn.IDReference + " does not exist") ctx.JSON(http.StatusNotFound, gin.H{"error": e.Error()}) return messageIn, message, topic, e } topicName := "" if messageIn.Action == "update" { topicName = messageIn.Topic } else if messageIn.Action == "reply" || messageIn.Action == "unbookmark" || messageIn.Action == "like" || messageIn.Action == "unlike" || messageIn.Action == "label" || messageIn.Action == "unlabel" || messageIn.Action == "tag" || messageIn.Action == "untag" { topicName = m.inverseIfDMTopic(ctx, message.Topics[0]) } else if messageIn.Action == "task" || messageIn.Action == "untask" { topicName, err = m.getTopicNonPrivateTasks(ctx, message.Topics) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return messageIn, message, topic, err } } else if messageIn.Action == "bookmark" { topicAction := m.getTopicNameFromAction(utils.GetCtxUsername(ctx), messageIn.Action) if !strings.HasPrefix(messageIn.Topic, topicAction) { e := fmt.Errorf("Invalid Topic name for action %s mTopic %s topicAction:%s ", messageIn.Action, messageIn.Topic, topicAction) ctx.JSON(http.StatusBadRequest, gin.H{"error": e.Error()}) return messageIn, message, topic, e } topicName = messageIn.Topic } else { e := errors.New("Invalid Call. IDReference not empty with unknown action") ctx.JSON(http.StatusBadRequest, gin.H{"error": e.Error()}) return messageIn, message, topic, e } err = topic.FindByTopic(topicName, true) if err != nil { e := errors.New("Topic " + topicName + " does not exist") ctx.JSON(http.StatusNotFound, gin.H{"error": e.Error()}) return messageIn, message, topic, e } } else { e := errors.New("Topic and IDReference are null. Wrong request") ctx.JSON(http.StatusBadRequest, gin.H{"error": e.Error()}) return messageIn, message, topic, e } return messageIn, message, topic, nil }