Пример #1
0
func (db *roomDb) SetRoomState(roomId types.RoomId, userId types.UserId, content types.TypedContent, stateKey string) (*matrixTypes.State, matrixTypes.Error) {
	db.roomsLock.RLock()
	defer db.roomsLock.RUnlock()
	room := db.rooms[roomId]
	if room == nil {
		return nil, matrixTypes.NotFoundError("room '" + roomId.String() + "' doesn't exist")
	}
	var eventId = types.DeriveEventId(utils.RandomString(16), types.Id(userId))
	stateId := stateId{content.GetEventType(), stateKey}

	state := new(matrixTypes.State)
	state.EventId = eventId
	state.RoomId = roomId
	state.UserId = userId
	state.EventType = content.GetEventType()
	state.StateKey = stateKey
	state.Timestamp = types.Timestamp{time.Now()}
	state.Content = content
	state.OldState = (*matrixTypes.OldState)(room.states[stateId])

	room.stateLock.Lock()
	defer room.stateLock.Unlock()
	room.states[stateId] = state

	return state, nil
}
Пример #2
0
func (s roomService) sendMessage(
	room ct.RoomId,
	user ct.UserId,
	content ct.TypedContent,
) (*types.Message, types.Error) {
	log.Printf("Sending message: %#v, %#v, %#v, %#v", room, user, content)

	message := new(types.Message)
	message.EventId = ct.DeriveEventId(utils.RandomString(16), ct.Id(user))
	message.RoomId = room
	message.UserId = user
	message.EventType = content.GetEventType()
	message.Timestamp = ct.Timestamp{time.Now()}
	message.Content = content

	_, err := s.eventSink.Send(message)
	if err != nil {
		return nil, err
	}
	return message, nil
}
Пример #3
0
func (s roomService) AddMessage(
	room ct.RoomId,
	caller ct.UserId,
	content ct.TypedContent,
) (*types.Message, types.Error) {
	eventType := content.GetEventType()
	if _, ok := disallowedMessageTypes[eventType]; ok {
		return nil, types.ForbiddenError("sending a message event of the type " + eventType + " is not permitted")
	}

	err := s.testPowerLevel(room, caller, func(pl *types.PowerLevelsEventContent) int {
		if eventLevel, ok := pl.Events[eventType]; ok {
			return eventLevel
		}
		return pl.EventDefault
	})
	if err != nil {
		return nil, err
	}

	return s.sendMessage(room, caller, content)
}
Пример #4
0
func (s roomService) SetState(
	room ct.RoomId,
	caller ct.UserId,
	content ct.TypedContent,
	stateKey string,
) (*types.State, types.Error) {
	userIdStateKey, parseErr := ct.ParseUserId(stateKey)
	isUserIdStateKey := parseErr == nil

	eventType := content.GetEventType()
	switch eventType {
	case types.EventTypeName:
		if stateKey != "" {
			return nil, types.ForbiddenError("state key must be empty for state " + eventType)
		}
	case types.EventTypeTopic:
		if stateKey != "" {
			return nil, types.ForbiddenError("state key must be empty for state " + eventType)
		}
	case types.EventTypeJoinRules:
		if stateKey != "" {
			return nil, types.ForbiddenError("state key must be empty for state " + eventType)
		}
	case types.EventTypePowerLevels:
		if stateKey != "" {
			return nil, types.ForbiddenError("state key must be empty for state " + eventType)
		}
	case types.EventTypeCreate:
		return nil, types.ForbiddenError("cannot set state " + eventType)

	case types.EventTypeAliases:
		return nil, types.ForbiddenError("cannot set state " + eventType)

	case types.EventTypeMembership:
		membership, ok := content.(*types.MembershipEventContent)
		if !ok || membership == nil {
			panic("expected membership event content, got " + reflect.TypeOf(content).String())
		}
		if !isUserIdStateKey {
			return nil, types.ForbiddenError("state key must be a user id for state " + eventType)
		}
		state, err := s.doMembershipChange(room, caller, userIdStateKey, membership)
		if err != nil {
			return nil, err
		}
		return state, nil
	}
	if isUserIdStateKey && userIdStateKey != caller {
		return nil, types.ForbiddenError("cannot set the state of another user")
	}

	existing, err := s.rooms.RoomState(room, eventType, stateKey)
	if err != nil {
		return nil, err
	}
	if existing != nil {
		err := s.testPowerLevel(room, caller, func(pl *types.PowerLevelsEventContent) int {
			return pl.CreateState
		})
		if err != nil {
			return nil, err
		}
	}
	err = s.testPowerLevel(room, caller, func(pl *types.PowerLevelsEventContent) int {
		if eventLevel, ok := pl.Events[eventType]; ok {
			return eventLevel
		}
		return pl.EventDefault
	})
	if err != nil {
		return nil, err
	}
	return s.setState(room, caller, content, stateKey)
}