Пример #1
0
func ParticipatedChannelCount(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	if accountId != c.Client.Account.Id {
		return response.NewBadRequest(models.ErrAccessDenied)
	}

	query := request.GetQuery(u)
	query = c.OverrideQuery(query)

	if query.Type == "" {
		query.Type = models.Channel_TYPE_TOPIC
	}
	cp := models.NewChannelParticipant()
	a := &models.Account{Id: query.AccountId}

	return response.HandleResultAndError(cp.ParticipatedChannelCount(a, query))
}
Пример #2
0
func GetWithRelated(u *url.URL, h http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	cm, err := getMessageByUrl(u)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if cm.Id == 0 {
		return response.NewNotFound()
	}

	ch, err := models.Cache.Channel.ById(cm.InitialChannelId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	q := request.GetQuery(u)
	query := ctx.OverrideQuery(q)

	canOpen, err := ch.CanOpen(query.AccountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewBadRequest(models.ErrCannotOpenChannel)
	}

	cmc := models.NewChannelMessageContainer()
	if err := cmc.Fetch(cm.Id, query); err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(cmc, cmc.Err)
}
Пример #3
0
// lists followed channels of an account
func ListChannels(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {

	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	if accountId != c.Client.Account.Id {
		return response.NewBadRequest(models.ErrAccessDenied)
	}

	query := request.GetQuery(u)
	query = c.OverrideQuery(query)

	if query.Type == "" {
		query.Type = models.Channel_TYPE_TOPIC
	}

	a := &models.Account{Id: accountId}
	channels, err := a.FetchChannels(query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	cc := models.NewChannelContainers()
	cc.PopulateWith(channels, query.AccountId).AddUnreadCount(query.AccountId)

	return response.HandleResultAndError(cc, cc.Err())
}
Пример #4
0
func FetchPostCount(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	accountId, err := request.GetId(u)
	if err != nil {
		return response.NewBadRequest(err)
	}

	c, err := models.Cache.Channel.ByGroupName(query.GroupName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// fetch user post count in koding channel
	q := request.NewQuery()
	q.AccountId = accountId
	q.Type = models.ChannelMessage_TYPE_POST
	q.GroupChannelId = c.Id
	cm := models.NewChannelMessage()

	count, err := cm.FetchTotalMessageCount(q)
	if err != nil {
		return response.NewBadRequest(err)
	}

	res := new(models.CountResponse)
	res.TotalCount = count

	return response.NewOK(res)
}
Пример #5
0
func ListPosts(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	buildMessageQuery := query.Clone()

	accountId, err := request.GetId(u)
	if err != nil {
		return response.NewBadRequest(err)
	}

	c, err := models.Cache.Channel.ByGroupName(query.GroupName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// fetch only channel messages
	query.Type = models.ChannelMessage_TYPE_POST
	query.AccountId = accountId
	cm := models.NewChannelMessage()
	messages, err := cm.FetchMessagesByChannelId(c.Id, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	buildMessageQuery.Limit = 3
	return response.HandleResultAndError(
		cm.BuildMessages(buildMessageQuery, messages),
	)
}
Пример #6
0
// ByName finds topics by their name
func ByName(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	q := context.OverrideQuery(request.GetQuery(u))

	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	if q.Type == "" {
		q.Type = models.Channel_TYPE_TOPIC
	}

	channel, err := models.NewChannel().ByName(q)
	if err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}

		if models.IsChannelLeafErr(err) {
			return http.StatusMovedPermanently,
				nil, nil,
				tigertonic.MovedPermanently{Err: err}
		}

		return response.NewBadRequest(err)
	}

	return handleChannelResponse(channel, q)
}
Пример #7
0
func List(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	query := context.OverrideQuery(request.GetQuery(u))

	if query.Id == 0 {
		return response.NewBadRequest(errors.New("channel id is not set"))
	}

	c, err := models.Cache.Channel.ById(query.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}

	canOpen, err := c.CanOpen(query.AccountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewAccessDenied(fmt.Errorf("user %d tried to open unattended channel %d", query.AccountId, query.Id))
	}

	return response.HandleResultAndError(
		fetchChannelParticipants(query),
	)
}
Пример #8
0
func Get(u *url.URL, h http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	cm, err := getMessageByUrl(u)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if cm.Id == 0 {
		return response.NewNotFound()
	}

	ch, err := models.Cache.Channel.ById(cm.InitialChannelId)
	if err != nil {
		response.NewBadRequest(err)
	}

	canOpen, err := ch.CanOpen(ctx.Client.Account.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewAccessDenied(models.ErrCannotOpenChannel)
	}

	cmc := models.NewChannelMessageContainer()
	return response.HandleResultAndError(cmc, cmc.Fetch(cm.Id, request.GetQuery(u)))
}
Пример #9
0
func Count(u *url.URL, h http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	// check if user logged in or not
	if !ctx.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	q := request.GetQuery(u)
	qry := ctx.OverrideQuery(q)

	query := getUserChannelsQuery(qry)

	// add exempt clause if needed
	if !q.ShowExempt {
		query = query.Where("api.channel.meta_bits = ?", models.Safe)
	}

	var count int
	query = query.Count(&count)
	if query.Error != nil {
		return response.NewBadRequest(query.Error)
	}

	res := new(models.CountResponse)
	res.TotalCount = count

	return response.NewOK(res)
}
Пример #10
0
func List(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	messageId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}
	accountId, err := request.GetURIInt64(u, "accountId")
	if err != nil {
		return response.NewBadRequest(err)
	}

	reply := models.NewMessageReply()
	reply.MessageId = messageId

	messages, err := reply.List(request.GetQuery(u))
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(
		helpers.ConvertMessagesToMessageContainers(
			messages,
			accountId,
		),
	)
}
Пример #11
0
func getMessageByUrl(u *url.URL) (*models.ChannelMessage, error) {

	// TODO
	// fmt.Println(`
	// 	------->
	//             ADD SECURTY CHECK FOR VISIBILTY OF THE MESSAGE
	//                         FOR THE REQUESTER
	//     ------->"`,
	// )

	id, err := request.GetURIInt64(u, "id")
	if err != nil {
		return nil, err
	}

	// get url query params
	q := request.GetQuery(u)

	query := &bongo.Query{
		Selector: map[string]interface{}{
			"id": id,
		},
		Pagination: *bongo.NewPagination(1, 0),
	}

	cm := models.NewChannelMessage()
	// add exempt info
	query.AddScope(models.RemoveTrollContent(cm, q.ShowExempt))

	if err := cm.One(query); err != nil {
		return nil, err
	}

	return cm, nil
}
Пример #12
0
func UpdatePresence(u *url.URL, h http.Header, participant *models.ChannelParticipant, context *models.Context) (int, http.Header, interface{}, error) {
	query := context.OverrideQuery(request.GetQuery(u))

	participant.ChannelId = query.Id
	// only requester can update their last seen date
	participant.AccountId = query.AccountId

	if err := checkChannelPrerequisites(
		query.Id,
		query.AccountId,
		[]*models.ChannelParticipant{participant},
	); err != nil {
		return response.NewBadRequest(err)
	}

	// @todo add a new function into participant just
	// for updating with lastSeenDate
	if err := participant.FetchParticipant(); err != nil {
		return response.NewBadRequest(err)
	}

	// glance the channel
	if err := participant.Glance(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(participant)
}
Пример #13
0
func RemoveMulti(u *url.URL, h http.Header, participants []*models.ChannelParticipant, context *models.Context) (int, http.Header, interface{}, error) {
	query := context.OverrideQuery(request.GetQuery(u))

	if err := checkChannelPrerequisites(
		query.Id,
		query.AccountId,
		participants,
	); err != nil {
		return response.NewBadRequest(err)
	}

	ch := models.NewChannel()
	err := ch.ById(query.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}
	if ch.TypeConstant == models.Channel_TYPE_BOT {
		return response.NewBadRequest(errors.New("can not remove participants for bot channel"))
	}

	isAdmin, err := modelhelper.IsAdmin(context.Client.Account.Nick, context.GroupName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	for i := range participants {
		// if the requester is trying to remove some other user than themselves, and they are not the channel owner
		// return bad request
		if participants[i].AccountId != query.AccountId && query.AccountId != ch.CreatorId {

			if !isAdmin {
				return response.NewBadRequest(fmt.Errorf("User is not allowed to kick other users"))
			}

		}

		participants[i].ChannelId = query.Id
		if err := participants[i].Delete(); err != nil {
			return response.NewBadRequest(err)
		}

		if err := addLeaveActivity(query.Id, query.AccountId, participants[i]); err != nil {
			return response.NewBadRequest(err)
		}
	}

	// this could be moved into another worker, but i did not want to create a new worker that will be used
	// for just a few times
	go func() {
		if err := DeleteDesertedChannelMessages(query.Id); err != nil {
			runner.MustGetLogger().Error("Could not delete channel messages: %s", err.Error())
		}
	}()

	go notifyParticipants(ch, models.ChannelParticipant_Removed_From_Channel_Event, participants)

	return response.NewOK(participants)
}
Пример #14
0
func AddMulti(u *url.URL, h http.Header, participants []*models.ChannelParticipant, context *models.Context) (int, http.Header, interface{}, error) {
	query := context.OverrideQuery(request.GetQuery(u))

	if err := checkChannelPrerequisites(
		query.Id,
		query.AccountId,
		participants,
	); err != nil {
		return response.NewBadRequest(err)
	}

	ch := models.NewChannel()
	err := ch.ById(query.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if ch.TypeConstant == models.Channel_TYPE_BOT {
		return response.NewBadRequest(errors.New("can not add participants for bot channel"))
	}

	for i := range participants {
		participant := models.NewChannelParticipant()
		participant.ChannelId = query.Id

		// prevent duplicate participant addition
		isParticipant, err := participant.IsParticipant(participants[i].AccountId)
		if err != nil {
			return response.NewBadRequest(err)
		}

		if isParticipant {
			continue
		}

		participant.AccountId = participants[i].AccountId
		//We can add users with requestpending status
		if participants[i].StatusConstant != "" {
			participant.StatusConstant = participants[i].StatusConstant
		}

		if err := participant.Create(); err != nil {
			return response.NewBadRequest(err)
		}

		participants[i] = participant

		if err := addJoinActivity(query.Id, participant, query.AccountId); err != nil {
			return response.NewBadRequest(err)
		}

	}

	go notifyParticipants(ch, models.ChannelParticipant_Added_To_Channel_Event, participants)

	return response.NewOK(participants)
}
Пример #15
0
// ListMembers lists the members of group
func ListMembers(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if err := context.IsGroupAdmin(); err != nil {
		return response.NewBadRequest(err)
	}

	query := request.GetQuery(u)
	query = context.OverrideQuery(query)
	p := &models.PresenceDaily{}
	return response.HandleResultAndError(p.FetchActiveAccounts(query))
}
Пример #16
0
// ByParticipants finds private message channels by their participants
func ByParticipants(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	// only logged in users
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	participantsStr, ok := u.Query()["id"]
	if !ok {
		return response.NewBadRequest(errors.New("participants not set"))
	}

	if len(participantsStr) == 0 {
		return response.NewBadRequest(errors.New("at least one participant is required"))
	}

	unify := make(map[string]interface{})

	// add current account to participants list
	unify[strconv.FormatInt(context.Client.Account.Id, 10)] = struct{}{}

	// remove duplicates from participants
	for i := range participantsStr {
		unify[participantsStr[i]] = struct{}{}
	}

	participants := make([]int64, 0)

	// convert strings to int64
	for participantStr := range unify {
		i, err := strconv.ParseInt(participantStr, 10, 64)
		if err != nil {
			return response.NewBadRequest(err)
		}

		participants = append(participants, i)
	}

	channels, err := models.NewChannel().ByParticipants(participants, query)
	if err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}
	}

	cc := models.NewChannelContainers().
		PopulateWith(channels, context.Client.Account.Id).
		AddLastMessage(context.Client.Account.Id).
		AddUnreadCount(context.Client.Account.Id)

	return response.HandleResultAndError(cc, cc.Err())
}
Пример #17
0
// Search searchs database against given channel name
// but only returns topic channels
func Search(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	q := request.GetQuery(u)
	q = context.OverrideQuery(q)
	if q.Type != models.Channel_TYPE_LINKED_TOPIC {
		q.Type = models.Channel_TYPE_TOPIC
	}

	channelList, err := models.NewChannel().Search(q)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return handleChannelListResponse(channelList, q)
}
Пример #18
0
func List(u *url.URL, h http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	// check if user logged in or not
	if !ctx.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}
	query := request.GetQuery(u)
	q := ctx.OverrideQuery(query)
	channelList, err := getPrivateChannels(q)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(buildContainer(channelList, q))
}
Пример #19
0
func CheckParticipation(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	q := context.OverrideQuery(request.GetQuery(u))
	if context.Client != nil && context.Client.Account != nil {
		q.AccountId = context.Client.Account.Id
	}

	if q.Type == "" || q.AccountId == 0 {
		return response.NewBadRequest(errors.New("type or accountid is not set"))
	}

	channel, err := models.NewChannel().ByName(q)
	if err != nil {
		return response.NewBadRequest(err)
	}

	res := models.NewCheckParticipationResponse()
	res.Channel = &channel
	res.Account = context.Client.Account
	if context.Client.Account != nil {
		res.AccountToken = context.Client.Account.Token
	}

	canOpen, err := channel.CanOpen(q.AccountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		cp := models.NewChannelParticipant()
		cp.ChannelId = channel.Id
		isInvited, err := cp.IsInvited(q.AccountId)
		if err != nil {
			return response.NewBadRequest(err)
		}

		if !isInvited {
			return response.NewAccessDenied(
				fmt.Errorf(
					"account (%d) tried to retrieve the unattended channel (%d)",
					q.AccountId,
					channel.Id,
				),
			)
		}
	}

	return response.NewOK(res)
}
Пример #20
0
func List(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	channelId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	c, err := models.Cache.Channel.ById(channelId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !query.ShowExempt {
		query.ShowExempt = context.Client.Account.IsTroll
	}

	// if channel is exempt and user should see the
	// content, return not found err
	if c.MetaBits.Is(models.Troll) && !query.ShowExempt {
		return response.NewNotFound()
	}

	canOpen, err := c.CanOpen(query.AccountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewAccessDenied(
			fmt.Errorf(
				"account (%d) tried to retrieve the unattended private channel (%d)",
				query.AccountId,
				c.Id,
			))
	}

	cml := models.NewChannelMessageList()
	cml.ChannelId = c.Id

	return response.HandleResultAndError(
		cml.List(query, false),
	)
}
Пример #21
0
func Update(u *url.URL, h http.Header, req *models.ChannelMessage, c *models.Context) (int, http.Header, interface{}, error) {
	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrAccessDenied)
	}

	id, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	body := req.Body
	payload := req.Payload
	if err := req.ById(id); err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}
		return response.NewBadRequest(err)
	}

	if req.AccountId != c.Client.Account.Id {
		isAdmin, err := modelhelper.IsAdmin(c.Client.Account.Nick, c.GroupName)
		if err != nil {
			return response.NewBadRequest(err)
		}

		if !isAdmin {
			return response.NewBadRequest(models.ErrAccessDenied)
		}

	}

	if req.Id == 0 {
		return response.NewBadRequest(err)
	}

	req.Body = body
	req.Payload = payload

	if err := req.Update(); err != nil {
		return response.NewBadRequest(err)
	}

	cmc := models.NewChannelMessageContainer()
	return response.HandleResultAndError(cmc, cmc.Fetch(id, request.GetQuery(u)))
}
Пример #22
0
func Get(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	id, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	q := request.GetQuery(u)
	q = context.OverrideQuery(q)

	c := models.NewChannel()
	if err := c.ById(id); err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}
		return response.NewBadRequest(err)
	}

	return handleChannelResponse(*c, q)
}
Пример #23
0
// List lists only topic channels
func List(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	c := models.NewChannel()
	q := request.GetQuery(u)

	query := context.OverrideQuery(q)
	// only list topic or linked topic channels
	if query.Type != models.Channel_TYPE_LINKED_TOPIC {
		query.Type = models.Channel_TYPE_TOPIC
	}

	// TODO
	// refactor this function just to return channel ids
	// we cache wisely
	channelList, err := c.List(query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return handleChannelListResponse(channelList, query)
}
Пример #24
0
func CheckOwnership(u *url.URL, h http.Header) (int, http.Header, interface{}, error) {
	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	query := request.GetQuery(u)

	ownershipResponse := func(err error) (int, http.Header, interface{}, error) {
		var success bool
		switch err {
		case bongo.RecordNotFound:
			success = false
		case nil:
			success = true
		default:
			return response.NewBadRequest(err)
		}
		return response.NewOK(map[string]bool{"success": success})
	}

	switch query.Type {
	case "channel":
		channel := models.NewChannel()
		err = channel.One(&bongo.Query{
			Selector: map[string]interface{}{
				"id":         query.ObjectId,
				"creator_id": accountId,
			},
		})
	case "channel-message":
		channelMessage := models.NewChannelMessage()
		err = channelMessage.One(&bongo.Query{
			Selector: map[string]interface{}{
				"id":         query.ObjectId,
				"account_id": accountId,
			},
		})
	}
	return ownershipResponse(err)
}
Пример #25
0
func GetBySlug(u *url.URL, h http.Header, _ interface{}, ctx *models.Context) (int, http.Header, interface{}, error) {
	q := request.GetQuery(u)

	if q.Slug == "" {
		return response.NewBadRequest(errors.New("slug is not set"))
	}

	cm := models.NewChannelMessage()
	if err := cm.BySlug(q); err != nil {
		if err == bongo.RecordNotFound {
			return response.NewNotFound()
		}
		return response.NewBadRequest(err)
	}

	ch := models.NewChannel()
	if err := ch.ById(cm.InitialChannelId); err != nil {
		return response.NewBadRequest(err)
	}

	query := ctx.OverrideQuery(q)

	// check if user can open
	canOpen, err := ch.CanOpen(query.AccountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewBadRequest(models.ErrCannotOpenChannel)
	}

	cmc := models.NewChannelMessageContainer()
	if err := cmc.Fetch(cm.Id, query); err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(cmc, cmc.Err)
}
Пример #26
0
func UnblockMulti(u *url.URL, h http.Header, participants []*models.ChannelParticipant, context *models.Context) (int, http.Header, interface{}, error) {
	query := context.OverrideQuery(request.GetQuery(u))

	if err := checkChannelPrerequisites(
		query.Id,
		query.AccountId,
		participants,
	); err != nil {
		return response.NewBadRequest(err)
	}

	ch := models.NewChannel()
	err := ch.ById(query.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}

	isAdmin, err := modelhelper.IsAdmin(context.Client.Account.Nick, context.GroupName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	for i := range participants {
		// if the requester is trying to remove some other user than themselves, and they are not the channel owner
		// return bad request
		if participants[i].AccountId != query.AccountId && query.AccountId != ch.CreatorId {
			if !isAdmin {
				return response.NewBadRequest(fmt.Errorf("User is not allowed to unblock other users"))
			}
		}

		participants[i].ChannelId = query.Id
		if err := participants[i].Unblock(); err != nil {
			return response.NewBadRequest(err)
		}
	}

	return response.NewOK(participants)
}
Пример #27
0
func RejectInvite(u *url.URL, h http.Header, participant *models.ChannelParticipant, ctx *models.Context) (int, http.Header, interface{}, error) {

	query := ctx.OverrideQuery(request.GetQuery(u))
	participant.StatusConstant = models.ChannelParticipant_STATUS_LEFT
	cp, err := updateStatus(participant, query, ctx)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if err := addLeaveActivity(query.Id, ctx.Client.Account.Id, cp); err != nil {
		return response.NewBadRequest(err)
	}

	ch := models.NewChannel()

	if err := ch.ById(query.Id); err != nil {
		return response.NewBadRequest(err)
	}

	go notifyParticipants(ch, models.ChannelParticipant_Removed_From_Channel_Event, []*models.ChannelParticipant{cp})

	return response.NewDefaultOK()
}
Пример #28
0
func AcceptInvite(u *url.URL, h http.Header, participant *models.ChannelParticipant, ctx *models.Context) (int, http.Header, interface{}, error) {

	query := ctx.OverrideQuery(request.GetQuery(u))

	participant.StatusConstant = models.ChannelParticipant_STATUS_ACTIVE
	cp, err := updateStatus(participant, query, ctx)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if err := addJoinActivity(query.Id, cp, 0); err != nil {
		return response.NewBadRequest(err)
	}

	ch := models.NewChannel()
	if err := ch.ById(query.Id); err != nil {
		return response.NewBadRequest(err)
	}

	go notifyParticipants(ch, models.ChannelParticipant_Added_To_Channel_Event, []*models.ChannelParticipant{cp})

	return response.NewDefaultOK()
}
Пример #29
0
// this is a TEMP function just for @usirin
func TempList(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	channelId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	c, err := models.Cache.Channel.ById(channelId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// if channel is exempt and user should see the
	// content, return not found err
	if !query.ShowExempt {
		query.ShowExempt = context.Client.Account.IsTroll
	}

	if c.MetaBits.Is(models.Troll) && !query.ShowExempt {
		return response.NewNotFound()
	}

	// check if channel is accessible by the requester
	canOpen, err := c.CanOpen(query.AccountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewAccessDenied(
			fmt.Errorf(
				"account (%d) tried to retrieve the unattended private channel (%d)",
				query.AccountId,
				c.Id,
			))
	}

	bq := &bongo.Query{
		Selector: map[string]interface{}{
			"initial_channel_id": c.Id,
		},
		Pagination: *bongo.NewPagination(query.Limit, query.Skip),
		Pluck:      "id",
	}

	bq.AddScope(models.SortedByCreatedAt)
	bq.AddScope(models.RemoveTrollContent(c, query.ShowExempt))
	bq.AddScope(models.ExcludeFields(query.Exclude))
	bq.AddScope(models.TillTo(query.From))

	bqq := bongo.B.BuildQuery(models.NewChannelMessage(), bq)
	var messages []int64
	if err := bongo.CheckErr(
		bqq.Pluck(bq.Pluck, &messages),
	); err != nil {
		return response.NewBadRequest(err)
	}

	// get the messages in regarding channel
	cmcs, err := models.
		NewChannelMessageList().
		PopulateChannelMessages(
			messages, query,
		)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// reduce replies
	replyIds := make([]int64, 0)
	for i := range cmcs {
		cmc := cmcs[i]
		if cmc.Message.TypeConstant == models.ChannelMessage_TYPE_REPLY {
			replyIds = append(replyIds, cmc.Message.Id)
		}
	}

	if len(replyIds) == 0 {
		return response.NewOK(cmcs)
	}

	// select replies
	var mrs []models.MessageReply
	gerr := bongo.B.
		BuildQuery(models.NewMessageReply(), &bongo.Query{}).
		Where("reply_id in (?)", replyIds).
		Find(&mrs)

	if err := bongo.CheckErr(gerr); err != nil {
		return response.NewBadRequest(err)
	}

	// set their parent ids
	for j, mr := range mrs {
		for i := range cmcs {
			if mr.ReplyId == cmcs[i].Message.Id {
				cmcs[i].ParentID = mrs[j].MessageId
			}
		}
	}

	// send response
	return response.NewOK(cmcs)
}
Пример #30
0
func Create(u *url.URL, h http.Header, req *models.ChannelMessage, c *models.Context) (int, http.Header, interface{}, error) {

	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrAccessDenied)
	}

	channelId, err := fetchInitialChannelId(u, c)
	if err != nil {
		return response.NewBadRequest(err)
	}

	ch := models.NewChannel()
	if err := ch.ById(channelId); err != nil {
		return response.NewBadRequest(models.ErrChannelNotFound)
	}

	canOpen, err := ch.CanOpen(c.Client.Account.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewBadRequest(models.ErrCannotOpenChannel)
	}

	// override message type
	// all of the messages coming from client-side
	// should be marked as POST
	req.TypeConstant = models.ChannelMessage_TYPE_POST

	req.InitialChannelId = channelId

	req.AccountId = c.Client.Account.Id

	if req.Payload == nil {
		req.Payload = gorm.Hstore{}
	}

	if c.Client.Account.IsShareLocationEnabled() {
		// gets the IP of the Client
		// and adds it to the payload of the ChannelMessage
		location := parseLocation(c)
		req.Payload["location"] = location
	}

	if err := checkThrottle(channelId, req.AccountId); err != nil {
		return response.NewBadRequest(err)
	}

	if err := req.Create(); err != nil {
		// todo this should be internal server error
		return response.NewBadRequest(err)
	}

	cml := models.NewChannelMessageList()
	// override channel id
	cml.ChannelId = channelId
	cml.MessageId = req.Id
	cml.ClientRequestId = req.ClientRequestId
	if err := cml.Create(); err != nil && !models.IsUniqueConstraintError(err) {
		// todo this should be internal server error
		return response.NewBadRequest(err)
	}

	cmc := models.NewChannelMessageContainer()
	err = cmc.Fetch(req.Id, request.GetQuery(u))
	if err != nil {
		return response.NewBadRequest(err)
	}

	// assign client request id back to message response because
	// client uses it for latency compansation
	cmc.Message.ClientRequestId = req.ClientRequestId
	return response.HandleResultAndError(cmc, err)
}