Пример #1
0
// HasCreditCard returns the existance status of group's credit card
func HasCreditCard(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	group, err := modelhelper.GetGroup(context.GroupName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if group.Payment.Customer.ID == "" {
		return response.NewNotFound()
	}

	err = payment.CheckCustomerHasSource(group.Payment.Customer.ID)
	if err == payment.ErrCustomerSourceNotExists {
		return response.NewNotFound()
	}

	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewDefaultOK()
}
Пример #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
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)
}
Пример #4
0
func (s *SneakerS3) Get(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	pathName := u.Query().Get("pathName")

	logger := s.createLogger(context, "Get", pathName, http.StatusBadRequest)
	if pathName == "" {
		return response.NewBadRequestWithLogger(logger, ErrPathNotFound)
	}

	if !context.IsLoggedIn() {
		return response.NewBadRequestWithLogger(logger, models.ErrNotLoggedIn)
	}

	downArray := []string{pathName}
	down, err := s.Manager.Download(downArray)
	if err != nil {
		return response.NewBadRequestWithLogger(logger, err)
	}

	if down[pathName] == nil {
		return response.NewBadRequestWithLogger(logger, ErrPathContentNotFound)
	}

	var kv KeyValue

	downX := bytes.NewReader(down[pathName])
	if err := json.NewDecoder(downX).Decode(&kv); err != nil {
		return response.NewBadRequestWithLogger(logger, err)
	}

	logger = s.createLogger(context, "Get", pathName, http.StatusOK)
	logger.Info("")

	return response.NewOK(kv)
}
Пример #5
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),
	)
}
Пример #6
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)
}
Пример #7
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)
}
Пример #8
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)
}
Пример #9
0
func updateStatus(participant *models.ChannelParticipant, query *request.Query, ctx *models.Context) (*models.ChannelParticipant, error) {

	if ok := ctx.IsLoggedIn(); !ok {
		return nil, models.ErrNotLoggedIn
	}

	query.AccountId = ctx.Client.Account.Id

	cp := models.NewChannelParticipant()
	cp.ChannelId = query.Id

	// check if the user is invited
	isInvited, err := cp.IsInvited(query.AccountId)
	if err != nil {
		return nil, err
	}

	if !isInvited {
		return nil, errors.New("uninvited user error")
	}

	cp.StatusConstant = participant.StatusConstant
	// update the status
	if err := cp.Update(); err != nil {
		return nil, err
	}

	return cp, nil
}
Пример #10
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))
}
Пример #11
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),
	)
}
Пример #12
0
func (h *Handler) GetToken(u *url.URL, header http.Header, req *socialapimodels.Account, context *socialapimodels.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(socialapimodels.ErrNotLoggedIn)
	}

	return responseWithCookie(req, context.Client.Account.Token)
}
Пример #13
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())
}
Пример #14
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)
}
Пример #15
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)
}
Пример #16
0
// CreateSubscription creates the subscription of group
func CreateSubscription(u *url.URL, h http.Header, params *stripe.SubParams, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	return response.HandleResultAndError(
		payment.EnsureSubscriptionForGroup(context.GroupName, params),
	)
}
Пример #17
0
// GetCustomer returns the customer info of a group
func GetCustomer(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)
	}

	return response.HandleResultAndError(
		payment.GetCustomerForGroup(context.GroupName),
	)
}
Пример #18
0
// createLogger creates the log system for sneaker S3 storage
func (s *SneakerS3) createLogger(context *models.Context, reqType, keyPath string, statusCode int) logging.Logger {
	ctx := s.log.New("SneakerS3")

	if context.IsLoggedIn() {
		return ctx.New("IP", context.Client.IP, "requester", context.Client.Account.Nick, "operation", reqType, "key path", keyPath, "status code", statusCode)
	} else {
		return ctx.New("operation", reqType, "key path", keyPath, "status code", statusCode)
	}
}
Пример #19
0
// GetSubscription gets the subscription of group
func GetSubscription(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	return response.HandleResultAndError(
		payment.GetSubscriptionForGroup(context.GroupName),
	)
}
Пример #20
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)
}
Пример #21
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))
}
Пример #22
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())
}
Пример #23
0
// DeleteCreditCard deletes the credit card of a group
func DeleteCreditCard(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)
	}

	if err := payment.DeleteCreditCardForGroup(context.GroupName); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewDefaultOK()
}
Пример #24
0
// PostMessage posts a message to a slack channel/group
func (s *Slack) PostMessage(u *url.URL, h http.Header, req *SlackMessageRequest, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}
	return response.HandleResultAndError(postMessage(token, req))
}
Пример #25
0
func Send(u *url.URL, h http.Header, req *models.ChannelRequest, ctx *models.Context) (int, http.Header, interface{}, error) {
	// check if user logged in or not
	if !ctx.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	req.AccountId = ctx.Client.Account.Id
	req.GroupName = ctx.GroupName

	return response.HandleResultAndError(req.Send())
}
Пример #26
0
// TeamInfo shows basic info regarding a slack team
func (s *Slack) TeamInfo(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getTeamInfo(token))
}
Пример #27
0
func Unfollow(u *url.URL, h http.Header, req *models.Account, context *models.Context) (int, http.Header, interface{}, error) {
	targetId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

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

	return response.HandleResultAndError(req.Unfollow(targetId))
}
Пример #28
0
// CreateCustomer creates the customer for a group
func CreateCustomer(u *url.URL, h http.Header, req *stripe.CustomerParams, context *models.Context) (int, http.Header, interface{}, error) {
	if err := context.IsGroupAdmin(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(
		payment.EnsureCustomerForGroup(
			context.Client.Account.Nick,
			context.GroupName,
			req,
		),
	)
}
Пример #29
0
// Ping handles the pings coming from client side
func Ping(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	// only logged in users can send a ping
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	req := &presence.Ping{
		GroupName: context.GroupName,
		AccountID: context.Client.Account.Id, // if client is logged in, those values are all set
	}

	return handlePing(u, h, req)
}
Пример #30
0
// Info return usage info for a group
func Info(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)
	}

	group, err := modelhelper.GetGroup(context.GroupName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(
		payment.EnsureInfoForGroup(group, context.Client.Account.Nick),
	)
}