diff options
author | David Spenler <15622190+DavidSpenler@users.noreply.github.com> | 2020-11-17 05:07:03 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-17 10:07:03 +0000 |
commit | 35ea55e70bf9d4e9db8fe0e0c741f685dcedf0ec (patch) | |
tree | 9f6bdc6d1c7a1c9d2f43ce0e6a51cb37ac452357 /clientapi | |
parent | d3b3371856b4593cded8b5c77a6edd02746804ed (diff) |
Implemented whois endpoint (#1573)
Co-authored-by: Neil Alexander <neilalexander@users.noreply.github.com>
Diffstat (limited to 'clientapi')
-rw-r--r-- | clientapi/routing/admin_whois.go | 88 | ||||
-rw-r--r-- | clientapi/routing/routing.go | 10 |
2 files changed, 98 insertions, 0 deletions
diff --git a/clientapi/routing/admin_whois.go b/clientapi/routing/admin_whois.go new file mode 100644 index 00000000..b448791c --- /dev/null +++ b/clientapi/routing/admin_whois.go @@ -0,0 +1,88 @@ +// Copyright 2020 David Spenler +// +// 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 routing + +import ( + "net/http" + + "github.com/matrix-org/dendrite/clientapi/jsonerror" + "github.com/matrix-org/dendrite/userapi/api" + + "github.com/matrix-org/util" +) + +type adminWhoisResponse struct { + UserID string `json:"user_id"` + Devices map[string]deviceInfo `json:"devices"` +} + +type deviceInfo struct { + Sessions []sessionInfo `json:"sessions"` +} + +type sessionInfo struct { + Connections []connectionInfo `json:"connections"` +} + +type connectionInfo struct { + IP string `json:"ip"` + LastSeen int64 `json:"last_seen"` + UserAgent string `json:"user_agent"` +} + +// GetAdminWhois implements GET /admin/whois/{userId} +func GetAdminWhois( + req *http.Request, userAPI api.UserInternalAPI, device *api.Device, + userID string, +) util.JSONResponse { + if userID != device.UserID { + // TODO: Still allow if user is admin + return util.JSONResponse{ + Code: http.StatusForbidden, + JSON: jsonerror.Forbidden("userID does not match the current user"), + } + } + + var queryRes api.QueryDevicesResponse + err := userAPI.QueryDevices(req.Context(), &api.QueryDevicesRequest{ + UserID: userID, + }, &queryRes) + if err != nil { + util.GetLogger(req.Context()).WithError(err).Error("GetAdminWhois failed to query user devices") + return jsonerror.InternalServerError() + } + + devices := make(map[string]deviceInfo) + for _, device := range queryRes.Devices { + connInfo := connectionInfo{ + IP: device.LastSeenIP, + LastSeen: device.LastSeenTS, + UserAgent: device.UserAgent, + } + dev, ok := devices[device.ID] + if !ok { + dev.Sessions = []sessionInfo{{}} + } + dev.Sessions[0].Connections = append(dev.Sessions[0].Connections, connInfo) + devices[device.ID] = dev + } + return util.JSONResponse{ + Code: http.StatusOK, + JSON: adminWhoisResponse{ + UserID: userID, + Devices: devices, + }, + } +} diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index 99d1bd09..65b622b3 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -651,6 +651,16 @@ func Setup( }), ).Methods(http.MethodGet) + r0mux.Handle("/admin/whois/{userID}", + httputil.MakeAuthAPI("admin_whois", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { + vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) + if err != nil { + return util.ErrorResponse(err) + } + return GetAdminWhois(req, userAPI, device, vars["userID"]) + }), + ).Methods(http.MethodGet) + r0mux.Handle("/user_directory/search", httputil.MakeAuthAPI("userdirectory_search", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { if r := rateLimits.rateLimit(req); r != nil { |