Update APIs to support ts

This commit is contained in:
Anant Prakash 2018-08-04 00:58:31 +05:30
parent 783501d977
commit c32703af04
No known key found for this signature in database
GPG key ID: C5D399F626523045
10 changed files with 84 additions and 30 deletions

View file

@ -0,0 +1,38 @@
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httputil
import (
"net/http"
"strconv"
"time"
)
// ParseTSParam takes a req (typically from an application service) and parses a Time object
// from the req if it exists in the query parameters. If it doesn't exist, the
// current time is returned.
func ParseTSParam(req *http.Request) time.Time {
// Use the ts parameter's value for event time if present
tsStr := req.URL.Query().Get("ts")
if tsStr == "" {
return time.Now()
}
// The parameter exists, parse into a Time object
ts, err := strconv.ParseInt(tsStr, 10, 64)
if err != nil {
return time.Unix(ts/1000, 0)
}
return time.Unix(ts/1000, 0)
}

View file

@ -113,7 +113,8 @@ type fledglingEvent struct {
} }
// CreateRoom implements /createRoom // CreateRoom implements /createRoom
func CreateRoom(req *http.Request, device *authtypes.Device, func CreateRoom(
req *http.Request, device *authtypes.Device,
cfg config.Dendrite, producer *producers.RoomserverProducer, cfg config.Dendrite, producer *producers.RoomserverProducer,
accountDB *accounts.Database, aliasAPI api.RoomserverAliasAPI, accountDB *accounts.Database, aliasAPI api.RoomserverAliasAPI,
) util.JSONResponse { ) util.JSONResponse {
@ -125,7 +126,8 @@ func CreateRoom(req *http.Request, device *authtypes.Device,
// createRoom implements /createRoom // createRoom implements /createRoom
// nolint: gocyclo // nolint: gocyclo
func createRoom(req *http.Request, device *authtypes.Device, func createRoom(
req *http.Request, device *authtypes.Device,
cfg config.Dendrite, roomID string, producer *producers.RoomserverProducer, cfg config.Dendrite, roomID string, producer *producers.RoomserverProducer,
accountDB *accounts.Database, aliasAPI api.RoomserverAliasAPI, accountDB *accounts.Database, aliasAPI api.RoomserverAliasAPI,
) util.JSONResponse { ) util.JSONResponse {
@ -142,8 +144,8 @@ func createRoom(req *http.Request, device *authtypes.Device,
return *resErr return *resErr
} }
evTime := httputil.ParseTSParam(req)
// TODO: visibility/presets/raw initial state/creation content // TODO: visibility/presets/raw initial state/creation content
// TODO: Create room alias association // TODO: Create room alias association
// Make sure this doesn't fall into an application service's namespace though! // Make sure this doesn't fall into an application service's namespace though!
@ -248,7 +250,7 @@ func createRoom(req *http.Request, device *authtypes.Device,
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()} builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()}
} }
var ev *gomatrixserverlib.Event var ev *gomatrixserverlib.Event
ev, err = buildEvent(&builder, &authEvents, cfg) ev, err = buildEvent(&builder, &authEvents, cfg, evTime)
if err != nil { if err != nil {
return httputil.LogThenError(req, err) return httputil.LogThenError(req, err)
} }
@ -307,10 +309,11 @@ func createRoom(req *http.Request, device *authtypes.Device,
} }
// buildEvent fills out auth_events for the builder then builds the event // buildEvent fills out auth_events for the builder then builds the event
func buildEvent(builder *gomatrixserverlib.EventBuilder, func buildEvent(
builder *gomatrixserverlib.EventBuilder,
provider gomatrixserverlib.AuthEventProvider, provider gomatrixserverlib.AuthEventProvider,
cfg config.Dendrite) (*gomatrixserverlib.Event, error) { cfg config.Dendrite, evTime time.Time,
) (*gomatrixserverlib.Event, error) {
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder) eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
if err != nil { if err != nil {
return nil, err return nil, err
@ -321,8 +324,7 @@ func buildEvent(builder *gomatrixserverlib.EventBuilder,
} }
builder.AuthEvents = refs builder.AuthEvents = refs
eventID := fmt.Sprintf("$%s:%s", util.RandomString(16), cfg.Matrix.ServerName) eventID := fmt.Sprintf("$%s:%s", util.RandomString(16), cfg.Matrix.ServerName)
now := time.Now() event, err := builder.Build(eventID, evTime, cfg.Matrix.ServerName, cfg.Matrix.KeyID, cfg.Matrix.PrivateKey)
event, err := builder.Build(eventID, now, cfg.Matrix.ServerName, cfg.Matrix.KeyID, cfg.Matrix.PrivateKey)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot build event %s : Builder failed to build. %s", builder.Type, err) return nil, fmt.Errorf("cannot build event %s : Builder failed to build. %s", builder.Type, err)
} }

View file

@ -18,7 +18,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
"time"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
@ -214,8 +213,9 @@ func (r joinRoomReq) joinRoomUsingServers(
return httputil.LogThenError(r.req, err) return httputil.LogThenError(r.req, err)
} }
evTime := httputil.ParseTSParam(r.req)
var queryRes roomserverAPI.QueryLatestEventsAndStateResponse var queryRes roomserverAPI.QueryLatestEventsAndStateResponse
event, err := common.BuildEvent(r.req.Context(), &eb, r.cfg, r.queryAPI, &queryRes) event, err := common.BuildEvent(r.req.Context(), &eb, r.cfg, evTime, r.queryAPI, &queryRes)
if err == nil { if err == nil {
if _, err = r.producer.SendEvents(r.req.Context(), []gomatrixserverlib.Event{*event}, r.cfg.Matrix.ServerName, nil); err != nil { if _, err = r.producer.SendEvents(r.req.Context(), []gomatrixserverlib.Event{*event}, r.cfg.Matrix.ServerName, nil); err != nil {
return httputil.LogThenError(r.req, err) return httputil.LogThenError(r.req, err)
@ -285,10 +285,10 @@ func (r joinRoomReq) joinRoomUsingServer(roomID string, server gomatrixserverlib
return nil, err return nil, err
} }
now := time.Now() evTime := httputil.ParseTSParam(r.req)
eventID := fmt.Sprintf("$%s:%s", util.RandomString(16), r.cfg.Matrix.ServerName) eventID := fmt.Sprintf("$%s:%s", util.RandomString(16), r.cfg.Matrix.ServerName)
event, err := respMakeJoin.JoinEvent.Build( event, err := respMakeJoin.JoinEvent.Build(
eventID, now, r.cfg.Matrix.ServerName, r.cfg.Matrix.KeyID, r.cfg.Matrix.PrivateKey, eventID, evTime, r.cfg.Matrix.ServerName, r.cfg.Matrix.KeyID, r.cfg.Matrix.PrivateKey,
) )
if err != nil { if err != nil {
res := httputil.LogThenError(r.req, err) res := httputil.LogThenError(r.req, err)

View file

@ -18,6 +18,7 @@ import (
"context" "context"
"errors" "errors"
"net/http" "net/http"
"time"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
@ -47,9 +48,10 @@ func SendMembership(
return *reqErr return *reqErr
} }
evTime := httputil.ParseTSParam(req)
inviteStored, err := threepid.CheckAndProcessInvite( inviteStored, err := threepid.CheckAndProcessInvite(
req.Context(), req.Context(), device, &body, cfg, queryAPI, accountDB, producer,
device, &body, cfg, queryAPI, accountDB, producer, membership, roomID, membership, roomID, evTime,
) )
if err == threepid.ErrMissingParameter { if err == threepid.ErrMissingParameter {
return util.JSONResponse{ return util.JSONResponse{
@ -81,7 +83,7 @@ func SendMembership(
} }
event, err := buildMembershipEvent( event, err := buildMembershipEvent(
req.Context(), body, accountDB, device, membership, roomID, cfg, queryAPI, req.Context(), body, accountDB, device, membership, roomID, cfg, evTime, queryAPI,
) )
if err == errMissingUserID { if err == errMissingUserID {
return util.JSONResponse{ return util.JSONResponse{
@ -113,7 +115,7 @@ func buildMembershipEvent(
ctx context.Context, ctx context.Context,
body threepid.MembershipRequest, accountDB *accounts.Database, body threepid.MembershipRequest, accountDB *accounts.Database,
device *authtypes.Device, membership string, roomID string, cfg config.Dendrite, device *authtypes.Device, membership string, roomID string, cfg config.Dendrite,
queryAPI api.RoomserverQueryAPI, evTime time.Time, queryAPI api.RoomserverQueryAPI,
) (*gomatrixserverlib.Event, error) { ) (*gomatrixserverlib.Event, error) {
stateKey, reason, err := getMembershipStateKey(body, device, membership) stateKey, reason, err := getMembershipStateKey(body, device, membership)
if err != nil { if err != nil {
@ -148,7 +150,7 @@ func buildMembershipEvent(
return nil, err return nil, err
} }
return common.BuildEvent(ctx, &builder, cfg, queryAPI, nil) return common.BuildEvent(ctx, &builder, cfg, evTime, queryAPI, nil)
} }
// loadProfile lookups the profile of a given user from the database and returns // loadProfile lookups the profile of a given user from the database and returns

View file

@ -18,6 +18,7 @@ import (
"context" "context"
"database/sql" "database/sql"
"net/http" "net/http"
"time"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
@ -151,7 +152,9 @@ func SetAvatarURL(
AvatarURL: r.AvatarURL, AvatarURL: r.AvatarURL,
} }
events, err := buildMembershipEvents(req.Context(), memberships, newProfile, userID, cfg, queryAPI) events, err := buildMembershipEvents(
req.Context(), memberships, newProfile, userID, cfg, httputil.ParseTSParam(req), queryAPI,
)
if err != nil { if err != nil {
return httputil.LogThenError(req, err) return httputil.LogThenError(req, err)
} }
@ -239,7 +242,9 @@ func SetDisplayName(
AvatarURL: oldProfile.AvatarURL, AvatarURL: oldProfile.AvatarURL,
} }
events, err := buildMembershipEvents(req.Context(), memberships, newProfile, userID, cfg, queryAPI) events, err := buildMembershipEvents(
req.Context(), memberships, newProfile, userID, cfg, httputil.ParseTSParam(req), queryAPI,
)
if err != nil { if err != nil {
return httputil.LogThenError(req, err) return httputil.LogThenError(req, err)
} }
@ -262,7 +267,7 @@ func buildMembershipEvents(
ctx context.Context, ctx context.Context,
memberships []authtypes.Membership, memberships []authtypes.Membership,
newProfile authtypes.Profile, userID string, cfg *config.Dendrite, newProfile authtypes.Profile, userID string, cfg *config.Dendrite,
queryAPI api.RoomserverQueryAPI, evTime time.Time, queryAPI api.RoomserverQueryAPI,
) ([]gomatrixserverlib.Event, error) { ) ([]gomatrixserverlib.Event, error) {
evs := []gomatrixserverlib.Event{} evs := []gomatrixserverlib.Event{}
@ -285,7 +290,7 @@ func buildMembershipEvents(
return nil, err return nil, err
} }
event, err := common.BuildEvent(ctx, &builder, *cfg, queryAPI, nil) event, err := common.BuildEvent(ctx, &builder, *cfg, evTime, queryAPI, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -63,6 +63,8 @@ func SendEvent(
return *resErr return *resErr
} }
evTime := httputil.ParseTSParam(req)
// create the new event and set all the fields we can // create the new event and set all the fields we can
builder := gomatrixserverlib.EventBuilder{ builder := gomatrixserverlib.EventBuilder{
Sender: userID, Sender: userID,
@ -76,7 +78,7 @@ func SendEvent(
} }
var queryRes api.QueryLatestEventsAndStateResponse var queryRes api.QueryLatestEventsAndStateResponse
e, err := common.BuildEvent(req.Context(), &builder, cfg, queryAPI, &queryRes) e, err := common.BuildEvent(req.Context(), &builder, cfg, evTime, queryAPI, &queryRes)
if err == common.ErrRoomNoExists { if err == common.ErrRoomNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,

View file

@ -89,6 +89,7 @@ func CheckAndProcessInvite(
device *authtypes.Device, body *MembershipRequest, cfg config.Dendrite, device *authtypes.Device, body *MembershipRequest, cfg config.Dendrite,
queryAPI api.RoomserverQueryAPI, db *accounts.Database, queryAPI api.RoomserverQueryAPI, db *accounts.Database,
producer *producers.RoomserverProducer, membership string, roomID string, producer *producers.RoomserverProducer, membership string, roomID string,
evTime time.Time,
) (inviteStoredOnIDServer bool, err error) { ) (inviteStoredOnIDServer bool, err error) {
if membership != "invite" || (body.Address == "" && body.IDServer == "" && body.Medium == "") { if membership != "invite" || (body.Address == "" && body.IDServer == "" && body.Medium == "") {
// If none of the 3PID-specific fields are supplied, it's a standard invite // If none of the 3PID-specific fields are supplied, it's a standard invite
@ -110,7 +111,9 @@ func CheckAndProcessInvite(
// No Matrix ID could be found for this 3PID, meaning that a // No Matrix ID could be found for this 3PID, meaning that a
// "m.room.third_party_invite" have to be emitted from the data in // "m.room.third_party_invite" have to be emitted from the data in
// storeInviteRes. // storeInviteRes.
err = emit3PIDInviteEvent(ctx, body, storeInviteRes, device, roomID, cfg, queryAPI, producer) err = emit3PIDInviteEvent(
ctx, body, storeInviteRes, device, roomID, cfg, queryAPI, producer, evTime,
)
inviteStoredOnIDServer = err == nil inviteStoredOnIDServer = err == nil
return return
@ -329,6 +332,7 @@ func emit3PIDInviteEvent(
body *MembershipRequest, res *idServerStoreInviteResponse, body *MembershipRequest, res *idServerStoreInviteResponse,
device *authtypes.Device, roomID string, cfg config.Dendrite, device *authtypes.Device, roomID string, cfg config.Dendrite,
queryAPI api.RoomserverQueryAPI, producer *producers.RoomserverProducer, queryAPI api.RoomserverQueryAPI, producer *producers.RoomserverProducer,
evTime time.Time,
) error { ) error {
builder := &gomatrixserverlib.EventBuilder{ builder := &gomatrixserverlib.EventBuilder{
Sender: device.UserID, Sender: device.UserID,
@ -350,7 +354,7 @@ func emit3PIDInviteEvent(
} }
var queryRes *api.QueryLatestEventsAndStateResponse var queryRes *api.QueryLatestEventsAndStateResponse
event, err := common.BuildEvent(ctx, builder, cfg, queryAPI, queryRes) event, err := common.BuildEvent(ctx, builder, cfg, evTime, queryAPI, queryRes)
if err != nil { if err != nil {
return err return err
} }

View file

@ -39,7 +39,7 @@ var ErrRoomNoExists = errors.New("Room does not exist")
// Returns an error if something else went wrong // Returns an error if something else went wrong
func BuildEvent( func BuildEvent(
ctx context.Context, ctx context.Context,
builder *gomatrixserverlib.EventBuilder, cfg config.Dendrite, builder *gomatrixserverlib.EventBuilder, cfg config.Dendrite, evTime time.Time,
queryAPI api.RoomserverQueryAPI, queryRes *api.QueryLatestEventsAndStateResponse, queryAPI api.RoomserverQueryAPI, queryRes *api.QueryLatestEventsAndStateResponse,
) (*gomatrixserverlib.Event, error) { ) (*gomatrixserverlib.Event, error) {
err := AddPrevEventsToEvent(ctx, builder, queryAPI, queryRes) err := AddPrevEventsToEvent(ctx, builder, queryAPI, queryRes)
@ -48,8 +48,7 @@ func BuildEvent(
} }
eventID := fmt.Sprintf("$%s:%s", util.RandomString(16), cfg.Matrix.ServerName) eventID := fmt.Sprintf("$%s:%s", util.RandomString(16), cfg.Matrix.ServerName)
now := time.Now() event, err := builder.Build(eventID, evTime, cfg.Matrix.ServerName, cfg.Matrix.KeyID, cfg.Matrix.PrivateKey)
event, err := builder.Build(eventID, now, cfg.Matrix.ServerName, cfg.Matrix.KeyID, cfg.Matrix.PrivateKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -18,6 +18,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"net/http" "net/http"
"time"
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
@ -65,7 +66,7 @@ func MakeJoin(
} }
var queryRes api.QueryLatestEventsAndStateResponse var queryRes api.QueryLatestEventsAndStateResponse
event, err := common.BuildEvent(ctx, &builder, cfg, query, &queryRes) event, err := common.BuildEvent(ctx, &builder, cfg, time.Now(), query, &queryRes)
if err == common.ErrRoomNoExists { if err == common.ErrRoomNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,

View file

@ -15,6 +15,7 @@ package routing
import ( import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"time"
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
@ -61,7 +62,7 @@ func MakeLeave(
} }
var queryRes api.QueryLatestEventsAndStateResponse var queryRes api.QueryLatestEventsAndStateResponse
event, err := common.BuildEvent(httpReq.Context(), &builder, cfg, query, &queryRes) event, err := common.BuildEvent(httpReq.Context(), &builder, cfg, time.Now(), query, &queryRes)
if err == common.ErrRoomNoExists { if err == common.ErrRoomNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,