aboutsummaryrefslogtreecommitdiff
path: root/userapi
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2020-11-20 11:29:02 +0000
committerGitHub <noreply@github.com>2020-11-20 11:29:02 +0000
commitc636be5070b575a2b4e986e1fd7fc0ba24991907 (patch)
tree9fb1d986afe8f8e89091a270760de2dc9b4777ae /userapi
parent13cbd50dc26721792a36ab47c17e62b7bb965a85 (diff)
Update last seen on sync requests (#1593)
* Update last seen on sync requests * Fix MSC2836 unit tests * Only update once per minute * Remove debug logging * Configurable option * Simplify updateLastSeen/cleanLastSeen
Diffstat (limited to 'userapi')
-rw-r--r--userapi/api/api.go12
-rw-r--r--userapi/internal/api.go15
-rw-r--r--userapi/inthttp/client.go13
-rw-r--r--userapi/inthttp/server.go13
-rw-r--r--userapi/storage/devices/interface.go2
-rw-r--r--userapi/storage/devices/postgres/devices_table.go6
-rw-r--r--userapi/storage/devices/postgres/storage.go4
-rw-r--r--userapi/storage/devices/sqlite3/devices_table.go6
-rw-r--r--userapi/storage/devices/sqlite3/storage.go4
9 files changed, 64 insertions, 11 deletions
diff --git a/userapi/api/api.go b/userapi/api/api.go
index 6c3f3c69..809ba047 100644
--- a/userapi/api/api.go
+++ b/userapi/api/api.go
@@ -29,6 +29,7 @@ type UserInternalAPI interface {
PerformPasswordUpdate(ctx context.Context, req *PerformPasswordUpdateRequest, res *PerformPasswordUpdateResponse) error
PerformDeviceCreation(ctx context.Context, req *PerformDeviceCreationRequest, res *PerformDeviceCreationResponse) error
PerformDeviceDeletion(ctx context.Context, req *PerformDeviceDeletionRequest, res *PerformDeviceDeletionResponse) error
+ PerformLastSeenUpdate(ctx context.Context, req *PerformLastSeenUpdateRequest, res *PerformLastSeenUpdateResponse) error
PerformDeviceUpdate(ctx context.Context, req *PerformDeviceUpdateRequest, res *PerformDeviceUpdateResponse) error
PerformAccountDeactivation(ctx context.Context, req *PerformAccountDeactivationRequest, res *PerformAccountDeactivationResponse) error
QueryProfile(ctx context.Context, req *QueryProfileRequest, res *QueryProfileResponse) error
@@ -183,6 +184,17 @@ type PerformPasswordUpdateResponse struct {
Account *Account
}
+// PerformLastSeenUpdateRequest is the request for PerformLastSeenUpdate.
+type PerformLastSeenUpdateRequest struct {
+ UserID string
+ DeviceID string
+ RemoteAddr string
+}
+
+// PerformLastSeenUpdateResponse is the response for PerformLastSeenUpdate.
+type PerformLastSeenUpdateResponse struct {
+}
+
// PerformDeviceCreationRequest is the request for PerformDeviceCreation
type PerformDeviceCreationRequest struct {
Localpart string
diff --git a/userapi/internal/api.go b/userapi/internal/api.go
index 81d00241..3b5f4978 100644
--- a/userapi/internal/api.go
+++ b/userapi/internal/api.go
@@ -172,6 +172,21 @@ func (a *UserInternalAPI) deviceListUpdate(userID string, deviceIDs []string) er
return nil
}
+func (a *UserInternalAPI) PerformLastSeenUpdate(
+ ctx context.Context,
+ req *api.PerformLastSeenUpdateRequest,
+ res *api.PerformLastSeenUpdateResponse,
+) error {
+ localpart, _, err := gomatrixserverlib.SplitID('@', req.UserID)
+ if err != nil {
+ return fmt.Errorf("gomatrixserverlib.SplitID: %w", err)
+ }
+ if err := a.DeviceDB.UpdateDeviceLastSeen(ctx, localpart, req.DeviceID, req.RemoteAddr); err != nil {
+ return fmt.Errorf("a.DeviceDB.UpdateDeviceLastSeen: %w", err)
+ }
+ return nil
+}
+
func (a *UserInternalAPI) PerformDeviceUpdate(ctx context.Context, req *api.PerformDeviceUpdateRequest, res *api.PerformDeviceUpdateResponse) error {
localpart, _, err := gomatrixserverlib.SplitID('@', req.RequestingUserID)
if err != nil {
diff --git a/userapi/inthttp/client.go b/userapi/inthttp/client.go
index 4d9dcc41..680e4cb5 100644
--- a/userapi/inthttp/client.go
+++ b/userapi/inthttp/client.go
@@ -32,6 +32,7 @@ const (
PerformAccountCreationPath = "/userapi/performAccountCreation"
PerformPasswordUpdatePath = "/userapi/performPasswordUpdate"
PerformDeviceDeletionPath = "/userapi/performDeviceDeletion"
+ PerformLastSeenUpdatePath = "/userapi/performLastSeenUpdate"
PerformDeviceUpdatePath = "/userapi/performDeviceUpdate"
PerformAccountDeactivationPath = "/userapi/performAccountDeactivation"
@@ -119,6 +120,18 @@ func (h *httpUserInternalAPI) PerformDeviceDeletion(
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
}
+func (h *httpUserInternalAPI) PerformLastSeenUpdate(
+ ctx context.Context,
+ req *api.PerformLastSeenUpdateRequest,
+ res *api.PerformLastSeenUpdateResponse,
+) error {
+ span, ctx := opentracing.StartSpanFromContext(ctx, "PerformLastSeen")
+ defer span.Finish()
+
+ apiURL := h.apiURL + PerformLastSeenUpdatePath
+ return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
+}
+
func (h *httpUserInternalAPI) PerformDeviceUpdate(ctx context.Context, req *api.PerformDeviceUpdateRequest, res *api.PerformDeviceUpdateResponse) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformDeviceUpdate")
defer span.Finish()
diff --git a/userapi/inthttp/server.go b/userapi/inthttp/server.go
index 81e936e5..e495e353 100644
--- a/userapi/inthttp/server.go
+++ b/userapi/inthttp/server.go
@@ -65,6 +65,19 @@ func AddRoutes(internalAPIMux *mux.Router, s api.UserInternalAPI) {
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
+ internalAPIMux.Handle(PerformLastSeenUpdatePath,
+ httputil.MakeInternalAPI("performLastSeenUpdate", func(req *http.Request) util.JSONResponse {
+ request := api.PerformLastSeenUpdateRequest{}
+ response := api.PerformLastSeenUpdateResponse{}
+ if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
+ return util.MessageResponse(http.StatusBadRequest, err.Error())
+ }
+ if err := s.PerformLastSeenUpdate(req.Context(), &request, &response); err != nil {
+ return util.ErrorResponse(err)
+ }
+ return util.JSONResponse{Code: http.StatusOK, JSON: &response}
+ }),
+ )
internalAPIMux.Handle(PerformDeviceUpdatePath,
httputil.MakeInternalAPI("performDeviceUpdate", func(req *http.Request) util.JSONResponse {
request := api.PerformDeviceUpdateRequest{}
diff --git a/userapi/storage/devices/interface.go b/userapi/storage/devices/interface.go
index 9953ba06..95fe99f3 100644
--- a/userapi/storage/devices/interface.go
+++ b/userapi/storage/devices/interface.go
@@ -33,9 +33,9 @@ type Database interface {
// Returns the device on success.
CreateDevice(ctx context.Context, localpart string, deviceID *string, accessToken string, displayName *string, ipAddr, userAgent string) (dev *api.Device, returnErr error)
UpdateDevice(ctx context.Context, localpart, deviceID string, displayName *string) error
+ UpdateDeviceLastSeen(ctx context.Context, localpart, deviceID, ipAddr string) error
RemoveDevice(ctx context.Context, deviceID, localpart string) error
RemoveDevices(ctx context.Context, localpart string, devices []string) error
// RemoveAllDevices deleted all devices for this user. Returns the devices deleted.
RemoveAllDevices(ctx context.Context, localpart, exceptDeviceID string) (devices []api.Device, err error)
- UpdateDeviceLastSeen(ctx context.Context, deviceID, ipAddr string) error
}
diff --git a/userapi/storage/devices/postgres/devices_table.go b/userapi/storage/devices/postgres/devices_table.go
index cc554fe7..7de9f5f9 100644
--- a/userapi/storage/devices/postgres/devices_table.go
+++ b/userapi/storage/devices/postgres/devices_table.go
@@ -95,7 +95,7 @@ const selectDevicesByIDSQL = "" +
"SELECT device_id, localpart, display_name FROM device_devices WHERE device_id = ANY($1)"
const updateDeviceLastSeen = "" +
- "UPDATE device_devices SET last_seen_ts = $1, ip = $2 WHERE device_id = $3"
+ "UPDATE device_devices SET last_seen_ts = $1, ip = $2 WHERE localpart = $3 AND device_id = $4"
type devicesStatements struct {
insertDeviceStmt *sql.Stmt
@@ -310,9 +310,9 @@ func (s *devicesStatements) selectDevicesByLocalpart(
return devices, rows.Err()
}
-func (s *devicesStatements) updateDeviceLastSeen(ctx context.Context, txn *sql.Tx, deviceID, ipAddr string) error {
+func (s *devicesStatements) updateDeviceLastSeen(ctx context.Context, txn *sql.Tx, localpart, deviceID, ipAddr string) error {
lastSeenTs := time.Now().UnixNano() / 1000000
stmt := sqlutil.TxStmt(txn, s.updateDeviceLastSeenStmt)
- _, err := stmt.ExecContext(ctx, lastSeenTs, ipAddr, deviceID)
+ _, err := stmt.ExecContext(ctx, lastSeenTs, ipAddr, localpart, deviceID)
return err
}
diff --git a/userapi/storage/devices/postgres/storage.go b/userapi/storage/devices/postgres/storage.go
index e318b260..6dd18b09 100644
--- a/userapi/storage/devices/postgres/storage.go
+++ b/userapi/storage/devices/postgres/storage.go
@@ -205,8 +205,8 @@ func (d *Database) RemoveAllDevices(
}
// UpdateDeviceLastSeen updates a the last seen timestamp and the ip address
-func (d *Database) UpdateDeviceLastSeen(ctx context.Context, deviceID, ipAddr string) error {
+func (d *Database) UpdateDeviceLastSeen(ctx context.Context, localpart, deviceID, ipAddr string) error {
return sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error {
- return d.devices.updateDeviceLastSeen(ctx, txn, deviceID, ipAddr)
+ return d.devices.updateDeviceLastSeen(ctx, txn, localpart, deviceID, ipAddr)
})
}
diff --git a/userapi/storage/devices/sqlite3/devices_table.go b/userapi/storage/devices/sqlite3/devices_table.go
index cdfe2bb9..955d8ac7 100644
--- a/userapi/storage/devices/sqlite3/devices_table.go
+++ b/userapi/storage/devices/sqlite3/devices_table.go
@@ -80,7 +80,7 @@ const selectDevicesByIDSQL = "" +
"SELECT device_id, localpart, display_name FROM device_devices WHERE device_id IN ($1)"
const updateDeviceLastSeen = "" +
- "UPDATE device_devices SET last_seen_ts = $1, ip = $2 WHERE device_id = $3"
+ "UPDATE device_devices SET last_seen_ts = $1, ip = $2 WHERE localpart = $3 AND device_id = $4"
type devicesStatements struct {
db *sql.DB
@@ -314,9 +314,9 @@ func (s *devicesStatements) selectDevicesByID(ctx context.Context, deviceIDs []s
return devices, rows.Err()
}
-func (s *devicesStatements) updateDeviceLastSeen(ctx context.Context, txn *sql.Tx, deviceID, ipAddr string) error {
+func (s *devicesStatements) updateDeviceLastSeen(ctx context.Context, txn *sql.Tx, localpart, deviceID, ipAddr string) error {
lastSeenTs := time.Now().UnixNano() / 1000000
stmt := sqlutil.TxStmt(txn, s.updateDeviceLastSeenStmt)
- _, err := stmt.ExecContext(ctx, lastSeenTs, ipAddr, deviceID)
+ _, err := stmt.ExecContext(ctx, lastSeenTs, ipAddr, localpart, deviceID)
return err
}
diff --git a/userapi/storage/devices/sqlite3/storage.go b/userapi/storage/devices/sqlite3/storage.go
index 25888eae..2eefb3f3 100644
--- a/userapi/storage/devices/sqlite3/storage.go
+++ b/userapi/storage/devices/sqlite3/storage.go
@@ -207,8 +207,8 @@ func (d *Database) RemoveAllDevices(
}
// UpdateDeviceLastSeen updates a the last seen timestamp and the ip address
-func (d *Database) UpdateDeviceLastSeen(ctx context.Context, deviceID, ipAddr string) error {
+func (d *Database) UpdateDeviceLastSeen(ctx context.Context, localpart, deviceID, ipAddr string) error {
return d.writer.Do(d.db, nil, func(txn *sql.Tx) error {
- return d.devices.updateDeviceLastSeen(ctx, txn, deviceID, ipAddr)
+ return d.devices.updateDeviceLastSeen(ctx, txn, localpart, deviceID, ipAddr)
})
}