From c4d1af68b13987a384bbeb2cbabf15c69a47f967 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 10 Jul 2017 11:55:27 +0100 Subject: [PATCH] Added auth on PUT /profile/{userID}/... --- .../dendrite/clientapi/readers/profile.go | 172 ++++++++++-------- .../dendrite/clientapi/routing/routing.go | 26 ++- 2 files changed, 118 insertions(+), 80 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/clientapi/readers/profile.go b/src/github.com/matrix-org/dendrite/clientapi/readers/profile.go index 039b393c1..a52ef2730 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/readers/profile.go +++ b/src/github.com/matrix-org/dendrite/clientapi/readers/profile.go @@ -65,103 +65,123 @@ func GetProfile( } } -// AvatarURL implements GET and PUT /profile/{userID}/avatar_url -func AvatarURL( +// GetAvatarURL implements GET /profile/{userID}/avatar_url +func GetAvatarURL( req *http.Request, accountDB *accounts.Database, userID string, ) util.JSONResponse { - if req.Method == "GET" { - localpart := getLocalPart(userID) - profile, err := accountDB.GetProfileByLocalpart(localpart) - if err == nil { - res := avatarURL{ - AvatarURL: profile.AvatarURL, - } - return util.JSONResponse{ - Code: 200, - JSON: res, - } - } + if req.Method != "GET" { return util.JSONResponse{ - Code: 500, - JSON: jsonerror.Unknown("Failed to load avatar URL"), + Code: 405, + JSON: jsonerror.NotFound("Bad method"), } - } else if req.Method == "PUT" { - var r avatarURL - if resErr := httputil.UnmarshalJSONRequest(req, &r); resErr != nil { - return *resErr - } - if r.AvatarURL == "" { - return util.JSONResponse{ - Code: 400, - JSON: jsonerror.BadJSON("'avatar_url' must be supplied."), - } - } - - localpart := getLocalPart(userID) - if err := accountDB.SetAvatarURL(localpart, r.AvatarURL); err != nil { - return util.JSONResponse{ - Code: 500, - JSON: jsonerror.Unknown("Failed to set avatar URL"), - } + } + localpart := getLocalPart(userID) + if profile, err := accountDB.GetProfileByLocalpart(localpart); err == nil { + res := avatarURL{ + AvatarURL: profile.AvatarURL, } return util.JSONResponse{ Code: 200, - JSON: struct{}{}, + JSON: res, } } return util.JSONResponse{ - Code: 405, - JSON: jsonerror.NotFound("Bad method"), + Code: 500, + JSON: jsonerror.Unknown("Failed to load avatar URL"), } } -// DisplayName implements GET and PUT /profile/{userID}/displayname -func DisplayName( +// SetAvatarURL implements PUT /profile/{userID}/avatar_url +func SetAvatarURL( req *http.Request, accountDB *accounts.Database, userID string, ) util.JSONResponse { - if req.Method == "GET" { - localpart := getLocalPart(userID) - profile, err := accountDB.GetProfileByLocalpart(localpart) - if err == nil { - res := displayName{ - DisplayName: profile.DisplayName, - } - return util.JSONResponse{ - Code: 200, - JSON: res, - } + if req.Method != "PUT" { + return util.JSONResponse{ + Code: 405, + JSON: jsonerror.NotFound("Bad method"), } + } + var r avatarURL + if resErr := httputil.UnmarshalJSONRequest(req, &r); resErr != nil { + return *resErr + } + if r.AvatarURL == "" { + return util.JSONResponse{ + Code: 400, + JSON: jsonerror.BadJSON("'avatar_url' must be supplied."), + } + } + + localpart := getLocalPart(userID) + if err := accountDB.SetAvatarURL(localpart, r.AvatarURL); err != nil { return util.JSONResponse{ Code: 500, - JSON: jsonerror.Unknown("Failed to load display name"), - } - } else if req.Method == "PUT" { - var r displayName - if resErr := httputil.UnmarshalJSONRequest(req, &r); resErr != nil { - return *resErr - } - if r.DisplayName == "" { - return util.JSONResponse{ - Code: 400, - JSON: jsonerror.BadJSON("'displayname' must be supplied."), - } - } - - localpart := getLocalPart(userID) - if err := accountDB.SetDisplayName(localpart, r.DisplayName); err != nil { - return util.JSONResponse{ - Code: 500, - JSON: jsonerror.Unknown("Failed to set display name"), - } - } - return util.JSONResponse{ - Code: 200, - JSON: struct{}{}, + JSON: jsonerror.Unknown("Failed to set avatar URL"), } } return util.JSONResponse{ - Code: 405, - JSON: jsonerror.NotFound("Bad method"), + Code: 200, + JSON: struct{}{}, + } +} + +// SetDisplayName implements GET /profile/{userID}/displayname +func GetDisplayName( + req *http.Request, accountDB *accounts.Database, userID string, +) util.JSONResponse { + if req.Method != "GET" { + return util.JSONResponse{ + Code: 405, + JSON: jsonerror.NotFound("Bad method"), + } + } + localpart := getLocalPart(userID) + if profile, err := accountDB.GetProfileByLocalpart(localpart); err == nil { + res := displayName{ + DisplayName: profile.DisplayName, + } + return util.JSONResponse{ + Code: 200, + JSON: res, + } + } + return util.JSONResponse{ + Code: 500, + JSON: jsonerror.Unknown("Failed to load display name"), + } +} + +// SetDisplayName implements PUT /profile/{userID}/displayname +func SetDisplayName( + req *http.Request, accountDB *accounts.Database, userID string, +) util.JSONResponse { + if req.Method != "PUT" { + return util.JSONResponse{ + Code: 405, + JSON: jsonerror.NotFound("Bad method"), + } + } + var r displayName + if resErr := httputil.UnmarshalJSONRequest(req, &r); resErr != nil { + return *resErr + } + if r.DisplayName == "" { + return util.JSONResponse{ + Code: 400, + JSON: jsonerror.BadJSON("'displayname' must be supplied."), + } + } + + localpart := getLocalPart(userID) + if err := accountDB.SetDisplayName(localpart, r.DisplayName); err != nil { + return util.JSONResponse{ + Code: 500, + JSON: jsonerror.Unknown("Failed to set display name"), + } + } + return util.JSONResponse{ + Code: 200, + JSON: struct{}{}, } } diff --git a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go index ad41d798d..3482344d3 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go @@ -171,16 +171,34 @@ func Setup( r0mux.Handle("/profile/{userID}/avatar_url", common.MakeAPI("profile_avatar_url", func(req *http.Request) util.JSONResponse { vars := mux.Vars(req) - return readers.AvatarURL(req, accountDB, vars["userID"]) + return readers.GetAvatarURL(req, accountDB, vars["userID"]) }), - ) + ).Methods("GET") + + r0mux.Handle("/profile/{userID}/avatar_url", + common.MakeAuthAPI("profile_avatar_url", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + vars := mux.Vars(req) + return readers.SetAvatarURL(req, accountDB, vars["userID"]) + }), + ).Methods("PUT", "OPTIONS") + // Browsers use the OPTIONS HTTP method to check if the CORS policy allows + // PUT requests, so we need to allow this method r0mux.Handle("/profile/{userID}/displayname", common.MakeAPI("profile_displayname", func(req *http.Request) util.JSONResponse { vars := mux.Vars(req) - return readers.DisplayName(req, accountDB, vars["userID"]) + return readers.GetDisplayName(req, accountDB, vars["userID"]) }), - ) + ).Methods("GET") + + r0mux.Handle("/profile/{userID}/displayname", + common.MakeAuthAPI("profile_displayname", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + vars := mux.Vars(req) + return readers.SetDisplayName(req, accountDB, vars["userID"]) + }), + ).Methods("PUT", "OPTIONS") + // Browsers use the OPTIONS HTTP method to check if the CORS policy allows + // PUT requests, so we need to allow this method r0mux.Handle("/account/3pid", common.MakeAPI("account_3pid", func(req *http.Request) util.JSONResponse {