let ParseTSParam return error when no int transmitted

This commit is contained in:
Krombel 2018-08-06 17:20:49 +02:00
parent 68f8ab24bd
commit cfd80a0871
7 changed files with 71 additions and 19 deletions

View file

@ -1,6 +1,6 @@
{
"Vendor": true,
"Cyclo": 12,
"Cyclo": 13,
"Deadline": "5m",
"Enable": [
"vetshadow",

View file

@ -13,26 +13,49 @@
package httputil
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/util"
)
// ParseIntParam takes a request and parses the query param to an int
// returns 0 when not present and -1 when parsing failed as int
func ParseIntParam(req *http.Request, param string) (int64, *util.JSONResponse) {
paramStr := req.URL.Query().Get(param)
if paramStr == "" {
return 0, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.MissingArgument(fmt.Sprintf("Param %s not found", param)),
}
}
paramInt, err := strconv.ParseInt(paramStr, 0, 64)
if err != nil {
return -1, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.InvalidArgumentValue(
fmt.Sprintf("Param %s is no valid int (%s)", param, err.Error()),
),
}
}
return paramInt, nil
}
// 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)
func ParseTSParam(req *http.Request) (time.Time, *util.JSONResponse) {
ts, err := ParseIntParam(req, "ts")
if err != nil {
return time.Unix(ts/1000, 0)
if ts == 0 {
// param was not available
return time.Now(), nil
}
return time.Time{}, err
}
return time.Unix(ts/1000, 0)
return time.Unix(ts/1000, 0), nil
}

View file

@ -147,7 +147,10 @@ func createRoom(
return *resErr
}
evTime := httputil.ParseTSParam(req)
evTime, resErr := httputil.ParseTSParam(req)
if resErr != nil {
return *resErr
}
// TODO: visibility/presets/raw initial state/creation content
// TODO: Create room alias association
// Make sure this doesn't fall into an application service's namespace though!

View file

@ -207,13 +207,17 @@ func (r joinRoomReq) writeToBuilder(eb *gomatrixserverlib.EventBuilder, roomID s
func (r joinRoomReq) joinRoomUsingServers(
roomID string, servers []gomatrixserverlib.ServerName,
) util.JSONResponse {
evTime, resErr := httputil.ParseTSParam(r.req)
if resErr != nil {
return *resErr
}
var eb gomatrixserverlib.EventBuilder
err := r.writeToBuilder(&eb, roomID)
if err != nil {
return httputil.LogThenError(r.req, err)
}
evTime := httputil.ParseTSParam(r.req)
var queryRes roomserverAPI.QueryLatestEventsAndStateResponse
event, err := common.BuildEvent(r.req.Context(), &eb, r.cfg, evTime, r.queryAPI, &queryRes)
if err == nil {
@ -272,6 +276,12 @@ func (r joinRoomReq) joinRoomUsingServers(
// server was invalid this returns an error.
// Otherwise this returns a JSONResponse.
func (r joinRoomReq) joinRoomUsingServer(roomID string, server gomatrixserverlib.ServerName) (*util.JSONResponse, error) {
// parse all data (and return an error) before doing some work
evTime, resErr := httputil.ParseTSParam(r.req)
if resErr != nil {
// this looks weird here but does what we want.
return resErr, resErr.JSON.(jsonerror.MatrixError)
}
respMakeJoin, err := r.federation.MakeJoin(r.req.Context(), server, roomID, r.userID)
if err != nil {
// TODO: Check if the user was not allowed to join the room.
@ -285,7 +295,6 @@ func (r joinRoomReq) joinRoomUsingServer(roomID string, server gomatrixserverlib
return nil, err
}
evTime := httputil.ParseTSParam(r.req)
eventID := fmt.Sprintf("$%s:%s", util.RandomString(16), r.cfg.Matrix.ServerName)
event, err := respMakeJoin.JoinEvent.Build(
eventID, evTime, r.cfg.Matrix.ServerName, r.cfg.Matrix.KeyID, r.cfg.Matrix.PrivateKey,

View file

@ -50,7 +50,11 @@ func SendMembership(
return *reqErr
}
evTime := httputil.ParseTSParam(req)
evTime, resErr := httputil.ParseTSParam(req)
if resErr != nil {
return *resErr
}
inviteStored, err := threepid.CheckAndProcessInvite(
req.Context(), device, &body, cfg, queryAPI, accountDB, producer,
membership, roomID, evTime,

View file

@ -107,6 +107,11 @@ func SetAvatarURL(
return httputil.LogThenError(req, err)
}
evTime, resErr := httputil.ParseTSParam(req)
if resErr != nil {
return *resErr
}
oldProfile, err := accountDB.GetProfileByLocalpart(req.Context(), localpart)
if err != nil {
return httputil.LogThenError(req, err)
@ -128,7 +133,7 @@ func SetAvatarURL(
}
events, err := buildMembershipEvents(
req.Context(), memberships, newProfile, userID, cfg, httputil.ParseTSParam(req), queryAPI,
req.Context(), memberships, newProfile, userID, cfg, evTime, queryAPI,
)
if err != nil {
return httputil.LogThenError(req, err)
@ -196,6 +201,11 @@ func SetDisplayName(
return httputil.LogThenError(req, err)
}
evTime, resErr := httputil.ParseTSParam(req)
if resErr != nil {
return *resErr
}
oldProfile, err := accountDB.GetProfileByLocalpart(req.Context(), localpart)
if err != nil {
return httputil.LogThenError(req, err)
@ -217,7 +227,7 @@ func SetDisplayName(
}
events, err := buildMembershipEvents(
req.Context(), memberships, newProfile, userID, cfg, httputil.ParseTSParam(req), queryAPI,
req.Context(), memberships, newProfile, userID, cfg, evTime, queryAPI,
)
if err != nil {
return httputil.LogThenError(req, err)

View file

@ -63,7 +63,10 @@ func SendEvent(
return *resErr
}
evTime := httputil.ParseTSParam(req)
evTime, resErr := httputil.ParseTSParam(req)
if resErr != nil {
return *resErr
}
// create the new event and set all the fields we can
builder := gomatrixserverlib.EventBuilder{