Exemple #1
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)
}
Exemple #2
0
// IsGroupAdmin checks if the current context is the admin of the context's
// group.
// mongo connection is required.
func (c *Context) IsGroupAdmin() error {
	if !c.IsLoggedIn() {
		return ErrNotLoggedIn
	}

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

	if !isAdmin {
		return ErrNotAdmin
	}

	return nil
}
Exemple #3
0
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()
}
Exemple #4
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)))
}
Exemple #5
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)
}
Exemple #6
0
func Delete(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	if !c.IsLoggedIn() {
		return response.NewAccessDenied(models.ErrNotLoggedIn)
	}

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

	if id == 0 {
		return response.NewBadRequest(models.ErrMessageIdIsNotSet)
	}

	cm := models.NewChannelMessage()
	cm.Id = id

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

	// Add isAdmin checking
	// is user is admin, then can delete another user's message
	if cm.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 this is a reply no need to delete it's replies
	if cm.TypeConstant == models.ChannelMessage_TYPE_REPLY {
		mr := models.NewMessageReply()
		mr.ReplyId = id
		parent, err := mr.FetchParent()
		if err != nil {
			return response.NewBadRequest(err)
		}

		// delete the message here
		err = cm.DeleteMessageAndDependencies(false)
		// then invalidate the cache of the parent message
		bongo.B.AddToCache(parent)

	} else {
		err = cm.DeleteMessageAndDependencies(true)
	}

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

	// yes it is deleted but not removed completely from our system
	return response.NewDeleted()
}
Exemple #7
0
func (k *Kloud) authorizedKlient(r *kite.Request) (*klient.Klient, error) {
	if r.Args == nil {
		return nil, NewError(ErrNoArguments)
	}

	var args *AdminRequest
	if err := r.Args.One().Unmarshal(&args); err != nil {
		return nil, err
	}

	if args.MachineId == "" {
		return nil, errors.New("machineId is not passed")
	}

	if args.GroupName == "" {
		return nil, errors.New("groupName is not passed")
	}

	k.Log.Debug("Got arguments %+v for method: %s", args, r.Method)

	isAdmin, err := modelhelper.IsAdmin(r.Username, args.GroupName)
	if err != nil {
		return nil, err
	}

	if !isAdmin {
		return nil, fmt.Errorf("User '%s' is not an admin of group '%s'", r.Username, args.GroupName)
	}

	k.Log.Debug("User '%s' is an admin. Checking for machine permission", r.Username)

	machine, err := modelhelper.GetMachine(args.MachineId)
	if err != nil {
		return nil, fmt.Errorf("getMachine(%s) err: %s", args.MachineId, err)
	}

	g, err := modelhelper.GetGroup(args.GroupName)
	if err != nil {
		return nil, err
	}

	isGroupMember := false
	for _, group := range machine.Groups {
		if group.Id.Hex() == g.Id.Hex() {
			isGroupMember = true
		}
	}
	if !isGroupMember {
		return nil, fmt.Errorf("'%s' machine does not belong to '%s' group",
			args.MachineId, args.GroupName)
	}

	k.Log.Debug("Incoming user is authorized, setting up DB and Klient connection")

	// Now we are ready to go.
	ctx := request.NewContext(context.Background(), r)
	ctx = k.ContextCreator(ctx)
	sess, ok := session.FromContext(ctx)
	if !ok {
		return nil, errors.New("internal server error (err: session context is not available)")
	}

	k.Log.Debug("Calling Klient method: %s", r.Method)
	return klient.NewWithTimeout(sess.Kite, machine.QueryString, time.Second*10)
}