From 40baacf020dd92fc8a31b272e9e0709cc2ab6f28 Mon Sep 17 00:00:00 2001 From: Dan Peleg Date: Sat, 24 Apr 2021 00:02:00 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20GET=20/=5Fmatrix/client/r0/pushers?= =?UTF-8?q?=20(=F0=9F=90=98postgres=20+=20sqlite=C2=B3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clientapi/routing/pusher.go | 9 ++- clientapi/routing/routing.go | 5 ++ userapi/api/api.go | 1 - .../storage/pushers/postgres/pushers_table.go | 42 ++++++------ userapi/storage/pushers/postgres/storage.go | 3 +- .../storage/pushers/sqlite3/pushers_table.go | 65 +++++++++++++------ userapi/storage/pushers/sqlite3/storage.go | 3 +- 7 files changed, 80 insertions(+), 48 deletions(-) diff --git a/clientapi/routing/pusher.go b/clientapi/routing/pusher.go index 902ad7c9..c657497a 100644 --- a/clientapi/routing/pusher.go +++ b/clientapi/routing/pusher.go @@ -17,6 +17,7 @@ package routing import ( "net/http" + "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/userapi/api" userapi "github.com/matrix-org/dendrite/userapi/api" @@ -25,7 +26,6 @@ import ( // https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-pushers type pusherJSON struct { - PusherID string `json:"pusher_id"` PushKey string `json:"pushkey"` Kind string `json:"kind"` AppID string `json:"app_id"` @@ -45,13 +45,13 @@ type pusherDataJSON struct { Format string `json:"format"` } -// GetPushersByLocalpart handles /pushers +// GetPushersByLocalpart handles /_matrix/client/r0/pushers func GetPushersByLocalpart( - req *http.Request, userAPI userapi.UserInternalAPI, pusher *api.Pusher, + req *http.Request, userAPI userapi.UserInternalAPI, device *api.Device, ) util.JSONResponse { var queryRes userapi.QueryPushersResponse err := userAPI.QueryPushers(req.Context(), &userapi.QueryPushersRequest{ - UserID: pusher.UserID, + UserID: device.UserID, }, &queryRes) if err != nil { util.GetLogger(req.Context()).WithError(err).Error("QueryPushers failed") @@ -62,7 +62,6 @@ func GetPushersByLocalpart( for _, pusher := range queryRes.Pushers { res.Pushers = append(res.Pushers, pusherJSON{ - PusherID: pusher.ID, PushKey: pusher.PushKey, Kind: pusher.Kind, AppID: pusher.AppID, diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index 9f980e0a..b8b7c978 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -803,6 +803,11 @@ func Setup( }), ).Methods(http.MethodPost, http.MethodOptions) + r0mux.Handle("/pushers", + httputil.MakeAuthAPI("get_pushers", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { + return GetPushersByLocalpart(req, userAPI, device) + }), + ).Methods(http.MethodGet, http.MethodOptions) // Stub implementations for sytest r0mux.Handle("/events", httputil.MakeExternalAPI("events", func(req *http.Request) util.JSONResponse { diff --git a/userapi/api/api.go b/userapi/api/api.go index 642225c2..c70fb018 100644 --- a/userapi/api/api.go +++ b/userapi/api/api.go @@ -283,7 +283,6 @@ type Device struct { // Pusher represents a push notification subscriber type Pusher struct { - ID string UserID string PushKey string Kind string diff --git a/userapi/storage/pushers/postgres/pushers_table.go b/userapi/storage/pushers/postgres/pushers_table.go index 872b27dd..a376f6ba 100644 --- a/userapi/storage/pushers/postgres/pushers_table.go +++ b/userapi/storage/pushers/postgres/pushers_table.go @@ -30,28 +30,32 @@ const pushersSchema = ` CREATE TABLE IF NOT EXISTS pusher_pushers ( -- The Matrix user ID localpart for this pusher localpart TEXT NOT NULL PRIMARY KEY, - -- The push key for this pusher - pushkey TEXT, - -- The pusher kind + -- This is a unique identifier for this pusher. See /set for more detail. Max length, 512 bytes. + pushkey VARCHAR(512) NOT NULL, + -- The kind of pusher. "http" is a pusher that sends HTTP pokes. kind TEXT, - -- The pusher Application ID - app_id TEXT, - -- The pusher application display name, human friendlier than app_id and updatable + -- This is a reverse-DNS style identifier for the application. Max length, 64 chars. + app_id VARCHAR(64), + -- A string that will allow the user to identify what application owns this pusher. app_display_name TEXT, - -- The pusher device display name, + -- A string that will allow the user to identify what device owns this pusher. device_display_name TEXT, - -- The pusher profile tag, + -- This string determines which set of device specific rules this pusher executes. profile_tag TEXT, - -- The pusher preferred language, - language TEXT, + -- The preferred language for receiving notifications (e.g. 'en' or 'en-US') + lang TEXT, + -- Required if kind is http. The URL to use to send notifications to. + url TEXT, + -- The format to use when sending notifications to the Push Gateway. + format TEXT, ); -- Pusher IDs must be unique for a given user. -CREATE UNIQUE INDEX IF NOT EXISTS pusher_localpart_id_idx ON pusher_pushers(localpart, pusher_id); +CREATE UNIQUE INDEX IF NOT EXISTS pusher_localpart_pushkey_idx ON pusher_pushers(localpart, pushkey); ` const selectPushersByLocalpartSQL = "" + - "SELECT pusher_id, display_name, last_seen_ts, ip, user_agent FROM pusher_pushers WHERE localpart = $1 AND pusher_id != $2" + "SELECT pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, language FROM pusher_pushers WHERE localpart = $1" type pushersStatements struct { selectPushersByLocalpartStmt *sql.Stmt @@ -67,15 +71,18 @@ func (s *pushersStatements) prepare(db *sql.DB, server gomatrixserverlib.ServerN if s.selectPushersByLocalpartStmt, err = db.Prepare(selectPushersByLocalpartSQL); err != nil { return } + if s.selectPushersByPushkeyStmt, err = db.Prepare(selectPushersByPushkeySQL); err != nil { + return + } s.serverName = server return } func (s *pushersStatements) selectPushersByLocalpart( - ctx context.Context, txn *sql.Tx, localpart, exceptPusherID string, + ctx context.Context, txn *sql.Tx, localpart string, ) ([]api.Pusher, error) { pushers := []api.Pusher{} - rows, err := sqlutil.TxStmt(txn, s.selectPushersByLocalpartStmt).QueryContext(ctx, localpart, exceptPusherID) + rows, err := sqlutil.TxStmt(txn, s.selectPushersByLocalpartStmt).QueryContext(ctx, localpart) if err != nil { return pushers, err @@ -84,14 +91,11 @@ func (s *pushersStatements) selectPushersByLocalpart( for rows.Next() { var pusher api.Pusher - var id, pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, language, url, format sql.NullString - err = rows.Scan(&id, &pushkey, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &language, &url, &format) + var pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, language, url, format sql.NullString + err = rows.Scan(&pushkey, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &language, &url, &format) if err != nil { return pushers, err } - if id.Valid { - pusher.ID = id.String - } if pushkey.Valid { pusher.PushKey = pushkey.String } diff --git a/userapi/storage/pushers/postgres/storage.go b/userapi/storage/pushers/postgres/storage.go index 4d96afec..76f0f89f 100644 --- a/userapi/storage/pushers/postgres/storage.go +++ b/userapi/storage/pushers/postgres/storage.go @@ -59,5 +59,6 @@ func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserver func (d *Database) GetPushersByLocalpart( ctx context.Context, localpart string, ) ([]api.Pusher, error) { - return d.pushers.selectPushersByLocalpart(ctx, nil, localpart, "") + return d.pushers.selectPushersByLocalpart(ctx, nil, localpart) +} } diff --git a/userapi/storage/pushers/sqlite3/pushers_table.go b/userapi/storage/pushers/sqlite3/pushers_table.go index 8ec4234c..374112e6 100644 --- a/userapi/storage/pushers/sqlite3/pushers_table.go +++ b/userapi/storage/pushers/sqlite3/pushers_table.go @@ -31,21 +31,21 @@ const pushersSchema = ` -- Stores data about pushers. CREATE TABLE IF NOT EXISTS pusher_pushers ( - access_token TEXT PRIMARY KEY, - session_id INTEGER, - pusher_id TEXT , - localpart TEXT , - created_ts BIGINT, - display_name TEXT, - last_seen_ts BIGINT, - ip TEXT, - user_agent TEXT, + pushkey VARCHAR(512) PRIMARY KEY, + kind TEXT , + app_id VARCHAR(64) , + app_display_name TEXT, + device_display_name TEXT, + profile_tag TEXT, + language TEXT, + url TEXT, + format TEXT, - UNIQUE (localpart, pusher_id) + UNIQUE (localpart, pushkey) ); ` const selectPushersByLocalpartSQL = "" + - "SELECT pusher_id, display_name, last_seen_ts, ip, user_agent FROM pusher_pushers WHERE localpart = $1 AND pusher_id != $2" + "SELECT pushkey, kind, app_id, app_display_name, device_display_name, profile_tag, language FROM pusher_pushers WHERE localpart = $1" type pushersStatements struct { db *sql.DB @@ -70,29 +70,52 @@ func (s *pushersStatements) prepare(db *sql.DB, writer sqlutil.Writer, server go } func (s *pushersStatements) selectPushersByLocalpart( - ctx context.Context, txn *sql.Tx, localpart, exceptPusherID string, + ctx context.Context, txn *sql.Tx, localpart string, ) ([]api.Pusher, error) { pushers := []api.Pusher{} - rows, err := sqlutil.TxStmt(txn, s.selectPushersByLocalpartStmt).QueryContext(ctx, localpart, exceptPusherID) + rows, err := sqlutil.TxStmt(txn, s.selectPushersByLocalpartStmt).QueryContext(ctx, localpart) if err != nil { return pushers, err } for rows.Next() { - var dev api.Pusher - var lastseents sql.NullInt64 - var id, displayname, ip, useragent sql.NullString - err = rows.Scan(&id, &displayname, &lastseents, &ip, &useragent) + var pusher api.Pusher + var pushkey, kind, appid, appdisplayname, devicedisplayname, profiletag, language, url, format sql.NullString + err = rows.Scan(&pushkey, &kind, &appid, &appdisplayname, &devicedisplayname, &profiletag, &language, &url, &format) if err != nil { return pushers, err } - if id.Valid { - dev.ID = id.String + if pushkey.Valid { + pusher.PushKey = pushkey.String + } + if kind.Valid { + pusher.Kind = kind.String + } + if appid.Valid { + pusher.AppID = appid.String + } + if appdisplayname.Valid { + pusher.AppDisplayName = appdisplayname.String + } + if devicedisplayname.Valid { + pusher.DeviceDisplayName = devicedisplayname.String + } + if profiletag.Valid { + pusher.ProfileTag = profiletag.String + } + if language.Valid { + pusher.Language = language.String + } + if url.Valid && format.Valid { + pusher.Data = api.PusherData{ + URL: url.String, + Format: format.String, + } } - dev.UserID = userutil.MakeUserID(localpart, s.serverName) - pushers = append(pushers, dev) + pusher.UserID = userutil.MakeUserID(localpart, s.serverName) + pushers = append(pushers, pusher) } return pushers, nil diff --git a/userapi/storage/pushers/sqlite3/storage.go b/userapi/storage/pushers/sqlite3/storage.go index ea20df19..8684f54b 100644 --- a/userapi/storage/pushers/sqlite3/storage.go +++ b/userapi/storage/pushers/sqlite3/storage.go @@ -61,5 +61,6 @@ func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserver func (d *Database) GetPushersByLocalpart( ctx context.Context, localpart string, ) ([]api.Pusher, error) { - return d.pushers.selectPushersByLocalpart(ctx, nil, localpart, "") + return d.pushers.selectPushersByLocalpart(ctx, nil, localpart) +} }