// HandleChannel handles channel operations func (c *Controller) HandleChannel(channel *models.Channel) error { if channel.TypeConstant != models.Channel_TYPE_GROUP { return nil } chans, err := channel.FetchAllChannelsOfGroup() if err != nil { return err } var errs *multierror.Error for _, ch := range chans { // we'r gonna innore all `not found` errors while deleting datas if err := ch.Delete(); err != nil && err != bongo.RecordNotFound { errs = multierror.Append(errs, err) } if err := ch.DeleteChannelParticipants(); err != nil { return err } } if errs.ErrorOrNil() != nil { return errs } return nil }
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) }
// makeSureMembership checks if the incoming account is a member of the group // channel that is persisted within incoming session data func makeSureMembership(groupChannel *models.Channel, accountId int64) error { isMember, err := models.Cache.Participant.ByChannelIdAndAccountId(groupChannel.Id, accountId) if err != nil { return err } // we dont need to do anything if the user is a member of group channel if isMember { return nil } _, err = groupChannel.AddParticipant(accountId) if err != nil && err != models.ErrAccountIsAlreadyInTheChannel { return err } return models.Cache.Participant.SetToCache(groupChannel.Id, accountId) }
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) }
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) }
func (f *Controller) fetchNotifiedParticipantIds(c *models.Channel, pe *models.ParticipantEvent, eventName string) ([]int64, error) { notifiedParticipantIds := make([]int64, 0) // notify added/removed participants for _, participant := range pe.Participants { notifiedParticipantIds = append(notifiedParticipantIds, participant.AccountId) } // When a user is removed from a private channel notify all channel participants to // make them update their sidebar channel list. if eventName == RemovedFromChannelEventName { if c.TypeConstant == models.Channel_TYPE_PRIVATE_MESSAGE || c.TypeConstant == models.Channel_TYPE_COLLABORATION { participantIds, err := c.FetchParticipantIds(&request.Query{}) if err != nil { return notifiedParticipantIds, err } notifiedParticipantIds = append(notifiedParticipantIds, participantIds...) } } return notifiedParticipantIds, nil }
func Delete(u *url.URL, h http.Header, req *models.Channel, context *models.Context) (int, http.Header, interface{}, error) { if !context.IsLoggedIn() { return response.NewBadRequest(models.ErrNotLoggedIn) } id, err := request.GetURIInt64(u, "id") if err != nil { return response.NewBadRequest(err) } if err := req.ById(id); err != nil { return response.NewBadRequest(err) } if req.TypeConstant == models.Channel_TYPE_GROUP { return response.NewBadRequest(errors.New("You can not delete group channel")) } canOpen, err := req.CanOpen(context.Client.Account.Id) if err != nil { return response.NewBadRequest(err) } if !canOpen { return response.NewBadRequest(models.ErrCannotOpenChannel) } // TO-DO // add super-admin check here if req.CreatorId != context.Client.Account.Id { isAdmin, err := modelhelper.IsAdmin(context.Client.Account.Nick, req.GroupName) if err != nil { return response.NewBadRequest(err) } if !isAdmin { return response.NewAccessDenied(models.ErrAccessDenied) } } if err := req.Delete(); err != nil { return response.NewBadRequest(err) } // yes it is deleted but not removed completely from our system return response.NewDeleted() }