1// Copyright 2017 Vector Creations Ltd 2// Copyright 2018 New Vector Ltd 3// Copyright 2019-2020 The Matrix.org Foundation C.I.C. 4// 5// Licensed under the Apache License, Version 2.0 (the "License"); 6// you may not use this file except in compliance with the License. 7// You may obtain a copy of the License at 8// 9// http://www.apache.org/licenses/LICENSE-2.0 10// 11// Unless required by applicable law or agreed to in writing, software 12// distributed under the License is distributed on an "AS IS" BASIS, 13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14// See the License for the specific language governing permissions and 15// limitations under the License. 16 17package api 18 19import ( 20 "encoding/json" 21 "fmt" 22 "strings" 23 24 "github.com/matrix-org/dendrite/clientapi/auth/authtypes" 25 "github.com/matrix-org/gomatrixserverlib" 26) 27 28// QueryLatestEventsAndStateRequest is a request to QueryLatestEventsAndState 29type QueryLatestEventsAndStateRequest struct { 30 // The room ID to query the latest events for. 31 RoomID string `json:"room_id"` 32 // The state key tuples to fetch from the room current state. 33 // If this list is empty or nil then *ALL* current state events are returned. 34 StateToFetch []gomatrixserverlib.StateKeyTuple `json:"state_to_fetch"` 35} 36 37// QueryLatestEventsAndStateResponse is a response to QueryLatestEventsAndState 38// This is used when sending events to set the prev_events, auth_events and depth. 39// It is also used to tell whether the event is allowed by the event auth rules. 40type QueryLatestEventsAndStateResponse struct { 41 // Does the room exist? 42 // If the room doesn't exist this will be false and LatestEvents will be empty. 43 RoomExists bool `json:"room_exists"` 44 // The room version of the room. 45 RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` 46 // The latest events in the room. 47 // These are used to set the prev_events when sending an event. 48 LatestEvents []gomatrixserverlib.EventReference `json:"latest_events"` 49 // The state events requested. 50 // This list will be in an arbitrary order. 51 // These are used to set the auth_events when sending an event. 52 // These are used to check whether the event is allowed. 53 StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"` 54 // The depth of the latest events. 55 // This is one greater than the maximum depth of the latest events. 56 // This is used to set the depth when sending an event. 57 Depth int64 `json:"depth"` 58} 59 60// QueryStateAfterEventsRequest is a request to QueryStateAfterEvents 61type QueryStateAfterEventsRequest struct { 62 // The room ID to query the state in. 63 RoomID string `json:"room_id"` 64 // The list of previous events to return the events after. 65 PrevEventIDs []string `json:"prev_event_ids"` 66 // The state key tuples to fetch from the state. If none are specified then 67 // the entire resolved room state will be returned. 68 StateToFetch []gomatrixserverlib.StateKeyTuple `json:"state_to_fetch"` 69} 70 71// QueryStateAfterEventsResponse is a response to QueryStateAfterEvents 72type QueryStateAfterEventsResponse struct { 73 // Does the room exist on this roomserver? 74 // If the room doesn't exist this will be false and StateEvents will be empty. 75 RoomExists bool `json:"room_exists"` 76 // The room version of the room. 77 RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` 78 // Do all the previous events exist on this roomserver? 79 // If some of previous events do not exist this will be false and StateEvents will be empty. 80 PrevEventsExist bool `json:"prev_events_exist"` 81 // The state events requested. 82 // This list will be in an arbitrary order. 83 StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"` 84} 85 86type QueryMissingAuthPrevEventsRequest struct { 87 // The room ID to query the state in. 88 RoomID string `json:"room_id"` 89 // The list of auth events to check the existence of. 90 AuthEventIDs []string `json:"auth_event_ids"` 91 // The list of previous events to check the existence of. 92 PrevEventIDs []string `json:"prev_event_ids"` 93} 94 95type QueryMissingAuthPrevEventsResponse struct { 96 // Does the room exist on this roomserver? 97 // If the room doesn't exist all other fields will be empty. 98 RoomExists bool `json:"room_exists"` 99 // The room version of the room. 100 RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` 101 // The event IDs of the auth events that we don't know locally. 102 MissingAuthEventIDs []string `json:"missing_auth_event_ids"` 103 // The event IDs of the previous events that we don't know locally. 104 MissingPrevEventIDs []string `json:"missing_prev_event_ids"` 105} 106 107// QueryEventsByIDRequest is a request to QueryEventsByID 108type QueryEventsByIDRequest struct { 109 // The event IDs to look up. 110 EventIDs []string `json:"event_ids"` 111} 112 113// QueryEventsByIDResponse is a response to QueryEventsByID 114type QueryEventsByIDResponse struct { 115 // A list of events with the requested IDs. 116 // If the roomserver does not have a copy of a requested event 117 // then it will omit that event from the list. 118 // If the roomserver thinks it has a copy of the event, but 119 // fails to read it from the database then it will fail 120 // the entire request. 121 // This list will be in an arbitrary order. 122 Events []*gomatrixserverlib.HeaderedEvent `json:"events"` 123} 124 125// QueryMembershipForUserRequest is a request to QueryMembership 126type QueryMembershipForUserRequest struct { 127 // ID of the room to fetch membership from 128 RoomID string `json:"room_id"` 129 // ID of the user for whom membership is requested 130 UserID string `json:"user_id"` 131} 132 133// QueryMembershipForUserResponse is a response to QueryMembership 134type QueryMembershipForUserResponse struct { 135 // The EventID of the latest "m.room.member" event for the sender, 136 // if HasBeenInRoom is true. 137 EventID string `json:"event_id"` 138 // True if the user has been in room before and has either stayed in it or left it. 139 HasBeenInRoom bool `json:"has_been_in_room"` 140 // True if the user is in room. 141 IsInRoom bool `json:"is_in_room"` 142 // The current membership 143 Membership string `json:"membership"` 144 // True if the user asked to forget this room. 145 IsRoomForgotten bool `json:"is_room_forgotten"` 146} 147 148// QueryMembershipsForRoomRequest is a request to QueryMembershipsForRoom 149type QueryMembershipsForRoomRequest struct { 150 // If true, only returns the membership events of "join" membership 151 JoinedOnly bool `json:"joined_only"` 152 // ID of the room to fetch memberships from 153 RoomID string `json:"room_id"` 154 // Optional - ID of the user sending the request, for checking if the 155 // user is allowed to see the memberships. If not specified then all 156 // room memberships will be returned. 157 Sender string `json:"sender"` 158} 159 160// QueryMembershipsForRoomResponse is a response to QueryMembershipsForRoom 161type QueryMembershipsForRoomResponse struct { 162 // The "m.room.member" events (of "join" membership) in the client format 163 JoinEvents []gomatrixserverlib.ClientEvent `json:"join_events"` 164 // True if the user has been in room before and has either stayed in it or 165 // left it. 166 HasBeenInRoom bool `json:"has_been_in_room"` 167 // True if the user asked to forget this room. 168 IsRoomForgotten bool `json:"is_room_forgotten"` 169} 170 171// QueryServerJoinedToRoomRequest is a request to QueryServerJoinedToRoom 172type QueryServerJoinedToRoomRequest struct { 173 // Server name of the server to find. If not specified, we will 174 // default to checking if the local server is joined. 175 ServerName gomatrixserverlib.ServerName `json:"server_name"` 176 // ID of the room to see if we are still joined to 177 RoomID string `json:"room_id"` 178} 179 180// QueryMembershipsForRoomResponse is a response to QueryServerJoinedToRoom 181type QueryServerJoinedToRoomResponse struct { 182 // True if the room exists on the server 183 RoomExists bool `json:"room_exists"` 184 // True if we still believe that the server is participating in the room 185 IsInRoom bool `json:"is_in_room"` 186} 187 188// QueryServerAllowedToSeeEventRequest is a request to QueryServerAllowedToSeeEvent 189type QueryServerAllowedToSeeEventRequest struct { 190 // The event ID to look up invites in. 191 EventID string `json:"event_id"` 192 // The server interested in the event 193 ServerName gomatrixserverlib.ServerName `json:"server_name"` 194} 195 196// QueryServerAllowedToSeeEventResponse is a response to QueryServerAllowedToSeeEvent 197type QueryServerAllowedToSeeEventResponse struct { 198 // Wether the server in question is allowed to see the event 199 AllowedToSeeEvent bool `json:"can_see_event"` 200} 201 202// QueryMissingEventsRequest is a request to QueryMissingEvents 203type QueryMissingEventsRequest struct { 204 // Events which are known previous to the gap in the timeline. 205 EarliestEvents []string `json:"earliest_events"` 206 // Latest known events. 207 LatestEvents []string `json:"latest_events"` 208 // Limit the number of events this query returns. 209 Limit int `json:"limit"` 210 // The server interested in the event 211 ServerName gomatrixserverlib.ServerName `json:"server_name"` 212} 213 214// QueryMissingEventsResponse is a response to QueryMissingEvents 215type QueryMissingEventsResponse struct { 216 // Missing events, arbritrary order. 217 Events []*gomatrixserverlib.HeaderedEvent `json:"events"` 218} 219 220// QueryStateAndAuthChainRequest is a request to QueryStateAndAuthChain 221type QueryStateAndAuthChainRequest struct { 222 // The room ID to query the state in. 223 RoomID string `json:"room_id"` 224 // The list of prev events for the event. Used to calculate the state at 225 // the event. 226 PrevEventIDs []string `json:"prev_event_ids"` 227 // The list of auth events for the event. Used to calculate the auth chain 228 AuthEventIDs []string `json:"auth_event_ids"` 229 // Should state resolution be ran on the result events? 230 // TODO: check call sites and remove if we always want to do state res 231 ResolveState bool `json:"resolve_state"` 232} 233 234// QueryStateAndAuthChainResponse is a response to QueryStateAndAuthChain 235type QueryStateAndAuthChainResponse struct { 236 // Does the room exist on this roomserver? 237 // If the room doesn't exist this will be false and StateEvents will be empty. 238 RoomExists bool `json:"room_exists"` 239 // The room version of the room. 240 RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` 241 // Do all the previous events exist on this roomserver? 242 // If some of previous events do not exist this will be false and StateEvents will be empty. 243 PrevEventsExist bool `json:"prev_events_exist"` 244 // The state and auth chain events that were requested. 245 // The lists will be in an arbitrary order. 246 StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"` 247 AuthChainEvents []*gomatrixserverlib.HeaderedEvent `json:"auth_chain_events"` 248} 249 250// QueryRoomVersionCapabilitiesRequest asks for the default room version 251type QueryRoomVersionCapabilitiesRequest struct{} 252 253// QueryRoomVersionCapabilitiesResponse is a response to QueryRoomVersionCapabilitiesRequest 254type QueryRoomVersionCapabilitiesResponse struct { 255 DefaultRoomVersion gomatrixserverlib.RoomVersion `json:"default"` 256 AvailableRoomVersions map[gomatrixserverlib.RoomVersion]string `json:"available"` 257} 258 259// QueryRoomVersionForRoomRequest asks for the room version for a given room. 260type QueryRoomVersionForRoomRequest struct { 261 RoomID string `json:"room_id"` 262} 263 264// QueryRoomVersionForRoomResponse is a response to QueryRoomVersionForRoomRequest 265type QueryRoomVersionForRoomResponse struct { 266 RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` 267} 268 269type QueryPublishedRoomsRequest struct { 270 // Optional. If specified, returns whether this room is published or not. 271 RoomID string 272} 273 274type QueryPublishedRoomsResponse struct { 275 // The list of published rooms. 276 RoomIDs []string 277} 278 279type QueryAuthChainRequest struct { 280 EventIDs []string 281} 282 283type QueryAuthChainResponse struct { 284 AuthChain []*gomatrixserverlib.HeaderedEvent 285} 286 287type QuerySharedUsersRequest struct { 288 UserID string 289 ExcludeRoomIDs []string 290 IncludeRoomIDs []string 291} 292 293type QuerySharedUsersResponse struct { 294 UserIDsToCount map[string]int 295} 296 297type QueryRoomsForUserRequest struct { 298 UserID string 299 // The desired membership of the user. If this is the empty string then no rooms are returned. 300 WantMembership string 301} 302 303type QueryRoomsForUserResponse struct { 304 RoomIDs []string 305} 306 307type QueryBulkStateContentRequest struct { 308 // Returns state events in these rooms 309 RoomIDs []string 310 // If true, treats the '*' StateKey as "all state events of this type" rather than a literal value of '*' 311 AllowWildcards bool 312 // The state events to return. Only a small subset of tuples are allowed in this request as only certain events 313 // have their content fields extracted. Specifically, the tuple Type must be one of: 314 // m.room.avatar 315 // m.room.create 316 // m.room.canonical_alias 317 // m.room.guest_access 318 // m.room.history_visibility 319 // m.room.join_rules 320 // m.room.member 321 // m.room.name 322 // m.room.topic 323 // Any other tuple type will result in the query failing. 324 StateTuples []gomatrixserverlib.StateKeyTuple 325} 326type QueryBulkStateContentResponse struct { 327 // map of room ID -> tuple -> content_value 328 Rooms map[string]map[gomatrixserverlib.StateKeyTuple]string 329} 330 331type QueryCurrentStateRequest struct { 332 RoomID string 333 StateTuples []gomatrixserverlib.StateKeyTuple 334} 335 336type QueryCurrentStateResponse struct { 337 StateEvents map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent 338} 339 340type QueryKnownUsersRequest struct { 341 UserID string `json:"user_id"` 342 SearchString string `json:"search_string"` 343 Limit int `json:"limit"` 344} 345 346type QueryKnownUsersResponse struct { 347 Users []authtypes.FullyQualifiedProfile `json:"profiles"` 348} 349 350type QueryServerBannedFromRoomRequest struct { 351 ServerName gomatrixserverlib.ServerName `json:"server_name"` 352 RoomID string `json:"room_id"` 353} 354 355type QueryServerBannedFromRoomResponse struct { 356 Banned bool `json:"banned"` 357} 358 359// MarshalJSON stringifies the room ID and StateKeyTuple keys so they can be sent over the wire in HTTP API mode. 360func (r *QueryBulkStateContentResponse) MarshalJSON() ([]byte, error) { 361 se := make(map[string]string) 362 for roomID, tupleToEvent := range r.Rooms { 363 for tuple, event := range tupleToEvent { 364 // use 0x1F (unit separator) as the delimiter between room ID/type/state key, 365 se[fmt.Sprintf("%s\x1F%s\x1F%s", roomID, tuple.EventType, tuple.StateKey)] = event 366 } 367 } 368 return json.Marshal(se) 369} 370 371func (r *QueryBulkStateContentResponse) UnmarshalJSON(data []byte) error { 372 wireFormat := make(map[string]string) 373 err := json.Unmarshal(data, &wireFormat) 374 if err != nil { 375 return err 376 } 377 r.Rooms = make(map[string]map[gomatrixserverlib.StateKeyTuple]string) 378 for roomTuple, value := range wireFormat { 379 fields := strings.Split(roomTuple, "\x1F") 380 roomID := fields[0] 381 if r.Rooms[roomID] == nil { 382 r.Rooms[roomID] = make(map[gomatrixserverlib.StateKeyTuple]string) 383 } 384 r.Rooms[roomID][gomatrixserverlib.StateKeyTuple{ 385 EventType: fields[1], 386 StateKey: fields[2], 387 }] = value 388 } 389 return nil 390} 391 392// MarshalJSON stringifies the StateKeyTuple keys so they can be sent over the wire in HTTP API mode. 393func (r *QueryCurrentStateResponse) MarshalJSON() ([]byte, error) { 394 se := make(map[string]*gomatrixserverlib.HeaderedEvent, len(r.StateEvents)) 395 for k, v := range r.StateEvents { 396 // use 0x1F (unit separator) as the delimiter between type/state key, 397 se[fmt.Sprintf("%s\x1F%s", k.EventType, k.StateKey)] = v 398 } 399 return json.Marshal(se) 400} 401 402func (r *QueryCurrentStateResponse) UnmarshalJSON(data []byte) error { 403 res := make(map[string]*gomatrixserverlib.HeaderedEvent) 404 err := json.Unmarshal(data, &res) 405 if err != nil { 406 return err 407 } 408 r.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent, len(res)) 409 for k, v := range res { 410 fields := strings.Split(k, "\x1F") 411 r.StateEvents[gomatrixserverlib.StateKeyTuple{ 412 EventType: fields[0], 413 StateKey: fields[1], 414 }] = v 415 } 416 return nil 417} 418