mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-04-21 11:13:40 +00:00
✅ Test 7 Pushers created with a the same access token are not deleted on password change
This commit is contained in:
parent
4c4cf8020a
commit
763354e371
11 changed files with 335 additions and 71 deletions
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type newPasswordRequest struct {
|
type newPasswordRequest struct {
|
||||||
|
@ -38,6 +39,11 @@ func Password(
|
||||||
var r newPasswordRequest
|
var r newPasswordRequest
|
||||||
r.LogoutDevices = true
|
r.LogoutDevices = true
|
||||||
|
|
||||||
|
logrus.WithFields(logrus.Fields{
|
||||||
|
"sessionId": device.SessionID,
|
||||||
|
"userId": device.UserID,
|
||||||
|
}).Debug("Changing password")
|
||||||
|
|
||||||
// Unmarshal the request.
|
// Unmarshal the request.
|
||||||
resErr := httputil.UnmarshalJSONRequest(req, &r)
|
resErr := httputil.UnmarshalJSONRequest(req, &r)
|
||||||
if resErr != nil {
|
if resErr != nil {
|
||||||
|
@ -107,6 +113,7 @@ func Password(
|
||||||
// If the request asks us to log out all other devices then
|
// If the request asks us to log out all other devices then
|
||||||
// ask the user API to do that.
|
// ask the user API to do that.
|
||||||
if r.LogoutDevices {
|
if r.LogoutDevices {
|
||||||
|
logrus.Debug("Logging out devices...")
|
||||||
logoutReq := &userapi.PerformDeviceDeletionRequest{
|
logoutReq := &userapi.PerformDeviceDeletionRequest{
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
DeviceIDs: nil,
|
DeviceIDs: nil,
|
||||||
|
@ -117,6 +124,41 @@ func Password(
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("PerformDeviceDeletion failed")
|
util.GetLogger(req.Context()).WithError(err).Error("PerformDeviceDeletion failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pushersReq := &userapi.QueryPushersRequest{
|
||||||
|
UserID: device.UserID,
|
||||||
|
}
|
||||||
|
pushersRes := &userapi.QueryPushersResponse{}
|
||||||
|
if err := userAPI.QueryPushers(req.Context(), pushersReq, pushersRes); err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("QueryPushers failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleted = len(pushersRes.Pushers)
|
||||||
|
// Deletes all pushers from other devices
|
||||||
|
for _, pusher := range pushersRes.Pushers {
|
||||||
|
if pusher.SessionID == device.SessionID {
|
||||||
|
logrus.Debugf("✅ Skipping pusher %d", pusher.SessionID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pusher.UserID == device.UserID {
|
||||||
|
deletionRes := userapi.PerformPusherDeletionResponse{}
|
||||||
|
if err := userAPI.PerformPusherDeletion(req.Context(), &userapi.PerformPusherDeletionRequest{
|
||||||
|
AppID: pusher.AppID,
|
||||||
|
PushKey: pusher.PushKey,
|
||||||
|
UserID: pusher.UserID,
|
||||||
|
}, &deletionRes); err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("PerformPusherDeletion failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
logrus.Debugf("💥 Successfully deleted pusher %d", pusher.SessionID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := userAPI.QueryPushers(req.Context(), pushersReq, pushersRes); err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("QueryPushers failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
logrus.Debugf("🗑 Deleted %d pushers...", deleted-len(pushersRes.Pushers))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a success code.
|
// Return a success code.
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-pushers
|
// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-pushers
|
||||||
|
@ -31,7 +32,7 @@ type pusherJSON struct {
|
||||||
AppID string `json:"app_id"`
|
AppID string `json:"app_id"`
|
||||||
AppDisplayName string `json:"app_display_name"`
|
AppDisplayName string `json:"app_display_name"`
|
||||||
DeviceDisplayName string `json:"device_display_name"`
|
DeviceDisplayName string `json:"device_display_name"`
|
||||||
ProfileTag *string `json:"profile_tag"`
|
ProfileTag string `json:"profile_tag"`
|
||||||
Language string `json:"lang"`
|
Language string `json:"lang"`
|
||||||
Data pusherDataJSON `json:"data"`
|
Data pusherDataJSON `json:"data"`
|
||||||
}
|
}
|
||||||
|
@ -67,12 +68,14 @@ func GetPushersByLocalpart(
|
||||||
AppID: pusher.AppID,
|
AppID: pusher.AppID,
|
||||||
AppDisplayName: pusher.AppDisplayName,
|
AppDisplayName: pusher.AppDisplayName,
|
||||||
DeviceDisplayName: pusher.DeviceDisplayName,
|
DeviceDisplayName: pusher.DeviceDisplayName,
|
||||||
ProfileTag: &pusher.ProfileTag,
|
ProfileTag: pusher.ProfileTag,
|
||||||
Language: pusher.Language,
|
Language: pusher.Language,
|
||||||
Data: pusherDataJSON(pusher.Data),
|
Data: pusherDataJSON(pusher.Data),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("😁 HTTP returning %d pushers", len(res.Pushers))
|
||||||
|
logrus.Debugf("🔮 Pushers %v", res.Pushers)
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
JSON: res,
|
JSON: res,
|
||||||
|
@ -85,21 +88,92 @@ func GetPushersByLocalpart(
|
||||||
func SetPusherByLocalpart(
|
func SetPusherByLocalpart(
|
||||||
req *http.Request, userAPI userapi.UserInternalAPI, device *api.Device,
|
req *http.Request, userAPI userapi.UserInternalAPI, device *api.Device,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
|
var deletionRes userapi.PerformPusherDeletionResponse
|
||||||
body := pusherJSON{}
|
body := pusherJSON{}
|
||||||
|
|
||||||
if resErr := httputil.UnmarshalJSONRequest(req, &body); resErr != nil {
|
if resErr := httputil.UnmarshalJSONRequest(req, &body); resErr != nil {
|
||||||
return *resErr
|
return *resErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
var queryRes userapi.QueryPushersResponse
|
||||||
// 1. if kind == null, GetPusherByPushkey and delete it! 🗑
|
err := userAPI.QueryPushers(req.Context(), &userapi.QueryPushersRequest{
|
||||||
// 2. if GetPusherByPushkey returns existing Pusher, update it with the received body
|
UserID: device.UserID,
|
||||||
// 3. if GetPusherByPushkey returns nothing, create a new Pusher with the received body
|
}, &queryRes)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("QueryPushers failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetPusher *userapi.Pusher
|
||||||
|
for _, pusher := range queryRes.Pushers {
|
||||||
|
if pusher.PushKey == body.PushKey {
|
||||||
|
targetPusher = &pusher
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No Pusher exists with the given PushKey for current user
|
||||||
|
if targetPusher == nil {
|
||||||
|
// Create a new Pusher for current user
|
||||||
|
var pusherResponse userapi.PerformPusherCreationResponse
|
||||||
|
err = userAPI.PerformPusherCreation(req.Context(), &userapi.PerformPusherCreationRequest{
|
||||||
|
Device: device,
|
||||||
|
PushKey: body.PushKey,
|
||||||
|
Kind: body.Kind,
|
||||||
|
AppID: body.AppID,
|
||||||
|
AppDisplayName: body.AppDisplayName,
|
||||||
|
DeviceDisplayName: body.DeviceDisplayName,
|
||||||
|
ProfileTag: body.ProfileTag,
|
||||||
|
Language: body.Language,
|
||||||
|
URL: body.Data.URL,
|
||||||
|
Format: body.Data.Format,
|
||||||
|
}, &pusherResponse)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("PerformPusherCreation failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
} else if body.Kind == "" {
|
||||||
|
if targetPusher == nil {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusNotFound,
|
||||||
|
JSON: jsonerror.NotFound("Unknown pusher"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if kind is null, delete the pusher! 🗑
|
||||||
|
err = userAPI.PerformPusherDeletion(req.Context(), &userapi.PerformPusherDeletionRequest{
|
||||||
|
AppID: targetPusher.AppID,
|
||||||
|
PushKey: targetPusher.PushKey,
|
||||||
|
UserID: targetPusher.UserID,
|
||||||
|
}, &deletionRes)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("PerformPusherDeletion failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var pusherResponse userapi.PerformPusherUpdateResponse
|
||||||
|
err = userAPI.PerformPusherUpdate(req.Context(), &userapi.PerformPusherUpdateRequest{
|
||||||
|
PushKey: body.PushKey,
|
||||||
|
Kind: body.Kind,
|
||||||
|
AppID: body.AppID,
|
||||||
|
AppDisplayName: body.AppDisplayName,
|
||||||
|
DeviceDisplayName: body.DeviceDisplayName,
|
||||||
|
ProfileTag: body.ProfileTag,
|
||||||
|
Language: body.Language,
|
||||||
|
URL: body.Data.URL,
|
||||||
|
Format: body.Data.Format,
|
||||||
|
}, &pusherResponse)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("PerformPusherUpdate failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
res := body
|
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
JSON: res,
|
JSON: struct{}{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,10 +29,11 @@ type UserInternalAPI interface {
|
||||||
PerformPasswordUpdate(ctx context.Context, req *PerformPasswordUpdateRequest, res *PerformPasswordUpdateResponse) error
|
PerformPasswordUpdate(ctx context.Context, req *PerformPasswordUpdateRequest, res *PerformPasswordUpdateResponse) error
|
||||||
PerformDeviceCreation(ctx context.Context, req *PerformDeviceCreationRequest, res *PerformDeviceCreationResponse) error
|
PerformDeviceCreation(ctx context.Context, req *PerformDeviceCreationRequest, res *PerformDeviceCreationResponse) error
|
||||||
PerformDeviceDeletion(ctx context.Context, req *PerformDeviceDeletionRequest, res *PerformDeviceDeletionResponse) error
|
PerformDeviceDeletion(ctx context.Context, req *PerformDeviceDeletionRequest, res *PerformDeviceDeletionResponse) error
|
||||||
PerformPusherCreation(ctx context.Context, req *PerformPusherCreationRequest, res *PerformPusherCreationResponse) error
|
|
||||||
PerformPusherDeletion(ctx context.Context, req *PerformPusherDeletionRequest, res *PerformPusherDeletionResponse) error
|
|
||||||
PerformLastSeenUpdate(ctx context.Context, req *PerformLastSeenUpdateRequest, res *PerformLastSeenUpdateResponse) error
|
PerformLastSeenUpdate(ctx context.Context, req *PerformLastSeenUpdateRequest, res *PerformLastSeenUpdateResponse) error
|
||||||
PerformDeviceUpdate(ctx context.Context, req *PerformDeviceUpdateRequest, res *PerformDeviceUpdateResponse) error
|
PerformDeviceUpdate(ctx context.Context, req *PerformDeviceUpdateRequest, res *PerformDeviceUpdateResponse) error
|
||||||
|
PerformPusherCreation(ctx context.Context, req *PerformPusherCreationRequest, res *PerformPusherCreationResponse) error
|
||||||
|
PerformPusherDeletion(ctx context.Context, req *PerformPusherDeletionRequest, res *PerformPusherDeletionResponse) error
|
||||||
|
PerformPusherUpdate(ctx context.Context, req *PerformPusherUpdateRequest, res *PerformPusherUpdateResponse) error
|
||||||
PerformAccountDeactivation(ctx context.Context, req *PerformAccountDeactivationRequest, res *PerformAccountDeactivationResponse) error
|
PerformAccountDeactivation(ctx context.Context, req *PerformAccountDeactivationRequest, res *PerformAccountDeactivationResponse) error
|
||||||
PerformOpenIDTokenCreation(ctx context.Context, req *PerformOpenIDTokenCreationRequest, res *PerformOpenIDTokenCreationResponse) error
|
PerformOpenIDTokenCreation(ctx context.Context, req *PerformOpenIDTokenCreationRequest, res *PerformOpenIDTokenCreationResponse) error
|
||||||
QueryProfile(ctx context.Context, req *QueryProfileRequest, res *QueryProfileResponse) error
|
QueryProfile(ctx context.Context, req *QueryProfileRequest, res *QueryProfileResponse) error
|
||||||
|
@ -81,6 +82,7 @@ type PerformDeviceDeletionResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformPusherDeletionRequest struct {
|
type PerformPusherDeletionRequest struct {
|
||||||
|
AppID string
|
||||||
PushKey string
|
PushKey string
|
||||||
UserID string
|
UserID string
|
||||||
}
|
}
|
||||||
|
@ -242,7 +244,7 @@ type PerformDeviceCreationResponse struct {
|
||||||
|
|
||||||
// PerformPusherCreationRequest is the request for PerformPusherCreation
|
// PerformPusherCreationRequest is the request for PerformPusherCreation
|
||||||
type PerformPusherCreationRequest struct {
|
type PerformPusherCreationRequest struct {
|
||||||
Localpart string
|
Device *Device
|
||||||
PushKey string
|
PushKey string
|
||||||
Kind string
|
Kind string
|
||||||
AppID string
|
AppID string
|
||||||
|
@ -258,6 +260,24 @@ type PerformPusherCreationRequest struct {
|
||||||
type PerformPusherCreationResponse struct {
|
type PerformPusherCreationResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PerformPusherUpdateRequest is the request for PerformPusherUpdate
|
||||||
|
type PerformPusherUpdateRequest struct {
|
||||||
|
Device *Device
|
||||||
|
PushKey string
|
||||||
|
Kind string
|
||||||
|
AppID string
|
||||||
|
AppDisplayName string
|
||||||
|
DeviceDisplayName string
|
||||||
|
ProfileTag string
|
||||||
|
Language string
|
||||||
|
URL string
|
||||||
|
Format string
|
||||||
|
}
|
||||||
|
|
||||||
|
// PerformPusherUpdateResponse is the response for PerformPusherUpdate
|
||||||
|
type PerformPusherUpdateResponse struct {
|
||||||
|
}
|
||||||
|
|
||||||
// PerformAccountDeactivationRequest is the request for PerformAccountDeactivation
|
// PerformAccountDeactivationRequest is the request for PerformAccountDeactivation
|
||||||
type PerformAccountDeactivationRequest struct {
|
type PerformAccountDeactivationRequest struct {
|
||||||
Localpart string
|
Localpart string
|
||||||
|
@ -312,6 +332,7 @@ type Device struct {
|
||||||
// Pusher represents a push notification subscriber
|
// Pusher represents a push notification subscriber
|
||||||
type Pusher struct {
|
type Pusher struct {
|
||||||
UserID string
|
UserID string
|
||||||
|
SessionID int64
|
||||||
PushKey string
|
PushKey string
|
||||||
Kind string
|
Kind string
|
||||||
AppID string
|
AppID string
|
||||||
|
|
|
@ -153,16 +153,34 @@ func (a *UserInternalAPI) PerformDeviceDeletion(ctx context.Context, req *api.Pe
|
||||||
|
|
||||||
func (a *UserInternalAPI) PerformPusherCreation(ctx context.Context, req *api.PerformPusherCreationRequest, res *api.PerformPusherCreationResponse) error {
|
func (a *UserInternalAPI) PerformPusherCreation(ctx context.Context, req *api.PerformPusherCreationRequest, res *api.PerformPusherCreationResponse) error {
|
||||||
util.GetLogger(ctx).WithFields(logrus.Fields{
|
util.GetLogger(ctx).WithFields(logrus.Fields{
|
||||||
"localpart": req.Localpart,
|
"userId": req.Device.UserID,
|
||||||
"pushkey": req.PushKey,
|
"pushkey": req.PushKey,
|
||||||
"display_name": req.AppDisplayName,
|
"display_name": req.AppDisplayName,
|
||||||
}).Info("PerformPusherCreation")
|
}).Info("PerformPusherCreation")
|
||||||
err := a.PusherDB.CreatePusher(ctx, req.PushKey, req.Kind, req.AppID, req.AppDisplayName, req.DeviceDisplayName, req.ProfileTag, req.Language, req.URL, req.Format, req.Localpart)
|
local, _, err := gomatrixserverlib.SplitID('@', req.Device.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = a.PusherDB.CreatePusher(ctx, req.Device.SessionID, req.PushKey, req.Kind, req.AppID, req.AppDisplayName, req.DeviceDisplayName, req.ProfileTag, req.Language, req.URL, req.Format, local)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *UserInternalAPI) PerformPusherUpdate(ctx context.Context, req *api.PerformPusherUpdateRequest, res *api.PerformPusherUpdateResponse) error {
|
||||||
|
util.GetLogger(ctx).WithFields(logrus.Fields{
|
||||||
|
"localpart": req.Device.UserID,
|
||||||
|
"pushkey": req.PushKey,
|
||||||
|
"display_name": req.AppDisplayName,
|
||||||
|
}).Info("PerformPusherUpdate")
|
||||||
|
local, _, err := gomatrixserverlib.SplitID('@', req.Device.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = a.PusherDB.UpdatePusher(ctx, req.PushKey, req.Kind, req.AppID, req.AppDisplayName, req.DeviceDisplayName, req.ProfileTag, req.Language, req.URL, req.Format, local)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *UserInternalAPI) PerformPusherDeletion(ctx context.Context, req *api.PerformPusherDeletionRequest, res *api.PerformPusherDeletionResponse) error {
|
func (a *UserInternalAPI) PerformPusherDeletion(ctx context.Context, req *api.PerformPusherDeletionRequest, res *api.PerformPusherDeletionResponse) error {
|
||||||
util.GetLogger(ctx).WithField("user_id", req.UserID).WithField("pushkey", req.PushKey).Info("PerformPusherDeletion")
|
util.GetLogger(ctx).WithField("user_id", req.UserID).WithField("pushkey", req.PushKey).WithField("app_id", req.AppID).Info("PerformPusherDeletion")
|
||||||
local, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
local, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -170,11 +188,10 @@ func (a *UserInternalAPI) PerformPusherDeletion(ctx context.Context, req *api.Pe
|
||||||
if domain != a.ServerName {
|
if domain != a.ServerName {
|
||||||
return fmt.Errorf("cannot PerformPusherDeletion of remote users: got %s want %s", domain, a.ServerName)
|
return fmt.Errorf("cannot PerformPusherDeletion of remote users: got %s want %s", domain, a.ServerName)
|
||||||
}
|
}
|
||||||
err = a.PusherDB.RemovePusher(ctx, local, req.PushKey)
|
err = a.PusherDB.RemovePusher(ctx, req.AppID, req.PushKey, local)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// create empty device keys and upload them to delete what was once there and trigger device list changes
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ const (
|
||||||
PerformPusherDeletionPath = "/userapi/performPusherDeletion"
|
PerformPusherDeletionPath = "/userapi/performPusherDeletion"
|
||||||
PerformLastSeenUpdatePath = "/userapi/performLastSeenUpdate"
|
PerformLastSeenUpdatePath = "/userapi/performLastSeenUpdate"
|
||||||
PerformDeviceUpdatePath = "/userapi/performDeviceUpdate"
|
PerformDeviceUpdatePath = "/userapi/performDeviceUpdate"
|
||||||
|
PerformPusherUpdatePath = "/userapi/performPusherUpdate"
|
||||||
PerformAccountDeactivationPath = "/userapi/performAccountDeactivation"
|
PerformAccountDeactivationPath = "/userapi/performAccountDeactivation"
|
||||||
PerformOpenIDTokenCreationPath = "/userapi/performOpenIDTokenCreation"
|
PerformOpenIDTokenCreationPath = "/userapi/performOpenIDTokenCreation"
|
||||||
|
|
||||||
|
@ -137,6 +138,18 @@ func (h *httpUserInternalAPI) PerformPusherCreation(
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *httpUserInternalAPI) PerformPusherUpdate(
|
||||||
|
ctx context.Context,
|
||||||
|
request *api.PerformPusherUpdateRequest,
|
||||||
|
response *api.PerformPusherUpdateResponse,
|
||||||
|
) error {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformPusherUpdate")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
apiURL := h.apiURL + PerformPusherUpdatePath
|
||||||
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
|
}
|
||||||
|
|
||||||
func (h *httpUserInternalAPI) PerformPusherDeletion(
|
func (h *httpUserInternalAPI) PerformPusherDeletion(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.PerformPusherDeletionRequest,
|
request *api.PerformPusherDeletionRequest,
|
||||||
|
|
|
@ -65,6 +65,19 @@ func AddRoutes(internalAPIMux *mux.Router, s api.UserInternalAPI) {
|
||||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
internalAPIMux.Handle(PerformPusherUpdatePath,
|
||||||
|
httputil.MakeInternalAPI("performPusherUpdate", func(req *http.Request) util.JSONResponse {
|
||||||
|
request := api.PerformPusherUpdateRequest{}
|
||||||
|
response := api.PerformPusherUpdateResponse{}
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
if err := s.PerformPusherUpdate(req.Context(), &request, &response); err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
|
}),
|
||||||
|
)
|
||||||
internalAPIMux.Handle(PerformDeviceCreationPath,
|
internalAPIMux.Handle(PerformDeviceCreationPath,
|
||||||
httputil.MakeInternalAPI("performDeviceCreation", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("performDeviceCreation", func(req *http.Request) util.JSONResponse {
|
||||||
request := api.PerformDeviceCreationRequest{}
|
request := api.PerformDeviceCreationRequest{}
|
||||||
|
|
|
@ -21,8 +21,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Database interface {
|
type Database interface {
|
||||||
CreatePusher(ctd context.Context, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string) error
|
CreatePusher(ctx context.Context, sessionId int64, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string) error
|
||||||
GetPushersByLocalpart(ctx context.Context, localpart string) ([]api.Pusher, error)
|
GetPushersByLocalpart(ctx context.Context, localpart string) ([]api.Pusher, error)
|
||||||
GetPusherByPushkey(ctx context.Context, pushkey, localpart string) (*api.Pusher, error)
|
GetPusherByPushkey(ctx context.Context, pushkey, localpart string) (*api.Pusher, error)
|
||||||
RemovePusher(ctx context.Context, pushkey, localpart string) error
|
UpdatePusher(ctx context.Context, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string) error
|
||||||
|
RemovePusher(ctx context.Context, appId, pushkey, localpart string) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,19 +23,19 @@ import (
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const pushersSchema = `
|
const pushersSchema = `
|
||||||
-- Stores data about pushers.
|
-- Stores data about pushers.
|
||||||
CREATE TABLE IF NOT EXISTS pusher_pushers (
|
CREATE TABLE IF NOT EXISTS pusher_pushers (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
-- The Matrix user ID localpart for this pusher
|
-- The Matrix user ID localpart for this pusher
|
||||||
localpart TEXT NOT NULL PRIMARY KEY,
|
localpart TEXT NOT NULL,
|
||||||
-- This is a unique identifier for this pusher.
|
-- The Session ID used to create the Pusher
|
||||||
-- The value you should use for this is the routing or destination address information for the notification, for example,
|
session_id BIGINT DEFAULT NULL,
|
||||||
-- the APNS token for APNS or the Registration ID for GCM. If your notification client has no such concept, use any unique identifier.
|
-- This string determines which set of device specific rules this pusher executes.
|
||||||
-- If the kind is "email", this is the email address to send notifications to.
|
profile_tag TEXT NOT NULL,
|
||||||
-- Max length, 512 bytes.
|
|
||||||
pushkey VARCHAR(512) NOT NULL,
|
|
||||||
-- The kind of pusher. "http" is a pusher that sends HTTP pokes.
|
-- The kind of pusher. "http" is a pusher that sends HTTP pokes.
|
||||||
kind TEXT,
|
kind TEXT,
|
||||||
-- This is a reverse-DNS style identifier for the application. Max length, 64 chars.
|
-- This is a reverse-DNS style identifier for the application. Max length, 64 chars.
|
||||||
|
@ -44,8 +44,12 @@ CREATE TABLE IF NOT EXISTS pusher_pushers (
|
||||||
app_display_name TEXT,
|
app_display_name TEXT,
|
||||||
-- A string that will allow the user to identify what device owns this pusher.
|
-- A string that will allow the user to identify what device owns this pusher.
|
||||||
device_display_name TEXT,
|
device_display_name TEXT,
|
||||||
-- This string determines which set of device specific rules this pusher executes.
|
-- This is a unique identifier for this pusher.
|
||||||
profile_tag TEXT,
|
-- The value you should use for this is the routing or destination address information for the notification, for example,
|
||||||
|
-- the APNS token for APNS or the Registration ID for GCM. If your notification client has no such concept, use any unique identifier.
|
||||||
|
-- If the kind is "email", this is the email address to send notifications to.
|
||||||
|
-- Max length, 512 bytes.
|
||||||
|
pushkey VARCHAR(512) NOT NULL,
|
||||||
-- The preferred language for receiving notifications (e.g. 'en' or 'en-US')
|
-- The preferred language for receiving notifications (e.g. 'en' or 'en-US')
|
||||||
lang TEXT,
|
lang TEXT,
|
||||||
-- Required if kind is http. The URL to use to send notifications to.
|
-- Required if kind is http. The URL to use to send notifications to.
|
||||||
|
@ -55,26 +59,29 @@ CREATE TABLE IF NOT EXISTS pusher_pushers (
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Pushkey must be unique for a given user.
|
-- Pushkey must be unique for a given user.
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS pusher_localpart_pushkey_idx ON pusher_pushers(localpart, pushkey);
|
CREATE UNIQUE INDEX IF NOT EXISTS pusher_app_id_pushkey_localpart_idx ON pusher_pushers(app_id, pushkey, localpart);
|
||||||
`
|
`
|
||||||
|
|
||||||
const insertPusherSQL = "" +
|
const insertPusherSQL = "" +
|
||||||
"INSERT INTO pusher_pushers(localpart, pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)"
|
"INSERT INTO pusher_pushers(localpart, session_id, pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)"
|
||||||
|
|
||||||
const selectPushersByLocalpartSQL = "" +
|
const selectPushersByLocalpartSQL = "" +
|
||||||
"SELECT pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format FROM pusher_pushers WHERE localpart = $1"
|
"SELECT session_id, pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format FROM pusher_pushers WHERE localpart = $1"
|
||||||
|
|
||||||
const selectPusherByPushkeySQL = "" +
|
const selectPusherByPushkeySQL = "" +
|
||||||
"SELECT pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format FROM pusher_pushers WHERE localpart = $1 AND pushkey = $2"
|
"SELECT session_id, pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format FROM pusher_pushers WHERE localpart = $1 AND pushkey = $2"
|
||||||
|
|
||||||
|
const updatePusherSQL = "" +
|
||||||
|
"UPDATE pusher_pushers SET kind = $1, app_id = $2, app_display_name = $3, device_display_name = $4, profile_tag = $5, lang = $6, url = $7, format = $8 WHERE localpart = $9 AND pushkey = $10"
|
||||||
|
|
||||||
const deletePusherSQL = "" +
|
const deletePusherSQL = "" +
|
||||||
"DELETE FROM pusher_pushers WHERE pushkey = $1 AND localpart = $2"
|
"DELETE FROM pusher_pushers WHERE app_id = $1 AND pushkey = $2 AND localpart = $3"
|
||||||
|
|
||||||
type pushersStatements struct {
|
type pushersStatements struct {
|
||||||
insertPusherStmt *sql.Stmt
|
insertPusherStmt *sql.Stmt
|
||||||
selectPushersByLocalpartStmt *sql.Stmt
|
selectPushersByLocalpartStmt *sql.Stmt
|
||||||
selectPusherByPushkeyStmt *sql.Stmt
|
selectPusherByPushkeyStmt *sql.Stmt
|
||||||
|
updatePusherStmt *sql.Stmt
|
||||||
deletePusherStmt *sql.Stmt
|
deletePusherStmt *sql.Stmt
|
||||||
serverName gomatrixserverlib.ServerName
|
serverName gomatrixserverlib.ServerName
|
||||||
}
|
}
|
||||||
|
@ -94,6 +101,9 @@ func (s *pushersStatements) prepare(db *sql.DB, server gomatrixserverlib.ServerN
|
||||||
if s.selectPusherByPushkeyStmt, err = db.Prepare(selectPusherByPushkeySQL); err != nil {
|
if s.selectPusherByPushkeyStmt, err = db.Prepare(selectPusherByPushkeySQL); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if s.updatePusherStmt, err = db.Prepare(updatePusherSQL); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
if s.deletePusherStmt, err = db.Prepare(deletePusherSQL); err != nil {
|
if s.deletePusherStmt, err = db.Prepare(deletePusherSQL); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -105,19 +115,12 @@ func (s *pushersStatements) prepare(db *sql.DB, server gomatrixserverlib.ServerN
|
||||||
// Returns an error if the user already has a pusher with the given pusher pushkey.
|
// Returns an error if the user already has a pusher with the given pusher pushkey.
|
||||||
// Returns nil error success.
|
// Returns nil error success.
|
||||||
func (s *pushersStatements) insertPusher(
|
func (s *pushersStatements) insertPusher(
|
||||||
ctx context.Context, txn *sql.Tx, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
ctx context.Context, txn *sql.Tx, session_id int64,
|
||||||
|
pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
||||||
) error {
|
) error {
|
||||||
stmt := sqlutil.TxStmt(txn, s.insertPusherStmt)
|
stmt := sqlutil.TxStmt(txn, s.insertPusherStmt)
|
||||||
_, err := stmt.ExecContext(ctx, localpart, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format)
|
_, err := stmt.ExecContext(ctx, localpart, session_id, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format)
|
||||||
return err
|
logrus.Debugf("🥳 Created pusher %d", session_id)
|
||||||
}
|
|
||||||
|
|
||||||
// deletePusher removes a single pusher by pushkey and user localpart.
|
|
||||||
func (s *pushersStatements) deletePusher(
|
|
||||||
ctx context.Context, txn *sql.Tx, pushkey, localpart string,
|
|
||||||
) error {
|
|
||||||
stmt := sqlutil.TxStmt(txn, s.deletePusherStmt)
|
|
||||||
_, err := stmt.ExecContext(ctx, pushkey, localpart)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,11 +137,15 @@ func (s *pushersStatements) selectPushersByLocalpart(
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var pusher api.Pusher
|
var pusher api.Pusher
|
||||||
|
var sessionid sql.NullInt64
|
||||||
var pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format sql.NullString
|
var pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format sql.NullString
|
||||||
err = rows.Scan(&pushkey, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &lang, &url, &format)
|
err = rows.Scan(&sessionid, &pushkey, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &lang, &url, &format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pushers, err
|
return pushers, err
|
||||||
}
|
}
|
||||||
|
if sessionid.Valid {
|
||||||
|
pusher.SessionID = sessionid.Int64
|
||||||
|
}
|
||||||
if pushkey.Valid {
|
if pushkey.Valid {
|
||||||
pusher.PushKey = pushkey.String
|
pusher.PushKey = pushkey.String
|
||||||
}
|
}
|
||||||
|
@ -171,6 +178,7 @@ func (s *pushersStatements) selectPushersByLocalpart(
|
||||||
pushers = append(pushers, pusher)
|
pushers = append(pushers, pusher)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("🤓 Database returned %d pushers", len(pushers))
|
||||||
return pushers, rows.Err()
|
return pushers, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,12 +186,16 @@ func (s *pushersStatements) selectPusherByPushkey(
|
||||||
ctx context.Context, localpart, pushkey string,
|
ctx context.Context, localpart, pushkey string,
|
||||||
) (*api.Pusher, error) {
|
) (*api.Pusher, error) {
|
||||||
var pusher api.Pusher
|
var pusher api.Pusher
|
||||||
var id, key, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format sql.NullString
|
var sessionid sql.NullInt64
|
||||||
|
var key, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format sql.NullString
|
||||||
|
|
||||||
stmt := s.selectPusherByPushkeyStmt
|
stmt := s.selectPusherByPushkeyStmt
|
||||||
err := stmt.QueryRowContext(ctx, localpart, pushkey).Scan(&id, &key, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &lang, &url, &format)
|
err := stmt.QueryRowContext(ctx, localpart, pushkey).Scan(&sessionid, &key, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &lang, &url, &format)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
if sessionid.Valid {
|
||||||
|
pusher.SessionID = sessionid.Int64
|
||||||
|
}
|
||||||
if key.Valid {
|
if key.Valid {
|
||||||
pusher.PushKey = key.String
|
pusher.PushKey = key.String
|
||||||
}
|
}
|
||||||
|
@ -217,3 +229,20 @@ func (s *pushersStatements) selectPusherByPushkey(
|
||||||
|
|
||||||
return &pusher, err
|
return &pusher, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *pushersStatements) updatePusher(
|
||||||
|
ctx context.Context, txn *sql.Tx, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
||||||
|
) error {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.updatePusherStmt)
|
||||||
|
_, err := stmt.ExecContext(ctx, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart, pushkey)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// deletePusher removes a single pusher by pushkey and user localpart.
|
||||||
|
func (s *pushersStatements) deletePusher(
|
||||||
|
ctx context.Context, txn *sql.Tx, appid, pushkey, localpart string,
|
||||||
|
) error {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.deletePusherStmt)
|
||||||
|
_, err := stmt.ExecContext(ctx, appid, pushkey, localpart)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Database represents a pusher database.
|
// Database represents a pusher database.
|
||||||
|
@ -56,9 +57,10 @@ func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) CreatePusher(
|
func (d *Database) CreatePusher(
|
||||||
ctx context.Context, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
ctx context.Context, session_id int64,
|
||||||
|
pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
||||||
) error {
|
) error {
|
||||||
return d.pushers.insertPusher(ctx, nil, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart)
|
return d.pushers.insertPusher(ctx, nil, session_id, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPushersByLocalpart returns the pushers matching the given localpart.
|
// GetPushersByLocalpart returns the pushers matching the given localpart.
|
||||||
|
@ -75,16 +77,28 @@ func (d *Database) GetPusherByPushkey(
|
||||||
return d.pushers.selectPusherByPushkey(ctx, localpart, pushkey)
|
return d.pushers.selectPusherByPushkey(ctx, localpart, pushkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdatePusher updates the given pusher with the display name.
|
||||||
|
// Returns SQL error if there are problems and nil on success.
|
||||||
|
func (d *Database) UpdatePusher(
|
||||||
|
ctx context.Context, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
||||||
|
) error {
|
||||||
|
return sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error {
|
||||||
|
return d.pushers.updatePusher(ctx, txn, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// RemovePusher revokes a pusher by deleting the entry in the database
|
// RemovePusher revokes a pusher by deleting the entry in the database
|
||||||
// matching with the given pushkey and user ID localpart.
|
// matching with the given pushkey and user ID localpart.
|
||||||
// If the pusher doesn't exist, it will not return an error
|
// If the pusher doesn't exist, it will not return an error
|
||||||
// If something went wrong during the deletion, it will return the SQL error.
|
// If something went wrong during the deletion, it will return the SQL error.
|
||||||
func (d *Database) RemovePusher(
|
func (d *Database) RemovePusher(
|
||||||
ctx context.Context, pushkey, localpart string,
|
ctx context.Context, appid, pushkey, localpart string,
|
||||||
) error {
|
) error {
|
||||||
return sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error {
|
return sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error {
|
||||||
if err := d.pushers.deletePusher(ctx, txn, pushkey, localpart); err != sql.ErrNoRows {
|
if err := d.pushers.deletePusher(ctx, txn, appid, pushkey, localpart); err != sql.ErrNoRows {
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
logrus.WithError(err).Debug("RemovePusher Error")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/userutil"
|
"github.com/matrix-org/dendrite/clientapi/userutil"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
@ -28,32 +29,36 @@ import (
|
||||||
const pushersSchema = `
|
const pushersSchema = `
|
||||||
-- Stores data about pushers.
|
-- Stores data about pushers.
|
||||||
CREATE TABLE IF NOT EXISTS pusher_pushers (
|
CREATE TABLE IF NOT EXISTS pusher_pushers (
|
||||||
localpart TEXT PRIMARY KEY,
|
localpart TEXT,
|
||||||
pushkey VARCHAR(512),
|
session_id BIGINT,
|
||||||
|
profile_tag TEXT,
|
||||||
kind TEXT,
|
kind TEXT,
|
||||||
app_id VARCHAR(64),
|
app_id VARCHAR(64),
|
||||||
app_display_name TEXT,
|
app_display_name TEXT,
|
||||||
device_display_name TEXT,
|
device_display_name TEXT,
|
||||||
profile_tag TEXT,
|
pushkey VARCHAR(512),
|
||||||
lang TEXT,
|
lang TEXT,
|
||||||
url TEXT,
|
url TEXT,
|
||||||
format TEXT,
|
format TEXT,
|
||||||
|
|
||||||
UNIQUE (localpart, pushkey)
|
UNIQUE (app_id, pushkey, localpart)
|
||||||
);
|
);
|
||||||
`
|
`
|
||||||
const insertPusherSQL = "" +
|
const insertPusherSQL = "" +
|
||||||
"INSERT INTO pusher_pushers (localpart, pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format)" +
|
"INSERT INTO pusher_pushers (localpart, session_id, pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format)" +
|
||||||
" VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9. $10)"
|
" VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)"
|
||||||
|
|
||||||
const selectPushersByLocalpartSQL = "" +
|
const selectPushersByLocalpartSQL = "" +
|
||||||
"SELECT pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format FROM pusher_pushers WHERE localpart = $1"
|
"SELECT session_id, pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format FROM pusher_pushers WHERE localpart = $1"
|
||||||
|
|
||||||
const selectPusherByPushkeySQL = "" +
|
const selectPusherByPushkeySQL = "" +
|
||||||
"SELECT pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format FROM pusher_pushers WHERE localpart = $1 AND pushkey = $2"
|
"SELECT session_id, pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, lang, url, format FROM pusher_pushers WHERE localpart = $1 AND pushkey = $2"
|
||||||
|
|
||||||
|
const updatePusherSQL = "" +
|
||||||
|
"UPDATE pusher_pushers SET kind = $1, app_id = $2, app_display_name = $3, device_display_name = $4, profile_tag = $5, lang = $6, url = $7, format = $8 WHERE localpart = $9 AND pushkey = $10"
|
||||||
|
|
||||||
const deletePusherSQL = "" +
|
const deletePusherSQL = "" +
|
||||||
"DELETE FROM pusher_pushers WHERE pushkey = $1 AND localpart = $2"
|
"DELETE FROM pusher_pushers WHERE app_id = $1 AND pushkey = $2 AND localpart = $3"
|
||||||
|
|
||||||
type pushersStatements struct {
|
type pushersStatements struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
|
@ -61,6 +66,7 @@ type pushersStatements struct {
|
||||||
insertPusherStmt *sql.Stmt
|
insertPusherStmt *sql.Stmt
|
||||||
selectPushersByLocalpartStmt *sql.Stmt
|
selectPushersByLocalpartStmt *sql.Stmt
|
||||||
selectPusherByPushkeyStmt *sql.Stmt
|
selectPusherByPushkeyStmt *sql.Stmt
|
||||||
|
updatePusherStmt *sql.Stmt
|
||||||
deletePusherStmt *sql.Stmt
|
deletePusherStmt *sql.Stmt
|
||||||
serverName gomatrixserverlib.ServerName
|
serverName gomatrixserverlib.ServerName
|
||||||
}
|
}
|
||||||
|
@ -82,6 +88,9 @@ func (s *pushersStatements) prepare(db *sql.DB, writer sqlutil.Writer, server go
|
||||||
if s.selectPusherByPushkeyStmt, err = db.Prepare(selectPusherByPushkeySQL); err != nil {
|
if s.selectPusherByPushkeyStmt, err = db.Prepare(selectPusherByPushkeySQL); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if s.updatePusherStmt, err = db.Prepare(updatePusherSQL); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
if s.deletePusherStmt, err = db.Prepare(deletePusherSQL); err != nil {
|
if s.deletePusherStmt, err = db.Prepare(deletePusherSQL); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -93,10 +102,12 @@ func (s *pushersStatements) prepare(db *sql.DB, writer sqlutil.Writer, server go
|
||||||
// Returns an error if the user already has a pusher with the given pusher pushkey.
|
// Returns an error if the user already has a pusher with the given pusher pushkey.
|
||||||
// Returns nil error success.
|
// Returns nil error success.
|
||||||
func (s *pushersStatements) insertPusher(
|
func (s *pushersStatements) insertPusher(
|
||||||
ctx context.Context, txn *sql.Tx, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
ctx context.Context, txn *sql.Tx, session_id int64,
|
||||||
|
pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
||||||
) error {
|
) error {
|
||||||
stmt := sqlutil.TxStmt(txn, s.insertPusherStmt)
|
stmt := sqlutil.TxStmt(txn, s.insertPusherStmt)
|
||||||
_, err := stmt.ExecContext(ctx, localpart, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format)
|
_, err := stmt.ExecContext(ctx, localpart, session_id, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format)
|
||||||
|
logrus.Debugf("🥳 Created pusher %d", session_id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,12 +122,17 @@ func (s *pushersStatements) selectPushersByLocalpart(
|
||||||
}
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
|
logrus.Debug("Next pusher row...")
|
||||||
var pusher api.Pusher
|
var pusher api.Pusher
|
||||||
|
var sessionid sql.NullInt64
|
||||||
var pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format sql.NullString
|
var pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format sql.NullString
|
||||||
err = rows.Scan(&pushkey, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &lang, &url, &format)
|
err = rows.Scan(&sessionid, &pushkey, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &lang, &url, &format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pushers, err
|
return pushers, err
|
||||||
}
|
}
|
||||||
|
if sessionid.Valid {
|
||||||
|
pusher.SessionID = sessionid.Int64
|
||||||
|
}
|
||||||
if pushkey.Valid {
|
if pushkey.Valid {
|
||||||
pusher.PushKey = pushkey.String
|
pusher.PushKey = pushkey.String
|
||||||
}
|
}
|
||||||
|
@ -149,6 +165,7 @@ func (s *pushersStatements) selectPushersByLocalpart(
|
||||||
pushers = append(pushers, pusher)
|
pushers = append(pushers, pusher)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("🤓 Database returned %d pushers", len(pushers))
|
||||||
return pushers, nil
|
return pushers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,10 +211,18 @@ func (s *pushersStatements) selectPusherByPushkey(
|
||||||
return &pusher, err
|
return &pusher, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pushersStatements) deletePusher(
|
func (s *pushersStatements) updatePusher(
|
||||||
ctx context.Context, txn *sql.Tx, id, localpart string,
|
ctx context.Context, txn *sql.Tx, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
||||||
) error {
|
) error {
|
||||||
stmt := sqlutil.TxStmt(txn, s.deletePusherStmt)
|
stmt := sqlutil.TxStmt(txn, s.updatePusherStmt)
|
||||||
_, err := stmt.ExecContext(ctx, id, localpart)
|
_, err := stmt.ExecContext(ctx, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart, pushkey)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *pushersStatements) deletePusher(
|
||||||
|
ctx context.Context, txn *sql.Tx, appid, pushkey, localpart string,
|
||||||
|
) error {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.deletePusherStmt)
|
||||||
|
_, err := stmt.ExecContext(ctx, appid, pushkey, localpart)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
@ -58,9 +59,10 @@ func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) CreatePusher(
|
func (d *Database) CreatePusher(
|
||||||
ctx context.Context, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
ctx context.Context, session_id int64,
|
||||||
|
pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
||||||
) error {
|
) error {
|
||||||
return d.pushers.insertPusher(ctx, nil, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart)
|
return d.pushers.insertPusher(ctx, nil, session_id, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPushersByLocalpart returns the pushers matching the given localpart.
|
// GetPushersByLocalpart returns the pushers matching the given localpart.
|
||||||
|
@ -77,16 +79,29 @@ func (d *Database) GetPusherByPushkey(
|
||||||
return d.pushers.selectPusherByPushkey(ctx, pushkey, localpart)
|
return d.pushers.selectPusherByPushkey(ctx, pushkey, localpart)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdatePusher updates the given device with the display name.
|
||||||
|
// Returns SQL error if there are problems and nil on success.
|
||||||
|
func (d *Database) UpdatePusher(
|
||||||
|
ctx context.Context, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart string,
|
||||||
|
) error {
|
||||||
|
return d.writer.Do(d.db, nil, func(txn *sql.Tx) error {
|
||||||
|
return d.pushers.updatePusher(ctx, txn, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, lang, url, format, localpart)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// RemovePusher revokes a pusher by deleting the entry in the database
|
// RemovePusher revokes a pusher by deleting the entry in the database
|
||||||
// matching with the given pusher pushkey and user ID localpart.
|
// matching with the given pusher pushkey and user ID localpart.
|
||||||
// If the pusher doesn't exist, it will not return an error
|
// If the pusher doesn't exist, it will not return an error
|
||||||
// If something went wrong during the deletion, it will return the SQL error.
|
// If something went wrong during the deletion, it will return the SQL error.
|
||||||
func (d *Database) RemovePusher(
|
func (d *Database) RemovePusher(
|
||||||
ctx context.Context, pushkey, localpart string,
|
ctx context.Context, appid, pushkey, localpart string,
|
||||||
) error {
|
) error {
|
||||||
return d.writer.Do(d.db, nil, func(txn *sql.Tx) error {
|
return d.writer.Do(d.db, nil, func(txn *sql.Tx) error {
|
||||||
if err := d.pushers.deletePusher(ctx, txn, pushkey, localpart); err != sql.ErrNoRows {
|
if err := d.pushers.deletePusher(ctx, txn, appid, pushkey, localpart); err != sql.ErrNoRows {
|
||||||
|
logrus.WithError(err).Debug("RemovePusher Yes Error")
|
||||||
return err
|
return err
|
||||||
|
} else {
|
||||||
|
logrus.WithError(err).Debug("RemovePusher No Error")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue