mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-12 01:13:10 -06:00
Use standard errors instead of JSON responses in threepid
This commit is contained in:
parent
bdc71b4757
commit
ba221c41c5
|
|
@ -65,8 +65,13 @@ func RequestEmailToken(req *http.Request, accountDB *accounts.Database, cfg conf
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.SID, err = threepid.CreateSession(body, cfg)
|
resp.SID, err = threepid.CreateSession(body, cfg)
|
||||||
if err != nil {
|
if err == threepid.ErrNotTrusted {
|
||||||
return threepid.ProcessIDServerError(req, err)
|
return util.JSONResponse{
|
||||||
|
Code: 400,
|
||||||
|
JSON: jsonerror.NotTrusted(body.IDServer),
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return httputil.LogThenError(req, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -87,8 +92,13 @@ func CheckAndSave3PIDAssociation(
|
||||||
|
|
||||||
// Check if the association has been validated
|
// Check if the association has been validated
|
||||||
verified, address, medium, err := threepid.CheckAssociation(body.Creds, cfg)
|
verified, address, medium, err := threepid.CheckAssociation(body.Creds, cfg)
|
||||||
if err != nil {
|
if err == threepid.ErrNotTrusted {
|
||||||
return threepid.ProcessIDServerError(req, err)
|
return util.JSONResponse{
|
||||||
|
Code: 400,
|
||||||
|
JSON: jsonerror.NotTrusted(body.Creds.IDServer),
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return httputil.LogThenError(req, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !verified {
|
if !verified {
|
||||||
|
|
@ -103,8 +113,14 @@ func CheckAndSave3PIDAssociation(
|
||||||
|
|
||||||
if body.Bind {
|
if body.Bind {
|
||||||
// Publish the association on the identity server if requested
|
// Publish the association on the identity server if requested
|
||||||
if err = threepid.PublishAssociation(body.Creds, device.UserID, cfg); err != nil {
|
err = threepid.PublishAssociation(body.Creds, device.UserID, cfg)
|
||||||
return threepid.ProcessIDServerError(req, err)
|
if err == threepid.ErrNotTrusted {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 400,
|
||||||
|
JSON: jsonerror.NotTrusted(body.Creds.IDServer),
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return httputil.LogThenError(req, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,11 @@ import (
|
||||||
"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"
|
||||||
"github.com/matrix-org/dendrite/clientapi/events"
|
"github.com/matrix-org/dendrite/clientapi/events"
|
||||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/producers"
|
"github.com/matrix-org/dendrite/clientapi/producers"
|
||||||
"github.com/matrix-org/dendrite/common"
|
"github.com/matrix-org/dendrite/common"
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"github.com/matrix-org/dendrite/common/config"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
||||||
"github.com/matrix-org/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MembershipRequest represents the body of an incoming POST request
|
// MembershipRequest represents the body of an incoming POST request
|
||||||
|
|
@ -66,22 +62,10 @@ type idServerStoreInviteResponse struct {
|
||||||
PublicKeys []common.PublicKey `json:"public_keys"`
|
PublicKeys []common.PublicKey `json:"public_keys"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessIDServerError differentiate errors caused by the absence of the identity
|
var (
|
||||||
// server in the list of trusted servers in the configuration file from normal
|
ErrMissingParameter = errors.New("'address', 'id_server' and 'medium' must all be supplied")
|
||||||
// errors caused by a failure in a process.
|
ErrNotTrusted = errors.New("Untrusted server")
|
||||||
// Returns the representation of a 400 error in the former case (without logging),
|
)
|
||||||
// and the one of a 500 error in the latter (with logging of the error).
|
|
||||||
func ProcessIDServerError(req *http.Request, err error) util.JSONResponse {
|
|
||||||
// Check whether this is an
|
|
||||||
mErr, ok := err.(*jsonerror.MatrixError)
|
|
||||||
if !ok || mErr.ErrCode != "M_SERVER_NOT_TRUSTED" {
|
|
||||||
return httputil.LogThenError(req, err)
|
|
||||||
}
|
|
||||||
return util.JSONResponse{
|
|
||||||
Code: 400,
|
|
||||||
JSON: mErr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckAndProcessInvite analyses the body of an incoming membership request.
|
// CheckAndProcessInvite analyses the body of an incoming membership request.
|
||||||
// If the fields relative to a third-party-invite are all supplied, lookups the
|
// If the fields relative to a third-party-invite are all supplied, lookups the
|
||||||
|
|
@ -100,24 +84,21 @@ func CheckAndProcessInvite(
|
||||||
req *http.Request, device *authtypes.Device, body *MembershipRequest,
|
req *http.Request, device *authtypes.Device, body *MembershipRequest,
|
||||||
cfg config.Dendrite, queryAPI api.RoomserverQueryAPI, db *accounts.Database,
|
cfg config.Dendrite, queryAPI api.RoomserverQueryAPI, db *accounts.Database,
|
||||||
producer *producers.RoomserverProducer, membership string, roomID string,
|
producer *producers.RoomserverProducer, membership string, roomID string,
|
||||||
) *util.JSONResponse {
|
) (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
|
||||||
// so return nil for it to be processed as such
|
// so return nil for it to be processed as such
|
||||||
return nil
|
return
|
||||||
} else if body.Address == "" || body.IDServer == "" || body.Medium == "" {
|
} else if body.Address == "" || body.IDServer == "" || body.Medium == "" {
|
||||||
// If at least one of the 3PID-specific fields is supplied but not all
|
// If at least one of the 3PID-specific fields is supplied but not all
|
||||||
// of them, return an error
|
// of them, return an error
|
||||||
return &util.JSONResponse{
|
err = ErrMissingParameter
|
||||||
Code: 400,
|
return
|
||||||
JSON: jsonerror.BadJSON("'address', 'id_server' and 'medium' must all be supplied"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lookupRes, storeInviteRes, err := queryIDServer(req, db, cfg, device, body, roomID)
|
lookupRes, storeInviteRes, err := queryIDServer(req, db, cfg, device, body, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resErr := ProcessIDServerError(req, err)
|
return
|
||||||
return &resErr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if lookupRes.MXID == "" {
|
if lookupRes.MXID == "" {
|
||||||
|
|
@ -125,28 +106,16 @@ func CheckAndProcessInvite(
|
||||||
// "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(body, storeInviteRes, device, roomID, cfg, queryAPI, producer)
|
err = emit3PIDInviteEvent(body, storeInviteRes, device, roomID, cfg, queryAPI, producer)
|
||||||
if err == events.ErrRoomNoExists {
|
inviteStoredOnIDServer = err == nil
|
||||||
return &util.JSONResponse{
|
|
||||||
Code: 404,
|
|
||||||
JSON: jsonerror.NotFound(err.Error()),
|
|
||||||
}
|
|
||||||
} else if err != nil {
|
|
||||||
resErr := httputil.LogThenError(req, err)
|
|
||||||
return &resErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// If everything went well, returns with an empty response.
|
return
|
||||||
return &util.JSONResponse{
|
|
||||||
Code: 200,
|
|
||||||
JSON: struct{}{},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Matrix ID have been found: set it in the body request and let the process
|
// A Matrix ID have been found: set it in the body request and let the process
|
||||||
// continue to create a "m.room.member" event with an "invite" membership
|
// continue to create a "m.room.member" event with an "invite" membership
|
||||||
body.UserID = lookupRes.MXID
|
body.UserID = lookupRes.MXID
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// queryIDServer handles all the requests to the identity server, starting by
|
// queryIDServer handles all the requests to the identity server, starting by
|
||||||
|
|
@ -163,7 +132,7 @@ func queryIDServer(
|
||||||
device *authtypes.Device, body *MembershipRequest, roomID string,
|
device *authtypes.Device, body *MembershipRequest, roomID string,
|
||||||
) (lookupRes *idServerLookupResponse, storeInviteRes *idServerStoreInviteResponse, err error) {
|
) (lookupRes *idServerLookupResponse, storeInviteRes *idServerStoreInviteResponse, err error) {
|
||||||
if err = isTrusted(body.IDServer, cfg); err != nil {
|
if err = isTrusted(body.IDServer, cfg); err != nil {
|
||||||
return nil, nil, err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup the 3PID
|
// Lookup the 3PID
|
||||||
|
|
@ -270,7 +239,6 @@ func queryIDServerStoreInvite(
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
// TODO: Log the error supplied with the identity server?
|
|
||||||
errMsg := fmt.Sprintf("Identity server %s responded with a %d error code", body.IDServer, resp.StatusCode)
|
errMsg := fmt.Sprintf("Identity server %s responded with a %d error code", body.IDServer, resp.StatusCode)
|
||||||
return nil, errors.New(errMsg)
|
return nil, errors.New(errMsg)
|
||||||
}
|
}
|
||||||
|
|
@ -296,7 +264,6 @@ func queryIDServerPubKey(idServerName string, keyID string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
// TODO: Log the error supplied with the identity server?
|
|
||||||
errMsg := fmt.Sprintf("Couldn't retrieve key %s from server %s", keyID, idServerName)
|
errMsg := fmt.Sprintf("Couldn't retrieve key %s from server %s", keyID, idServerName)
|
||||||
return nil, errors.New(errMsg)
|
return nil, errors.New(errMsg)
|
||||||
}
|
}
|
||||||
|
|
@ -318,7 +285,6 @@ func checkIDServerSignatures(body *MembershipRequest, res *idServerLookupRespons
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check if the domain is part of a list of trusted ID servers
|
|
||||||
signatures, ok := res.Signatures[body.IDServer]
|
signatures, ok := res.Signatures[body.IDServer]
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("No signature for domain " + body.IDServer)
|
return errors.New("No signature for domain " + body.IDServer)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"github.com/matrix-org/dendrite/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -175,5 +174,5 @@ func isTrusted(idServer string, cfg config.Dendrite) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return jsonerror.NotTrusted(idServer)
|
return ErrNotTrusted
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,36 @@ func SendMembership(
|
||||||
return *reqErr
|
return *reqErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if res := threepid.CheckAndProcessInvite(
|
inviteStored, err := threepid.CheckAndProcessInvite(
|
||||||
req, device, &body, cfg, queryAPI, accountDB, producer, membership, roomID,
|
req, device, &body, cfg, queryAPI, accountDB, producer, membership, roomID,
|
||||||
); res != nil {
|
)
|
||||||
return *res
|
if err == threepid.ErrMissingParameter {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 400,
|
||||||
|
JSON: jsonerror.BadJSON(err.Error()),
|
||||||
|
}
|
||||||
|
} else if err == threepid.ErrNotTrusted {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 400,
|
||||||
|
JSON: jsonerror.NotTrusted(body.IDServer),
|
||||||
|
}
|
||||||
|
} else if err == events.ErrRoomNoExists {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 404,
|
||||||
|
JSON: jsonerror.NotFound(err.Error()),
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return httputil.LogThenError(req, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If an invite has been stored on an identity server, it means that a
|
||||||
|
// m.room.third_party_invite event has been emitted and that we shouldn't
|
||||||
|
// emit a m.room.member one.
|
||||||
|
if inviteStored {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 200,
|
||||||
|
JSON: struct{}{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event, err := buildMembershipEvent(
|
event, err := buildMembershipEvent(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue