1// Copyright 2017 New Vector Ltd 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package routing 16 17import ( 18 "context" 19 "encoding/json" 20 "net/http" 21 "time" 22 23 "github.com/matrix-org/dendrite/roomserver/api" 24 "github.com/matrix-org/gomatrixserverlib" 25 "github.com/matrix-org/util" 26) 27 28// GetEvent returns the requested event 29func GetEvent( 30 ctx context.Context, 31 request *gomatrixserverlib.FederationRequest, 32 rsAPI api.RoomserverInternalAPI, 33 eventID string, 34 origin gomatrixserverlib.ServerName, 35) util.JSONResponse { 36 err := allowedToSeeEvent(ctx, request.Origin(), rsAPI, eventID) 37 if err != nil { 38 return *err 39 } 40 event, err := fetchEvent(ctx, rsAPI, eventID) 41 if err != nil { 42 return *err 43 } 44 45 return util.JSONResponse{Code: http.StatusOK, JSON: gomatrixserverlib.Transaction{ 46 Origin: origin, 47 OriginServerTS: gomatrixserverlib.AsTimestamp(time.Now()), 48 PDUs: []json.RawMessage{ 49 event.JSON(), 50 }, 51 }} 52} 53 54// allowedToSeeEvent returns no error if the server is allowed to see this event, 55// otherwise it returns an error response which can be sent to the client. 56func allowedToSeeEvent( 57 ctx context.Context, 58 origin gomatrixserverlib.ServerName, 59 rsAPI api.RoomserverInternalAPI, 60 eventID string, 61) *util.JSONResponse { 62 var authResponse api.QueryServerAllowedToSeeEventResponse 63 err := rsAPI.QueryServerAllowedToSeeEvent( 64 ctx, 65 &api.QueryServerAllowedToSeeEventRequest{ 66 EventID: eventID, 67 ServerName: origin, 68 }, 69 &authResponse, 70 ) 71 if err != nil { 72 resErr := util.ErrorResponse(err) 73 return &resErr 74 } 75 76 if !authResponse.AllowedToSeeEvent { 77 resErr := util.MessageResponse(http.StatusForbidden, "server not allowed to see event") 78 return &resErr 79 } 80 81 return nil 82} 83 84// fetchEvent fetches the event without auth checks. Returns an error if the event cannot be found. 85func fetchEvent(ctx context.Context, rsAPI api.RoomserverInternalAPI, eventID string) (*gomatrixserverlib.Event, *util.JSONResponse) { 86 var eventsResponse api.QueryEventsByIDResponse 87 err := rsAPI.QueryEventsByID( 88 ctx, 89 &api.QueryEventsByIDRequest{EventIDs: []string{eventID}}, 90 &eventsResponse, 91 ) 92 if err != nil { 93 resErr := util.ErrorResponse(err) 94 return nil, &resErr 95 } 96 97 if len(eventsResponse.Events) == 0 { 98 return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil} 99 } 100 101 return eventsResponse.Events[0].Event, nil 102} 103