DeleteDeviceById handles DELETE requests to /devices/{deviceId}
( req *http.Request, userInteractiveAuth *auth.UserInteractive, userAPI api.ClientUserAPI, device *api.Device, deviceID string, )
| 161 | |
| 162 | // DeleteDeviceById handles DELETE requests to /devices/{deviceId} |
| 163 | func DeleteDeviceById( |
| 164 | req *http.Request, userInteractiveAuth *auth.UserInteractive, userAPI api.ClientUserAPI, device *api.Device, |
| 165 | deviceID string, |
| 166 | ) util.JSONResponse { |
| 167 | var ( |
| 168 | deleteOK bool |
| 169 | sessionID string |
| 170 | ) |
| 171 | defer func() { |
| 172 | if deleteOK { |
| 173 | sessions.deleteSession(sessionID) |
| 174 | } |
| 175 | }() |
| 176 | ctx := req.Context() |
| 177 | defer req.Body.Close() // nolint:errcheck |
| 178 | bodyBytes, err := io.ReadAll(req.Body) |
| 179 | if err != nil { |
| 180 | return util.JSONResponse{ |
| 181 | Code: http.StatusBadRequest, |
| 182 | JSON: jsonerror.BadJSON("The request body could not be read: " + err.Error()), |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | // check that we know this session, and it matches with the device to delete |
| 187 | s := gjson.GetBytes(bodyBytes, "auth.session").Str |
| 188 | if dev, ok := sessions.getDeviceToDelete(s); ok { |
| 189 | if dev != deviceID { |
| 190 | return util.JSONResponse{ |
| 191 | Code: http.StatusForbidden, |
| 192 | JSON: jsonerror.Forbidden("session & device mismatch"), |
| 193 | } |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | if s != "" { |
| 198 | sessionID = s |
| 199 | } |
| 200 | |
| 201 | login, errRes := userInteractiveAuth.Verify(ctx, bodyBytes, device) |
| 202 | if errRes != nil { |
| 203 | switch data := errRes.JSON.(type) { |
| 204 | case auth.Challenge: |
| 205 | sessions.addDeviceToDelete(data.Session, deviceID) |
| 206 | default: |
| 207 | } |
| 208 | return *errRes |
| 209 | } |
| 210 | |
| 211 | localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) |
| 212 | if err != nil { |
| 213 | util.GetLogger(ctx).WithError(err).Error("gomatrixserverlib.SplitID failed") |
| 214 | return jsonerror.InternalServerError() |
| 215 | } |
| 216 | |
| 217 | // make sure that the access token being used matches the login creds used for user interactive auth, else |
| 218 | // 1 compromised access token could be used to logout all devices. |
| 219 | if login.Username() != localpart && login.Username() != device.UserID { |
| 220 | return util.JSONResponse{ |
no test coverage detected