Example #1
0
func (s *session) handleSendCommand(cmd *proto.SendCommand) *response {
	if s.Identity().Name() == "" {
		return &response{err: fmt.Errorf("you must choose a name before you may begin chatting")}
	}

	if len(cmd.Content) > proto.MaxMessageLength {
		return &response{err: proto.ErrMessageTooLong}
	}

	msgID, err := snowflake.New()
	if err != nil {
		return &response{err: err}
	}

	var isValidParent bool
	if s.managedRoom != nil {
		isValidParent, err = s.managedRoom.IsValidParent(cmd.Parent)
	} else {
		isValidParent, err = s.room.IsValidParent(cmd.Parent)
	}
	if err != nil {
		return &response{err: err}
	}
	if !isValidParent {
		return &response{err: proto.ErrInvalidParent}
	}
	msg := proto.Message{
		ID:      msgID,
		Content: cmd.Content,
		Parent:  cmd.Parent,
		Sender:  s.View(proto.Host),
	}

	if s.keyID != "" {
		key := s.client.Authorization.MessageKeys[s.keyID]
		if err := proto.EncryptMessage(&msg, s.keyID, key); err != nil {
			return &response{err: err}
		}
	}

	sent, err := s.room.Send(s.ctx, s, msg)
	if err != nil {
		return &response{err: err}
	}

	if s.privilegeLevel() == proto.General {
		sent.Sender.ClientAddress = ""
	}

	packet, err := proto.DecryptPayload(proto.SendReply(sent), &s.client.Authorization, s.privilegeLevel())
	return &response{
		packet: packet,
		err:    err,
		cost:   10,
	}
}
Example #2
0
func (s *session) handleSendCommand(cmd *proto.SendCommand) *response {
	if s.Identity().Name() == "" {
		return &response{err: fmt.Errorf("you must choose a name before you may begin chatting")}
	}

	msgID, err := snowflake.New()
	if err != nil {
		return &response{err: err}
	}

	isValidParent, err := s.room.IsValidParent(cmd.Parent)
	if err != nil {
		return &response{err: err}
	}
	if !isValidParent {
		return &response{err: proto.ErrInvalidParent}
	}
	msg := proto.Message{
		ID:      msgID,
		Content: cmd.Content,
		Parent:  cmd.Parent,
		Sender:  s.View(),
	}

	if s.keyID != "" {
		key := s.client.Authorization.MessageKeys[s.keyID]
		if err := proto.EncryptMessage(&msg, s.keyID, key); err != nil {
			return &response{err: err}
		}
	}

	sent, err := s.room.Send(s.ctx, s, msg)
	if err != nil {
		return &response{err: err}
	}

	packet, err := proto.DecryptPayload(proto.SendReply(sent), &s.client.Authorization)
	return &response{
		packet: packet,
		err:    err,
		cost:   10,
	}
}
Example #3
0
func TestDeleteMessage(t *testing.T) {
	ctx := scope.New()
	kms := security.LocalKMS()
	kms.SetMasterKey(make([]byte, security.AES256.KeySize()))
	session := mock.TestSession("test", "T1", "ip1")

	sendMessage := func(room proto.Room) (proto.Message, error) {
		msg := proto.Message{
			Sender: proto.SessionView{
				SessionID:    "test",
				IdentityView: proto.IdentityView{ID: "test"},
			},
			Content: "test",
		}

		if managedRoom, ok := room.(proto.ManagedRoom); ok {
			key, err := managedRoom.MessageKey(ctx)
			if err != nil {
				return proto.Message{}, err
			}

			if key != nil {
				mkey := key.ManagedKey()
				if err := kms.DecryptKey(&mkey); err != nil {
					return proto.Message{}, err
				}
				if err := proto.EncryptMessage(&msg, key.KeyID(), &mkey); err != nil {
					return proto.Message{}, err
				}
			}
		}

		return room.Send(ctx, session, msg)
	}

	Convey("Delete message in public room", t, func() {
		ctrl := &Controller{
			backend: &mock.TestBackend{},
			kms:     kms,
		}
		term := &testTerm{}

		public, err := ctrl.backend.CreateRoom(ctx, kms, false, "public")
		So(err, ShouldBeNil)
		sent, err := sendMessage(public)
		So(err, ShouldBeNil)

		runCommand(ctx, ctrl, "delete-message", term, []string{"public:" + sent.ID.String()})

		deleted, err := public.GetMessage(ctx, sent.ID)
		So(err, ShouldBeNil)
		So(time.Time(deleted.Deleted).IsZero(), ShouldBeFalse)
	})

	Convey("Delete message in private room", t, func() {
		ctrl := &Controller{
			backend: &mock.TestBackend{},
			kms:     kms,
		}
		term := &testTerm{}

		private, err := ctrl.backend.CreateRoom(ctx, kms, true, "private")
		So(err, ShouldBeNil)
		runCommand(ctx, ctrl, "lock-room", term, []string{"private"})

		sent, err := sendMessage(private)
		So(err, ShouldBeNil)

		runCommand(ctx, ctrl, "delete-message", term, []string{"private:" + sent.ID.String()})

		deleted, err := private.GetMessage(ctx, sent.ID)
		So(err, ShouldBeNil)
		So(time.Time(deleted.Deleted).IsZero(), ShouldBeFalse)
	})
}