Beispiel #1
0
func Update(u *url.URL, h http.Header, req *models.Channel, c *models.Context) (int, http.Header, interface{}, error) {
	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

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

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

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

	participant, err := existingOne.IsParticipant(c.Client.Account.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}
	if !participant {
		return response.NewBadRequest(models.ErrAccountIsNotParticipant)
	}

	// if user is participant in the channel, then user can update only purpose of the channel
	// other fields cannot be updated by participant or anyone else. Only creator can update
	// purpose and other fields of the channel
	if participant {
		if req.Purpose != "" {
			existingOne.Purpose = req.Purpose
		}
	}

	// if user is the creator of the channel, then can update all fields of the channel
	if existingOne.CreatorId == c.Client.Account.Id {
		if req.Name != "" {
			existingOne.Name = req.Name
		}

		// some of the channels stores sparse data
		existingOne.Payload = req.Payload
	}

	// update channel
	if err := existingOne.Update(); err != nil {
		return response.NewBadRequest(err)
	}

	// generate container data
	cc := models.NewChannelContainer()
	if err := cc.PopulateWith(*existingOne, c.Client.Account.Id); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(cc)
}
Beispiel #2
0
// notifyParticipants notifies related participants when they join/leave private channel
// or follow/unfollow a topic.
// this is used for updating sidebar.
func (f *Controller) notifyChannelParticipants(c *models.Channel, pe *models.ParticipantEvent, eventName string) {
	if c.TypeConstant != models.Channel_TYPE_PRIVATE_MESSAGE &&
		c.TypeConstant != models.Channel_TYPE_COLLABORATION &&
		c.TypeConstant != models.Channel_TYPE_TOPIC {
		return
	}

	notifiedParticipantIds, err := f.fetchNotifiedParticipantIds(c, pe, eventName)
	if err != nil {
		f.log.Error("Could not fetch participants: %s", err)
		return
	}

	for _, participantId := range notifiedParticipantIds {
		cc := models.NewChannelContainer()
		err = cc.PopulateWith(*c, participantId)
		if err != nil {
			f.log.Error("Could not create channel container for participant %d: %s", pe.Id, err)
			continue
		}

		if err = f.sendNotification(
			participantId,
			c.GroupName,
			eventName,
			cc,
		); err != nil {
			f.log.Error("Ignoring err %s ", err.Error())
		}
	}
}
Beispiel #3
0
func GetChannelContainer(id int64) (*models.ChannelContainer, error) {
	url := fmt.Sprintf("/channel/%d", id)
	cc := models.NewChannelContainer()
	cmI, err := sendModel("GET", url, cc)
	if err != nil {
		return nil, err
	}

	return cmI.(*models.ChannelContainer), nil
}
Beispiel #4
0
func GetChannelContainerWithToken(id int64, token string) (*models.ChannelContainer, error) {
	url := fmt.Sprintf("/channel/%d", id)
	cc := models.NewChannelContainer()
	cmI, err := sendModelWithAuth("GET", url, cc, token)
	if err != nil {
		return nil, err
	}

	return cmI.(*models.ChannelContainer), nil
}
Beispiel #5
0
func SendPrivateChannelRequest(pmr models.ChannelRequest, token string) (*models.ChannelContainer, error) {
	url := "/privatechannel/init"
	res, err := marshallAndSendRequestWithAuth("POST", url, pmr, token)
	if err != nil {
		return nil, err
	}

	model := models.NewChannelContainer()
	err = json.Unmarshal(res, model)
	if err != nil {
		return nil, err
	}

	return model, nil
}
Beispiel #6
0
func UpdateChannel(cm *models.Channel, token string) (*models.Channel, error) {
	url := fmt.Sprintf("/channel/%d/update", cm.Id)

	res, err := marshallAndSendRequestWithAuth("POST", url, cm, token)
	if err != nil {
		return nil, err
	}

	cc := models.NewChannelContainer()
	err = json.Unmarshal(res, cc)
	if err != nil {
		return nil, err
	}

	return cc.Channel, nil
}
Beispiel #7
0
func Create(u *url.URL, h http.Header, req *models.Channel, context *models.Context) (int, http.Header, interface{}, error) {
	// only logged in users can create a channel
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	// get group name from context
	req.GroupName = context.GroupName
	req.CreatorId = context.Client.Account.Id

	if req.PrivacyConstant == "" {
		req.PrivacyConstant = models.Channel_PRIVACY_PRIVATE

		// if group is koding, then make it public, because it was public before
		if req.GroupName == models.Channel_KODING_NAME {
			req.PrivacyConstant = models.Channel_PRIVACY_PUBLIC
		}
	}

	if req.TypeConstant == "" {
		req.TypeConstant = models.Channel_TYPE_TOPIC
	}

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

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

	if _, err := req.AddParticipant(req.CreatorId); err != nil {
		// channel create works as idempotent, that channel might have been created before
		if err != models.ErrAccountIsAlreadyInTheChannel {
			return response.NewBadRequest(err)
		}
	}

	cc := models.NewChannelContainer()
	if err := cc.PopulateWith(*req, context.Client.Account.Id); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(cc)
}
Beispiel #8
0
func handleChannelResponse(c models.Channel, q *request.Query) (int, http.Header, interface{}, error) {
	// add troll mode filter
	if c.MetaBits.Is(models.Troll) && !q.ShowExempt {
		return response.NewNotFound()
	}

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

	if !canOpen {
		cp := models.NewChannelParticipant()
		cp.ChannelId = c.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,
					c.Id,
				),
			)
		}
	}

	cc := models.NewChannelContainer()

	if err := cc.Fetch(c.GetId(), q); err != nil {
		return response.NewBadRequest(err)
	}

	cc.AddIsParticipant(q.AccountId)

	// TODO this should be in the channel cache by default
	cc.AddLastMessage(q.AccountId)
	cc.AddUnreadCount(q.AccountId)
	return response.HandleResultAndError(cc, cc.Err)
}
Beispiel #9
0
func CreateChannelByGroupNameAndType(creatorId int64, groupName, typeConstant, token string) (*models.Channel, error) {
	c := models.NewChannel()
	c.GroupName = groupName
	c.CreatorId = creatorId
	c.TypeConstant = typeConstant
	c.PrivacyConstant = models.Channel_PRIVACY_PUBLIC
	c.Name = c.Name + strconv.Itoa(rand.Intn(100000000))
	res, err := marshallAndSendRequestWithAuth("POST", "/channel", c, token)
	if err != nil {
		return nil, err
	}

	cc := models.NewChannelContainer()
	err = json.Unmarshal(res, cc)
	if err != nil {
		return nil, err
	}

	return cc.Channel, nil
}